获取kernel32.dll基址
获取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;
}
获取kernel32.dll基址相关推荐
- 利用FS寄存器获取KERNEL32.DLL基址算法的证明
FS寄存器指向当前活动线程的TEB结构(线程结构) 偏移 说明 000 指向SEH链指针 004 线程堆栈顶部 008 线程堆栈底部 00C SubSystemTib 010 FiberD ...
- 利用FS寄存器获取KERNEL32.DLL基址算法的证明(ZZ)
转自:http://blog.csdn.net/int2e/archive/2008/01/09/2032732.aspx FS寄存器指向当前活动线程的TEB结构(线程结构) 偏移 说明 000 ...
- Windows x64平台 获取PEB表,并获取kernel32.dll的基址,并获取它的函数
参考了:https://www.cnblogs.com/aliflycoris/p/5185097.html 和另一位博主 话不多说,进入正题: 首先是获取PEB基址,先得懂怎么在64位平台嵌入汇编代 ...
- 重定位(搜索KERNEL32.DLL得到API地址)
1 ;-------------------------------- 2 ;动态加载功能实现 3 ;moriarty 4 ;2012/04/13 5 ;----------------------- ...
- GetModuleHandle(NULL)获取当前DLL模块基址?
做一项目想在DLL内部代码实现获取本DLL的模块基址,而且不知道本DLL名称 最简单的方法是想到GetModuleHandle(NULL),是否可以呢? 参看http://blog.csdn.net/ ...
- Python Pymem 游戏内存基址读取修改 - 获取游戏DLL模块基址
运行环境 python3.9.0 - 64位 安装pymem pip install pymem Pymem 的文档 https://pymem.readthedocs.io/en/latest/ 读 ...
- c++ dll返回容器_Windows x86 Shellcode开发:寻找Kernel32.dll地址
前言 针对一个已经学习了Linux Shellcode开发,并开始在Windows上尝试的研究人员来说,这一过程可能要比想象的更加艰难.Windows内核与Linux完全不同.尽管如此,但Linux内 ...
- 易语言python模块_Python获取指定模块基址
image 因为昨天研究FPS游戏时候,发现有个动态地址每次重启电脑都会不同,然后因为有过用C和易语言编写指定模块名获取基址的经验,所以打算用Python来试试 在网上搜索了一点资料,发现有吾爱有一篇 ...
- Python 获取指定模块基址
因为昨天研究FPS游戏时候,发现有个动态地址每次重启电脑都会不同,然后因为有过用C和易语言编写指定模块名获取基址的经验,所以打算用Python来试试 在网上搜索了一点资料,发现有吾爱有一篇是使用Pyt ...
最新文章
- 最怕的是,你永远也忘不掉 BY顾明烟
- redis setnx 分布式锁_手写Redis分布式锁
- Linux网络编程 | Socket编程(一):Socket的介绍、UDPSocket的封装、UDP服务器/客户端的实现
- 10 Equality constrained minimization
- 分布式系统中,权限设计实践
- 关于树状数组的个人理解
- Java中的引用数据类型-BigDecimal
- 拼多多摄像头是否安全的检测
- MySQL创建数据库 easyShopping,包括area表、goods表、customer表、orders表、ordersdetall表、test表
- 基于JS/H5实现二维码扫码增强版-带视频演示
- 矩阵求逆 —— 初等变换法(高斯-约旦消元)
- 揭秘本世纪惊心动魄的粮食战争!中国反败为胜,但国际粮商仍未服输
- 如何选购计算机的硬盘,教你如何选配电脑—硬盘篇
- 梅特勒托利多xk3124电子秤说明书_梅特勒-托利多电子称设置方法
- Linux shell复习
- 华为鸿蒙价格是多少,华为5G新旗舰已确认,双曲面屏+升级到鸿蒙2.0,价格很感人...
- 洛谷P1005 矩阵取数游戏 ACM 大数+区间dp
- Linux内核之misc框架
- Android手机摇一摇功能的简单实现
- 一起学java-韩顺平老师