进程注入器在 CreateRemoteThread 上崩溃
Process Injector Crashes on CreateRemoteThread
为了检测工程的目的,我在 C 中创建了一个进程 DLL 注入器,它似乎对我在 shell 中生成的测试进程非常有效(可能是因为它们在同一条路径上,或者与非-shells 和 printf) 但每当我在随机进程上测试它时,它会在 CreateRemoteThread 步骤中崩溃所述进程,想知道你们是否可以提供帮助谢谢。
如果有帮助的话,这是我使用的命令 (Bash):
./ProcessInjector.exe [PID] C:\Users\wsam\Documents\Process-Injection\bad_dll.dll
编辑:我注意到如果我取出 bad_dll.dll while 循环中的所有代码,它会成功创建线程并且不会使进程崩溃,这是为什么?
ProcessInjector.c
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <tlhelp32.h>
int main(int argc, char* argv[]){
char dllPath[MAX_PATH];
strcpy(dllPath, argv[2]);
printf("Victim PID : %s\n", argv[1]);
// use full or relative path
printf("DLL to inject : %s\n", argv[2]);
// get Handle from proc id
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, atoi(argv[1]));
if (hProcess == NULL) {
printf("[---] Failed to open process %s.\n", argv[1]);
return 1;
}
printf("Press Enter to attempt DLL injection.");
getchar();
// Allocate memory for DLL's path
LPVOID dllPathAlloc = VirtualAllocEx(hProcess, NULL, strlen(dllPath), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(dllPathAlloc == NULL){
printf("[---] VirtualAllocEx unsuccessful.\n");
getchar();
return 1;
}
// Write path to memory
BOOL pathWrote = WriteProcessMemory(hProcess, dllPathAlloc, dllPath, strlen(dllPath), NULL);
if(!pathWrote){
printf("[---] WriteProcessMemory unsuccessful.\n");
getchar();
return 1;
}
// returns pointer to LoadLibrary address, same in every process.
LPVOID loadLibraryAddress = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(loadLibraryAddress == NULL){
printf("[---] LoadLibrary not found in process.\n");
getchar();
return 1;
}
// creates remote thread and start mal dll
HANDLE remoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddress, dllPathAlloc, 0, NULL);
if(remoteThread == NULL){
printf("[---] CreateRemoteThread unsuccessful.\n");
getchar();
return 1;
}
//Start-Address:kernel32.dll!LoadLibraryA
CloseHandle(hProcess);
return 0;
}
bad_dll.c
#include <windows.h>
#include <stdio.h>
#include <unistd.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
FILE * fp;
fp = fopen ("C:\Users\wsam\Documents\Hacked.txt","w");
fprintf (fp, "Hacked\n");
fclose (fp);
while(1){
printf("HACKED\n");
fflush(stdout);
sleep(1);
}
}
这是我使用 VirtualAllocEx、CreateRemoteThread 和 LoadLibrary 的 dll 注入器的非常基本的示例:
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
DWORD GetPid(char * targetProcess)
{
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap && snap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(snap, &pe))
{
do
{
if (!_stricmp(pe.szExeFile, targetProcess))
{
CloseHandle(snap);
return pe.th32ProcessID;
}
} while (Process32Next(snap, &pe));
}
}
return 0;
}
int main()
{
char * dllpath = "C:\Users\me\Desktop\dll.dll";
char * processToInject = "csgo.exe";
long pid = 0;
while (!pid)
{
pid = GetPid(processToInject);
Sleep(10);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if (hProc && hProc != INVALID_HANDLE_VALUE)
{
void * loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, loc, dllpath, strlen(dllpath) + 1, 0);
HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0);
CloseHandle(hThread);
}
CloseHandle(hProc);
return 0;
}
此代码包括获取路径字符串的空终止符:
strlen(dllpath) + 1
EDIT: I noticed if I take out all code in the bad_dll.dll while loop
it succeeds in creating a thread and doesn't crash the process, why is
that?
我相信 DllMain 中的无限循环是导致问题的原因,它永远不会 returns。当您删除循环中的代码时,您的编译器会优化循环并因此停止崩溃。
每个人都说永远不要从 DllMain 调用 CreateThread(),但数百万人都在毫无问题地这样做。问题在于加载程序死锁,但我注入 DLL 已有 5 年,从未遇到过任何问题,这是我的经验,我的信念源于经验。您至少应该通过阅读和访问 this question.
中的链接来了解可能存在的问题
忽略 DLLMain 中的所有 CRT 我建议你这样做:
DWORD __stdcall hackthread(HMODULE hModule)
{
FILE * fp;
fp = fopen ("C:\Users\wsam\Documents\Hacked.txt","w");
fprintf (fp, "Hacked\n");
fclose (fp);
while(1){
printf("HACKED\n");
fflush(stdout);
sleep(1);
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, PVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
HANDLE hThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)hackthread, hModule, 0, nullptr);
CloseHandle(hThread);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
以这种方式,CreateThread 和 DllMain return 99.9999% 的时间。
这是根据我的经验得出的概念证明。
为了检测工程的目的,我在 C 中创建了一个进程 DLL 注入器,它似乎对我在 shell 中生成的测试进程非常有效(可能是因为它们在同一条路径上,或者与非-shells 和 printf) 但每当我在随机进程上测试它时,它会在 CreateRemoteThread 步骤中崩溃所述进程,想知道你们是否可以提供帮助谢谢。
如果有帮助的话,这是我使用的命令 (Bash): ./ProcessInjector.exe [PID] C:\Users\wsam\Documents\Process-Injection\bad_dll.dll
编辑:我注意到如果我取出 bad_dll.dll while 循环中的所有代码,它会成功创建线程并且不会使进程崩溃,这是为什么?
ProcessInjector.c
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <tlhelp32.h>
int main(int argc, char* argv[]){
char dllPath[MAX_PATH];
strcpy(dllPath, argv[2]);
printf("Victim PID : %s\n", argv[1]);
// use full or relative path
printf("DLL to inject : %s\n", argv[2]);
// get Handle from proc id
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, atoi(argv[1]));
if (hProcess == NULL) {
printf("[---] Failed to open process %s.\n", argv[1]);
return 1;
}
printf("Press Enter to attempt DLL injection.");
getchar();
// Allocate memory for DLL's path
LPVOID dllPathAlloc = VirtualAllocEx(hProcess, NULL, strlen(dllPath), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(dllPathAlloc == NULL){
printf("[---] VirtualAllocEx unsuccessful.\n");
getchar();
return 1;
}
// Write path to memory
BOOL pathWrote = WriteProcessMemory(hProcess, dllPathAlloc, dllPath, strlen(dllPath), NULL);
if(!pathWrote){
printf("[---] WriteProcessMemory unsuccessful.\n");
getchar();
return 1;
}
// returns pointer to LoadLibrary address, same in every process.
LPVOID loadLibraryAddress = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(loadLibraryAddress == NULL){
printf("[---] LoadLibrary not found in process.\n");
getchar();
return 1;
}
// creates remote thread and start mal dll
HANDLE remoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddress, dllPathAlloc, 0, NULL);
if(remoteThread == NULL){
printf("[---] CreateRemoteThread unsuccessful.\n");
getchar();
return 1;
}
//Start-Address:kernel32.dll!LoadLibraryA
CloseHandle(hProcess);
return 0;
}
bad_dll.c
#include <windows.h>
#include <stdio.h>
#include <unistd.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
FILE * fp;
fp = fopen ("C:\Users\wsam\Documents\Hacked.txt","w");
fprintf (fp, "Hacked\n");
fclose (fp);
while(1){
printf("HACKED\n");
fflush(stdout);
sleep(1);
}
}
这是我使用 VirtualAllocEx、CreateRemoteThread 和 LoadLibrary 的 dll 注入器的非常基本的示例:
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
DWORD GetPid(char * targetProcess)
{
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap && snap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(snap, &pe))
{
do
{
if (!_stricmp(pe.szExeFile, targetProcess))
{
CloseHandle(snap);
return pe.th32ProcessID;
}
} while (Process32Next(snap, &pe));
}
}
return 0;
}
int main()
{
char * dllpath = "C:\Users\me\Desktop\dll.dll";
char * processToInject = "csgo.exe";
long pid = 0;
while (!pid)
{
pid = GetPid(processToInject);
Sleep(10);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if (hProc && hProc != INVALID_HANDLE_VALUE)
{
void * loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, loc, dllpath, strlen(dllpath) + 1, 0);
HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0);
CloseHandle(hThread);
}
CloseHandle(hProc);
return 0;
}
此代码包括获取路径字符串的空终止符:
strlen(dllpath) + 1
EDIT: I noticed if I take out all code in the bad_dll.dll while loop it succeeds in creating a thread and doesn't crash the process, why is that?
我相信 DllMain 中的无限循环是导致问题的原因,它永远不会 returns。当您删除循环中的代码时,您的编译器会优化循环并因此停止崩溃。
每个人都说永远不要从 DllMain 调用 CreateThread(),但数百万人都在毫无问题地这样做。问题在于加载程序死锁,但我注入 DLL 已有 5 年,从未遇到过任何问题,这是我的经验,我的信念源于经验。您至少应该通过阅读和访问 this question.
中的链接来了解可能存在的问题忽略 DLLMain 中的所有 CRT 我建议你这样做:
DWORD __stdcall hackthread(HMODULE hModule)
{
FILE * fp;
fp = fopen ("C:\Users\wsam\Documents\Hacked.txt","w");
fprintf (fp, "Hacked\n");
fclose (fp);
while(1){
printf("HACKED\n");
fflush(stdout);
sleep(1);
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, PVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
HANDLE hThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)hackthread, hModule, 0, nullptr);
CloseHandle(hThread);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
以这种方式,CreateThread 和 DllMain return 99.9999% 的时间。
这是根据我的经验得出的概念证明。