您的位置:首页 > 其它

获取kernel32.dll基址

2016-01-03 11:00 309 查看
获取kernel32.dll基址


一 原理和概述

找kernel32基地址的方法一般有三种:暴力搜索法、异常处理链表搜索法、PEB法。

暴力搜索法是最早的动态查找kernel32基地址的方法。它的原理是: 几乎所有的win32可执行文件(pe格

式文件)运行的时候都加载kernel32.dll,可执行文件进入入口点执行后esp中存放的一般是

Kernel32.DLL 中的某个地址,沿着这个地址向上查找就可以找到kernel32的基地址。

那么如何知道找到的地址是kernel32的基地址?

因为kernel32.dll也是标准的pe结构文件,pe结构文件的开始是IMAGE_DOS_HEADER结构,

IMAGE_DOS_HEADER结构的第一个字段是e_magic,它的值为’MZ’用于证明这是DOS兼容的

文件类型,所以如果我们找到的地址所指向的字符串为’MZ’,那么我们可以确信这是kernel32的基地址

所谓异常处理链表就是系统提供的处理异常的机制,当系统遇到一个不知道如何处理的异常时就会查找异

常处理链表,找到对应的异常处理程序,把保存的处理程序地址赋给eip,并执行处理程序,避免系统崩

溃,异常处理链表的最后一项

是默认异常处理函数UnhandledExceptionFilter,因为UnhandledExceptionFilter在kernel32中,所以从

UNhandledExceptionFilter地址向上搜索即可找到kernel32的基地址

PEB法

在NT内核系统中fs寄存器指向TEB结构,TEB+0x30处指向PEB结构,PEB+0x0c处指向PEB_LDR_DATA结构,
PEB_LDR_DATA+0x1c处存放一些动态链接库地址,第一个指向ntdl.dll,第二个就是kernel32.dll的基地址了

此方法是通过TEB获得PEB结构地址,然后再获得PEB_LDR_DATA结构地址,然后遍历模块列表,查找kernel32.dll模块的基地址。

  TEB是线程环境块(Thread Environment Block)结构, 我们的fs段选择子所对应的段指向TEB,也就是fs:[0]指向TEB.那么TEB的ProcessEnvironmentBlock结构成员指

向我们的PEB进程环境块结构(Process Environment Block),然后通过PEB结构来获得PEB_LDR_DATA。 接下来我们通过windbg来查看下相关结构。

看下TEB结构,通过windbg的dt命令。

lkd> dt _TEB

nt!_TEB

   +0x000 NtTib            : _NT_TIB

   +0x01c EnvironmentPointer : Ptr32 Void

   +0x020 ClientId         : _CLIENT_ID

   +0x028 ActiveRpcHandle  : Ptr32 Void

   +0x02c ThreadLocalStoragePointer : Ptr32 Void

   +0x030 ProcessEnvironmentBlock : Ptr32 _PEB

可以看到TEB结构的0x30偏移处存储的我们的PEB结构的地址

二 PEB和TEB结构

1 TEB结构

 //

 // Thread Environment Block (TEB)

 //

 typedef struct _TEB

 {

     NT_TIB Tib;                             /* 00h */

     PVOID EnvironmentPointer;               /* 1Ch */

     CLIENT_ID Cid;                          /* 20h */

     PVOID ActiveRpcHandle;                  /* 28h */

     PVOID ThreadLocalStoragePointer;        /* 2Ch */

     struct _PEB *ProcessEnvironmentBlock;   /* 30h */

     ULONG LastErrorValue;                   /* 34h */

     ULONG CountOfOwnedCriticalSections;     /* 38h */

     PVOID CsrClientThread;                  /* 3Ch */

     struct _W32THREAD* Win32ThreadInfo;     /* 40h */

     ULONG User32Reserved[0x1A];             /* 44h */

     ULONG UserReserved[5];                  /* ACh */

     PVOID WOW32Reserved;                    /* C0h */

     LCID CurrentLocale;                     /* C4h */

     ULONG FpSoftwareStatusRegister;         /* C8h */

     PVOID SystemReserved1[0x36];            /* CCh */

     LONG ExceptionCode;                     /* 1A4h */

     struct _ACTIVATION_CONTEXT_STACK *ActivationContextStackPointer; /* 1A8h */

     UCHAR SpareBytes1[0x28];                /* 1ACh */

     GDI_TEB_BATCH GdiTebBatch;              /* 1D4h */

     CLIENT_ID RealClientId;                 /* 6B4h */

     PVOID GdiCachedProcessHandle;           /* 6BCh */

     ULONG GdiClientPID;                     /* 6C0h */

     ULONG GdiClientTID;                     /* 6C4h */

     PVOID GdiThreadLocalInfo;               /* 6C8h */

     ULONG Win32ClientInfo[62];              /* 6CCh */

     PVOID glDispatchTable[0xE9];            /* 7C4h */

     ULONG glReserved1[0x1D];                /* B68h */

     PVOID glReserved2;                      /* BDCh */

     PVOID glSectionInfo;                    /* BE0h */

     PVOID glSection;                        /* BE4h */

     PVOID glTable;                          /* BE8h */

     PVOID glCurrentRC;                      /* BECh */

     PVOID glContext;                        /* BF0h */

     NTSTATUS LastStatusValue;               /* BF4h */

     UNICODE_STRING StaticUnicodeString;     /* BF8h */

     WCHAR StaticUnicodeBuffer[0x105];       /* C00h */

     PVOID DeallocationStack;                /* E0Ch */

     PVOID TlsSlots[0x40];                   /* E10h */

     LIST_ENTRY TlsLinks;                    /* F10h */

     PVOID Vdm;                              /* F18h */

     PVOID ReservedForNtRpc;                 /* F1Ch */

     PVOID DbgSsReserved[0x2];               /* F20h */

     ULONG HardErrorDisabled;                /* F28h */

     PVOID Instrumentation[14];              /* F2Ch */

     PVOID SubProcessTag;                    /* F64h */

     PVOID EtwTraceData;                     /* F68h */

     PVOID WinSockData;                      /* F6Ch */

     ULONG GdiBatchCount;                    /* F70h */

     BOOLEAN InDbgPrint;                     /* F74h */

     BOOLEAN FreeStackOnTermination;         /* F75h */

     BOOLEAN HasFiberData;                   /* F76h */

     UCHAR IdealProcessor;                   /* F77h */

     ULONG GuaranteedStackBytes;             /* F78h */

     PVOID ReservedForPerf;                  /* F7Ch */

     PVOID ReservedForOle;                   /* F80h */

     ULONG WaitingOnLoaderLock;              /* F84h */

     ULONG SparePointer1;                    /* F88h */

     ULONG SoftPatchPtr1;                    /* F8Ch */

     ULONG SoftPatchPtr2;                    /* F90h */

     PVOID *TlsExpansionSlots;               /* F94h */

     ULONG ImpersionationLocale;             /* F98h */

     ULONG IsImpersonating;                  /* F9Ch */

     PVOID NlsCache;                         /* FA0h */

     PVOID pShimData;                        /* FA4h */

     ULONG HeapVirualAffinity;               /* FA8h */

     PVOID CurrentTransactionHandle;         /* FACh */

     PTEB_ACTIVE_FRAME ActiveFrame;          /* FB0h */

     PVOID FlsData;                          /* FB4h */

     UCHAR SafeThunkCall;                    /* FB8h */

     UCHAR BooleanSpare[3];                  /* FB9h */

 } TEB, *PTEB; 

2 PEB结构

 typedef struct _PEB

 {

     UCHAR InheritedAddressSpace; // 00h

     UCHAR ReadImageFileExecOptions; // 01h

     UCHAR BeingDebugged; // 02h

     UCHAR Spare; // 03h

     PVOID Mutant; // 04h

     PVOID ImageBaseAddress; // 08h

     PPEB_LDR_DATA Ldr; // 0Ch

     PRTL_USER_PROCESS_PARAMETERS ProcessParameters; // 10h

     PVOID SubSystemData; // 14h

     PVOID ProcessHeap; // 18h

     PVOID FastPebLock; // 1Ch

     PPEBLOCKROUTINE FastPebLockRoutine; // 20h

     PPEBLOCKROUTINE FastPebUnlockRoutine; // 24h

     ULONG EnvironmentUpdateCount; // 28h

     PVOID* KernelCallbackTable; // 2Ch

     PVOID EventLogSection; // 30h

     PVOID EventLog; // 34h

     PPEB_FREE_BLOCK FreeList; // 38h

     ULONG TlsExpansionCounter; // 3Ch

     PVOID TlsBitmap; // 40h

     ULONG TlsBitmapBits[0x2]; // 44h

     PVOID ReadOnlySharedMemoryBase; // 4Ch

     PVOID ReadOnlySharedMemoryHeap; // 50h

     PVOID* ReadOnlyStaticServerData; // 54h

     PVOID AnsiCodePageData; // 58h

     PVOID OemCodePageData; // 5Ch

     PVOID UnicodeCaseTableData; // 60h

     ULONG NumberOfProcessors; // 64h

     ULONG NtGlobalFlag; // 68h

     UCHAR Spare2[0x4]; // 6Ch

     LARGE_INTEGER CriticalSectionTimeout; // 70h

     ULONG HeapSegmentReserve; // 78h

     ULONG HeapSegmentCommit; // 7Ch

     ULONG HeapDeCommitTotalFreeThreshold; // 80h

     ULONG HeapDeCommitFreeBlockThreshold; // 84h

     ULONG NumberOfHeaps; // 88h

     ULONG MaximumNumberOfHeaps; // 8Ch

     PVOID** ProcessHeaps; // 90h

     PVOID GdiSharedHandleTable; // 94h

     PVOID ProcessStarterHelper; // 98h

     PVOID GdiDCAttributeList; // 9Ch

     PVOID LoaderLock; // A0h

     ULONG OSMajorVersion; // A4h

     ULONG OSMinorVersion; // A8h

     ULONG OSBuildNumber; // ACh

     ULONG OSPlatformId; // B0h

     ULONG ImageSubSystem; // B4h

     ULONG ImageSubSystemMajorVersion; // B8h

     ULONG ImageSubSystemMinorVersion; // C0h

     ULONG GdiHandleBuffer[0x22]; // C4h

     PVOID ProcessWindowStation; // ???

 } PEB, *PPEB;

原理:在NT内核系统中fs寄存器指向TEB结构,TEB+0x30处指向PEB结构,PEB+0x0c处指向PEB_LDR_DATA结构,

PEB_LDR_DATA+0x1c处存放一些动态链接库地址,第一个指向ntdl.dll,第二个就是kernel32.dll的基地址了

 

三 暴力搜索法代码

1 程序1

 #include "stdafx.h"

 #include <stdio.h>

 

 int main()

 {

 

 

 _asm { jmp Start }

 int ieax;

 

 

 

 _asm{

 Start:

 

 

 GetKernelBase:                    ;查找 kernel地址

         mov eax,7c800000h        ;因为有非法访问我直接把我本机的kerne32.dll地址(7c800000h) 

给eax 就可以了

 

 Compare:

         cmp eax,80000000h

         jl    SearchFinal

         cmp word ptr[eax],'ZM'

         je FindedKernelBase

         add    eax,010000h

         jmp Compare

 

 

 }

 FindedKernelBase:

 {

         _asm{ mov ieax,eax}

         printf("kernel addr offset %x \n",ieax);

         return 0;

 }

 SearchFinal    :

 {            //;查找结束

         printf("find kernel faild \n ");

         return 0;

 }

     return 0;

 }

2 程序2,汇编代码

;**********获得image of kernel32.dll的基址***************** 

GetKBase: 

mov edi , [esp+04h] 

and edi , 0FFFF0000h 

.while TRUE 

.if WORD ptr [edi] == IMAGE_DOS_SIGNATURE ;判断是否是MZ 

mov esi, edi 

add esi, DWORD ptr [esi+03Ch] ;esi指向PE标志

.if DWORD ptr [esi] ==IMAGE_NT_SIGNATURE;是否有PE标志

.break;如果有跳出循环 

.endif 

.endif

sub edi, 010000h 

.if edi < MIN_KERNEL_SEARCH_BASE ;win9x 

mov edi, 0bff70000h ;0bff7000h=9x"base 

.break 

.endif 

.endw 

mov hKernel32[ebx],edi;把找到的KERNEL32。DLL的基地址保存起来

ret 

四 异常处理链表搜索法代码

1 程序1

这个方法适用于XP, win7上获得是ntdll.dll的地址。

#include <stdio.h>  

#include <tchar.h>  

#include <windows.h>  

  

int _tmain(int argc, _TCHAR* argv[])  

{  

    DWORD dwKrnlAddr = 0;  

  

    __asm  

    {  

        mov edx, fs:[0]     // 获得EXCEPTION_REGISTRATION结构地址  

Next:  

        inc dword ptr [edx] // 将prev+1,如果是-1为0  

        jz Krnl  

        dec dword ptr [edx] // 不为-1,还原  

        mov edx, [edx]      // 获得prev指向的地址  

        jmp Next  

  

Krnl:  

        dec dword ptr [edx] // 恢复  

        mov edx, [edx + 4]  // 获得handle指向的地址  

  

Looop:  

        cmp word ptr [edx], 'ZM'  

        jz IsPe  

        dec edx  

        xor dx, dx  

        jmp Looop  

  

IsPe:  

        mov eax, dword ptr [edx + 3ch]  

        cmp word ptr [edx + eax], 'EP'  

        jnz Next  

        mov dwKrnlAddr, edx  

    }  

    _tprintf(TEXT("Kernel32.dll address: %x\r\n"), dwKrnlAddr);  

    _tprintf(TEXT("GetModuleHandle Kernel32.dll address: %x\r\n"),   

        GetModuleHandle(TEXT("kernel32.dll")));  

  

    return 0;  



五 PEB法代码

1 程序1

#include <stdio.h>  

#include <tchar.h>  

#include <windows.h>  

  

int _tmain(int argc, _TCHAR* argv[])  

{  

    DWORD dwKrnlAddr = 0;  

  

    __asm  

    {  

        mov edx, fs:[30h]       // 取得PEB  

        mov edx, [edx + 0ch]    // PEB_LDR_DATA  

        mov edx, [edx + 1ch]    // 获得InInitializationOrderModuleList.Flink指向的地址,也即指向第一个LDR_MODULE                  

        mov edx, [edx]      // 因为edx当前为InInitializationOrderModuleList  

                    // 而它的第一成员Flink又指向下一个LDR_MODULE, 所以直接读取就是下一个  

        mov edx, [edx + 8h]  

        mov dwKrnlAddr, edx  

    }  

    _tprintf(TEXT("Kernel32.dll address: %x\r\n"), dwKrnlAddr);  

    _tprintf(TEXT("GetModuleHandle Kernel32.dll address: %x\r\n"),   

        GetModuleHandle(TEXT("kernel32.dll")));  

  

    return 0;  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  win32 Kernel32