williballenthin / python-idb

Pure Python parser and analyzer for IDA Pro database files (.idb).
Apache License 2.0
455 stars 73 forks source link

The FlowChart() contains the basic blocks outside the function. #73

Open bjchan9an opened 4 years ago

bjchan9an commented 4 years ago

The following is the display of ida pro. The function sub_3000 is in.plt . Although it is not a user-defined code, it is regarded as a function by IDA Pro. I found that while calling FlowChart() on these functions, python-idb includes the basic blocks outside of the function. This action does not match the logic of ida pro.

.plt:0000000000003000 sub_3000        proc near               ; CODE XREF: .plt:000000000000301B↓j
.plt:0000000000003000                                         ; .plt:000000000000302B↓j ...
.plt:0000000000003000 ; __unwind {
.plt:0000000000003000                 push    cs:qword_226E58
.plt:0000000000003006                 jmp     cs:qword_226E60
.plt:0000000000003006 sub_3000        endp
.plt:0000000000003006
.plt:0000000000003006 ; ---------------------------------------------------------------------------
.plt:000000000000300C                 align 10h
.plt:0000000000003010 ; [00000006 BYTES: COLLAPSED FUNCTION _free. PRESS CTRL-NUMPAD+ TO EXPAND]
.plt:0000000000003016 ; ---------------------------------------------------------------------------
.plt:0000000000003016                 push    0
.plt:000000000000301B                 jmp     sub_3000
.plt:0000000000003020 ; [00000006 BYTES: COLLAPSED FUNCTION _putchar. PRESS CTRL-NUMPAD+ TO EXPAND]
.plt:0000000000003026 ; ---------------------------------------------------------------------------
.plt:0000000000003026                 push    1
.plt:000000000000302B                 jmp     sub_3000
.plt:0000000000003030 ; [00000006 BYTES: COLLAPSED FUNCTION ___vfprintf_chk. PRESS CTRL-NUMPAD+ TO EXPAND]
.plt:0000000000003036 ; ---------------------------------------------------------------------------
.plt:0000000000003036                 push    2
.plt:000000000000303B                 jmp     sub_3000
.plt:0000000000003040 ; [00000006 BYTES: COLLAPSED FUNCTION ___errno_location. PRESS CTRL-NUMPAD+ TO EXPAND]

In IDA pro:

Python>func = idaapi.get_func(0x3000)
Python>[hex(x.startEA) for x in idaapi.FlowChart(func)]
['0x3000L']

In python-idb:

In [4]: func = api.idaapi.get_func(0x3000)

In [5]: hex(func.startEA)
Out[5]: '0x3000'

In [6]: hex(func.endEA)
Out[6]: '0x300c'

In [7]: [hex(x.startEA) for x in api.idaapi.FlowChart(func)]
Out[7]: 
['0x3000',
 '0x3116',
 '0x3086',
 '0x31a6',
 '0x31e6',
 '0x3226',
 '0x3266',
 '0x32a6',
 '0x3096',
...
]

I think a mitigation method is to check if the basic block is in range of (func.startEA, func.endEA) in FlowChart().