狗儿

热爱的话就坚持吧~

0%

胖虎也想学idapython

那你能帮帮我吗?

若无特殊说明则表示代码是胖虎自己写的。

函数

idc.ScreenEA()当前光标

idautils.FuncItems(ea)选中函数的所有指令地址

idc.GetDisasm(addr)汇编代码

idc.GetOpnd(addr, 1)第1个操作数(0开始)

idc.GetMnem操作码

idc.MakeUnkn(addr, 0)undefined code

idc.MakeCode(addr)转换成汇编

idc.GetFunctionAttr(ea, idc.FUNCATTR_START)当前函数起始地址

idc.MakeFunction(func_start)转换成函数

脚本

当前函数的全部汇编代码

1
2
3
4
5
6
7
8
9
10
11
print "[-] 开始导出反汇编代码"
import idautils
ea = idc.ScreenEA()
addrs = idautils.FuncItems(ea)
text = ''
for addr in addrs:
#print idc.GetDisasm(addr)
text += idc.GetDisasm(addr) + '\n'
with open("D:\\disasm.txt", 'w')as f:
f.write(text)
print "[+] 成功将当前函数的反汇编代码写入d:\\disasm.txt"

当前函数所有汇编操作码及出现次数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
print "[-] 开始统计操作码!"
import idautils
ea = idc.ScreenEA()
addrs = idautils.FuncItems(ea)
op_list = []
for addr in addrs:
op_list.append(idc.GetMnem(addr))
op_dic = {}
for item in set(op_list):
op_dic[item] = op_list.count(item)
op_dic = sorted(op_dic.items(), key=lambda item:item[1])
for item in op_dic:
print "%s\t%d" % (item[0], item[1])
print "[+] 成功统计操作码!"

output:

1
2
3
4
5
6
7
8
9
10
11
12
[-] 开始统计操作码!
sub 1
retn 1
add 1
pop 4
push 4
shl 779
mov 31754
shr 31988
and 32767
xor 32767
[+] 成功统计操作码!

批量nop

1
2
3
4
5
6
7
import idautils

start_addr = 0x402FD0
end_addr = 0x402FF8

for i in range(start_addr, end_addr):
PatchByte(i, 0x90)

批量undefine

1
2
3
4
5
6
7
import idautils

start_addr = 0x467168
end_addr = 0x46726E

for i in range(start_addr, end_addr):
MakeUnkn(i, 0x90)

所有函数地址和名称

https://cloud.tencent.com/developer/article/1097793

1
2
3
for ea in Segments(): #遍历所有段
for function in Functions(SegStart(ea), SegEnd(ea)): #遍历该段中所有函数
print hex(function), GetFunctionName(function) #输出函数起势地址和函数名

从所有函数中查找具体的某条指令

1
2
3
4
5
6
7
8
9
10
11
12
13
print '开始运行脚本,当前时间:%s'%time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 

import idautils
#遍历所有段
for ea in Segments():
#遍历该段中所有函数
for function_addr in Functions(SegStart(ea), SegEnd(ea)):
instruction_addrs = idautils.FuncItems(function_addr)
for addr in instruction_addrs:
if idc.GetMnem(addr) == 'syscall':
print hex(addr)[2:-1], idc.GetMnem(addr)

print '结束运行脚本,当前时间:%s\n'%time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

从所有指令中查找具体的某条指令

1
2
3
4
5
6
7
8
9
10
11
print '开始运行脚本,当前时间:%s'%time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 

import idautils
ea = MinEA()
maxea = MaxEA()
while ea < maxea:
if idc.GetMnem(ea) == 'syscall':
print hex(ea)[2:-1], idc.GetMnem(ea)
ea = idc.NextAddr(ea)

print '结束运行脚本,当前时间:%s\n'%time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

上一个脚本只能从已知函数中查找,但是有的时候,有些指令不会在已知的函数内。这个脚本可以从所有的指令中查找。

两个脚本的效果对比:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
开始运行脚本,当前时间:2020-11-15 17:39:06
401159 syscall
结束运行脚本,当前时间:2020-11-15 17:39:06

开始运行脚本,当前时间:2020-11-15 17:42:10
401159 syscall
4011a5 syscall
4011ae syscall
4011d2 syscall
4011db syscall
4012e5 syscall
4013f5 syscall
401459 syscall
401472 syscall
4014d1 syscall
401530 syscall
40158f syscall
4015ec syscall
40162f syscall
4017e8 syscall
结束运行脚本,当前时间:2020-11-15 17:42:10

最简单的smc修复

1
2
3
4
5
6
7
8
import idautils

target = 0x875188
key = "you_can_not_find_me"

for i in range(658):
result = ord(key[i % len(key)]) ^ Byte(target + i)
PatchByte(target + i, result)

xnaca的一道题中的一部分知识点。

这里的smc是运行时将数据异或后的数据当成代码运行。

该脚本可以将数据改成运行时的代码。

参考网站