CreateRemoteThread + LoadLibraryA 尽管成功但什么也没做
CreateRemoteThread + LoadLibraryA doesn't do anything despite succeeding
尽管内存 allocation/write,找到 LoadLibraryA
地址并创建远程线程 return 有效(非 NULL)结果,之后绝对没有任何反应(主要是 DllMain加载的 DLL 似乎没有被调用)。
#define PROC_NAME L"TestConsole.exe"
#define DLL_NAME "TestLib.dll[=10=]"
HANDLE GetProcessByName(const wchar_t* name);
int main()
{
const char dllName[] = DLL_NAME;
int dllNameSize = strlen(dllName) + 1;
HANDLE process = GetProcessByName(PROC_NAME);
LPVOID allocMem = VirtualAllocEx(process, NULL, dllNameSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(process, allocMem, dllName, dllNameSize, NULL);
// Just to make sure
char buff[20];
ReadProcessMemory(process, allocMem, buff, dllNameSize, NULL);
printf("Data: %s\n", buff);
LPVOID libraryAddress =
(LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
HANDLE remoteThread = CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)libraryAddress, allocMem, NULL, NULL);
}
HANDLE GetProcessByName(const wchar_t* name)
{
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (wcscmp(entry.szExeFile, name) == 0)
{
return OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ParentProcessID);
}
}
}
return NULL;
}
事情我 know/checked:
- 创建了线程并 return 编辑了一个有效(非空)句柄。尽管如此,什么也没有发生。
- 我很确定不是 DLL 的错。它非常简单,加载时只需打印到控制台,只需与
CreateThread()
. 一起使用即可正常工作
- 注入器、DLL 和我要注入的应用程序都是 64 位的。如果我选择任何其他平台(对于所有 3 个平台),除了
CreateRemoteThread()
,其他一切都一样,现在失败了。
entry.th32ParentProcessID
是创建这个进程的进程的标识符(它的父进程)。这意味着您确实注入了目标进程的父进程(在我的测试中为 explorer.exe)。您应该改用 entry.th32ProcessID
。
另外,OpenProcess
中使用的开放权限PROCESS_ALL_ACCESS
太大,你只需要使用CreateRemoteThread
文档要求的:PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
尽管内存 allocation/write,找到 LoadLibraryA
地址并创建远程线程 return 有效(非 NULL)结果,之后绝对没有任何反应(主要是 DllMain加载的 DLL 似乎没有被调用)。
#define PROC_NAME L"TestConsole.exe"
#define DLL_NAME "TestLib.dll[=10=]"
HANDLE GetProcessByName(const wchar_t* name);
int main()
{
const char dllName[] = DLL_NAME;
int dllNameSize = strlen(dllName) + 1;
HANDLE process = GetProcessByName(PROC_NAME);
LPVOID allocMem = VirtualAllocEx(process, NULL, dllNameSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(process, allocMem, dllName, dllNameSize, NULL);
// Just to make sure
char buff[20];
ReadProcessMemory(process, allocMem, buff, dllNameSize, NULL);
printf("Data: %s\n", buff);
LPVOID libraryAddress =
(LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
HANDLE remoteThread = CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)libraryAddress, allocMem, NULL, NULL);
}
HANDLE GetProcessByName(const wchar_t* name)
{
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (wcscmp(entry.szExeFile, name) == 0)
{
return OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ParentProcessID);
}
}
}
return NULL;
}
事情我 know/checked:
- 创建了线程并 return 编辑了一个有效(非空)句柄。尽管如此,什么也没有发生。
- 我很确定不是 DLL 的错。它非常简单,加载时只需打印到控制台,只需与
CreateThread()
. 一起使用即可正常工作
- 注入器、DLL 和我要注入的应用程序都是 64 位的。如果我选择任何其他平台(对于所有 3 个平台),除了
CreateRemoteThread()
,其他一切都一样,现在失败了。
entry.th32ParentProcessID
是创建这个进程的进程的标识符(它的父进程)。这意味着您确实注入了目标进程的父进程(在我的测试中为 explorer.exe)。您应该改用 entry.th32ProcessID
。
另外,OpenProcess
中使用的开放权限PROCESS_ALL_ACCESS
太大,你只需要使用CreateRemoteThread
文档要求的:PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ