WriteProcessMemory で Windows でプロセス注入を実行する方法
WindowsでWriteProcessMemory関数を使ったプロセスインジェクションを行う手順は次のとおりです。
- OpenProcess 関数を使用して、目標プロセスのハンドルを取得します。プロセス ID とアクセス権限を渡す必要があります。
- VirtualAllocEx 関数を使用して、ターゲットプロセスにメモリー領域を割り当てることで、注入するコードのバッファーとして使用します。
- 注入コードをWriteProcessMemory関数を使用して対象プロセスのメモリ空間に書き込みます。対象プロセスのハンドル、注入コードのアドレス、注入コードの内容、長さを指定します。
- CreateRemoteThread関数を用いて、対象プロセスにリモートスレッドを作成し、そこで注入するコードを実行させます。対象プロセスのハンドル、注入するコードのエントリポイントアドレス、注入するコードに渡す引数を指定する必要があります。
以下は、WriteProcessMemory を使用してプロセス注入を行う簡単なサンプルコードです。
#include <windows.h>
#include <stdio.h>
int main() {
DWORD pid = 1234; // 目标进程的ID
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess == NULL) {
printf("无法打开目标进程\n");
return 1;
}
LPVOID pRemoteBuf = VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (pRemoteBuf == NULL) {
printf("无法在目标进程中分配内存\n");
CloseHandle(hProcess);
return 1;
}
// 注入代码
char szDllPath[] = "C:\\path\\to\\your\\dll.dll";
WriteProcessMemory(hProcess, pRemoteBuf, szDllPath, sizeof(szDllPath), NULL);
// 获取LoadLibraryA函数的地址
HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
LPTHREAD_START_ROUTINE pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryA");
// 创建远程线程执行LoadLibraryA函数
HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
if (hRemoteThread == NULL) {
printf("无法在目标进程中创建远程线程\n");
VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 1;
}
WaitForSingleObject(hRemoteThread, INFINITE);
VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
CloseHandle(hRemoteThread);
CloseHandle(hProcess);
printf("注入成功\n");
return 0;
}
コードでは、まずOpenProcess関数を使用して対象プロセスを開き、次にVirtualAllocEx関数を使用して対象プロセスにメモリ空間を割り当て、次にWriteProcessMemory関数を使用してインジェクションコードを対象プロセスのメモリ空間に書き込みます。次に、GetModuleHandleA関数を使用してkernel32.dllモジュールのハンドルを取得し、GetProcAddress関数を使用してLoadLibraryA関数のアドレスを取得します。最後に、CreateRemoteThread関数を使用してリモートスレッドを作成し、対象プロセスでLoadLibraryA関数を実行して指定されたDLLファイルをロードします。
実際の使用ではDLLファイルとしてコードをインジェクトし、インジェクトの完了後には、リソースが漏れないように割り当てたメモリとハンドルを解放する必要がある。