def testSetValue(self): pykd.setByte(target.module.ullValuePlace, pykd.ptrByte(target.module.bigValue)) self.assertEqual(pykd.ptrByte(target.module.bigValue), pykd.ptrByte(target.module.ullValuePlace)) pykd.setWord(target.module.ullValuePlace, pykd.ptrWord(target.module.bigValue)) self.assertEqual(pykd.ptrWord(target.module.bigValue), pykd.ptrWord(target.module.ullValuePlace)) pykd.setDWord(target.module.ullValuePlace, pykd.ptrDWord(target.module.bigValue)) self.assertEqual(pykd.ptrDWord(target.module.bigValue), pykd.ptrDWord(target.module.ullValuePlace)) pykd.setQWord(target.module.ullValuePlace, pykd.ptrQWord(target.module.bigValue)) self.assertEqual(pykd.ptrQWord(target.module.bigValue), pykd.ptrQWord(target.module.ullValuePlace)) pykd.setSignByte(target.module.ullValuePlace, -128) self.assertEqual(-128, pykd.ptrSignByte(target.module.ullValuePlace)) pykd.setSignWord(target.module.ullValuePlace, pykd.ptrSignWord(target.module.bigValue)) self.assertEqual(pykd.ptrSignWord(target.module.bigValue), pykd.ptrSignWord(target.module.ullValuePlace)) pykd.setSignDWord(target.module.ullValuePlace, pykd.ptrSignDWord(target.module.bigValue)) self.assertEqual(pykd.ptrSignDWord(target.module.bigValue), pykd.ptrSignDWord(target.module.ullValuePlace)) pykd.setSignQWord(target.module.ullValuePlace, pykd.ptrSignQWord(target.module.bigValue)) self.assertEqual(pykd.ptrSignQWord(target.module.bigValue), pykd.ptrSignQWord(target.module.ullValuePlace)) pykd.setFloat(target.module.floatValuePlace, pykd.ptrFloat(target.module.floatValue)) self.assertEqual(pykd.ptrFloat(target.module.floatValue), pykd.ptrFloat(target.module.floatValuePlace)) pykd.setDouble(target.module.doubleValuePlace, pykd.ptrDouble(target.module.doubleValue)) self.assertEqual(pykd.ptrDouble(target.module.doubleValue), pykd.ptrDouble(target.module.doubleValuePlace))
def get_value(symbol): global cache_values k = symbol if k not in cache_values: mozglue = pykd.module('mozglue') symbol_addr = mozglue.offset(symbol) cache_values[k] = pykd.ptrDWord(symbol_addr) return cache_values[k]
def testPtrRead( self ): self.assertEqual( 0x80, pykd.ptrByte( target.module.g_bigValue ) ) self.assertEqual( 0x8080, pykd.ptrWord( target.module.g_bigValue ) ) self.assertEqual( 0x80808080, pykd.ptrDWord( target.module.g_bigValue ) ) self.assertEqual( 0x8080808080808080, pykd.ptrQWord( target.module.g_bigValue ) ) self.assertEqual( -128, pykd.ptrSignByte( target.module.g_bigValue ) ) self.assertEqual( -32640, pykd.ptrSignWord( target.module.g_bigValue ) ) self.assertEqual( -2139062144, pykd.ptrSignDWord( target.module.g_bigValue ) ) self.assertEqual( -9187201950435737472, pykd.ptrSignQWord( target.module.g_bigValue ) )
def rewrite_filename(): """ Overwrite the terminating NUL-byte for the first filename. This effectively concatenates the first two filenames. """ this = pykd.reg("ecx") buf = pykd.ptrPtr(this + 1036) buf_size = pykd.ptrDWord(this + 1040) files = list(Path().iterdir()) files_hdr = len(files) * 4 * 2 files_len = files_hdr + sum(len(x.name) + 1 for x in files) if files_len == buf_size: names = pykd.loadBytes(buf + files_hdr, buf_size - files_hdr) for i, byte in enumerate(names): if byte == 0: pykd.writeBytes(buf + files_hdr + i, [0x41]) break
def main(): usage = "!py %prog -o <option> -s <size>" usage += "\nExample: !py %prog -l" usage += "\nExample: !py %prog -o find_ub" usage += "\nExample: !py %prog -o find_ub -s 0x6c" parser = optparse.OptionParser(usage=usage) parser.add_option("-o", type="string", action="store", dest="option", help="The option to specify") parser.add_option("-s", type="int", action="store", dest="size", help="The size of the object to look for") parser.add_option("-l", action="store_true", dest="list", help="List the options available") (options, args) = parser.parse_args() print(banner()) if len(sys.argv) < 2: parser.print_help() sys.exit(1) if options.list: print("(+) options available:\r\n") print("(1) 'find_ub' - find uninitialized buffers") print("(2) 'find_ob' - find objects via vtables") sys.exit(1) available_options = ["find_ub", "find_ob"] opt = options.option.lower() if opt in available_options: f = foxit_js_bridge() if "find_ub" == opt: for a in f.allocs: try: # TODO: add a check here for page heap and alert user if not enabled if pykd.ptrDWord(a) == 0xc0c0c0c0: heap_check = pykd.dbgCommand("!heap -p -a 0x%08x" % a) if "busy" in heap_check: print("(+) found uninitialized chunk: 0x%08x" % a) if options.size: size = "%x -" % options.size if size in heap_check: print(heap_check) print(pykd.dbgCommand("dd 0x%08x" % a)) else: print(heap_check) print(pykd.dbgCommand("dd 0x%08x" % a)) finally: pass elif "find_ob" in opt: for a in f.allocs: try: # Turns out that most foxit objects have offset +0x10 set to -1 # TODO: patch this to check for vftables if pykd.ptrDWord(a + 0x10) == 0xffffffff: heap_check = pykd.dbgCommand("!heap -p -a 0x%08x" % a) if "busy" in heap_check: print("(+) found uninitialized chunk: 0x%08x" % a) if options.size: size = "%x -" % options.size if size in heap_check: print(heap_check) print(pykd.dbgCommand("dd 0x%08x" % a)) else: print(heap_check) print(pykd.dbgCommand("dd 0x%08x" % a)) finally: pass print("(+) done!")
def get_value(symbol): mozglue = pykd.module('mozglue') symbol_addr = mozglue.offset(symbol) return pykd.ptrDWord(symbol_addr)
def inspectIatEatHook(modulelist, eprocessaddr=None, targetmodulebase=None): try: if eprocessaddr: cmdline='.process /P /r %x' % eprocessaddr r=pykd.dbgCommand(cmdline) importfunctable=[] exportfunctable={} for mo in modulelist: modulepath=mo.filepath modulename=mo.name.lower() s=os.path.splitext(modulename) if len(s)>=2: modulebasename=s[0] else: modulebasename=modulename baseaddr=mo.baseaddr if not os.path.exists(modulepath): continue elif not baseaddr: continue filedata=open(modulepath, 'rb').read() pe = pefile.PE(data=filedata, fast_load=True) if pe.DOS_HEADER.e_magic!=0X5A4D or pe.NT_HEADERS.Signature!=0x4550: raise Exception("%s is not a pe file" % modulepath) pe.parse_data_directories(pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_EXPORT']) if hasattr(pe,'DIRECTORY_ENTRY_EXPORT'): exporttable=pe.DIRECTORY_ENTRY_EXPORT for i in exporttable.symbols: funcoffset=pe.get_rva_from_offset(i.address_offset) funcaddr=baseaddr+i.address #print hex(baseaddr+funcoffset) ,hex(funcaddr) info=ExportFuncInfo(i.name, modulename, baseaddr, funcaddr, funcoffset, i.ordinal, i.forwarder) exportfunctable[funcaddr]=info pe.parse_data_directories(pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_IMPORT']) if hasattr(pe,'DIRECTORY_ENTRY_IMPORT'): importtable=pe.DIRECTORY_ENTRY_IMPORT for importitem in importtable: importname=importitem.dll for i in importitem.imports: #thunkvalue=i.bound iatoffset=i.address-pe.OPTIONAL_HEADER.ImageBase+baseaddr funcname=i.name #print '%s %s %x %x %s' % (importname, funcname, baseaddr, iatoffset, i.ordinal) info=ImportFuncInfo(funcname, modulename, importname, baseaddr, iatoffset, i.ordinal) importfunctable.append(info) #for info in exportfunctable.values(): # print info.funcname, hex(info.funcaddr) #return #inspect export table for info in exportfunctable.values(): if not targetmodulebase or (targetmodulebase==info.baseaddr): sourceoffsetvalue=info.funcaddr-info.baseaddr try: currentoffsetvalue=pykd.ptrDWord(info.funcoffset+info.baseaddr) except Exception, err: print 'EATHOOK:(%s!%s) baseaddr:%x offset:%x value:%x<->????????' % (info.modulename, info.funcname, info.baseaddr, info.funcoffset, sourceoffsetvalue) continue if sourceoffsetvalue!=currentoffsetvalue: print 'EATHOOK:(%s!%s) baseaddr:%x offset:%x value:%x<->%x' % (info.modulename, info.funcname, info.baseaddr, info.funcoffset, sourceoffsetvalue, currentoffsetvalue) print 'inspect EATHOOK completely' #inspect import table for i in importfunctable: if not targetmodulebase or (targetmodulebase==i.baseaddr): try: currentfuncaddr=pykd.ptrPtr(i.iatoffset) except Exception, err: if i.ordinal: #by ordinal print 'IATHOOK:(source:%s import:idx:%s!%d)<->????????' % (i.sourcemodulename, i.importmodulename,i.ordinal) else: #by name print 'IATHOOK:(source:%s import:%s!%s)<->????????' % (i.sourcemodulename, i.importmodulename,i.funcname) continue if not exportfunctable.get(currentfuncaddr): hookfuncname=pykd.findSymbol(currentfuncaddr) if i.ordinal: #by ordinal print 'IATHOOK:(source:%s import:%s!idx:%d)<->%x(%s)' % (i.sourcemodulename, i.importmodulename,i.ordinal, currentfuncaddr, hookfuncname) else: #by name print 'IATHOOK:(source:%s import:%s!%s)<->%x(%s)' % (i.sourcemodulename, i.importmodulename,i.funcname, currentfuncaddr, hookfuncname)
def get_uint32(pos): return pykd.ptrDWord(pos)
def get_int32(pos): return struct.unpack("i", struct.pack("I", pykd.ptrDWord(pos)))[0]
string += "ERROR(%u)" % opcode break string += "%-16s" % vbs_itable[opcode].name if (vbs_itable[opcode].argfmt is not None): string += vbs_itable[opcode].argfmt(addr, position + 1) pprint(indent_level, string) position += 1 + vbs_itable[opcode].argsize def dump(addr): funcs = addr + get_uint32(addr + 0x10) funcs_count = get_uint32(addr + 0x14) bos_info = addr + get_uint32(addr + 0x1C) bos_data = addr + get_uint32(addr + 0x28) for i in range(funcs_count): pfnc = addr + get_uint32(funcs + i * 4) print_info(1, addr, pfnc, i) print_code(1, addr, pfnc, bos_info, bos_data) print dump(pykd.ptrDWord(pykd.reg("ecx") + 0xC0))