WaxfordSqueers
December 5th, 2004, 22:33
Quote:
[Originally Posted by Clandestiny]
You might want to read an introductory book on ASM like Randall Hyde's Art Of Assembly before you delve too deeply into this RCE stuff. It is free and in ebook format, btw 
Cheers,
Clandestiny |
I remember reading something about this is Matt Pietrek's book, Windows 95 Programming Secrets. On page 654 of Chapter 9, there is a section called 'Identifying local variables'. Earlier in the chapter, Matt describes the EBP register as a stack frame register. The variables from functions are passed on the stack between CALLing functions and the function called. The EBP register usually points to the bottom of the local stack.
Matt gives this example:
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
This is a declaration for function WndProc. Inside the WndProc code, the stack frame for a 32 bit process looks like this:
lParam DWORD PTR [EBP+14]
wParam DWORD PTR [EBP+10]
msg DWPRD PRT [EBP+0C]
hWnd DWORD PTR [EBP+08]
return EIP DWORD PTR [EBP+04]
previous EBP DWORD PTR [EBP+00]
(My notation)The functions parameters have been pushed onto the stack from right to left, and the EBP is pointing to the previous EBP. By examining the code in positive offsets of double words, you can find each of the functions parameters, which follow the original EBP and EIP doublewords.
A newbie might be interested to know that the values before a CALL statement can be identified if you have a handy API reference that describes functions and their parameters. Look for PUSH statements, in general, immediately before a CALL function, and they will most likely be pushing parameters for that function onto the stack. You have to be careful because sometimes the parameters are passed by more devious means. If you look at the function layout in an API reference, they will be pushed as above. Careful scrutiny will tell you what's what.
Matt goes on to say: Like function parameters, a routine's local variables are also usually found on the stack. The key difference in distinguishing between a parameter and a local variable is that the code references local variables with a negative offset from the stack frame. For example, in 16-bit code, [BP-04], or in 32-bit, [EBP-04].
Unlike parameters, there's no semi-mechanical method for determining the types, uses, and locations of local variables. Instead, you have to examine how the function's code uses a particular memory location.
----snip----
Determining that a program is using a global variable is particularly easy. Almost any memory reference that uses a hardcoded address is a global variable. Put another way, global variables don't require the assistance of registers like EBP to address them. In 32-bit code, a global variable reference would look something like this:
MOV EAX, [00464398]
Anybody who is interested can read the rest for themselves.