3

LoadLibrary および CreateRemoteThread アプローチを使用して、既存のプロセスに dll を挿入しようとしています。DllMain が何らかの理由で呼び出されていないという事実を除いて、私のコードはすべて美しく機能しています。

私は頭を悩ませ、できる限り多くのインターネット調査を行いましたが、どの提案も役に立ちませんでした.

dll をサンプル プロジェクトに静的にロードすると、見事に動作します。

LoadLibrary を使用してサンプル プロジェクトに dll を動的にロードすると、問題なく動作します。

DllMain が呼び出されないのは、LoadLibrary および CreateRemoteThread アプローチを使用してプロセスに挿入しようとしているときだけです。私は頭が痛いです!

SimpleDLL.dll ファイルがロックされており、notepad.exe を閉じるまで削除または上書きできないため、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 に答える