[C] 纯文本查看 复制代码
// 参数类型
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]
}