idapython初探 也到了该系统学习idapython的阶段了!
之前看别人的wp用的idapython在新的版本中已经不能用来,idapython升级了!现大概学习一下怎么用,然后在文档中学习:
idapython官方函数文档:https://www.hex-rays.com/products/ida/support/idapython_docs/
旧版本和新版本差异:https://www.hex-rays.com/products/ida/support/ida74_idapython_no_bc695_porting_guide.shtml
idapython图片集合版:https://github.com/inforion/idapython-cheatsheet/blob/master/IDAPython-7x_cheatsheet_web_en.png
1、获取函数地址 1 2 3 4 5 6 7 8 9 10 11 print (hex (idc.here()))/print (hex (idc.get_screen_ea()))print (hex (ida_ida.inf_get_min_ea()))print (hex (ida_ida.inf_get_max_ea()))print (hex (idc.read_selection_start()))print (hex (idc.read_selection_end()))if idaapi.BADADDR == idc.here(): print ("BadAddress addr invalid" ) else : print ("addr is ok" )
idaapi.BADADDR ,用来判断函数是否存在
2.获取数值 在之前看wp,用Byte永远是错的,今天才知道原来改了函数:
1 2 3 4 idc.get_wide_byte(addr)//以字节为单位获取地址处的值 idc.get_wide_word(addr)//获取2 字节的值 idc.get_wide_dword(addr)//获取4 字节 idc.get_qword(addr)//获取8 字节
下面进行一个获取当前地址下的数值操作,如果不是数据段,获得的是硬编码,在hex显示中能看到的
1 2 3 4 import idcea = idc.get_screen_ea() value = idc.get_wide_byte(ea) print ("{}" .format (hex (value)))
idc.isByte() Word Dwrd Qwrd
ida_bytes.is_byte word dword qword
上面是对应的判断函数
3.修改数值操作 修改数值的方法,一般用patch,或者用python也行。
当然修改的值韩式byte是1字节,word2字节,Dword4字节,Qword8字节
1 2 3 4 5 6 7 8 ea = idc.get_screen_ea() value = idc.get_wide_byte(ea) print ("修改前{}" .format (hex (value)))ida_bytes.patch_byte(ea,0x90 ) value = idc.get_wide_byte(ea) print ("修改前{}" .format (hex (value)))
我们修改当前选中地址的数据
如果要将一段地址中所有0x0换成0x77,如何写呢?
1 2 3 4 5 6 7 8 9 10 import idcimport idaapiimport idautilsstart_addr = 0x0040b1cd end_addr = 0x0040b1ff for i in range (end_addr - start_addr): now_addr = i + start_addr tmp = idc.get_wide_byte(now_addr) if tmp == 0 : ida_bytes.patch_byte(now_addr,0x77 )
我的建议是每次写的时候将三个import全部导入,反正就这三个。
4.汇编提取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import idcimport idaapiimport idautilsea = idc.here() print ("当前模块基址{}" .format (hex (idaapi.get_imagebase())))print ("当前汇编指令{}" .format (idc.print_insn_mnem(ea)))print ("当前汇编语句{}" .format (idc.GetDisasm(ea)))print ("当前操作数{}" .format (idc.print_operand(ea,0 )))print ("当前的操作数值为: {}" .format (idc.get_operand_value(ea,0 )))
5.段操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import idcimport idaapiimport idautilsfor seg in idautils.Segments(): segname = idc.get_segm_name(seg) segstart = idc.get_segm_start(seg) segend = idc.get_segm_end(seg) print ("段名 = {} 起始地址 = {} 结束地址 = {}" .format (segname, hex (segstart), hex (segend)))
6.函数操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import idcimport idaapiimport idautilsfor seg in idautils.Segments(): segname = idc.get_segm_name(seg) segstart = idc.get_segm_start(seg) segend = idc.get_segm_end(seg) print ("段名 = {} 起始地址= {} 结束地址 = {} " .format (segname,hex (segstart),hex (segend))) if segname == '.text' : for funcaddr in Functions(segstart, segend): funname = idc.get_func_name(funcaddr) funend = idc.find_func_end(funcaddr) funnext = idc.get_next_func(funcaddr) funnextname = idc.get_func_name(funnext) print ("当前函数名 = {} 当前结束地址 = {} 下一个函数地址 = {} 下一个函数名 = {}" .format (funname, hex (funend), hex (funnext), funnextname)) ea = idc.get_screen_ea() funnextoffset = idc.get_func_off_str(ea) print ("当前选择地址距离当前函数的偏移:{}" .format (funnextoffset))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 段名 = .text 起始地址= 0x401000 结束地址 = 0x404000 当前函数名 = __mingw_invalidParameterHandler 当前结束地址 = 0x401001 下一个函数地址 = 0x401010 下一个函数名 = pre_c_init 当前函数名 = pre_c_init 当前结束地址 = 0x401121 下一个函数地址 = 0x401130 下一个函数名 = pre_cpp_init 当前函数名 = pre_cpp_init 当前结束地址 = 0x401179 下一个函数地址 = 0x401180 下一个函数名 = __tmainCRTStartup 当前函数名 = __tmainCRTStartup 当前结束地址 = 0x4014a6 下一个函数地址 = 0x4014b0 下一个函数名 = WinMainCRTStartup 当前函数名 = WinMainCRTStartup 当前结束地址 = 0x4014d2 下一个函数地址 = 0x4014e0 下一个函数名 = mainCRTStartup 当前函数名 = mainCRTStartup 当前结束地址 = 0x401502 下一个函数地址 = 0x401510 下一个函数名 = atexit 当前函数名 = atexit 当前结束地址 = 0x401529 下一个函数地址 = 0x401530 下一个函数名 = __gcc_register_frame 当前函数名 = __gcc_register_frame 当前结束地址 = 0x40153c 下一个函数地址 = 0x401540 下一个函数名 = __gcc_deregister_frame 当前函数名 = __gcc_deregister_frame 当前结束地址 = 0x401541 下一个函数地址 = 0x401550 下一个函数名 = input 当前函数名 = input 当前结束地址 = 0x40163d 下一个函数地址 = 0x40163d 下一个函数名 = output 当前函数名 = output 当前结束地址 = 0x401725 下一个函数地址 = 0x401725 下一个函数名 = Findmax 当前函数名 = Findmax 当前结束地址 = 0x4017a6 下一个函数地址 = 0x4017a6 下一个函数名 = sort 当前函数名 = sort 当前结束地址 = 0x4019a0 下一个函数地址 = 0x4019a0 下一个函数名 = main 当前函数名 = main 当前结束地址 = 0x401aeb 下一个函数地址 = 0x401af0 下一个函数名 = __do_global_dtors 当前函数名 = __do_global_dtors 当前结束地址 = 0x401b25 下一个函数地址 = 0x401b30 下一个函数名 = __do_global_ctors 当前函数名 = __do_global_ctors 当前结束地址 = 0x401b96 下一个函数地址 = 0x401ba0 下一个函数名 = __main 当前函数名 = __main 当前结束地址 = 0x401bbf 下一个函数地址 = 0x401bc0 下一个函数名 = my_lconv_init 当前函数名 = my_lconv_init 当前结束地址 = 0x401bc7 下一个函数地址 = 0x401bd0 下一个函数名 = _setargv 当前函数名 = _setargv 当前结束地址 = 0x401bd3 下一个函数地址 = 0x401be0 下一个函数名 = __security_init_cookie 当前函数名 = __security_init_cookie 当前结束地址 = 0x401cb6 下一个函数地址 = 0x401cc0 下一个函数名 = __report_gsfailure 当前函数名 = __report_gsfailure 当前结束地址 = 0x401db8 下一个函数地址 = 0x401dc0 下一个函数名 = __dyn_tls_dtor 当前函数名 = __dyn_tls_dtor 当前结束地址 = 0x401def 下一个函数地址 = 0x401df0 下一个函数名 = __dyn_tls_init 当前函数名 = __dyn_tls_init 当前结束地址 = 0x401e63 下一个函数地址 = 0x401e70 下一个函数名 = __tlregdtor 当前函数名 = __tlregdtor 当前结束地址 = 0x401e73 下一个函数地址 = 0x401e80 下一个函数名 = __mingw_raise_matherr 当前函数名 = __mingw_raise_matherr 当前结束地址 = 0x401ec1 下一个函数地址 = 0x401ed0 下一个函数名 = __mingw_setusermatherr 当前函数名 = __mingw_setusermatherr 当前结束地址 = 0x401edc 下一个函数地址 = 0x401ee0 下一个函数名 = _matherr 当前函数名 = _matherr 当前结束地址 = 0x401fdc 下一个函数地址 = 0x401fe0 下一个函数名 = fpreset 当前函数名 = fpreset 当前结束地址 = 0x401fe3 下一个函数地址 = 0x401ff0 下一个函数名 = _decode_pointer 当前函数名 = _decode_pointer 当前结束地址 = 0x401ff4 下一个函数地址 = 0x402000 下一个函数名 = _encode_pointer 当前函数名 = _encode_pointer 当前结束地址 = 0x402004 下一个函数地址 = 0x402010 下一个函数名 = __write_memory.part.0 当前函数名 = __write_memory.part.0 当前结束地址 = 0x4021dc 下一个函数地址 = 0x4021e0 下一个函数名 = _pei386_runtime_relocator 当前函数名 = _pei386_runtime_relocator 当前结束地址 = 0x40249a 下一个函数地址 = 0x4024a0 下一个函数名 = __mingw_SEH_error_handler 当前函数名 = __mingw_SEH_error_handler 当前结束地址 = 0x402640 下一个函数地址 = 0x402640 下一个函数名 = __mingw_init_ehandler 当前函数名 = __mingw_init_ehandler 当前结束地址 = 0x40272c 下一个函数地址 = 0x402920 下一个函数名 = __mingwthr_run_key_dtors.part.0 当前函数名 = __mingwthr_run_key_dtors.part.0 当前结束地址 = 0x40298a 下一个函数地址 = 0x402990 下一个函数名 = ___w64_mingwthr_add_key_dtor 当前函数名 = ___w64_mingwthr_add_key_dtor 当前结束地址 = 0x402a0f 下一个函数地址 = 0x402a10 下一个函数名 = ___w64_mingwthr_remove_key_dtor 当前函数名 = ___w64_mingwthr_remove_key_dtor 当前结束地址 = 0x402ab0 下一个函数地址 = 0x402ab0 下一个函数名 = __mingw_TLScallback 当前函数名 = __mingw_TLScallback 当前结束地址 = 0x402b8a 下一个函数地址 = 0x402b90 下一个函数名 = _ValidateImageBase.part.0 当前函数名 = _ValidateImageBase.part.0 当前结束地址 = 0x402bae 下一个函数地址 = 0x402bb0 下一个函数名 = _ValidateImageBase 当前函数名 = _ValidateImageBase 当前结束地址 = 0x402bc2 下一个函数地址 = 0x402bd0 下一个函数名 = _FindPESection 当前函数名 = _FindPESection 当前结束地址 = 0x402c14 下一个函数地址 = 0x402c20 下一个函数名 = _FindPESectionByName 当前函数名 = _FindPESectionByName 当前结束地址 = 0x402cad 下一个函数地址 = 0x402cb0 下一个函数名 = __mingw_GetSectionForAddress 当前函数名 = __mingw_GetSectionForAddress 当前结束地址 = 0x402d24 下一个函数地址 = 0x402d30 下一个函数名 = __mingw_GetSectionCount 当前函数名 = __mingw_GetSectionCount 当前结束地址 = 0x402d6e 下一个函数地址 = 0x402d70 下一个函数名 = _FindPESectionExec 当前函数名 = _FindPESectionExec 当前结束地址 = 0x402ddf 下一个函数地址 = 0x402de0 下一个函数名 = _GetPEImageBase 当前函数名 = _GetPEImageBase 当前结束地址 = 0x402e17 下一个函数地址 = 0x402e20 下一个函数名 = _IsNonwritableInCurrentImage 当前函数名 = _IsNonwritableInCurrentImage 当前结束地址 = 0x402eb1 下一个函数地址 = 0x402ec0 下一个函数名 = __mingw_enum_import_library_names 当前函数名 = __mingw_enum_import_library_names 当前结束地址 = 0x402f66 下一个函数地址 = 0x402f70 下一个函数名 = ___chkstk_ms 当前函数名 = ___chkstk_ms 当前结束地址 = 0x402fa2 下一个函数地址 = 0x402fb0 下一个函数名 = vfprintf 当前函数名 = vfprintf 当前结束地址 = 0x402fb6 下一个函数地址 = 0x402fb8 下一个函数名 = strncmp 当前函数名 = strncmp 当前结束地址 = 0x402fbe 下一个函数地址 = 0x402fc0 下一个函数名 = strlen 当前函数名 = strlen 当前结束地址 = 0x402fc6 下一个函数地址 = 0x402fc8 下一个函数名 = signal 当前函数名 = signal 当前结束地址 = 0x402fce 下一个函数地址 = 0x402fd0 下一个函数名 = scanf 当前函数名 = scanf 当前结束地址 = 0x402fd6 下一个函数地址 = 0x402fd8 下一个函数名 = printf 当前函数名 = printf 当前结束地址 = 0x402fde 下一个函数地址 = 0x402fe0 下一个函数名 = memcpy 当前函数名 = memcpy 当前结束地址 = 0x402fe6 下一个函数地址 = 0x402fe8 下一个函数名 = malloc 当前函数名 = malloc 当前结束地址 = 0x402fee 下一个函数地址 = 0x402ff0 下一个函数名 = fwrite 当前函数名 = fwrite 当前结束地址 = 0x402ff6 下一个函数地址 = 0x402ff8 下一个函数名 = free 当前函数名 = free 当前结束地址 = 0x402ffe 下一个函数地址 = 0x403000 下一个函数名 = fprintf 当前函数名 = fprintf 当前结束地址 = 0x403006 下一个函数地址 = 0x403008 下一个函数名 = exit 当前函数名 = exit 当前结束地址 = 0x40300e 下一个函数地址 = 0x403010 下一个函数名 = calloc 当前函数名 = calloc 当前结束地址 = 0x403016 下一个函数地址 = 0x403018 下一个函数名 = abort 当前函数名 = abort 当前结束地址 = 0x40301e 下一个函数地址 = 0x403020 下一个函数名 = _onexit 当前函数名 = _onexit 当前结束地址 = 0x403026 下一个函数地址 = 0x403028 下一个函数名 = _initterm 当前函数名 = _initterm 当前结束地址 = 0x40302e 下一个函数地址 = 0x403030 下一个函数名 = _cexit 当前函数名 = _cexit 当前结束地址 = 0x403036 下一个函数地址 = 0x403038 下一个函数名 = _amsg_exit 当前函数名 = _amsg_exit 当前结束地址 = 0x40303e 下一个函数地址 = 0x403040 下一个函数名 = __setusermatherr 当前函数名 = __setusermatherr 当前结束地址 = 0x403046 下一个函数地址 = 0x403048 下一个函数名 = __set_app_type 当前函数名 = __set_app_type 当前结束地址 = 0x40304e 下一个函数地址 = 0x403050 下一个函数名 = __lconv_init 当前函数名 = __lconv_init 当前结束地址 = 0x403056 下一个函数地址 = 0x403058 下一个函数名 = __getmainargs 当前函数名 = __getmainargs 当前结束地址 = 0x40305e 下一个函数地址 = 0x403060 下一个函数名 = __C_specific_handler 当前函数名 = __C_specific_handler 当前结束地址 = 0x403066 下一个函数地址 = 0x403070 下一个函数名 = __acrt_iob_func 当前函数名 = __acrt_iob_func 当前结束地址 = 0x40308f 下一个函数地址 = 0x403090 下一个函数名 = _get_invalid_parameter_handler 当前函数名 = _get_invalid_parameter_handler 当前结束地址 = 0x403098 下一个函数地址 = 0x4030a0 下一个函数名 = _set_invalid_parameter_handler 当前函数名 = _set_invalid_parameter_handler 当前结束地址 = 0x4030ab 下一个函数地址 = 0x4030b0 下一个函数名 = __p__acmdln 当前函数名 = __p__acmdln 当前结束地址 = 0x4030bb 下一个函数地址 = 0x4030c0 下一个函数名 = __p__fmode 当前函数名 = __p__fmode 当前结束地址 = 0x4030cb 下一个函数地址 = 0x4030d0 下一个函数名 = __iob_func 当前函数名 = __iob_func 当前结束地址 = 0x4030d6 下一个函数地址 = 0x4030e0 下一个函数名 = VirtualQuery 当前函数名 = VirtualQuery 当前结束地址 = 0x4030e6 下一个函数地址 = 0x4030e8 下一个函数名 = VirtualProtect 当前函数名 = VirtualProtect 当前结束地址 = 0x4030ee 下一个函数地址 = 0x4030f0 下一个函数名 = UnhandledExceptionFilter 当前函数名 = UnhandledExceptionFilter 当前结束地址 = 0x4030f6 下一个函数地址 = 0x4030f8 下一个函数名 = TlsGetValue 当前函数名 = TlsGetValue 当前结束地址 = 0x4030fe 下一个函数地址 = 0x403100 下一个函数名 = TerminateProcess 当前函数名 = TerminateProcess 当前结束地址 = 0x403106 下一个函数地址 = 0x403108 下一个函数名 = Sleep 当前函数名 = Sleep 当前结束地址 = 0x40310e 下一个函数地址 = 0x403110 下一个函数名 = SetUnhandledExceptionFilter 当前函数名 = SetUnhandledExceptionFilter 当前结束地址 = 0x403116 下一个函数地址 = 0x403118 下一个函数名 = RtlVirtualUnwind 当前函数名 = RtlVirtualUnwind 当前结束地址 = 0x40311e 下一个函数地址 = 0x403120 下一个函数名 = RtlLookupFunctionEntry 当前函数名 = RtlLookupFunctionEntry 当前结束地址 = 0x403126 下一个函数地址 = 0x403128 下一个函数名 = RtlCaptureContext 当前函数名 = RtlCaptureContext 当前结束地址 = 0x40312e 下一个函数地址 = 0x403130 下一个函数名 = RtlAddFunctionTable 当前函数名 = RtlAddFunctionTable 当前结束地址 = 0x403136 下一个函数地址 = 0x403138 下一个函数名 = QueryPerformanceCounter 当前函数名 = QueryPerformanceCounter 当前结束地址 = 0x40313e 下一个函数地址 = 0x403140 下一个函数名 = LeaveCriticalSection 当前函数名 = LeaveCriticalSection 当前结束地址 = 0x403146 下一个函数地址 = 0x403148 下一个函数名 = InitializeCriticalSection 当前函数名 = InitializeCriticalSection 当前结束地址 = 0x40314e 下一个函数地址 = 0x403150 下一个函数名 = GetTickCount 当前函数名 = GetTickCount 当前结束地址 = 0x403156 下一个函数地址 = 0x403158 下一个函数名 = GetSystemTimeAsFileTime 当前函数名 = GetSystemTimeAsFileTime 当前结束地址 = 0x40315e 下一个函数地址 = 0x403160 下一个函数名 = GetStartupInfoA 当前函数名 = GetStartupInfoA 当前结束地址 = 0x403166 下一个函数地址 = 0x403168 下一个函数名 = GetLastError 当前函数名 = GetLastError 当前结束地址 = 0x40316e 下一个函数地址 = 0x403170 下一个函数名 = GetCurrentThreadId 当前函数名 = GetCurrentThreadId 当前结束地址 = 0x403176 下一个函数地址 = 0x403178 下一个函数名 = GetCurrentProcessId 当前函数名 = GetCurrentProcessId 当前结束地址 = 0x40317e 下一个函数地址 = 0x403180 下一个函数名 = GetCurrentProcess 当前函数名 = GetCurrentProcess 当前结束地址 = 0x403186 下一个函数地址 = 0x403188 下一个函数名 = EnterCriticalSection 当前函数名 = EnterCriticalSection 当前结束地址 = 0x40318e 下一个函数地址 = 0x403190 下一个函数名 = DeleteCriticalSection 当前函数名 = DeleteCriticalSection 当前结束地址 = 0x403196 下一个函数地址 = 0x4031a0 下一个函数名 = .text_46 当前函数名 = .text_46 当前结束地址 = 0x403209 下一个函数地址 = 0x403210 下一个函数名 = register_frame_ctor 当前函数名 = register_frame_ctor 当前结束地址 = 0x403215 下一个函数地址 = 0xffffffffffffffff 下一个函数名 = 段名 = .data 起始地址= 0x404000 结束地址 = 0x405000 段名 = .rdata 起始地址= 0x405000 结束地址 = 0x406000 段名 = .pdata 起始地址= 0x406000 结束地址 = 0x407000 段名 = .xdata 起始地址= 0x407000 结束地址 = 0x408000 段名 = .bss 起始地址= 0x408000 结束地址 = 0x409000 段名 = .idata 起始地址= 0x4091dc 结束地址 = 0x40937c 段名 = .CRT 起始地址= 0x40a000 结束地址 = 0x40b000 段名 = .tls 起始地址= 0x40b000 结束地址 = 0x40c000 当前选择地址距离当前函数的偏移:__security_init_cookie+9B
7.搜索函数
1 2 3 4 5 6 flag的取值: SEARCH_DOWN 向下搜索 SEARCH_UP 向上搜索 SEARCH_NEXT 获取下一个找到的对象。 SEARCH_CASE 指定大小写敏感度 SEARCH_UNICODE 搜索 Unicode 字符串。
1 2 3 4 5 6 7 8 import idcimport idaapiimport idautilsea = idc.here() value = ida_search.find_binary(ea, SEARCH_DOWN, '8D 4D 08' ) value1 = ida_search.find_code(ea, SEARCH_DOWN) value2 = ida_search.find_data(ea, SEARCH_DOWN)
上述idc.find_binary已经不用了,被ida_search.find_binary代替了
8.数据检验函数 也就是相当于进行一个判断,判断是否传回正确的值!
1 2 3 4 5 6 7 8 9 10 import idcea = here() value1 = idc.find_code(ea,SEARCH_DOWN) print (hex (value1))flag = ida_bytes.get_full_flags(value1) print (flag)print (ida_bytes.is_code(flag))
9.交叉引用
1 2 3 4 import idcea = here() for i in CodeRefsTo(ea,False ): print (hex (i))
这个一般是对着函数用的。
就先写这么多,什么时候遇到再补充,最起码现在遇见idapython不慌了!