|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
C语言编写的DLL注入工具源代码
注入方式使用的是代码注入,参考了《逆向工程核心原理》中的相关代码。代码注入占用内存少并难以查找痕迹,在代码量小的时候比较合适。
不过这边有一个问题就是在执行用户选择的启动函数时我- // 参数类型
- typedef struct _INJECTTHREAD_PARAM
- {
- FARPROC pFunc[3];
- char szBuf[2][128];
- } INJECTTHREAD_PARAM, *PINJECTTHREAD_PARAM;
-
- // 此函数以代码形式注入目标进程
- DWORD WINAPI InjectThreadProc(LPVOID param)
- {
- PINJECTTHREAD_PARAM pParam = (PINJECTTHREAD_PARAM)param;
- HMODULE hModule;
- FARPROC pFunc;
- HANDLE hThread;
-
- // 注入的代码里不能直接调用API函数
- // LoadLibraryA(szDllPath)
- hModule = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);
- if (!hModule)
- {
- return 1;
- }
-
- // GetProcAddress(hModule, szFunc)
- pFunc = ((PFGETPROCADDRESS)pParam->pFunc[1])(hModule, pParam->szBuf[1]);
- if (!pFunc)
- {
- return 1;
- }
-
- // CreateThread()执行加载时要运行的函数, 不知道使用这种方式合不合适
- hThread = ((PFCREATETHREAD)pParam->pFunc[2])(NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, NULL, 0, NULL);
-
- return 0;
- }
-
- BOOL InjectDll(DWORD dwPID, LPCSTR szDllPath, LPCSTR szFunc)
- {
- HMODULE hModule;
- INJECTTHREAD_PARAM param;
- HANDLE hProcess;
- HANDLE hThread;
- LPVOID pRemoteBuf[2];
- DWORD dwSize;
-
- hModule = GetModuleHandleW(L"kernel32.dll");
- memset(¶m, 0, sizeof(INJECTTHREAD_PARAM));
- // 要进行代码注入, 就必需要把要调用参数先写入目标进程
- param.pFunc[0] = GetProcAddress(hModule, "LoadLibraryA");
- param.pFunc[1] = GetProcAddress(hModule, "GetProcAddress");
- param.pFunc[2] = GetProcAddress(hModule, "CreateThread");
- strcpy_s(param.szBuf[0], strlen(szDllPath) + 1, szDllPath);
- strcpy_s(param.szBuf[1], strlen(szFunc) + 1, szFunc);
-
- if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
- {
- return FALSE;
- }
-
- // 判断环境
- if (Is64BitProcess(GetCurrentProcess()) != Is64BitProcess(hProcess))
- {
- MessageBox(NULL, TEXT("打开动态链接库文件失败"), TEXT("提示"), MB_ICONERROR | MB_OK);
- CloseHandle(hProcess);
- return FALSE;
- }
-
- dwSize = sizeof(INJECTTHREAD_PARAM);
- if (!(pRemoteBuf[0] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE)))
- {
- return FALSE;
- }
- // 将全部的参数作为结构体整个写入
- if (!WriteProcessMemory(hProcess, pRemoteBuf[0], (LPVOID)¶m, dwSize, NULL))
- {
- return FALSE;
- }
-
- dwSize = (DWORD)InjectDll - (DWORD)InjectThreadProc;
- if (!(pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
- {
- return FALSE;
- }
- // 再将InjectThreadProc的函数代码写入目标进程
- if (!WriteProcessMemory(hProcess, pRemoteBuf[1], (LPVOID)InjectThreadProc, dwSize, NULL))
- {
- return FALSE;
- }
-
- // pRemoteBuf[1]就是InjectThreadProc在目标进程中的起始地址, 已经被写入, pRemoteBuf[0]则是写入的参数地址
- if (!(hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1], pRemoteBuf[0], 0, NULL)))
- {
- return FALSE;
- }
-
- WaitForSingleObject(hThread, INFINITE);
-
- VirtualFreeEx(hProcess, pRemoteBuf[0], 0, MEM_RELEASE);
- VirtualFreeEx(hProcess, pRemoteBuf[1], 0, MEM_RELEASE);
-
- CloseHandle(hThread);
- CloseHandle(hProcess);
-
- return TRUE;
- [align=left]
- }
复制代码
选择让目标进程使用CreateThread来调用dll的导出函数,这样做是否合适?测试了一些暂时还没发现什么问题
|
|