Log in

View Full Version : Function Start/End Addresses in IDA (IDC coding)


Bengaly
August 7th, 2004, 06:01
hey all,

i want to create a more detail *.map file from IDA,
i start with Functions (EP/Subroutines) which are defined in map as only beginning of a function.
e.g:
Code:

0001:00000000 start
0001:00000031 sub_401031
0001:00000118 sub_401118


the problem is that, map does not give us detail about the address of the end of a function, only address of next Function.

so therefor this is not true that sub_401031 starts at 401031 and end in 00401118.
yes we know that already, but if we try to enum all function via IDC and try get the start and end, we will get the same thing as above.
mabye there are some functions that i am unaware of (?) so i tried to write some code to give us a real start/end of a function insted.

function example in IDA

Code:

sub_401031 proc near

00401031 ; first instruction here
...
... ; code here
...
00401115; last function instruction here

sub_401031 endp


as you can see the real function bound is: 00401031-00401115 and NOT 00401031-00401118 as IDA gives us by internal IDC function.

'normaly' a function ends with a single byte instruction 'ret' or a 3 bytes instruction 'ret xxxx' but ofcourse it can end with just about any other instruction lenght.
so the usual 'remove 3' or 'remove 1' from the 00401118 (function ida gives us) is wrong.
and the only approach is to 'backward' instruction count.

IDC supports a function called FindCode(..) with a nice flag SEARCH_DOWN, but not SEARCH_UP

the idea i had is to set: end_addr - xx bytes, FindCode(..) == address of instruction with a lowest addr than the last instruction of the end function. and count instruction down until we pass the last instruction's address, and this is the real adderss.

the IDC i wrote works well in some cases, and other cases it crashes (loops forever) because the backward number puts us in wrong instruction i think.
the script will try to ignore APIs which defined as a function entrypoint as well.

if some have way better ides, please post here.

; rename *.txt to *.idc, load exe, w8 for the process to finish, execute this script.

regards,
Bengaly

dELTA
August 7th, 2004, 12:49
In case you settle with the assumption that the functions will always end with ret or ret xxxx, why don't you just simply count forward from the function start until you reach the start address of the next function, and simply store the address of the last ret you have found?

Peres
August 7th, 2004, 15:49
Maybe you could trace the code until the value of the ESP register is zero - with respect to the beginning of the function, of course. Beware you have to trust IDA's calculation of the stack which is not always accurate because of routines that FLIRT failed to - or couldn't - recognize.
You could combine this ESP-tracing approach with some pattern analysis as dELTA pointed out. For example, you can test if the line you found actually transfers control to some other location via a ret, call or jmp instruction.

Peres

Bengaly
August 7th, 2004, 17:54
hi Delta,

yes, this indeed can be done, no metter the ret/ret xxxx instructions.
also bear that if the function's body is long, such process can take time to handle out vast amount of functions analysed by ida.

my approach was to go back x instructions back from the end, but it seems to be a false way as it can not be trusted in extreem cases, but can play the role of a back-up way.

in the up comming dawn i shall try the primitive way, as for speed we care not.

hi Peres,
i am not using idc debugger built-in idc instructions, so i can not test registers and follow control flow.
nor i have needed this way.

thank you for your replies,
Bengaly