我知道有关于此的各种问题和书籍,但我似乎无法将我的C ++ DLL注入任何进程。
注入DLL的代码:
#include <iostream>
#include "windows.h"
bool Inject(DWORD pId, char *dllName);
using namespace std;
int main()
{
Inject(600, "C:\\d.dll");
return 0;
}
bool Inject(DWORD pId, char *dllName)
{
HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, pId);
if(h)
{
LPVOID LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
LPVOID dereercomp = VirtualAllocEx(h, NULL, strlen(dllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(h, dereercomp, dllName, strlen(dllName), NULL);
HANDLE asdc = CreateRemoteThread(h, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, dereercomp, 0, NULL);
WaitForSingleObject(asdc, INFINITE);
VirtualFreeEx(h, dereercomp, strlen(dllName), MEM_RELEASE);
CloseHandle(asdc);
CloseHandle(h);
return true;
}
return false;
}
和我试图注入的DLL:
#include <windows.h>
#include <stdio.h>
BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
MessageBox (0, "From DLL\n", "Process Attach", MB_ICONINFORMATION);
break;
case DLL_PROCESS_DETACH:
MessageBox (0, "From DLL\n", "Process Detach", MB_ICONINFORMATION);
break;
case DLL_THREAD_ATTACH:
MessageBox (0, "From DLL\n", "Thread Attach", MB_ICONINFORMATION);
break;
case DLL_THREAD_DETACH:
MessageBox (0, "From DLL\n", "Thread Detach", MB_ICONINFORMATION);
break;
}
return TRUE;
}
我不知道足够的C ++知道这出错的地方。我已经在我尝试注入的进程上运行Process Explorer(进程以admin身份运行),但它没有被注入。当我运行它时,没有任何反应,任何想法?
答案 0 :(得分:26)
不要从MessageBox
执行DllMain
。为什么?参见:
您的消息框可能会在出现之前陷入僵局。为确保您能够访问感兴趣的代码行,请改用OutputDebugString
。正如您所说,您熟悉Process Explorer,您可能会注意到那里创建的线程(您可以通过在CreateRemoteThread
中提供最后一个参数来获取其在启动器中的标识符)以及在内核库中执行时的锁定状态。
这是您需要放置OutputDebugString
:
BOOL APIENTRY DllMain(HMODULE hModule, DWORD nReason, VOID* pvReserved)
{
pvReserved;
TCHAR pszMessage[1024] = { 0 };
_stprintf_s(pszMessage, _T("GetCurrentProcessId() %d, hModule 0x%p, nReason %d\r\n"), GetCurrentProcessId(), hModule, nReason);
OutputDebugString(pszMessage);
/*switch(nReason)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}*/
return TRUE;
}
要确保的另一件事是你正在加载正确位数的DLL。 Win32
DLL进入Win32
进程,或x64
DLL进入x64
进程。
更新。我从评论中提出这个问题:这是Visual Studio 2010项目的源代码:SVN或Trac。
DebugView
显示输出ProcessExplorer
显示创建的主题,并且还打印了标识符答案 1 :(得分:6)
您可能遇到的问题是,由于ASLR - 专门设计用于阻止您的活动的技术{{3}},您的应用程序中LoadLibraryA()的地址可能与目标进程中的地址不同。重新尝试。现代版本的Windows(Vista +)默认为系统DLL启用
为了做你想做的事,你需要在你的应用程序中实现一个正确的ThreadProc来加载你的DLL,在你的目标进程中分配一些可执行内存(PAGE_EXECUTE)内存,在那里复制它,并使用这个地址作为你的线程起点。
答案 2 :(得分:5)
管理员帐户无需隐式拥有SE_DEBUG权限。 如果您在Vista / Win7下运行,请确保已禁用UAC。 在尝试打开进程内存之前,请使用此代码启用它:
BOOL EnableDebugPrivilege()
{
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))
{
return FALSE;
}
if(!LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid ))
{
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = luid;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges( hToken, false, &tkp, sizeof( tkp ), NULL, NULL ))
{
return FALSE;
}
if(!CloseHandle( hToken ))
{
return FALSE;
}
return TRUE;
}
答案 3 :(得分:3)
我会从其他人的工作示例开始,然后从那里开始。 CodeProject上的示例项目,教程和解释非常可靠。
这是Hooking and DLLs上的一个。
another。并为您google search。
对于某些类型的挂钩,您必须克服权限限制,或者您必须接受不能挂钩每个进程的事实。
将UI-Access设置为true,并将您的可执行文件设置为C:/ Program Files /,并对您的dll进行数字签名有助于访问Windows中的某些安全窗口。这是article,讨论了其中的一些内容。
希望有所帮助。
答案 4 :(得分:0)
SetWindowsHookEx还可以将您的DLL注入另一个进程。