First write a very simple main function:
int Main () { printf ("main"address (? ):%08x", Main);}
Single-step debugging, you can know the main function of the real entry address is: 00be91a0
However, the value of our console output is
Why is there such a difference? There is an article in the yard that Daniel wrote about injection: http://www.cnblogs.com/fanzhidongyzby/archive/2012/08/30/2664287.html, which mentions this problem.
It mentions an algorithm to parse the real address:
//converts a function address to a real addressUnsignedintgetfunrealaddr (lpvoid fun) {unsignedintREALADDR = (unsignedint) Fun;//virtual function Address//calculate function Real AddressUnsignedChar* Funaddr = (unsignedChar*) fun; if(funaddr[0] ==0xe9)//To determine if it is a virtual function address, E9 is the JMP Directive { intDISP = * (int*) (FUNADDR +1);//gets the offset of the jump instructionRealaddr + =5+ disp;//fixed to real function address } returnrealaddr;}
I believe the novice friends are just like me for this code how to come to the touch of the mind. Hereby I have a single-step commissioning study, only to understand the principle of general:
The address of the main function name is actually a Jmp XXX directive,
From the disassembly debug code of VS can be seen, the first parameter main into the stack, the corresponding assembly code is the push 0be135ch, the number in the stack is just the console output of the address. So obviously this address is the address of the function main's "function name" (in fact, there should be no strings of "main" in the assembly, so it might be possible to see them in a debugger like VS or OD, which is the result of these debuggers being inferred from experience.) )。 Then we enter the address in the Address bar 0be135ch, we can jump to the relative position.
The assembler code for JMP is E9, and the back 4 bytes "3F 7E 00 00" are actually reversed relative address 0x00007e3f. That's what we see as main. Of course, this address is only the relative position of the code, if after running, add the current module base address is the absolute addresses.
So, since this "main" position is just a jump instruction (JMP), it must have jumped to the location of the address followed by JMP, which means the address is the real address of the main function.
Of course, 0be135ch is from E9 3F 7E 00 00 This instruction began to count. That is, starting from the position of E9 3F 7E 00 00, jumping past 0x00007e3f bytes, to the real main function entrance.
So the real address is
0be135ch+5 (instruction accounted for the number of bytes in JMP main) +0x00007e3f=00be91a0.
So let's go back to the function section.
UINT REALADDR = (uint) main;//The unboxing is converted into unsigned int data. Represents the address represented by the name of the main functionUnsignedChar* funcaddr = (uchar*) main;//here is the byte content of the main address, the content is "E9 3F 7E XX" (JMP main), so as long as the previous byte instruction is E9 to know if it is the real address, if it is JMP (E9) is not the real address. if(funcaddr[0] ==0xe9){//becauseuchar* FA = funcaddr +1;//The pointer moves back one bit, from E9 to 3f. int* as= (int*) (FA);//take the pointer = int data (total 4 bytes), which is actually a jump address. intDISP = * as;//take the contents of the pointerRealaddr + =5+ disp;//On the base of the main address +jmp The bytes of main and the number of bytes to jump forward}
VC Get function name real address