peb 进程环境块
下面是peb部分结构
在peb偏移0xc的位置有这样一个结构体
_PEB_LDR_DATA
这个结构体里面存储这个程序所有的加载的模块
dt _PEB_LDR_DATA结构体,里面有三个双向链表,链表中程序加载的模块信息
模块基址,,模块的入口,模块的大小,模块的绝对路径和名称
我们要实现GetModuleHandle的关键就是遍历这个链表,获取模块的入口地址
粗体文本
c代码的实现:
这里需要注意teb里面的字符串是Unicode编码的,所以需要自己转换一下
+
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 :
0x77b089c0
_PEB_LDR_DATA
/
*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
*
/
+
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 :
0x77b089c0
_PEB_LDR_DATA
/
*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
*
/
+
0x000
Length :
0x30
+
0x004
Initialized :
0x1
''
+
0x008
SsHandle : (null)
/
*
加载模块的顺序的列表
*
/
+
0x00c
InLoadOrderModuleList : _LIST_ENTRY [
0x6d3778
-
0x6d9880
]
/
*
内存顺序模块列表
*
/
+
0x014
InMemoryOrderModuleList : _LIST_ENTRY [
0x6d3780
-
0x6d9888
]
/
*
初始化顺序模块列表
*
/
+
0x01c
InInitializationOrderModuleList : _LIST_ENTRY [
0x6d3670
-
0x6d9890
]
+
0x024
EntryInProgress : (null)
+
0x028
ShutdownInProgress :
0
''
+
0x02c
ShutdownThreadId : (null)
+
0x000
Length :
0x30
+
0x004
Initialized :
0x1
''
+
0x008
SsHandle : (null)
/
*
加载模块的顺序的列表
*
/
+
0x00c
InLoadOrderModuleList : _LIST_ENTRY [
0x6d3778
-
0x6d9880
]
/
*
内存顺序模块列表
*
/
+
0x014
InMemoryOrderModuleList : _LIST_ENTRY [
0x6d3780
-
0x6d9888
]
/
*
初始化顺序模块列表
*
/
+
0x01c
InInitializationOrderModuleList : _LIST_ENTRY [
0x6d3670
-
0x6d9890
]
+
0x024
EntryInProgress : (null)
+
0x028
ShutdownInProgress :
0
''
+
0x02c
ShutdownThreadId : (null)
HMODULE MyGetModuleHandle(LPCTSTR lpModuleName) {
LIST_ENTRY
*
pListEntry
=
NULL;
LDR_DATA_TABLE_ENTRY
*
pLdrDataTableEntry
=
NULL;
PEB
*
pPeb
=
NULL;
pPeb
=
(PPEB)__readfsdword(
0x30
);
/
/
拿到peb
/
/
peb数据
pLdrDataTableEntry
=
(PLDR_DATA_TABLE_ENTRY)pPeb
-
>Ldr
-
>InMemoryOrderModuleList.Flink;
/
/
peb的节点
pListEntry
=
pPeb
-
>Ldr
-
>InMemoryOrderModuleList.Flink;
strlwr((char
*
)lpModuleName);
/
/
强制转换为小写
if
(!strcmp(lpModuleName,"")) {
/
/
为空直接返回
return
(HMODULE)pLdrDataTableEntry
-
>Reserved2[
0
];
}
int
nSize
=
strlen(lpModuleName);
int
nRet
=
(
int
)strstr(lpModuleName,
"."
);
if
(nRet
=
=
0
)
/
/
没找到 我们给字符串加上.dll
{
strcat((char
*
)lpModuleName,
".dll"
);
}
else
if
(nRet
=
=
((
int
)lpModuleName
+
nSize
-
1
)) {
char
*
addr
=
(char
*
)lpModuleName
+
nSize
-
1
;
addr[
0
]
=
'\0'
;
}
do
{
char
str
[
100
]
=
{
0
};
int
nASize
=
WideCharToMultiByte(CP_UTF8,
0
, pLdrDataTableEntry
-
>FullDllName.
Buffer
, pLdrDataTableEntry
-
>FullDllName.Length, NULL,
0
, NULL, NULL);
WideCharToMultiByte( CP_UTF8,
0
, pLdrDataTableEntry
-
>FullDllName.
Buffer
, pLdrDataTableEntry
-
>FullDllName.Length,
str
, nASize, NULL, NULL);
strlwr(
str
);
/
/
判断
nRet
=
strcmp(lpModuleName,
str
);
if
(nRet
=
=
0
) {
/
/
相等 返回句柄
return
(HMODULE)pLdrDataTableEntry
-
>Reserved2[
0
];
}
pLdrDataTableEntry
=
(PLDR_DATA_TABLE_ENTRY)pListEntry
-
>Flink;
pListEntry
=
pListEntry
-
>Flink;
}
while
(pListEntry !
=
pPeb
-
>Ldr
-
>InMemoryOrderModuleList.Flink);
return
NULL;
};
int
main()
{
char dllName[
30
]
=
"kernel32.dll"
;
HMODULE hHandle
=
MyGetModuleHandle(dllName);
}
HMODULE MyGetModuleHandle(LPCTSTR lpModuleName) {
LIST_ENTRY
*
pListEntry
=
NULL;
LDR_DATA_TABLE_ENTRY
*
pLdrDataTableEntry
=
NULL;
PEB
*
pPeb
=
NULL;
pPeb
=
(PPEB)__readfsdword(
0x30
);
/
/
拿到peb
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-11-28 16:20
被mb_kbkqyusp编辑
,原因: