If you’ve coded shellcode before, you know that the code often needs to find out the base address address where kernel32.dll is loaded in memory. Most publicly available code expects the second entry in the “InitializationOrder” list to be kernel32. Unfortunately, it seems that this is not the case in the public Windows 7 beta.
I’ve create a solution to this problem that should be able to find kernel32.dll on all versions of Windows with minimal code size increase. It works by walking the “InInitializationOrder” list mentioned above and checking the length of the name of the module: the Unicode string “kernel32.dll” has a terminating 0 as the 12th character. From my (limited) testing, it seems that scanning for a 0 as the 24th byte in the name allows the code to find kernel32.dll correctly.
More details can be found .
The code:
XOR ECX, ECX ; ECX = 0
MOV ESI, [FS:ECX + 0x30] ; ESI = &(PEB) ([FS:0x30])
MOV ESI, [ESI + 0x0C] ; ESI = PEB->Ldr
MOV ESI, [ESI + 0x1C] ; ESI = PEB->Ldr.InInitOrder
next_module:
MOV EBP, [ESI + 0x08] ; EBP = InInitOrder[X].base_address
MOV EDI, [ESI + 0x20] ; EBP = InInitOrder[X].module_name (unicode)
MOV ESI, [ESI] ; ESI = InInitOrder[X].flink (next module)
CMP [EDI + 12*2], CL ; modulename[12] == 0 ?
JNE next_module ; No: try next module.
NB. See for a problem (and solution) on Win2K targets courtesy of aniway.