我正在尝试学习一些手动dll注入,但是似乎无法使dlls代码执行正常工作。我是Windows C ++的新手,因此感谢您提供任何改进我的代码的技巧。我也只发布了相关代码。
进样器程序:
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, getPID(TARGET_NAME));
DWORD gotDLL = GetFullPathName(DLL_NAME, MAX_PATH, dllPath, NULL);
hFile = CreateFile(dllPath, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
dllFileSize = GetFileSize(hFile, NULL);
memAddrForDLL = VirtualAllocEx(hProcess, NULL, dllFileSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
loadedDLL = HeapAlloc(GetProcessHeap(), NULL, dllFileSize);
// Load dll into allocated memory in current process
ReadFile(hFile, loadedDLL, dllFileSize, &bytesRead, NULL))
// Find offset of dll entry point
IMAGE_NT_HEADERS* pOldNtHeader = reinterpret_cast<IMAGE_NT_HEADERS*>(reinterpret_cast<BYTE*>(loadedDLL) + reinterpret_cast<IMAGE_DOS_HEADER*>(loadedDLL)->e_lfanew);
IMAGE_OPTIONAL_HEADER* pOldOptHeader = &pOldNtHeader->OptionalHeader;
entryPointOffset = pOldOptHeader->AddressOfEntryPoint;
// Load dll into allocated memory in target process
WriteProcessMemory(hProcess, memAddrForDLL, loadedDLL, bytesRead, NULL)
LPTHREAD_START_ROUTINE entryPoint = (LPTHREAD_START_ROUTINE)((unsigned __int64)memAddrForDLL + entryPointOffset);
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibrary, entryPoint, NULL, NULL)
DLL:
DWORD WINAPI OnDllAttach(LPVOID base){
typedef void func(void);
func* f = (func*)0x00007FF605EC5835;
f();
FreeLibraryAndExitThread(static_cast<HMODULE>(base),1);
}
BOOL WINAPI OnDllDetach(){
return TRUE;
}
BOOL WINAPI DllMain(_In_ HINSTANCE hinstDll,
_In_ DWORD fdwReason,
_In_opt_ LPVOID lpvReserved){
typedef void func(void);
func* f = (func*)0x00007FF605EC5835;
f();
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDll);
CreateThread(nullptr, 0, OnDllAttach, hinstDll, 0, nullptr);
return TRUE;
case DLL_PROCESS_DETACH:
if(lpvReserved == nullptr)
return OnDllDetach();
return TRUE;
default:
return TRUE;
}
}
目标程序包含此功能:
void printer(){
cout << "test" << endl;
}
我的注射器产生以下输出
1. Attempting to attatch to process target.exe
--- Got target.exe PID: 14640
--- Got target.exe Handle: 0x0000000000000084
2. Attempting to allocate memory
--- Found dll: D:\projects\injector\hack.dll
--- Got hack.dll Handle: 0x0000000000000088
--- Allocated memory in target.exe at 0x0000017BEB690000
3. Attempting to copy dll to target.exe
--- Allocated memory at 0x00000226A060FFE0
--- Loaded hack.dll in current process at 0x00000226A060FFE0
--- hack.dll is a valid DLL
--- Loaded hack.dll into target.exe at 0x0000017BEB690000
4. Attempting to execute dll
--- Offset from start of file to entrypoint: 0x3cf6
--- Began execution of hack.dll in target.exe at 0x0000017BEB693CF6
使用Ghidra,我可以确认这是dll入口点的正确偏移量。但是,当运行我的注射器时,目标进程中没有任何反应,我也尝试使用cout从dll中打印一条消息,但是却什么也没得到(我不认为它甚至可以工作,因为什么都没有被重新定位)
我正在使用
CreateRemoteThread(hProcess, NULL, NULL, entryPoint, memAddrForDLL, NULL, NULL)
在第四个参数称为lpStartAddress之前,我认为这应该是入口点,但这导致目标进程崩溃,我看到的每个示例都使用了当前在代码中使用的方式。
在我的dll中,我正在通过地址在目标进程中调用该函数。
编辑:我正在自己的控制台应用程序上对此进行测试。
答案 0 :(得分:0)
加载到内存中的.DLL与磁盘上的.DLL文件不同。部分的布局不同,您需要处理重定位,导入表和PEB加载的模块列表。您基本上必须重新实现NTDLL!Ldr*
。
在CreateRemoteThread
上调用LoadLibrary
是另一种技术,执行此操作时,线程参数需要指向远程进程中的.DLLs路径,而不是入口点。
答案 1 :(得分:0)
DLL注入的最基本形式是:
您已经有了这个,但是,您的目标是手动映射DLL,并避免使用LoadLibrary()。您提供的代码无法解决,大约还有5个步骤。您需要模拟LoadLibrary()通常执行的所有操作:
手动映射的好处是,您将在ToolHelp32Snapshot()中隐藏,并在PEB和NtQueryVirtualMemory中浏览模块链接列表。
如果您想做正确的事,并通过体面的错误检查,大约需要350行代码,而且会变得很复杂。所有这些都是通过解析PE标头完成的。
现在,您的DLL已加载,并且DLL_PROCESS_ATTACH开关的情况正在执行。显然,这要复杂得多,但这就是想法。
没有我的朋友Broihon教给我,我将一无所知,所以我想将此答案归功于他。祝你好运