0%

idapython初探

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()))#如果你选择了某块地址 那么使用此函数则返回你选择的这块地址的起始地址,否则返回-1,选择的意思是光标选择其地址
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永远是错的,今天才知道原来改了函数:

image-20220411155039777

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 idc
ea = 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也行。

image-20220411162518089

当然修改的值韩式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
#修改前0x90

我们修改当前选中地址的数据

如果要将一段地址中所有0x0换成0x77,如何写呢?

1
2
3
4
5
6
7
8
9
10
import idc
import idaapi
import idautils
start_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.汇编提取

image-20220411170422358

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import idc
import idaapi
import idautils

ea = 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)))

#当前模块基址0x400000
#当前汇编指令xor
#当前汇编语句xor rsi, qword ptr [rsp+58h+PerformanceCount]
#当前操作数rsi
#当前的操作数值为: 6

5.段操作

image-20220411181105721

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import idc
import idaapi
import idautils

for 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)))
#段名 = .text 起始地址 = 0x401000 结束地址 = 0x404000
#段名 = .data 起始地址 = 0x404000 结束地址 = 0x405000
#段名 = .rdata 起始地址 = 0x405000 结束地址 = 0x406000
#段名 = .pdata 起始地址 = 0x406000 结束地址 = 0x407000
#段名 = .xdata 起始地址 = 0x407000 结束地址 = 0x408000
#段名 = .bss 起始地址 = 0x408000 结束地址 = 0x409000
#段名 = .idata 起始地址 = 0x4091dc 结束地址 = 0x40937c
#段名 = .CRT 起始地址 = 0x40a000 结束地址 = 0x40b000
#段名 = .tls 起始地址 = 0x40b000 结束地址 = 0x40c000

6.函数操作

image-20220411182506660

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import idc
import idaapi
import idautils

for 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.搜索函数

image-20220411185445159

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 idc
import idaapi
import idautils

ea = 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.数据检验函数

也就是相当于进行一个判断,判断是否传回正确的值!

image-20220411190928332

1
2
3
4
5
6
7
8
9
10
import idc
ea = 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))
#0x401c6e
#67465
#True

9.交叉引用

image-20220411191332094

1
2
3
4
import idc
ea = here()
for i in CodeRefsTo(ea,False):
print(hex(i))

这个一般是对着函数用的。

就先写这么多,什么时候遇到再补充,最起码现在遇见idapython不慌了!