学习笔记通过PEB获取kernal32.dll基地址

原始代码来自PE权威指南

;------------------------

; 获取kernel32.dll的基址

; 从PEB结构中搜索kernel32.dll的基地址

; 戚利

; 2010.6.27

;------------------------

    .386

    .model flat,stdcall

    option casemap:none

 

include    windows.inc

include    user32.inc

includelib user32.lib

include    kernel32.inc

includelib kernel32.lib

 

;数据段

    .data

 

szText  db 'kernel32.dll的基地址为%08x',0

szOut   db '%08x',0dh,0ah,0

szBuffer db 256 dup(0)

 

;代码段

    .code

 

start:

 

   assume fs:nothing

   mov eax,fs:[30h] ;获取PEB所在地址

   mov eax,[eax+0ch] ;获取PEB_LDR_DATA 结构指针

   mov esi,[eax+1ch] ;获取InInitializationOrderModuleList 链表头

                     ;第一个LDR_MODULE节点InInitializationOrderModuleList成员的指针

   lodsd             ;获取双向链表当前节点后继的指针

   mov eax,[eax+8]   ;获取kernel32.dll的基地址

 

   ;输出模块基地址

   invoke wsprintf,addr szBuffer,addr szText,eax

   invoke MessageBox,NULL,addr szBuffer,NULL,MB_OK

   ret

   end start

这个是网上找的神图

 

可以看到fs:[30]放着PEB指针, [fs:[30]+0ch]存放ldr

ldr的后三个LIST_ENTRY类型的成员, 是一个双向链表

_LIST_ENTRY中的FLnk对应着_LDR_DATA_TABLE_ENTRY的相应LIST_ENTRY成员

 

上Debuger

 执行完第一条指令我们就可以看到eax已经指向的PEB了

0:000> t

eax=00288000 ebx=00288000 ecx=00401000 edx=00401000 esi=00401000 edi=00401000

eip=00401006 esp=0019ff74 ebp=0019ff80 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

pebkernelbase+0x1006:

00401006 8b400c          mov     eax,dword ptr [eax+0Ch] ds:002b:0028800c={ntdll!PebLdr (7730dca0)}

 

0:000> u

pebkernelbase+0x1006:

00401006 8b400c          mov     eax,dword ptr [eax+0Ch]

00401009 8b701c          mov     esi,dword ptr [eax+1Ch]

0040100c ad              lods    dword ptr [esi]

0040100d 8b4008          mov     eax,dword ptr [eax+8]

00401010 50              push    eax

00401011 6800304000      push    offset pebkernelbase+0x3000 (00403000)

00401016 6822304000      push    offset pebkernelbase+0x3022 (00403022)

0040101b e814000000      call    pebkernelbase+0x1034 (00401034)

0:000> dt _PEB 00288000

 

0:000> dt _PEB 00288000

ntdll!_PEB

   +0x000 InheritedAddressSpace : 0 ''

   +0x001 ReadImageFileExecOptions : 0 ''

   +0x002 BeingDebugged    : 0x1 ''

   +0x003 BitField         : 0 ''

   +0x003 ImageUsesLargePages : 0y0

   +0x003 IsProtectedProcess : 0y0

   +0x003 IsImageDynamicallyRelocated : 0y0

   +0x003 SkipPatchingUser32Forwarders : 0y0

   +0x003 IsPackagedProcess : 0y0

   +0x003 IsAppContainer   : 0y0

   +0x003 IsProtectedProcessLight : 0y0

   +0x003 IsLongPathAwareProcess : 0y0

   +0x004 Mutant           : 0xffffffff Void

   +0x008 ImageBaseAddress : 0x00400000 Void

   +0x00c Ldr              : 0x7730dca0 _PEB_LDR_DATA    我们主要看这个,它的类型_PEB_LDR_DATA可以从上图看到

 

主要看绿色的成员

0:000> dx -r1 ((ntdll!_PEB_LDR_DATA *)0x7730dca0)

((ntdll!_PEB_LDR_DATA *)0x7730dca0)                 : 0x7730dca0 [Type: _PEB_LDR_DATA *]

    [+0x000] Length           : 0x30 [Type: unsigned long]

    [+0x004] Initialized      : 0x1 [Type: unsigned char]

    [+0x008] SsHandle         : 0x0 [Type: void *]

    [+0x00c] InLoadOrderModuleList [Type: _LIST_ENTRY]

    [+0x014] InMemoryOrderModuleList [Type: _LIST_ENTRY]

    [+0x01c] InInitializationOrderModuleList [Type: _LIST_ENTRY]  它的VA为0X7730DCBC 点击这个继续看下面

    [+0x024] EntryInProgress  : 0x0 [Type: void *]

    [+0x028] ShutdownInProgress : 0x0 [Type: unsigned char]

    [+0x02c] ShutdownThreadId : 0x0 [Type: void *]

可以看到这个双向链表有11个节点, 从0x463268 ~ 0x469b50  (看InInitializationOrderModuleList )

0:000> dx -r1 (*((ntdll!_LIST_ENTRY *)0x7730dcbc))

(*((ntdll!_LIST_ENTRY *)0x7730dcbc))                 [Type: _LIST_ENTRY]

    [+0x000] Flink            : 0x463268 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x469b50 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x463268)

((ntdll!_LIST_ENTRY *)0x463268)                 : 0x463268 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x463b10 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x7730dcbc [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x463b10)

((ntdll!_LIST_ENTRY *)0x463b10)                 : 0x463b10 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x463750 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x463268 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x463750)

((ntdll!_LIST_ENTRY *)0x463750)                 : 0x463750 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x464948 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x463b10 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x464948)

((ntdll!_LIST_ENTRY *)0x464948)                 : 0x464948 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x465670 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x463750 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x465670)

((ntdll!_LIST_ENTRY *)0x465670)                 : 0x465670 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x465398 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x464948 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x465398)

((ntdll!_LIST_ENTRY *)0x465398)                 : 0x465398 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x4650a8 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x465670 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x4650a8)

((ntdll!_LIST_ENTRY *)0x4650a8)                 : 0x4650a8 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x464b88 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x465398 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x464b88)

((ntdll!_LIST_ENTRY *)0x464b88)                 : 0x464b88 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x464698 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x4650a8 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x464698)

((ntdll!_LIST_ENTRY *)0x464698)                 : 0x464698 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x469b50 [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x464b88 [Type: _LIST_ENTRY *]

0:000> dx -r1 ((ntdll!_LIST_ENTRY *)0x469b50)

((ntdll!_LIST_ENTRY *)0x469b50)                 : 0x469b50 [Type: _LIST_ENTRY *]

    [+0x000] Flink            : 0x7730dcbc [Type: _LIST_ENTRY *]

    [+0x004] Blink            : 0x464698 [Type: _LIST_ENTRY *]

 

用!peb指令看下, 系统默认dump出来的东东,看下面的绿色

 

0:000> !peb

PEB at 00288000

    InheritedAddressSpace:    No

    ReadImageFileExecOptions: No

    BeingDebugged:            Yes

    ImageBaseAddress:         00400000

    NtGlobalFlag:             70

    NtGlobalFlag2:            0

    Ldr                       7730dca0

    Ldr.Initialized:          Yes

    Ldr.InInitializationOrderModuleList: 00463268 . 00469b50 !!!!!!!!

    Ldr.InLoadOrderModuleList:           00463360 . 00469b40

    Ldr.InMemoryOrderModuleList:         00463368 . 00469b48

            Base TimeStamp                     Module

          400000 4d5b904f Feb 16 16:52:31 2011 D:\技术书籍\随书代码\Windows_PE权威指南》source\《Windows_PE权威指南》source\chapter11\pebkernelbase.exe

        771f0000 C:\WINDOWS\SYSTEM32\ntdll.dll

        74a60000 7b5427ec Jul 27 09:33:32 2035 C:\WINDOWS\System32\KERNEL32.DLL

        76b80000 54734dee Nov 24 23:25:34 2014 C:\WINDOWS\System32\KERNELBASE.dll

        768e0000 C:\WINDOWS\System32\user32.dll

        755b0000 6b5c1b19 Jan 29 12:52:41 2027 C:\WINDOWS\System32\win32u.dll

        74c40000 527faf7f Nov 11 00:08:31 2013 C:\WINDOWS\System32\GDI32.dll

        76eb0000 C:\WINDOWS\System32\gdi32full.dll

        75930000 47892406 Jan 13 04:33:10 2008 C:\WINDOWS\System32\msvcp_win.dll

        75d10000 6dbf7eae May 07 06:52:30 2028 C:\WINDOWS\System32\ucrtbase.dll

        75750000 60562aa5 Mar 21 01:02:29 2021 C:\WINDOWS\System32\IMM32.DLL

 

可以看到每个节点都有前驱和后继

仍然用第一个LDR说明InIntializationOrderModuleList说明

我们知道_LIST_ENTRY结构包含两个指针成员, 作为双向链表的链, 同时这两个指针又对应着下面这个结构体中的相应LIST_ENTRY

 

 

 

对第一个节点的Flink,看下面的数据, FLINK作为_LIST_ENTRY结构总共为8bytes, 由于当前我们的LIST_ENTRY来自的是InInitializationOrderModuleList,  所以它指向_LDR_DATA_TRABLE_ENTRY中的第三个成员InInitializationOrderLinks。 如果LIST_ENTRY来自_PEB_LDR_DATA中的InLoadOrderModuleList,那么FLINK就指向的是_LDR_DATA_TABLE_ENTRY中的InLoadOrderLinker成员

 

所以0x463268 +8 后就是_LDR_DATA_TABLE_ENTRY的dllbase 了, 可以看到是771F0000 对应着上面!peb中的ntdll。。。 名字来自的是FULLDLLName。 从InInitializationOrderLinks开始偏移为 +8(List_entry) +4(DLLBASE)+4(Entrypoint)+4(SizeOfImage)+4(_Unicode_string的后4Bytes才是Buffer)

FullDllName就是下面的00463138

0:000> dd 0x463268      ntdll.dll

00463268  00463b10 7730dcbc 771f0000 00000000

00463278  0019a000 003c003a 00463138 00140012

00463288  771f9270 0000a2c4 0000ffff 7730db40

 

0:000> dt _unicode_string

ntdll!_UNICODE_STRING

+0x000 Length : Uint2B

+0x002 MaximumLength : Uint2B

+0x004 Buffer : Ptr32 Uint2B

刚好对应了ntdll.dll的fullName

0:000> db 00463138

00463138  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

00463148  57 00 53 00 5c 00 53 00-59 00 53 00 54 00 45 00  W.S.\.S.Y.S.T.E.

00463158  4d 00 33 00 32 00 5c 00-6e 00 74 00 64 00 6c 00  M.3.2.\.n.t.d.l.

00463168  6c 00 2e 00 64 00 6c 00-6c 00 00 00 ab ab ab ab  l...d.l.l.......

同理771F9270对应着baseDllname

0:000> db 771F9270

771f9270  6e 00 74 00 64 00 6c 00-6c 00 2e 00 64 00 6c 00  n.t.d.l.l.

 

0x463268 指向的下一个LIST_ENTRY结点中的Flink为463b10, 来看这个FLink对应的_LDR_DATA_TABLE_ENTRY

0:000> dd 0x463b10    kernalBase.dll

00463b10  00463750 00463268 76b80000 76c6d6e0       绿色对应kernalBase的基地址  

00463b20  001fd000 00460044 00463c08 001e001c       

00463b30  00463c30 0008a2cc 0000ffff 7730dac0

00463b40  7730dac0 54734dee 00000000 00000000

00463b50  00463bc0 00463bc0 00463bc0 00000000

00463b60  74a60000 771f1304 004656c8 004632c0

00463b70  004649a0 004633d4 004649ac 004637b5

00463b80  76b80000 00000000 3724d21d 01d5f2f1

 

0:000> db 00463c08

00463c08  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

00463c18  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

00463c28  6d 00 33 00 32 00 5c 00-4b 00 45 00 52 00 4e 00  m.3.2.\.K.E.R.N.

00463c38  45 00 4c 00 42 00 41 00-53 00 45 00 2e 00 64 00  E.L.B.A.S.E...d.

00463c48  6c 00 6c 00 00 00 ab ab-ab ab ab ab ab ab ee fe  l.l

---------------------------

同理我们遍历上面的双链表各个结点

0:000> dd 0x463750        kernal32.dll

00463750  00464948 00463b10 74a60000 74a75f70

00463760  000e0000 00420040 00463848 001a0018

00463770  00463870 000ca2cc 0000ffff 7730db30

00463780  7730db30 7b5427ec 00000000 00000000

00463790  00463800 00463800 00463800 00000000

004637a0  00000000 771f1304 004633c8 00464be0

004637b0  004649a0 00463b74 004646fc 00000000

004637c0  74a60000 00000000 3724d21d 01d5f2f1

 

0:000> db 00463848

00463848  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

00463858  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

00463868  6d 00 33 00 32 00 5c 00-4b 00 45 00 52 00 4e 00  m.3.2.\.K.E.R.N.

00463878  45 00 4c 00 33 00 32 00-2e 00 44 00 4c 00 4c 00  E.L.3.2...D.L.L.

---------------------

0:000> dd 0x464948    win32u.dll

00464948  00465670 00463750 755b0000 00000000

00464958  00017000 003e003c 00464a40 00160014

00464968  00464a68 8008a2ec 00000006 004650d4

00464978  7730db20 6b5c1b19 00000000 00000000

 

0:000> db 00464a40

00464a40  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

00464a50  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

00464a60  6d 00 33 00 32 00 5c 00-77 00 69 00 6e 00 33 00  m.3.2.\.w.i.n.3.

00464a70  32 00 75 00 2e 00 64 00-6c 00 6c 00 00 00 ab ab  2.u...d.l.l.....

--------------------

 

0:000> dd 0x465670    ucrtbase.dll

00465670  00465398 00464948 75d10000 75d37670

00465680  0011f000 00420040 00465768 001a0018

00465690  00465790 8008a2ec 00000006 7730db58

 

0:000> db 00465768

00465768  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

00465778  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

00465788  6d 00 33 00 32 00 5c 00-75 00 63 00 72 00 74 00  m.3.2.\.u.c.r.t.

00465798  62 00 61 00 73 00 65 00-2e 00 64 00 6c 00 6c 00  b.a.s.e...d.l.l.

-------------------

 

0:000> dd 0x465398    msvcp_win.dll

00465398  004650a8 00465670 75930000 75946760

004653a8  0007c000 00440042 00465490 001c001a

004653b8  004654b8 800ca2ec 00000006 7730db20

004653c8  004650d4 47892406 00000000 00000000

 

0:000> db 00465490

00465490  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

004654a0  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

004654b0  6d 00 33 00 32 00 5c 00-6d 00 73 00 76 00 63 00  m.3.2.\.m.s.v.c.

004654c0  70 00 5f 00 77 00 69 00-6e 00 2e 00 64 00 6c 00  p._.w.i.n...d.l.

-------------------------

 

0:000> dd 0x4650a8   gdi32full.dll

004650a8  00464b88 00465398 76eb0000 76f70e50

004650b8  0015a000 00440042 004651a0 001c001a

004650c8  004651c8 800ca2ec 00000006 004653c4

004650d8  00464974 b22d992c 00000000 00000000

 

0:000> db 004651a0

004651a0  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

004651b0  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

004651c0  6d 00 33 00 32 00 5c 00-67 00 64 00 69 00 33 00  m.3.2.\.g.d.i.3.

004651d0  32 00 66 00 75 00 6c 00-6c 00 2e 00 64 00 6c 00  2.f.u.l.l...d.l.

004651e0  6c 00 00 00 ab ab ab ab-ab ab ab ab ee fe ee fe  l...............

----------------------

 

0:000> dd 0x464b88  gdi32.dll

00464b88  00464698 004650a8 74c40000 74c44b50

00464b98  00021000 003c003a 00464c80 00140012

00464ba8  00464ca8 800ca2ec 00000006 7730daa8

 

0:000> db 00464c80   

00464c80  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

00464c90  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

00464ca0  6d 00 33 00 32 00 5c 00-47 00 44 00 49 00 33 00  m.3.2.\.G.D.I.3.

00464cb0  32 00 2e 00 64 00 6c 00-6c 00 00 00 ab ab ab ab  2...d.l.l.......

-----------

0:000> dd 0x464698    user32.dll

00464698  00469b50 00464b88 768e0000 7690c630

004646a8  00197000 003e003c 00464790 00160014

004646b8  004647b8 800ca2ec 00000006 7730daa0

 

0:000> db 00464790

00464790  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

004647a0  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

004647b0  6d 00 33 00 32 00 5c 00-75 00 73 00 65 00 72 00  m.3.2.\.u.s.e.r.

004647c0  33 00 32 00 2e 00 64 00-6c 00 6c 00 00 00 ab ab  3.2...d.l.l.....

-------------------

0:000> dd 0x469b50   imm32.dll

00469b50  7730dcbc 00464698 75750000 75754390

00469b60  00025000 003c003a 00469c48 00140012

00469b70  00469c70 8008a2cc 00000006 7730db90

 

0:000> db 00469c48

00469c48  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.

00469c58  57 00 53 00 5c 00 53 00-79 00 73 00 74 00 65 00  W.S.\.S.y.s.t.e.

00469c68  6d 00 33 00 32 00 5c 00-49 00 4d 00 4d 00 33 00  m.3.2.\.I.M.M.3.

00469c78  32 00 2e 00 44 00 4c 00-4c 00 00 00 ab ab ab ab  2...D.L.L

------------------------

注意链表最后一个结点有意思, 它只是作为一个结束标记。 可以看到DLLBASE DLLname等关键字段都是null

0:000> dd 0x7730dcbc

7730dcbc  00463268 00469b50 00000000 00000000

7730dccc  00000000 00000002 00000000 00000000

7730dcdc  00000000 00000000 00000000 00000000

 

上面可以看到装载过程中的所有dll和!peb 的dump出来的信息一样, 0x7730dcbc 这个结点的base和dllname貌似直接来自!peb中的ImageBaseAddress和ImagePathName?!

上面就是如何求装载的dll名字, 以及装载基地址的过程。。。。

最后再注意: LDR中的下面字段几个list_entry分别指向_ldr_data_table_entry中同名的list_entry.

所以计算的时候一定注意 正确求出偏移地址。。。e.g. 通过Ldr.InInitializationOrderModuleList找DLL加载地址偏移应该是+8 (从最靠近DLLBASE的LIST_ENTRY),也就是上面我们计算式的黄色标注

Ldr.InLoadOrderModuleList找DLL加载偏移地址为0X18 (与DLLBASE间隔3个LIST_ENTRY)

Ldr.InMemoryOrderModuleList找DLL加载偏移地址为0X10 (与DLLBASE讲个两个LIST_ENTRY)

Sizeof(LIST_ENTRY) == 8

 

OK,在不同OS上面,汇编生成的PE返回不同的基地址, 这个自己调试就可以知道为什么有时候不是kernel32.dll的基地址了。。。我用的是win10

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值