DllMain没有被注入的dll调用

时间:2013-11-19 02:31:26

标签: dll loadlibrary dllmain

我正在尝试使用LoadLibrary和CreateRemoteThread方法将dll注入现有进程。我的所有代码都工作得很漂亮,除了因为某些原因没有调用DllMain这一事实。

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

当我将dll静态加载到示例项目中时,它可以很好地工作。

当我使用LoadLibrary将dll动态加载到示例项目中时,它可以很好地工作。

唯一没有调用DllMain的时候是我尝试使用LoadLibrary和CreateRemoteThread方法将其注入进程。我的智慧结束了!

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

Fyi,我的ide是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; 
}

Simple Injector的输出:

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

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

1 个答案:

答案 0 :(得分:2)

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