23

これに関するさまざまな質問や本があることは知っていますが、C++ 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;
}

そして、私が注入しようとしている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;
}

これがどこで間違っているのかを知るのに十分なC++を知りません。注入しようとしているプロセス (管理者として実行されるプロセス) で Process Explorer を実行しましたが、注入されていません。実行しても何も起こりません。何かアイデアはありますか?

4

5 に答える 5

26

MessageBoxからしないでくださいDllMain。なんで?見る:

メッセージボックスが表示される前にデッドロックする可能性があります。目的のコード行に確実に到達するには、OutputDebugString代わりにを使用してください。Process Explorerに精通していることを示したように、そこで作成されたスレッド(ランチャーで最後の引数を指定することで、ランチャーでその識別子を取得できますCreateRemoteThread)と、カーネルライブラリ内での実行によるロック状態に気付く場合があります。

これはあなたが置く必要がある場所です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;
}

確認するもう1つのことは、正しいビット数のDLLをロードしていることです。Win32DLLをWin32プロセスに、またはx64DLLをx64プロセスに。

アップデート。私はコメントからこれを上げています:これは、SVNまたはTracということを行うVisualStudio2010プロジェクトのソースコードです。

  • プロセス識別子をソースコードに入れます
  • 実行可能ファイルはリモートスレッドを作成し、ライブラリをロードします
  • ライブラリはDllMainから始まり、デバッグ出力を生成します
  • DebugView出力を表示します
  • ProcessExplorer作成されたスレッドが表示され、その識別子も印刷されます
于 2012-06-11T14:07:35.473 に答える
6

あなたが直面している可能性が高い問題は、 ASLRが原因で、アプリケーションの LoadLibraryA() のアドレスがターゲット プロセスで同じでない可能性があることです。これは、試みているアクティビティを阻止するために特別に設計されたテクノロジです。最新バージョンの Windows (Vista+) では、システム DLL に対してこれがデフォルトで有効になっています。

必要なことを行うには、DLL をロードするアプリケーションに適切な ThreadProc を実装し、ターゲット プロセスに実行可能メモリ (PAGE_EXECUTE) メモリを割り当て、そこにコピーし、このアドレスをスレッドの開始として使用する必要があります。点。

于 2012-06-11T14:15:09.843 に答える
5

管理者アカウントは、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;
}
于 2012-06-07T12:46:45.440 に答える
3

私は他の誰かの実際の例から始めて、そこから始めます。CodeProject のサンプル プロジェクト、チュートリアル、説明は非常に充実しています。

これはHooking と DLLに関するものです。

そしてもう一つ。そして、あなたのためのグーグル検索

特定の種類のフックについては、克服しなければならないアクセス許可の制限があります。または、すべてのプロセスをフックできないという事実を受け入れる必要があります。

UI-Access を true に設定し、実行可能ファイルを C:/Program Files/ に置き、dll にデジタル署名を付けると、Windows のセキュリティで保護されたウィンドウにアクセスするのに役立ちます。これらのことのいくつかを説明する記事を次に示します。

それが役立つことを願っています。

于 2012-06-13T05:17:01.233 に答える
0

SetWindowsHookEx は、DLL を別のプロセスに挿入することもできます。

于 2012-06-17T01:54:57.153 に答える