def decode_kdbg(self, vals): """Decoder the KDBG block using the provided magic values and the algorithm reversed from the Windows kernel file.""" block_encoded, kdbg_block, wait_never, wait_always = vals # just take the maximum. if we decode a tiny bit of # extra data in some cases, its totally fine. kdbg_size = max(self.unique_sizes()) buffer = "" entries = obj.Object("Array", targetType="unsigned long long", count=kdbg_size / 8, offset=kdbg_block, vm=self.obj_vm) for entry in entries: low_byte = (wait_never & 0xFFFFFFFF) & 0xFF entry = patchguard.rol(entry ^ wait_never, low_byte) swap_xor = block_encoded.obj_offset | 0xFFFF000000000000 entry = patchguard.bswap(entry ^ swap_xor) buffer += struct.pack("Q", entry ^ wait_always) return buffer
def Dpc(self): vm = self.obj_vm profile = vm.profile bits = profile.metadata.get("memory_model") if bits == "32bit": return self.m("Dpc") # cycle through the parents until we reach the top parent = self.obj_parent while parent and parent.obj_name != "_KDDEBUGGER_DATA64": parent = parent.obj_parent if not parent: return obj.NoneObject("Parent is not a KDBG structure") # test if the patchguard magic is already available to us if (not hasattr(parent, 'wait_always') or not hasattr(parent, 'wait_never')): # this scans for the patchguard magic by indirectly # finding the KdCopyDataBlock function kdbg = win8_kdbg.VolatilityKDBG("", offset = 0, vm = vm).v() if not kdbg: return obj.NoneObject("Cannot find KDBG structure") # transfer the attributes to our parent parent.newattr('wait_never', kdbg.wait_never) parent.newattr('wait_always', kdbg.wait_always) dpc = self.m("Dpc").v() decoded = patchguard.bswap(patchguard.rol(dpc ^ \ parent.wait_never, parent.wait_never & 0xFF) ^ \ self.obj_offset) ^ parent.wait_always return obj.Object("_KDPC", offset = decoded, vm = vm)
def decode_kdbg(self, vals): """Decoder the KDBG block using the provided magic values and the algorithm reversed from the Windows kernel file.""" block_encoded, kdbg_block, wait_never, wait_always = vals header = obj.VolMagic(self.obj_vm).KDBGHeader.v() kdbg_size = struct.unpack("<H", header[-2:])[0] buffer = "" entries = obj.Object("Array", targetType = "unsigned long long", count = kdbg_size / 8, offset = kdbg_block, vm = self.obj_vm) for entry in entries: low_byte = (wait_never & 0xFFFFFFFF) & 0xFF entry = patchguard.rol(entry ^ wait_never, low_byte) swap_xor = block_encoded.obj_offset | 0xFFFF000000000000 entry = patchguard.bswap(entry ^ swap_xor) buffer += struct.pack("Q", entry ^ wait_always) return buffer
def decode_kdbg(self, vals): """Decoder the KDBG block using the provided magic values and the algorithm reversed from the Windows kernel file.""" block_encoded, kdbg_block, wait_never, wait_always = vals header = obj.VolMagic(self.obj_vm).KDBGHeader.v() kdbg_size = struct.unpack("<H", header[-2:])[0] buffer = "" entries = obj.Object("Array", targetType="unsigned long long", count=kdbg_size / 8, offset=kdbg_block, vm=self.obj_vm) for entry in entries: low_byte = (wait_never & 0xFFFFFFFF) & 0xFF entry = patchguard.rol(entry ^ wait_never, low_byte) swap_xor = block_encoded.obj_offset | 0xFFFF000000000000 entry = patchguard.bswap(entry ^ swap_xor) buffer += struct.pack("Q", entry ^ wait_always) return buffer
def decode_kdbg(self, vals): """Decoder the KDBG block using the provided magic values and the algorithm reversed from the Windows kernel file.""" block_encoded, kdbg_block, wait_never, wait_always = vals # just take the maximum. if we decode a tiny bit of # extra data in some cases, its totally fine. kdbg_size = max(self.unique_sizes()) buffer = "" entries = obj.Object("Array", targetType = "unsigned long long", count = kdbg_size / 8, offset = kdbg_block, vm = self.obj_vm) for entry in entries: low_byte = (wait_never & 0xFFFFFFFF) & 0xFF entry = patchguard.rol(entry ^ wait_never, low_byte) swap_xor = block_encoded.obj_offset | 0xFFFF000000000000 entry = patchguard.bswap(entry ^ swap_xor) buffer += struct.pack("Q", entry ^ wait_always) return buffer