The principle is as follows:
The winmain code of each user-state process is called by the START code (crtstartup), and the start code is called by a function in kernel32.dll, of course, there may also be no functions such as winmain and winmaincrtstart (such as the Code Compiled by Delphi). However, after the process is started, an unknown code location in kernel32.dll must be stored in the stack, therefore, the base address of kernel32.dll can be found from the top to the bottom of the test stack, and a short piece of code is written. It passes the test under Win XP SP2 and VC ++ 6.0 SP5, the base address of kernel32.dll on my machine is 0x7c800000.
Code:
# Include <stdio. h>
# Include <conio. h>
# Include <windows. h>
DWORD getkernel32 (void)
{
DWORD tryaddr = 0;
Pimage_dos_header PDOS = NULL;
Pimage_nt_headers PNT = NULL;
Pimage_export_directory pied = NULL;
DWORD * pkernel = NULL;
Int I = 0;
Pdword PESP = (pdword) & PESP;
Bool bfound = false;
Do
{
_ Try
{
Tryaddr = * PESP;
For (I = 0; I <4; I ++)
{
Tryaddr & = 0xffff0000 <(I <2 );
PDOS = (pimage_dos_header) tryaddr;
PNT = (pimage_nt_headers) (tryaddr + PDOS-> e_lfanew );
If (PDOS-> e_magic = 'zm' & PNT-> Signature = 'EP ')
{
Pied = (pimage_export_directory) (tryaddr + PNT-> optionalheader. datadirectory [0]. virtualaddress );
Pkernel = (DWORD *) (tryaddr + pied-> name );
// Kernel32 or Kernel32
If (* pkernel = 'nrek' & * (pkernel + 1) = '23le') |
(* Pkernel = 'nrek' & * (pkernel + 1) = '23le '))
{
Bfound = true;
Break;
}; // End if pkernel
} // End if PDOS
} // End for I
}
_ Partition T (1)
{
NULL;
}
PESP ++;
} While (! Bfound );
Return tryaddr;
}
Int main (void)
{
Printf ("kernel32.dll at: 0x %. 8x/N", getkernel32 ());
Return getchar ();
}