Search This Blog

Tuesday 9 September 2014

WinDbg : Trying To Find The Entry Point Of A Binary

WinDbg : Trying To Find The Entry Point Of A Binary


Alright. I did a lot of talking about the WinDbg commands so far. It is time to walk the talk, and put these commands to some practical usage. Lets start with trying to find the entry point of a binary in memory loaded in memory. The list of commands which would be used in this article are:


  1. !process
  2. ,process
  3. !dh
  4. u
In this example, we are connected to the debugee as a kernel debugger. The commands might slightly vary if run through user mode. I will try to give such specific examples as and where necessary.

For this example we will use lsass.exe, you can use any other process you like.


kd> !process 0 0 lsass.exe

PROCESS 84cdc860  SessionId: 0  Cid: 0208    Peb: 7ffda000  ParentCid: 018c
    DirBase: 1eed30e0  ObjectTable: 95f00d18  HandleCount: 513.
    Image: lsass.exe

Now lets shift the debugger context to the process lsass.exe
kd> .process /p /r 84cdc860  
Implicit process is now 84cdc860
Loading User Symbols
............................................................

Lets run the !dh command on lsass.exe to see what all it contains.
kd> !dh lsass.exe

File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
     14C machine (i386)
       4 number of sections
4A5BBF3E time date stamp Tue Jul 14 04:41:58 2009

       0 file pointer to symbol table
       0 number of symbols
      E0 size of optional header
     122 characteristics
            Executable
            App can handle >2gb addresses
            32 bit word machine

OPTIONAL HEADER VALUES
     10B magic #
    9.00 linker version
    4200 size of code
    1000 size of initialized data
       0 size of uninitialized data
    2F3D address of entry point
    1000 base of code
         ----- new -----
00d90000 image base
    1000 section alignment
     200 file alignment
       2 subsystem (Windows GUI)
    6.01 operating system version
    6.01 image version
    6.01 subsystem version
    9000 size of image
     600 size of headers
    6193 checksum
00040000 size of stack reserve
00006000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
    8140  DLL characteristics
            Dynamic base
            NX compatible
            Terminal server aware
    1EC4 [      6B] address [size] of Export Directory
     4478 [     154] address [size] of Import Directory
     7000 [     700] address [size] of Resource Directory
          0 [         0] address [size] of Exception Directory
          0 [         0] address [size] of Security Directory
     8000 [     368] address [size] of Base Relocation Directory
     5080 [       38] address [size] of Debug Directory
          0 [         0] address [size] of Description Directory
          0 [         0] address [size] of Special Directory
          0 [         0] address [size] of Thread Storage Directory
    3F90 [        40] address [size] of Load Configuration Directory
      280 [      294] address [size] of Bound Import Directory
    1000 [     1AC] address [size] of Import Address Table Directory
         0 [          0] address [size] of Delay Import Directory
         0 [          0] address [size] of COR20 Header Directory
         0 [          0] address [size] of Reserved Directory


SECTION HEADER #1
   .text name
    40DE virtual size
    1000 virtual address
    4200 size of raw data
     600 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         (no align specified)
         Execute Read


Debug Directories(2)
Type       Size     Address  Pointer
cv           22        50bc     46bc Format: RSDS, guid, 2, lsass.pdb
(    10)       4        50b8     46b8

SECTION HEADER #2
   .data name
     3CC virtual size
    6000 virtual address
     400 size of raw data
    4800 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0000040 flags
         Initialized Data
         (no align specified)
         Read Write

SECTION HEADER #3
   .rsrc name
     700 virtual size
    7000 virtual address
     800 size of raw data
    4C00 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
40000040 flags
         Initialized Data
         (no align specified)
         Read Only

SECTION HEADER #4
  .reloc name
     368 virtual size
    8000 virtual address
     400 size of raw data
    5400 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
42000040 flags
         Initialized Data
         Discardable
         (no align specified)
         Read Only

The output shows us, among other useful information, the relative virtual address offset of the entry point to the binary (in bold above). For this binary instance, it is at hex 0x2F3D.So if we disassemble this offset from the starting of the image, we should be able to see the code for the Main function. Lets try that:

kd> u 2F3D+lsass.exe
lsass!mainCRTStartup:
00d92f3d e80dffffff      call    lsass!__security_init_cookie (00d92e4f)
00d92f42 6a10            push    10h
00d92f44 683030d900      push    offset lsass!SspiSrvClientCallback+0xc (00d93030)
00d92f49 e84e030000      call    lsass!_SEH_prolog4 (00d9329c)
00d92f4e 33db            xor     ebx,ebx
00d92f50 895dfc          mov     dword ptr [ebp-4],ebx
00d92f53 64a118000000    mov     eax,dword ptr fs:[00000018h]
00d92f59 8b7004          mov     esi,dword ptr [eax+4]

As we see, it is indeed Main, or MainCRTStartup, which is the true entry point to the binary. Also worth noting, is the ImageBase field (again in bold above), that is the virtual address where lsass.exe is actually loaded. So in the unassemble command we could have given that address instead of the string lsass.exe to get the same output.

kd> u 2F3D+00d90000 
lsass!mainCRTStartup:
00d92f3d e80dffffff      call    lsass!__security_init_cookie (00d92e4f)
00d92f42 6a10            push    10h
00d92f44 683030d900      push    offset lsass!SspiSrvClientCallback+0xc (00d93030)
00d92f49 e84e030000      call    lsass!_SEH_prolog4 (00d9329c)
00d92f4e 33db            xor     ebx,ebx
00d92f50 895dfc          mov     dword ptr [ebp-4],ebx
00d92f53 64a118000000    mov     eax,dword ptr fs:[00000018h]
00d92f59 8b7004          mov     esi,dword ptr [eax+4]

While doing this exercise, it comes to ones mind, lsass is an executable, what if we run the commands for a DLL, would it give us similar outputs? Lets find out. For this example, I am going to use ntdll.dll which is usually mapped to every win32 proecss. You can, use the same commands for other DLLs as well.

kd> !dh ntdll.dll

File Type: DLL
FILE HEADER VALUES
     14C machine (i386)
       5 number of sections
4CE7B96E time date stamp Sat Nov 20 17:35:02 2010

       0 file pointer to symbol table
       0 number of symbols
      E0 size of optional header
    2102 characteristics
            Executable
            32 bit word machine
            DLL

OPTIONAL HEADER VALUES
     10B magic #
    9.00 linker version
   D5000 size of code
   63200 size of initialized data
       0 size of uninitialized data
       0 address of entry point
    1000 base of code
         ----- new -----
77ba0000 image base
    1000 section alignment
     200 file alignment
       3 subsystem (Windows CUI)
    6.01 operating system version
    6.01 image version
    6.01 subsystem version
  13C000 size of image
     400 size of headers
  1490D9 checksum
00040000 size of stack reserve
00001000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
     140  DLL characteristics
            Dynamic base
            NX compatible
   36190 [    F018] address [size] of Export Directory
       0 [       0] address [size] of Import Directory
   E0000 [   560D8] address [size] of Resource Directory
       0 [       0] address [size] of Exception Directory
  137000 [    3928] address [size] of Security Directory
  137000 [    4C3C] address [size] of Base Relocation Directory
   D5D08 [      38] address [size] of Debug Directory
       0 [       0] address [size] of Description Directory
       0 [       0] address [size] of Special Directory
       0 [       0] address [size] of Thread Storage Directory
   1E080 [      40] address [size] of Load Configuration Directory
       0 [       0] address [size] of Bound Import Directory
       0 [       0] address [size] of Import Address Table Directory
       0 [       0] address [size] of Delay Import Directory
       0 [       0] address [size] of COR20 Header Directory
       0 [       0] address [size] of Reserved Directory


SECTION HEADER #1
   .text name
   D4D66 virtual size
    1000 virtual address
   D4E00 size of raw data
     400 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         (no align specified)
         Execute Read


Debug Directories(2)
Type       Size     Address  Pointer
Can't read debug dir

SECTION HEADER #2
      RT name
     1DC virtual size
   D6000 virtual address
     200 size of raw data
   D5200 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         (no align specified)
         Execute Read

SECTION HEADER #3
   .data name
    8064 virtual size
   D7000 virtual address
    6C00 size of raw data
   D5400 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0000040 flags
         Initialized Data
         (no align specified)
         Read Write

SECTION HEADER #4
   .rsrc name
   560D8 virtual size
   E0000 virtual address
   56200 size of raw data
   DC000 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
40000040 flags
         Initialized Data
         (no align specified)
         Read Only

SECTION HEADER #5
  .reloc name
    4C3C virtual size
  137000 virtual address
    4E00 size of raw data
  132200 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
42000040 flags
         Initialized Data
         Discardable
         (no align specified)
         Read Only

Just as we suspected, there is no entry point for a DLL, the address is zero. Also check, the File Type filed for a DLL, it says 'DLL'. where as for the executable it said 'EXECUTABLE IMAGE'.

Lets try this command for a driver (ntfs.sys), to see how that shows up:

1: kd> !dh ntfs.sys

File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
    8664 machine (X64)
       8 number of sections
4A5BC14F time date stamp Tue Jul 14 04:50:47 2009

       0 file pointer to symbol table
       0 number of symbols
      F0 size of optional header
      22 characteristics
            Executable
            App can handle >2gb addresses

OPTIONAL HEADER VALUES
     20B magic #
    9.00 linker version
  157200 size of code
   46A00 size of initialized data
       0 size of uninitialized data
  17E06C address of entry point
    1000 base of code
         ----- new -----
fffff80002213000 image base
    1000 section alignment
     200 file alignment
       1 subsystem (Native)
    6.01 operating system version
    6.01 image version
    6.01 subsystem version
  1A3000 size of image
     400 size of headers
  195F88 checksum
0000000000040000 size of stack reserve
0000000000001000 size of stack commit
0000000000100000 size of heap reserve
0000000000001000 size of heap commit
       0  DLL characteristics
           0 [            0] address [size] of Export Directory
  18013C [          64] address [size] of Import Directory
   185000 [   1CFF0] address [size] of Resource Directory
     67000 [      9600] address [size] of Exception Directory
   193800 [      1C50] address [size] of Security Directory
   1A2000 [        134] address [size] of Base Relocation Directory
     45158 [          38] address [size] of Debug Directory
            0 [            0] address [size] of Description Directory
            0 [            0] address [size] of Special Directory
            0 [            0] address [size] of Thread Storage Directory
            0 [            0] address [size] of Load Configuration Directory
            0 [            0] address [size] of Bound Import Directory
     46000 [        F68] address [size] of Import Address Table Directory
            0 [            0] address [size] of Delay Import Directory
            0 [            0] address [size] of COR20 Header Directory
            0 [            0] address [size] of Reserved Directory


SECTION HEADER #1
   .text name
   441B5 virtual size
    1000 virtual address
   44200 size of raw data
     400 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
68000020 flags
         Code
         Not Paged
         (no align specified)
         Execute Read


Debug Directories(2)
Type       Size     Address  Pointer
cv           21       45194    44594 Format: RSDS, guid, 2, ntfs.pdb
(    10)       4       45190    44590

SECTION HEADER #2
  .rdata name
   14BB4 virtual size
   46000 virtual address
   14C00 size of raw data
   44600 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
48000040 flags
         Initialized Data
         Not Paged
         (no align specified)
         Read Only

SECTION HEADER #3
   .data name
    B4E0 virtual size
   5B000 virtual address
     E00 size of raw data
   59200 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C8000040 flags
         Initialized Data
         Not Paged
         (no align specified)
         Read Write

SECTION HEADER #4
  .pdata name
    9600 virtual size
   67000 virtual address
    9600 size of raw data
   5A000 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
48000040 flags
         Initialized Data
         Not Paged
         (no align specified)
         Read Only

SECTION HEADER #5
    PAGE name
  10CD8A virtual size
   71000 virtual address
  10CE00 size of raw data
   63600 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         (no align specified)
         Execute Read

SECTION HEADER #6
    INIT name
    603C virtual size
  17E000 virtual address
    6200 size of raw data
  170400 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
E2000020 flags
         Code
         Discardable
         (no align specified)
         Execute Read Write

SECTION HEADER #7
   .rsrc name
   1CFF0 virtual size
  185000 virtual address
   1D000 size of raw data
  176600 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
40000040 flags
         Initialized Data
         (no align specified)
         Read Only

SECTION HEADER #8
  .reloc name
     134 virtual size
  1A2000 virtual address
     200 size of raw data
  193600 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
42000040 flags
         Initialized Data
         Discardable
         (no align specified)

         Read Only

Field Name
Executable (lsass.exe, ntfs.sys)
DLL (ntdll.dll)
File Type
EXECUTABLE_IMAGE
DLL
Address Of Entry Point
A valid Offset inside the image from the Image Base
Zero
Image Base
A valid virtual address
A valid virtual address

Note: The output for the driver section is taken from a x64 OS, hence the extra bytes in the address ranges.












No comments:

Post a Comment