为“calculator.exe”进程编写了一个简单的Dll注入器,打印出一些行我确认注入器完成了它的工作,但是没有出现消息框。
上下文:
-void inject_dll(DWORD,char *)获取我想要注入的进程的ID以及它将注入的dll的名称。
-DWORD get_PId(const w_char_t *)是一个返回给定参数(processname)的processID的函数
我已经确认get_PId函数正常工作,因此错误应该在其他地方。
注射器代码:
#include "stdafx.h"
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
void inject_dll(DWORD PId, char* DllName)
{
HANDLE hProcess;
PVOID Alloc;
SIZE_T DllPathLen;
HMODULE Kernel32Base;
PVOID LoadLibAddress;
if (PId != 0 && DllName != NULL)
{
DllPathLen = strlen(DllName);
Kernel32Base = GetModuleHandleA("Kernel32.dll");
if (Kernel32Base == NULL)
{
std::cout << "kernel32.dll not found" << std::endl;
return;
}
LoadLibAddress = GetProcAddress(Kernel32Base, "LoadLibraryA");
if (LoadLibAddress == NULL)
{
std::cout << "LoadLibraryA not found" << std::endl;
return;
}
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PId);
if (hProcess == NULL)
{
std::cout << "hProcess handle not opened" << std::endl;
return;
}
Alloc = VirtualAllocEx(hProcess, NULL, DllPathLen + 1, MEM_COMMIT, PAGE_READWRITE);
if (Alloc == NULL)
{
std::cout << "no memory allocated for DllPath" << std::endl;
return;
}
if (!WriteProcessMemory(hProcess, Alloc, DllName, DllPathLen + 1, NULL))
{
std::cout << "didn't write dll to processmemory" << std::endl;
return;
}
CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddress, Alloc, 0, NULL);
std::cout << "end reached" << std::endl;
}
}
DWORD get_PId( const wchar_t* ProcessName) {
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (hSnapshot != NULL)
{
if (Process32First(hSnapshot, &pe32)) {
do
{
if (!wcscmp(pe32.szExeFile, ProcessName))
return pe32.th32ProcessID;
} while (Process32Next(hSnapshot, &pe32));
}
}
return 0;
}
int main(int argc, char* argv[])
{
DWORD pid = get_PId(L"Calculator.exe");
std::cout << pid << std::endl;
if (pid) {
char dllName[] = "CORRECT PATH (dont worry about this)";
std::cout << dllName << std::endl;
inject_dll(pid, dllName);
}
ExitPoint:
system("Pause");
return 0;
}
Dll代码,当它在注入进程的内存中时,它应该显示一个消息框:
#include <windows.h>
VOID ShowMessageBox() {
MessageBoxA(NULL, "injected", "injector", MB_OK);
}
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
ShowMessageBox();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
答案 0 :(得分:0)
我也不是100%确信这一点,但是我认为这是因为Windows Vista及更高版本中的会话分离。您可以详细了解here。
自Vista以来,随着“会话分离”的引入,情况发生了变化。这是Vista中为保护系统而引入的众多防御措施之一。 “会话分离”确保了包括服务在内的核心系统进程始终在会话0中运行,而所有用户进程在不同的会话中运行。结果,在用户会话中运行的任何进程都无法将DLL注入系统进程,因为CreateRemoteThread无法跨会话边界工作...
在诸如notepad.exe
或paint.exe
之类的进程上,注入应该可以正常工作。
答案 1 :(得分:-2)
我怀疑你遇到了DllMain的一个限制,你不应该从DllMain中调用user32.dll或gdi32.dll中的任何内容。