2011-12-31 6 views
1

私が書き込んだDLLをロードしてそこから関数を実行するリモートスレッドを作成しようとしています。 DLLが正常に動作していますが、何らかの理由でリモートスレッドが失敗し、作成されたプロセスが応答を停止します。 LoadLibraryへの呼び出し時にエラー87でリモートスレッドが失敗しています

は、私が試してみて、間違って起こっているかを見るためにollyDebugを使用して、私は正確にリモートスレッド
  • スレッドに渡されている2つの事...

    1. 私の文字列(DLL名と関数名を)気づきました最終エラーコード87「ERROR_INVALID_PARAMETER」とのLoadLibraryに失敗し

    私の最高の推測で何とか、リモートスレッドがLoadLibraryのを(見つけることができないということです。このリンカーは私のproccess ???、ジャストにrepspectで行われるので、推測する...)

    私は間違っていますか?

    これは、リモート関数にコードされ:

    static DWORD WINAPI SetRemoteHook (DATA *data) 
    { 
        HINSTANCE dll; 
        HHOOK WINAPI hook; 
        HOOK_PROC hookAdress; 
    
        dll = LoadLibrary(data->dll); 
    
        hookAdress = (HOOK_PROC) GetProcAddress(dll,data->func); 
        if (hookAdress != NULL) 
        { 
        (hookAdress)(); 
        } 
        return 1; 
    } 
    

    編集:

    これは私がリモートproccessにメモリを割り当てている部分である:

    typedef struct 
    { 
        char* dll; 
        char* func; 
    } DATA; 
    
    char* dllName = "C:\\Windows\\System32\\cptnhook.dll"; 
    char* funcName = "SetHook"; 
    char* targetPrgm = "mspaint.exe"; 
    Data lData; 
    lData.dll = (char*) VirtualAllocEx(explorer, 0, sizeof(char)*strlen(dllName), MEM_COMMIT, PAGE_READWRITE); 
    lData.func = (char*) VirtualAllocEx(explorer, 0, sizeof(char)*strlen(funcName), MEM_COMMIT, PAGE_READWRITE); 
    WriteProcessMemory(explorer, lData.func, funcName, sizeof(char)*strlen(funcName), &v); 
    WriteProcessMemory(explorer, lData.dll, dllName, sizeof(char)*strlen(dllName), &v); 
    rDataP = (DATA*) VirtualAllocEx(explorer, 0, sizeof(DATA), MEM_COMMIT, PAGE_READWRITE); 
    WriteProcessMemory(explorer, rDataP, &lData, sizeof(DATA), NULL); 
    

    編集: 問題は、リモートスレッドがLoadLibraryベースアドレスの代わりに "ゴミ"アドレス を呼び出しているようです。 Visual Studioにリンクされている可能性がありますか? リモートプロセスのLoadLibraryアドレスが間違っていますか?

    編集: ローカルスレッドと同じ正確なコードを実行しようとすると(私はCreateRemoteThreadの現在のproccesへのハンドルを使用します)、すべて正常に機能します。何が原因でしょうか?

    呼び出し関数コードを追加する必要がありますか?それは のコードを実行しているようです...

    コードはVS2010でコンパイルされています。

    dataは、char *を名前に持つ単純な構造体です。 (コード内に文字列を明示的に記述すると、元のプロセスへのポインタにつながる)。

    私は間違っていますか?

  • +0

    は、明示的なdllファイルのパスとLoadLibrary関数を使用しようとしたがありますか?例:LoadLibrary( "C:\\ project \\ my_app.dll");パラメータが渡されたことを確認するだけですOK – marcinj

    +0

    はい。私はフルパスを使用しています。 (これは、exeとdllが同じディレクトリにあるため、dllの名前だけで動作するはずです)。私はまた、LoadLibrary関数が失敗しているという事実も推測であるということを言及するべきです。 (私はそれが1つのパラメータを持つ関数であり、正しいパスであることがわかります.LoadLibrary ...) –

    +0

    "データ"をリモートスレッドにどのように伝達しますか? 「データ」が指すメモリをどのように割り当てて埋めるのですか? –

    答えて

    1

    ERROR_INVALID_PARAMETERで失敗すると、渡されたパラメータに問題があることを示します。

    したがって、問題の唯一のパラメータであるdata->dllを見てください。

    ここでは初期化される:

    lData.dll = VirtualAllocEx(explorer, 0, sizeof(char) * (strlen(dllName) + 1), MEM_COMMIT, PAGE_READWRITE);

    をそれでは参照のメモリの割り当てが本当にsucceded lData.dllに格納するかどうかのチェックを追加してみましょう。そうした

    if (!lData.dll) { 
        // do some error logging/handling/whatsoever 
    } 
    

    、あなたが実装され、コールが(VirtualAllocEx()のためにそのままMSDNから)ので、失敗したことを検出している場合があります:あなたがされていないページをコミットしようとすると、関数が失敗し

    は予約済みです。結果のエラーコードはERROR_INVALID_ADDRESSです。 (MSDNから再び逐語的に)推奨されているよう

    ですから、問題のコールの第四パラメータをmodifiyしたいかもしれません:

    を予約し、コミットページをワンステップで、 MEM_COMMITでVirtualAllocExを呼び出すには| MEM_RESERVE。

    PS:lData.funcを割り当てるためにこの演習を繰り返します。 ;-)

    0

    LoadLibraryは実際にはUnicodeバージョンであるLoadLibraryW(プロジェクト設定によって異なる)のエイリアシングである可能性があります。 "TCHAR"ではなく "char"文字列を使用してWindows APIを使用する場合は、明示的にANSIバージョン名を使用する必要があります。これにより、コードが書かれたときにデバッグの手間が省けます。また、プロジェクトが今後Unicodeに変わる場合に備えて、将来的にはあなたや他の人のためにデバッグができなくなります。その恐ろしい終端されていない文字列の問題を解決するのに加えて、だから、

    、使用してください:

    LoadLibraryA(data->dll); 
    
    関連する問題