3

我正在尝试使用 LoadLibrary 和 CreateRemoteThread 方法将 dll 注入现有进程。除了由于某种原因没有调用 DllMain 之外,我所有的代码都运行良好。

我已经绞尽脑汁做了尽可能多的互联网研究,但这些建议都没有帮助。

当我将 dll 静态加载到示例项目中时,它运行良好。

当我使用 LoadLibrary 将 dll 动态加载到示例项目中时,它运行良好。

唯一一次不调用 DllMain 是当我尝试使用 LoadLibrary 和 CreateRemoteThread 方法将其注入进程时。我无计可施!

我已验证 dll 已从注入器加载到 notepad.exe 进程中,因为 SimpleDLL.dll 文件已被锁定,在我关闭 notepad.exe 之前无法删除或覆盖。

仅供参考,我的想法是 Microsoft Visual Studio 2010 Ultimate。

// SimpleDLL.h
#pragma once

#include "Stdafx.h"

#ifdef COMPILE_MYLIBRARY
  #define MYLIBRARY_EXPORT __declspec(dllexport)
#else
  #define MYLIBRARY_EXPORT __declspec(dllimport)
#endif

.

//SimpleDLL.cpp
#include "Stdafx.h"
#include "SimpleDll.h"

extern "C" int __stdcall DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) {

    printf("SimpleDll: DllMain called.\n");

    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
            printf("SimpleDll: DLL_PROCESS_ATTACH.\n");
            break;
        case DLL_PROCESS_DETACH:
            printf("SimpleDll: DLL_PROCESS_DETACH.\n");
            break;
        case DLL_THREAD_ATTACH:
            printf("SimpleDll: DLL_THREAD_ATTACH.\n");
            break;
        case DLL_THREAD_DETACH:
            printf("SimpleDll: DLL_THREAD_DETACH.\n");
            break;
    }

    return TRUE;
};

SimpleDLLCaller.cpp - 它运行正确并打印出来自 DllMain 的消息。这是我构建的一个项目,用于验证 dll 是否正确构建。从我可以看到的输出中,以这种方式加载时它似乎运行正常。

// SimpleDLLCaller.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    LoadLibraryA( "C:\\SimpleDll.dll" );

    _getch(); 

    return 0;
}

SimpleDllCaller 的输出:

SimpleDll: DllMain called.
SimpleDll: DLL_PROCESS_ATTACH.

Simple Injector.cpp - 这是一个独立于 SimpleDLLCaller 的项目,可以成功编译/运行而不会出现警告(只要 notepad.exe 已经在运行),但不会显示来自 DllMain 的消息。

// Simple Injector.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <windows.h> 
#include <tlhelp32.h> 
#include <shlwapi.h> 
#include <conio.h> 
#include <stdio.h> 

#define WIN32_LEAN_AND_MEAN 
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ) 

BOOL Inject(DWORD pID, const char * dll_name ) 
{ 
    HANDLE targetProcess, createdThread; 
    //HMODULE hLib; 
    char buf[50] = {0}; 
    LPVOID myRemoteString, LoadLibAddy;

    if( ! pID ) 
    {
        return FALSE;
    }

    targetProcess = OpenProcess( CREATE_THREAD_ACCESS, FALSE, pID );
    if( ! targetProcess ) 
    { 
        sprintf_s(buf, "OpenProcess() failed: %d", GetLastError()); 
        MessageBox(NULL, buf, "Loader", MB_OK); 
        printf(buf); 
        return false; 
    }

    LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    if( ! LoadLibAddy )
    {
        printf( "ERROR: Problems with GetProcAddress.  Error code: %d\n", GetLastError() );
        return false;
    }

    // Allocate space in the process for the dll 
    myRemoteString = (LPVOID)VirtualAllocEx( targetProcess, NULL, strlen(dll_name), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    if( ! myRemoteString )
    {
        printf( "ERROR: Problems with VirtualAllocEx.  Error code: %d\n", GetLastError() );
        return false;
    }

    // Write the string name of the dll in the memory allocated 
    if( ! WriteProcessMemory( targetProcess, (LPVOID)myRemoteString, dll_name, strlen(dll_name), NULL) )
    {
        printf( "ERROR: Problems with WriteProcessMemory.  Error code: %d\n", GetLastError() );
        return false;
    }

    // Load the dll
    createdThread = CreateRemoteThread( targetProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)myRemoteString, NULL, NULL);
    if( ! createdThread )
    {
        printf( "ERROR: Problems with CreateRemoteThread.  Error code: %d\n", GetLastError() );
        return false;
    }

    WaitForSingleObject(createdThread, INFINITE);

    // Free the memory that is not being using anymore. 
    if( myRemoteString != NULL ) VirtualFreeEx( targetProcess, myRemoteString, 0, MEM_RELEASE );
    if( createdThread != NULL ) CloseHandle( createdThread );
    if( targetProcess != NULL ) CloseHandle( targetProcess );

    //VirtualFreeEx(hProcess , (LPVOID)Memory , 0, MEM_RELEASE); 

    return true; 
} 

DWORD GetTargetThreadIDFromProcName(const char *ProcName) 
{ 
   PROCESSENTRY32 pe; 
   HANDLE thSnapShot; 
   BOOL retval, ProcFound = false; 

   thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
   if(thSnapShot == INVALID_HANDLE_VALUE) 
   { 
      //MessageBox(NULL, "Error: Unable <strong class="highlight">to</strong> create toolhelp snapshot!", "2MLoader", MB_OK); 
      printf("Error: Unable to create toolhelp snapshot!"); 
      return false; 
   } 

   pe.dwSize = sizeof(PROCESSENTRY32); 

   retval = Process32First(thSnapShot, &pe); 
   while(retval) 
   { 
      if( !strcmp(pe.szExeFile, ProcName) ) 
      { 
         return pe.th32ProcessID; 
      } 
      retval = Process32Next(thSnapShot, &pe); 
   } 
   return 0; 
}

int _tmain(int argc, _TCHAR* argv[])
{
   // Retrieve process ID 
   DWORD pID = GetTargetThreadIDFromProcName("notepad.exe"); 
    if( !pID )
    {
        printf( "ERROR: Could not find any process for notepad.exe.\n");
        _getch();
        return 0;
    }

    // Get the dll's full path name 
    char buf[MAX_PATH] = {0}; 
    // GetFullPathName("..\\SimpleDLL.dll", MAX_PATH, buf, NULL); 
    sprintf_s(buf, "C:\\SimpleDLL.dll");

    printf( "Dll path = %s\n", buf );

    // Inject our main dll 
    if(!Inject(pID, buf)) 
    {
        printf("Dll not loaded."); 
    }
    else
    {
        printf("Dll loaded."); 
    }

    _getch();
    return 0; 
}

简单注射器的输出:

Dll path = C:\SimpleDLL.dll
Dll loaded.

请告诉我我在这里做错了什么。欢迎任何反馈。

4

1 回答 1

3

您的 DLL 可能已正确加载。不要指望你的 printf 做任何事情。如果您需要证明,请将您的消息写入文本文件,或使用 MessageBox,或使用 Process Explorer。

于 2013-11-19T08:13:48.880 回答