[IDA Pro][python 脚本] :: 如何导出一个地址的二进制模式直到结束?
[IDA Pro][python Script] :: How to Export binary pattern of an address up to it is end?
我想使用 IDA pro 中的 python 脚本导出一个函数的二进制模式,从它的起始地址到它的结束地址。
例如:sub_454345
。我想首先确定该函数在哪个地址开始,然后在哪个地址结束,然后导出函数 sub_454345
.
的整个二进制模式
输出示例:
sub_454345
Start Address : 0x401000
End Address : 0xD5B000
Binary Pattern : 55 8B EC 51 51 56 57 8B 7D 08 8D 45
这远非防错,但这是一个可能的开始:
from __future__ import print_function
def dump_instruction_opcodes(start, end):
opcodes = list()
for ea in xrange(start, end):
opcodes.append(idaapi.idaapi.get_original_byte(ea))
return opcodes
def main():
# get cursor position
screen_ea = ScreenEA()
func = idaapi.get_func(screen_ea)
if not func:
print("No function at address {:#x}".format(screen_ea))
return
elif not func.does_return:
print("Function doesn't have an exit point...")
return
func_start = func.startEA
func_end = func.endEA
func_name = GetFunctionName(func_start)
print("Function '{}' starts at {:#x} and ends at {:#x}".format(func_name, func_start, func_end))
# traverse code or data in function boundaries
for head in Heads(func_start, func_end):
# we just want code, not data
if isCode(GetFlags(head)):
next_head = NextHead(head, func_end)
#if last instruction, set end to func_end
if next_head == BADADDR:
next_head = func_end
#print("Current inst: {:#x}, next inst: {:#x}".format(head, next_head))
opcodes = dump_instruction_opcodes(head, next_head)
printable_opcodes = ["{:02x}".format(op) for op in opcodes]
print("Current inst: {:#x} [{}]".format(head, ' '.join(printable_opcodes)))
print("[*] Done!")
if __name__ == "__main__":
main()
例子
输入:
.text:0040F120 sub_40F120 proc near ; CODE XREF: sub_40A8E0+2Dp
.text:0040F120
.text:0040F120 arg_0 = dword ptr 8
.text:0040F120
.text:0040F120 push ebp
.text:0040F121 mov ebp, esp
.text:0040F123 push esi
.text:0040F124 mov esi, [ebp+arg_0]
.text:0040F127 test esi, esi
.text:0040F129 jnz short loc_40F133
.text:0040F12B
.text:0040F12B loc_40F12B: ; CODE XREF: 40F120+1Ej
.text:0040F12B ; 40F120+28j
.text:0040F12B mov eax, 0FFFFFFFEh
...
输出:
Function 'sub_40F120' starts at 0x40f120 and ends at 0x40f180
Current inst: 0x40f120 [55]
Current inst: 0x40f121 [8b ec]
Current inst: 0x40f123 [56]
Current inst: 0x40f124 [8b 75 08]
Current inst: 0x40f127 [85 f6]
Current inst: 0x40f129 [75 08]
Current inst: 0x40f12b [b8 fe ff ff ff]
...
以上脚本大部分时间都可以工作,但可能会出现多个问题,包括:
- 函数有 thunk(s)[你需要检查 inst 是否是流指令并检查目标是否在函数范围内]
- 其中一个退出点扰乱了 CFG(syscall、int 等)[您需要引用...]
- 函数有内部调用
我想使用 IDA pro 中的 python 脚本导出一个函数的二进制模式,从它的起始地址到它的结束地址。
例如:sub_454345
。我想首先确定该函数在哪个地址开始,然后在哪个地址结束,然后导出函数 sub_454345
.
输出示例:
sub_454345
Start Address : 0x401000
End Address : 0xD5B000
Binary Pattern : 55 8B EC 51 51 56 57 8B 7D 08 8D 45
这远非防错,但这是一个可能的开始:
from __future__ import print_function
def dump_instruction_opcodes(start, end):
opcodes = list()
for ea in xrange(start, end):
opcodes.append(idaapi.idaapi.get_original_byte(ea))
return opcodes
def main():
# get cursor position
screen_ea = ScreenEA()
func = idaapi.get_func(screen_ea)
if not func:
print("No function at address {:#x}".format(screen_ea))
return
elif not func.does_return:
print("Function doesn't have an exit point...")
return
func_start = func.startEA
func_end = func.endEA
func_name = GetFunctionName(func_start)
print("Function '{}' starts at {:#x} and ends at {:#x}".format(func_name, func_start, func_end))
# traverse code or data in function boundaries
for head in Heads(func_start, func_end):
# we just want code, not data
if isCode(GetFlags(head)):
next_head = NextHead(head, func_end)
#if last instruction, set end to func_end
if next_head == BADADDR:
next_head = func_end
#print("Current inst: {:#x}, next inst: {:#x}".format(head, next_head))
opcodes = dump_instruction_opcodes(head, next_head)
printable_opcodes = ["{:02x}".format(op) for op in opcodes]
print("Current inst: {:#x} [{}]".format(head, ' '.join(printable_opcodes)))
print("[*] Done!")
if __name__ == "__main__":
main()
例子
输入:
.text:0040F120 sub_40F120 proc near ; CODE XREF: sub_40A8E0+2Dp
.text:0040F120
.text:0040F120 arg_0 = dword ptr 8
.text:0040F120
.text:0040F120 push ebp
.text:0040F121 mov ebp, esp
.text:0040F123 push esi
.text:0040F124 mov esi, [ebp+arg_0]
.text:0040F127 test esi, esi
.text:0040F129 jnz short loc_40F133
.text:0040F12B
.text:0040F12B loc_40F12B: ; CODE XREF: 40F120+1Ej
.text:0040F12B ; 40F120+28j
.text:0040F12B mov eax, 0FFFFFFFEh
...
输出:
Function 'sub_40F120' starts at 0x40f120 and ends at 0x40f180
Current inst: 0x40f120 [55]
Current inst: 0x40f121 [8b ec]
Current inst: 0x40f123 [56]
Current inst: 0x40f124 [8b 75 08]
Current inst: 0x40f127 [85 f6]
Current inst: 0x40f129 [75 08]
Current inst: 0x40f12b [b8 fe ff ff ff]
...
以上脚本大部分时间都可以工作,但可能会出现多个问题,包括:
- 函数有 thunk(s)[你需要检查 inst 是否是流指令并检查目标是否在函数范围内]
- 其中一个退出点扰乱了 CFG(syscall、int 等)[您需要引用...]
- 函数有内部调用