注入 C++ DLL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10930353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Injecting C++ DLL
提问by Bali C
I know there are various questions and books on this but I can't seem to get my C++ DLL injected into any processes.
我知道有很多关于这方面的问题和书籍,但我似乎无法将我的 C++ DLL 注入任何进程。
The code to inject the 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;
}
and the DLL I am trying to inject:
和我试图注入的 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;
}
I don't know enough C++ to know where this is going wrong. I have run Process Explorer on the process I am trying to inject to (process run as admin aswell) but it isn't being injected. When I run it, nothing happens, any ideas?
我不知道足够的 C++ 知道这哪里出错了。我已经在我尝试注入的进程上运行了 Process Explorer(进程也以管理员身份运行),但它没有被注入。当我运行它时,没有任何反应,有什么想法吗?
回答by Roman R.
Don't do MessageBox
from DllMain
. Why? See:
不要MessageBox
从DllMain
. 为什么?看:
- DLL_PROCESS_ATTACH failing to execute on Windows 7 C++
- Some reasons not to do anything scary in your DllMain
- Don't use standard library/CRT functions in static initializers/DllMain!
Your message box might just deadlock before showing up there. To ensure you reach the code line of interest, use OutputDebugString
instead. As you indicated you are familiar with Process Explorer, you might notice created thread there (you can obtain its identifier in your launcher by providing last argument in your CreateRemoteThread
) and its locked state with execution inside kernel libraries.
您的消息框可能会在出现之前陷入僵局。为确保您到达感兴趣的代码行,请OutputDebugString
改用。正如您表示您熟悉 Process Explorer,您可能会注意到在那里创建的线程(您可以通过在您的 中提供最后一个参数来在您的启动器中获取它的标识符CreateRemoteThread
)以及它在内核库中执行时的锁定状态。
This is where you need to put OutputDebugString
:
这是您需要放置的地方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;
}
Another thing to make sure is that you are loading DLL of correct bitness. Win32
DLL into Win32
process, or x64
DLL into x64
process.
要确保的另一件事是您正在加载正确位数的 DLL。Win32
DLL 进入Win32
进程,或x64
DLL 进入x64
进程。
UPDATE. I am putting this up from comment: here is the source code for the Visual Studio 2010 project that does the thing: SVNor Trac.
更新。我是从评论中提出来的:这是执行此操作的 Visual Studio 2010 项目的源代码:SVN或Trac。
- You put process identifier into source code
- The executable creates remote thread and loads library
- The library starts from DllMain and generates debug output
DebugView
shows you the outputProcessExplorer
shows you the thread created, and you also have its identifier printed
- 您将进程标识符放入源代码中
- 可执行文件创建远程线程并加载库
- 该库从 DllMain 启动并生成调试输出
DebugView
向您展示输出ProcessExplorer
向您显示创建的线程,并且您还打印了它的标识符
回答by Bukes
The problem you're likely running into is that the address of LoadLibraryA() in your application might not be the same in the target process, due to ASLR- a technology designed specifically to thwart the activity you're attempting. Modern versions of Windows (Vista+) have this enabled by default for system DLLs
您可能遇到的问题是您的应用程序中 LoadLibraryA() 的地址在目标进程中可能不同,这是由于ASLR- 一种专门设计用于阻止您尝试的活动的技术。现代版本的 Windows (Vista+) 默认情况下为系统 DLL 启用此功能
In order to do what you want, you'll need to implement a proper ThreadProc in your application that loads your DLL, allocate some executable memory (PAGE_EXECUTE) memory in your target process, copy it there, and use this address as your thread start point.
为了做你想做的事,你需要在你的应用程序中实现一个合适的 ThreadProc 来加载你的 DLL,在你的目标进程中分配一些可执行内存(PAGE_EXECUTE)内存,将它复制到那里,并使用这个地址作为你的线程开始观点。
回答by rkosegi
Admin account does not need to implicitly own SE_DEBUG privilege. If you run under Vista/Win7, make sure that UAC is disabled. Use this code to enable it before you try to open process memory:
管理员帐户不需要隐式拥有 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;
}
回答by phyatt
I would start with someone else's working example and go from there. The example projects, tutorials, and explanations on CodeProject are really solid.
我会从其他人的工作示例开始,然后从那里开始。CodeProject 上的示例项目、教程和解释非常扎实。
Here is one on Hooking and DLLs.
这是关于Hooking 和 DLLs 的一个。
And another. And a google searchfor you.
For certain kinds of hooks, there are permission limitations that you have to overcome, or you have to accept the fact that you can't hook every process.
对于某些类型的挂钩,您必须克服权限限制,或者您必须接受无法挂钩每个进程的事实。
Setting the UI-Access to true, and having your executable in C:/Program Files/, and having your dll digitally signed helps to access some of the secure windows in Windows. Here is an articlethat discusses some of these things.
将 UI-Access 设置为 true,将可执行文件放在 C:/Program Files/ 中,并对 dll 进行数字签名有助于访问 Windows 中的一些安全窗口。这是一篇讨论其中一些事情的文章。
Hope that helps.
希望有帮助。
回答by Chris O
SetWindowsHookEx can also inject your DLL into another process.
SetWindowsHookEx 还可以将您的 DLL 注入另一个进程。