PEB结构的获取
2014-08-15 10:44
411 查看
32位获取KERNEL32地址汇编代码PEB结构----枚举用户模块列表。
PEB地址的取得:
1:通过CreateProcess()创建新的被挂起的进程,此时其初始化线程上下文中,ebx 指向其PEB结构, EAX指向其EIP(代码执行地址)
demo:
CreateProcess(NULL, TARGETPROC,
NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, pi))
{
ctx->ContextFlags=CONTEXT_FULL;
GetThreadContext(pi->hThread, ctx); //获得线程的所有重要的寄存器CTX
DWORD *pebInfo = (DWORD *)ctx->Ebx; //ctx->Ebx = points to PEB
2:如果线程没被挂起, 通过FS寄存器指向当前TEB结构 , 再TEB偏移0x30处是PEB指针 ,通过这个指针可以取得PEB结构的地址
demo:
__asm
{
mov eax,fs:[0x30]
mov PEB,eax
}
3:X64程序下的FS寄存器角色已经换成了gs
暂时发现的一些东西:
gs:[0x30] TEB
gs:[0x40] Pid
gs:[0x48] Tid
gs:[0x60] PEB
gs:[0x68] LastError.
虽然gs:[0x60]直接存放的PEB,但是由于vista/7后的地址随机化机制,还是从TEB获取比较靠谱。
0:009> dt 000007fffff98000 _TEB
ntdll!_TEB
+0×000 NtTib : _NT_TIB
+0×038 EnvironmentPointer : (null)
+0×040 ClientId : _CLIENT_ID
+0×050 ActiveRpcHandle : (null)
+0×058 ThreadLocalStoragePointer : (null)
+0×060 ProcessEnvironmentBlock : 0x000007ff`fffd5000 _PEB //这里即是PEB
//用c语言描述就是
#define x64_GetPeb() ( (LONG64*)(*((LONG64*)((BYTE*)x64_GetTeb()+0×060))) )
得到了PEB,剩下的就和x86下一样了.只是偏移不一样了
0:009> dt 0x000007ff`fffd5000 _PEB
ntdll!_PEB
+0×000 InheritedAddressSpace : 0 ”
+0×001 ReadImageFileExecOptions : 0 ”
+0×002 BeingDebugged : 0×1 ”
+0×003 BitField : 0×8 ”
+0×003 ImageUsesLargePages : 0y0
+0×003 IsProtectedProcess : 0y0
+0×003 IsLegacyProcess : 0y0
+0×003 IsImageDynamicallyRelocated : 0y1
+0×003 SkipPatchingUser32Forwarders : 0y0
+0×003 SpareBits : 0y000
+0×008 Mutant : 0xffffffff`ffffffff Void
+0×010 ImageBaseAddress : 0×00000000`ff310000 Void
+0×018 Ldr : 0×00000000`77222640 _PEB_LDR_DATA
0:009> dt 0×00000000`77222640 _PEB_LDR_DATA
ntdll!_PEB_LDR_DATA
+0×000 Length : 0×58
+0×004 Initialized : 0×1 ”
+0×008 SsHandle : (null) //length 8 ,32位系统length 4
+0×010 InLoadOrderModuleList : _LIST_ENTRY [ 0x00000000`00202780 - 0x2421b0 ] //length 0x10h , x86 length 0x8h .结构多8字节
+0×020 InMemoryOrderModuleList : _LIST_ENTRY [ 0x00000000`00202790 - 0x2421c0 ] //同上
+0×030 InInitializationOrderModuleList : _LIST_ENTRY [ 0x00000000`00202890 - 0x2421d0 ] //同上
同样的,搜索InInitializationOrderModuleList 即可得到Kernel32的基址.
由于x64下vs2005没法直接使用内联汇编,所以只把必须使用汇编来做的事情写成单独的asm
x64下.指针的长度已经是8个字节,所以偏移不一样了.
0:009> dt _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0×000 InLoadOrderLinks : _LIST_ENTRY
+0×010 InMemoryOrderLinks : _LIST_ENTRY
+0×020 InInitializationOrderLinks : _LIST_ENTRY
+0×030 DllBase : Ptr64 Void
+0×038 EntryPoint : Ptr64 Void
+0×040 SizeOfImage : Uint4B
+0×048 FullDllName : _UNICODE_STRING
C语言表示x64搜索过程:
win7 x64下测试通过win7 x64下测试通过
32位程序的通用Kernel32地址获取方法
PEB地址的取得:
1:通过CreateProcess()创建新的被挂起的进程,此时其初始化线程上下文中,ebx 指向其PEB结构, EAX指向其EIP(代码执行地址)
demo:
CreateProcess(NULL, TARGETPROC,
NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, pi))
{
ctx->ContextFlags=CONTEXT_FULL;
GetThreadContext(pi->hThread, ctx); //获得线程的所有重要的寄存器CTX
DWORD *pebInfo = (DWORD *)ctx->Ebx; //ctx->Ebx = points to PEB
2:如果线程没被挂起, 通过FS寄存器指向当前TEB结构 , 再TEB偏移0x30处是PEB指针 ,通过这个指针可以取得PEB结构的地址
demo:
__asm
{
mov eax,fs:[0x30]
mov PEB,eax
}
3:X64程序下的FS寄存器角色已经换成了gs
暂时发现的一些东西:
gs:[0x30] TEB
gs:[0x40] Pid
gs:[0x48] Tid
gs:[0x60] PEB
gs:[0x68] LastError.
虽然gs:[0x60]直接存放的PEB,但是由于vista/7后的地址随机化机制,还是从TEB获取比较靠谱。
0:009> dt 000007fffff98000 _TEB
ntdll!_TEB
+0×000 NtTib : _NT_TIB
+0×038 EnvironmentPointer : (null)
+0×040 ClientId : _CLIENT_ID
+0×050 ActiveRpcHandle : (null)
+0×058 ThreadLocalStoragePointer : (null)
+0×060 ProcessEnvironmentBlock : 0x000007ff`fffd5000 _PEB //这里即是PEB
//用c语言描述就是
#define x64_GetPeb() ( (LONG64*)(*((LONG64*)((BYTE*)x64_GetTeb()+0×060))) )
得到了PEB,剩下的就和x86下一样了.只是偏移不一样了
0:009> dt 0x000007ff`fffd5000 _PEB
ntdll!_PEB
+0×000 InheritedAddressSpace : 0 ”
+0×001 ReadImageFileExecOptions : 0 ”
+0×002 BeingDebugged : 0×1 ”
+0×003 BitField : 0×8 ”
+0×003 ImageUsesLargePages : 0y0
+0×003 IsProtectedProcess : 0y0
+0×003 IsLegacyProcess : 0y0
+0×003 IsImageDynamicallyRelocated : 0y1
+0×003 SkipPatchingUser32Forwarders : 0y0
+0×003 SpareBits : 0y000
+0×008 Mutant : 0xffffffff`ffffffff Void
+0×010 ImageBaseAddress : 0×00000000`ff310000 Void
+0×018 Ldr : 0×00000000`77222640 _PEB_LDR_DATA
0:009> dt 0×00000000`77222640 _PEB_LDR_DATA
ntdll!_PEB_LDR_DATA
+0×000 Length : 0×58
+0×004 Initialized : 0×1 ”
+0×008 SsHandle : (null) //length 8 ,32位系统length 4
+0×010 InLoadOrderModuleList : _LIST_ENTRY [ 0x00000000`00202780 - 0x2421b0 ] //length 0x10h , x86 length 0x8h .结构多8字节
+0×020 InMemoryOrderModuleList : _LIST_ENTRY [ 0x00000000`00202790 - 0x2421c0 ] //同上
+0×030 InInitializationOrderModuleList : _LIST_ENTRY [ 0x00000000`00202890 - 0x2421d0 ] //同上
同样的,搜索InInitializationOrderModuleList 即可得到Kernel32的基址.
由于x64下vs2005没法直接使用内联汇编,所以只把必须使用汇编来做的事情写成单独的asm
x64下.指针的长度已经是8个字节,所以偏移不一样了.
0:009> dt _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0×000 InLoadOrderLinks : _LIST_ENTRY
+0×010 InMemoryOrderLinks : _LIST_ENTRY
+0×020 InInitializationOrderLinks : _LIST_ENTRY
+0×030 DllBase : Ptr64 Void
+0×038 EntryPoint : Ptr64 Void
+0×040 SizeOfImage : Uint4B
+0×048 FullDllName : _UNICODE_STRING
C语言表示x64搜索过程:
HMODULE x64_GetKernel32(void) { HMODULE hKernel32 = NULL; UNICODE_STRING * pBaseName = NULL; LIST_ENTRY * pNode = NULL; pNode = X64_GetPebInitOrderList(); while{1} { pBaseName = (UNICODE_STRING *)((BYTE *)pNode + 0x038); if (*(pBaseName->Buffer)+12=='\0') { /* code */ hKernel32 = (HMODULE)(*((LONG64*)((BYTE*)pNode+0x010))); break; } pNode = pNode->Flink; } return hKernel32; }
win7 x64下测试通过win7 x64下测试通过
32位程序的通用Kernel32地址获取方法
相关文章推荐
- 通过PEB->LDR_DATA结构获取模块基址
- 搜索PEB的相关结构获取Kernel32.DLL的基址
- 第2讲:搜索PEB结构获取kernel32.dll的基址暴力搜索内存空间获得 Api 的线性地址
- 搜索PEB结构获取Kernel32.dll基址
- 搜索PEB结构获取Kernel32.dll基址
- 如何用SQL查询语句获取Oracle表 树形结构的记录(PL/SQL )
- bcb获取控件的结构
- SQL SERVER 2000获取表结构的SQL语句
- 获取表结构
- 获取表结构的小技巧
- 获取数据库表结构
- 获取oracle表结构的字段信息
- SqlServer中获取表结构的几个系统存储过程
- java 获取表结构
- sql-------获取 用户自定义 所有表和 表结构
- Sql Server 2005 获取表结构信息
- 在逻辑层快速获取一个表的结构
- 获取表结构信息
- Sql2005里获取表的结构-SQL
- 获取sql2005表结构