- 2
- 0
- 约3.85千字
- 约 4页
- 2019-07-15 发布于未知
- 举报
脱壳相关的重要函数介绍
1.GetModuleHandle 函数
如果文件已经被映射进了调用进程的地址空间,则此函数返回指定模块的句柄,
HMODULE GetModuleHandle(
LPCTSTR lpModuleName // 需要返回句柄的模块名的地址
);
参数:
lpModuleName 指向一个包含模块名字的以 0 结尾的串(或者是 a .DLL 或者.EXE 文件).如
果函数扩展名省略掉,默认为库文件扩展名.DLL。文件名串可以尾部可以是一个点(.) ,指
明模块没有扩展名。该串不必指定路径。当指定路径时务必用反斜杠(\), 而不是正斜杠
(/). 名字与映射进进程地址空间的模块比较。如果此参数为空 NULL, GetModuleHandle 返
回创建调用进程的文件句柄。
返回值:
如果函数成功调用,返回值是指定模块的句柄。如果函数失败,返回 NULL.要得到更进一
步的错误信息,调用 GetLastError 函数。
备注:
返回的句柄不是全局的,可继承的或者可复制的,它不可以被另外的进程使用。
由GetModuleHandle 和 LoadLibrary 返回的句柄可以在同一个函数内使用(例如
GetProcAddress, FreeLibrary, 或者 LoadResource )吗?两个函数之间的区别在于引用次数
(reference count )。LoadLibrary 把模块映射进调用进程的地址空间内,映射进地址空间
后,如果必要,则增加模块的引用次数。 然而 GetModuleHandle 却是在不增加引用次数
的情况下返回已映射模块的句柄。
注意:引用次数被 FreeLibrary 用来决定是否把一个函数从进程地址空间释放掉。由于这个
原因,当把由 GetModuleHandle 返回的句柄用于 FreeLibrary 时,必须小心,因为如此以
来可能导致一个 DLL 模块被提前释放掉。
在多线程应用里,要小心使用这个函数。因为在一个函数返回句柄和另一个函数使用句柄
期间,无法保证模块句柄保持有效。比如一个线程可能通过 GetModuleHandle 提取模块句
柄。在线程于某个函数内使用句柄之前,第二个线程可能释放了句柄,系统可能加载了另
一个模块,而且给它赋予和刚释放的模块相同的句柄值。 第一个线程则被留下一个引用了
不同模块的句柄,此模块并非它想要的那个模块。
2. GetProcAddress 函数
GetProcAddress 函数返回指定的输出动态链接库内的函数地址。
FARPROC GetProcAddress(
HMODULE hModule, // DLL 模块句柄
LPCSTR lpProcName // 函数名
);
参数:
(1)hModule
Handle 是包含函数的 DLL 模块的句柄。该句柄由 LoadLibrary 或 GetModuleHandle 返回。
(2 )lpProcName
指向以 0 结尾的函数名字符串,或者指定函数的序号值。如果参数是序号值,必须出现在
低字部分,高字部分置 0。
返回值:
如果函数成功,返回 DLL 输出函数的地址。如果失败,返回 NULL.得到更多错误信息,使
用 GetLastError 函数.
备注:
GetProcAddress 函数用来提取在 DLL 内的输出函数的地址。由lpProcName 指向的函数名
的拼写和大小写必须与 DLL 模块定义文件(.DEF) 的 EXPORTS 声明的函数一致。Win32 API
函数的输出名也许与你代码内调用的函数名不一样。这些差异被SDK 头文件内使用的宏隐
藏起来了。
lpProcName 参数可以通过指定一个函数序号(在输出声明中关联到一个函数上)来表明一
个 DLL 函数。GetProcAddress 校验指定的序号是否在.DEF 文件声明的从 1 和最高序号值
之间。 然后函数使用序号作为索引从一个函数表内读取函数地址。如果.DEF 文件没有对
函数连续从 1 到 N 编号的话,错误产生了,该函数返回一个无效的非 0 地址,即使没有函
数使用指定的序号。在函数不操作的情况下,函数必须以名字指出而非序号。
3.LoadLibrary 函数
LoadLibrary 函数把指定的可执行模块映射进调用进程的地址空间。
HINSTANCE LoadLibrary(
LPCTSTR lpLibFileName //可执行模块的文件名
);
参数:
lpLibFileName 是指向以 0 结尾的字符串命名的可执行模块。
原创力文档

文档评论(0)