LoadLibrary 加载 DLL
尝试复现 knowDlls 无文件注入,前置实验,进程 DLL 的调用
rundll32 Rundll32 是 Win95 开始提供的一个加载 DLL 的程序,可以启动一些 DLL ,Rundll32
创建测试 DLL
file:hello.c 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35/*
* @Description:
* @Author: Yuan Jie
* @Data:
* @LastEdit: moogila@outlook.com
* @LastEditTime: 2022-04-02 10:06:44
* @FileName: hello.c
*/
__declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
MessageBox(NULL, "Hello world!", "Hello World!", 0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
__declspec(dllexport)
void show()
{
MessageBoxA(NULL,"xsxsxs","xsxsx",0);
}使用 msvc 编译
cl hello.c /LD
生成 hello.dll 和 hello.lib 文件
使用 rundll32 测试
命令 rundll32 hello.dll show
结果
image-20220402145746849编写测试程序 main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/*
* @Description:
* @Author: Yuan Jie
* @Data:
* @LastEdit: moogila@outlook.com
* @LastEditTime: 2022-04-02 15:02:49
* @FileName:
*/
int main() {
HMODULE modl = LoadLibrary(".\\hello.dll");
if (!modl){
char msg[30] = {0};
sprintf(msg,"Load Dll Fail,Errcode: %d",GetLastError());
MessageBox(NULL, msg, "ERROR", MB_OK);
return 0;
}
typedef void(*show)(void);
show p_func = (show)GetProcAddress(modl, "show");
if (p_func){
p_func();
} else{
MessageBox(NULL, "load Func Fail", "ERROR", MB_OK);
}
return 0;
}
正常g++ main.cpp 编译完成之后,运行结果为
Load Dll Fail,ErrCode : 193
193 的错误为:非正常的 win32 程序
加入 -m32 编译为 32 位程序,正常运行
但是,使用 g++ main.cpp -m32 编译时,程序运行出错
image-20220402150948965
原因不详
使用 msvc 编译时
#pragma comment(lib, “user32.lib”)
是必须的
Note
- 函数指针的使用
动态加载 Dll ,需要使用 LoadLibrary() 和 GetProcAddress()
GetProcAddress 返回函数指针需要进行类型转化,我函数指针用的不清不白,在这个地方愣住,在网上找了一圈,没有找到详细结果,最后只得接收 先 typedef 这种使用方法。
typedef void(*show)(void);
#pragma comment(lib, “user32.lib”)
这个看得确实不太明白,目前理解来说,这很像是 java 里面的注解 (comment ?!)
使用这个注解,提示编译器,在编译时链接动态库,也就是说,实际上,你需要在编译时指定链接库,但是,使用这个注解会让编译器自动完成,当然,这样的注解还有很多,但并非标准。
pragma 是预处理指令
[ 参考资料 ]
- 《Windows API 编程》清华大学出版社·冉林仓·2005
Author: 哒琳
Permalink: http://blog.jieis.cn/2021/87ed2d37-be5f-4fa3-8b10-d6988be3331a.html
Comments