[toc]

c语言程序动态链接库的简单实例

1. 新建一个动态库项目,在动态库入口点中弹出一个MessageBoxW

在动态链接库项目中关闭预编译头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// dllmain.c : Defines the entry point for the DLL application.
#include <windows.h>

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxW(NULL, L"how you doing", L"what's up", MB_OK);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}


2.使用C语言将动态链接库通过远程线程加载到windows程序中

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
36
37
38
//Message.c
#include <stdio.h>
#include <Windows.h>

BOOL Inject(DWORD dwProcessID, const WCHAR* szPath)
{
//LoadLibrary
//CreateRemoteThread
//1.打开目标进程获取句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
//2.在目标进程体内申请空间
LPVOID lpAddress = VirtualAllocEx(hProcess, NULL, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
//3.写入DLL路径
SIZE_T sWriteLength = 0;
BOOL bRet = WriteProcessMemory(hProcess, lpAddress, szPath, ((wcslen(szPath) + 1) * 2), &sWriteLength);
if (bRet == FALSE)
{
MessageBoxW(NULL, L"WriteProcessMemory Failed!", L"Error", MB_OK);
}
//4.创建远程线程,执行回调
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryW, lpAddress, NULL, NULL);
//5.等待远程线程执行结束(LoadLibrary返回了)
WaitForSingleObject(hThread, INFINITE);
//6.释放空间
VirtualFreeEx(hProcess, lpAddress, 0, MEM_RELEASE);
//7.释放句柄
CloseHandle(hProcess);
CloseHandle(hThread);
//8.返回结果
return TRUE;
}
int main()
{
//传入的两个参数分别为进程id与dll的绝对路径
Inject(53556, L"D:\\test\\CC++\\c生万物之windows程序开发\\C+windows\\x64\\Debug\\Dll1.dll");
system("pause");
return 0;
}

3. 卸载Dll的代码

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//UnloadDll.c
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>
void UnInject(DWORD dwPid, TCHAR* szDllName)
{
OutputDebugStringW(szDllName);
DWORD m_Pid = dwPid;
ULONG uIndex = 0;
MODULEENTRY32 me32;
me32.dwSize = sizeof(MODULEENTRY32);
BOOL bFlag = FALSE;
HANDLE hTool = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, m_Pid);
if (hTool != NULL)
{
BOOL bRet = Module32First(hTool, &me32);
if (bRet == TRUE)
{
do
{
bFlag = (0 == _tcsicmp(me32.szModule, szDllName) || 0 == _tcsicmp(me32.szExePath, szDllName));
if (bFlag)
{
break;
}

} while (Module32Next(hTool, &me32));

}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (hProcess == NULL)
{
return;
}
LPTHREAD_START_ROUTINE lpThreadFun = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "FreeLibrary");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, me32.modBaseAddr, 0, NULL);
WaitForSingleObject(hThread, -1);
CloseHandle(hThread);
CloseHandle(hProcess);
return;
}
CloseHandle(hTool);
}


int main()
{
// 传入的两个参数分别为进程 id 与 dll 的名称
UnInject(19756, L"D:\\test\\CC++\\C+Windows+Pragrma\\C+windows\\Debug\\Dll1.dll");
//Unload(20020, L"Dll1.dll"); // 只传递 DLL 名称
return 0;
}