2012-11-12 38 views
3

我正在尝试使用CreateRemoteThread将DLL注入到现有进程中。问题是,当从Visual Studio 2010中启动应用程序时,它不起作用。DLL注入只有在不从Visual Studio启动时才有效

的DLL注入作品:

  1. 当手动启动它(从资源管理器)

  2. 当手动启动它,并在注射前附接VS 2010调试器。

当我选择:在Visual Studio 2010中启动调试(F5),CreateRemoteThread返回OK。我甚至在注入的过程中在LoadLibraryA上放置了一个断点,并且它被击中。所以线程启动了,但是没有达到DllMain的功能。 LoadLibraryA被执行,但是模块不会被加载。

注入代码:

void InjectDll(DWORD processId, string dllFile) 
{ 
    HANDLE hProcess = OpenProcess(CREATE_THREAD_ACCESS, FALSE, processId); 
    if (hProcess != NULL) 
    { 
     int lenWrite = dllFile.length(); 
     LPVOID allocMem = (LPVOID)VirtualAllocEx(hProcess, NULL, lenWrite, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); 
     WriteProcessMemory(hProcess, allocMem , dllFile.c_str(), lenWrite, NULL); 
     LPTHREAD_START_ROUTINE injector = (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); 

     if(!injector) 
      return; 
     DWORD threadId; 
     HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, injector, allocMem, 0, &threadId); 

     DWORD Result = WaitForSingleObject(hThread, 10*1000); //Time out : 10 secondes 
     VirtualFreeEx(hProcess, allocMem, lenWrite, MEM_RELEASE); 
     CloseHandle(hProcess); 
     CloseHandle(hThread); 
    } 
} 

而且DllMain的代码:

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 
{ 
    switch (ul_reason_for_call) 
    { 
     case DLL_PROCESS_ATTACH: 
      HelloWorldMessageBox(); 
     case DLL_THREAD_ATTACH: 
     case DLL_THREAD_DETACH: 
     case DLL_PROCESS_DETACH: 
      break; 
    } 
    return TRUE; 
} 

感谢您的帮助!

编辑:

我用OllyDbg的放置在LoadLibraryA一个断点。我将汇编指令“ret”替换为对GetLastError的调用,并且我在EAX寄存器中得到了以下值:126.从MSDN系统错误代码126意味着ERROR_MOD_NOT_FOUND(指定的模块找不到)。很奇怪,它只发生在Visual Studio运行注入应用程序时。

+2

不需要永远做DLL注入,我真的好奇。是不是API执行此有效附加作为调试器,强制加载,并启动一个线程,然后分离?如果是这样,是否有可能失败是因为多个调试器不能同时连接到同一个进程?正如我所说,我完全是猜测。 – WhozCraig

+0

我只附加一个调试器,VS2010之一。当我从手动启动(双击.exe文件)应用程序附加它时,一切正常。当VS2010开始这个过程时,它不起作用,因为她的子进程 – Darxis

+1

也许我没有说清楚。是否有可能您正在调用的API正在制作**您的程序**表现为一个逐个调试器(检查OpenProcess()调用),因此VS调试器也无法作为结果附加?这更清楚吗? (反之亦然,顺便说一句) – WhozCraig

回答

2

最后我发现了这个问题!

要获得完整的模块路径我用

GetFullPathName("Inj_DLL.dll", MAX_PATH, dll_path, NULL); 

它使用当前的工作目录来确定该文件的路径。

当我手动启动应用程序时,工作目录是exe文件的路径,但是当它从Visual Studio启动时,它使用工程目录 - >配置属性 - >调试。

由于默认设置为“$(ProjectDir)”,并且注入的dll位于Debug/Release目录中,因此找不到dll文件,所以错误126 ERROR_MOD_NOT_FOUND。

我已经将此属性更改为“$(SolutionDir)$(Configuration)\”,现在所有东西都像魅力一样。

感谢任何试图帮助我解决这个问题的人,我发现了一些调试非工作应用程序的新方法。

相关问题