Author | Message | Time |
---|---|---|
LivedKrad | I'm having a hard time figuring out how to find what the parameters of a function are. I'm trying to see what is pushed/popped from the stack in relation to some jump to an offset for a function, but it isn't working out to really find what the parameter names are and such. (This is in general btw, no specific function applicable). Any thoughts? | September 12, 2004, 6:18 AM |
K | You can't really find out what the original names were of the parameters (unless there are debug symbols?); you need to look at how they are used and determine it from there. However, if you're looking at a Win32 API call - then you just need to check msdn for the appropriate interface. Keep in mind that the stack is not the only place you should look; if a function uses the fastcall calling convention, you need to look at ecx and edx too. Excuse spelling errors. Been drinking margaritas all night. | September 12, 2004, 6:25 AM |
iago | If you use IDA, it does a good job guessing number of parameters, and even naming them sometimes (if the parameter is passed to a function where the name is known). | September 12, 2004, 7:27 AM |
Adron | [quote author=LivedKrad link=board=7;threadid=8647;start=0#msg79839 date=1094969901] I'm having a hard time figuring out how to find what the parameters of a function are. I'm trying to see what is pushed/popped from the stack in relation to some jump to an offset for a function, but it isn't working out to really find what the parameter names are and such. (This is in general btw, no specific function applicable). Any thoughts? [/quote] I don't think you'll have any luck looking at what's popped from the stack. Typically you want to look at accesses to [esp+X] or [ebp+X] depending on whether the function sets up a stack frame pointer in ebp. | September 12, 2004, 12:21 PM |
LivedKrad | So it would be best to look into values for registers to see what is in parameters? If they used fastcall to put arguments in ebx and ecx, would that not mean that they would have to keep removing and the adding different values to these registers? I could possibly look for that.. Also, I'm sort of novice with ASM, could you possibly explain a little more simply about frame pointers in the stack? [Adron] | September 12, 2004, 2:01 PM |
Adron | [quote author=LivedKrad link=board=7;threadid=8647;start=0#msg79877 date=1094997703] Also, I'm sort of novice with ASM, could you possibly explain a little more simply about frame pointers in the stack? [Adron] [/quote] First step is to know how the stack works: [quote author=Adron link=board=30;threadid=6381;start=0#msg55857 date=1082407815] There's something called stack. This is a memory area. When you call functions, the stack is used to store data for them. Local variables that you declare in a function are stored on the stack. The stack typically builds downwards. Return addresses and function arguments are also typically stored on the stack. To keep track of how much of the stack is in use, there's a stack pointer. The stack pointer marks the boundary between "in use" and "free". [/quote] Now, lets look at the example in that post: [code] ... av ac <the address that called main> a (14) <an address in main> x (28) b (84) <an address in func1> c (168) <an address in func2> ... [/code] In that example, which is slightly simplified, I haven't indicated any use of ebp for setting up a fixed stack frame pointer. When func1 is entered, esp will point to "an address in main". At that time, func1's argument "a" can be found at [esp+4]. One of the first instructions in func1 will make room for "x" on stack by decreasing esp by 4. Then "a" will be found at [esp+8] and "x" at [esp]. This means that throughout a function, a certain argument or local variable will be found at different offsets from esp (but a constant location in memory). You need to track this manually if your tool doesn't track it for you (IDA does). In the good old days, programs used to save the value of esp into a different register at the time when the function was entered, and then use that as a base for addressing variables. This is called setting up a stack frame pointer. Typically ebp is saved on the stack and then the value of esp is saved into the ebp. If no other registers are saved, you can then find the first argument at [ebp+8] and the first local variable at [ebp-4]. The return address is at [ebp+4] and the saved ebp at [ebp]. Recent programs mostly don't use ebp for a stack frame pointer. This optimization is called frame pointer omission - FPO. | September 12, 2004, 2:40 PM |
LivedKrad | I'm still slightly confused on how the first value "a" is determined to be at [esp+4]. If this newly declared value is on the stack, would it not be at esp before it's at [esp+4]? Because when I look at your post, you said when value "x" is declared its position then becomes [esp] and not [esp+4] so that "a" can be [esp+8]. Something isn't 'clicking' within my mind just yet.. :( | September 12, 2004, 3:13 PM |
Adron | [quote author=LivedKrad link=board=7;threadid=8647;start=0#msg79887 date=1095002010] I'm still slightly confused on how the first value "a" is determined to be at [esp+4]. If this newly declared value is on the stack, would it not be at esp before it's at [esp+4]? Because when I look at your post, you said when value "x" is declared its position then becomes [esp] and not [esp+4] so that "a" can be [esp+8]. Something isn't 'clicking' within my mind just yet.. :( [/quote] It's there because [esp] holds "an address in main", i.e. the return address for the function. I referred to the layout of the stack when the function is entered, not when "a" has just been pushed. | September 12, 2004, 4:36 PM |
LivedKrad | Ohhhhhh, thanks for clearing that up. :D | September 13, 2004, 10:47 AM |