Hacking/Shellcode/kernel32

From Skypher

Jump to: navigation, search

Main Page
├─▷Programming
└─▼Hacking
  ├─▼Shellcode
  │ ├─▷Bind
  │ ├─○Restricted instruction set
  │ ├─▷Alphanumeric
  │ ├─▷ASCII Art
  │ ├─●kernel32
  │ ├─○GetPC
  │ └─▷Egg hunt
  ├─▷Windows internals
  ├─○Vulnerabilities
  ├─○Heap spraying
  └─○List of security teams contact information


If you’ve coded shellcode before, you know that the code often needs to find out the address where kernel32 is loaded in memory. Below is code that use the FS: segment register to find the TEB, which in turn can be used to find the PEB. The PEB then contains a pointer to LoaderData, which contains linked lists with information on loaded modules. From these lists the location of kernel32.dll can be determined: in all versions of Windows up to Windows 7, it is the second entry in the "InitializationOrder" list.

    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 (ntdll.dll)
    LODSD                               ; EAX = PEB->Ldr.InInitOrder.flink (kernel32.dll)
    MOV     EBP, [EAX + 0x08]           ; EBP = PEB->Ldr.InInitOrder.flink.base_address

Unfortunately, it seems that in the public Windows 7 beta, the order is different: another module is loaded as the second module and kernel32.dll is the third.

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.

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.
Personal tools