4

問題は、PR_Write() を含む DLL が npsr4.dll ではなく nss3.dll と呼ばれ、フックが存在しないライブラリから GetProcAddress() を見つけられなかったことです。

PR_Write() Firefox メソッド (nspr4.dll にあります) からデータを収集する Firefox フックを作成しようとしています。私はよくグーグルで検索し、それを行うために多くの方法を試しましたが、残念ながらフックを挿入すると Firefox がクラッシュします。

  • まず、この方法を使用して、 DLLを使用しないようにしました。 CreateRemoteProcess()*

  • セキュリティ上の問題により、Win7 では CreateRemoteProcess() が機能しないと読みました。この方法を使用することにしました: http://syprog.blogspot.com/2012/05/createremotethread-bypass-windows.htmlしかし、DLL をロードすることさえできませんでした。(記事冒頭にソースあり)

  • 次に、SetWindowsHookEx() を使用して DLL を挿入することにしました。DLL が機能したので、テスト MessageBox を使用してそれを確認しました (ただし、SetWindowsHookEx() の最後のパラメーターを正しく指定したかどうかはわかりません)。

  • Firefoxの例でChromライブラリを見つけました(2つ以上のリンクを投稿することはできませんが、Google:「chrom-lib」)。コードを DLL に適用しましたが、挿入すると Firefox がクラッシュします。

私は ASM、スタック、およびメモリ管理をよく知りません。何が問題で、どのように修正すればよいかわかりません。私は asm jump hook を使用する必要があることしか知りませんが、どのように?. すぐに使えるコードが必要です:/

pr_write() アドレスを取得し、そのコール スタック (関数の引数) を取得して、それらを使用して自分の関数を呼び出す方法があるのではないでしょうか? または、「MS Detours を使用した API フック」を試す必要があるかもしれません (ここでもリンクを投稿できません :< )

私は何をすべきか?

編集自分のコンピューターに npsr4.dll がないことに気づきました。では、Firefox はこの lib なしでどのように HTTP リクエストを作成するのでしょうか?

現在の DLL コード (VirtualProtect() を使用した Chrom ベース)

#define SIZE 6

struct Hook{

    DWORD original_function;
    DWORD destination_function;

    BYTE original_bytes[SIZE];
    BYTE JMP_instruction[SIZE];
    DWORD original_protection, new_protection;

    Hook(){

    original_protection= PAGE_EXECUTE_READWRITE; 
    new_protection = PAGE_EXECUTE_READWRITE;

    }

    ~Hook(){

    memcpy((void*) original_function, original_bytes, SIZE);

    }

    int Initialize(char * function, char * module_name, void * destination_function_ptr)
    {
        original_function = (DWORD)GetProcAddress(GetModuleHandle(module_name), 
                             function);

        destination_function = (DWORD) destination_function_ptr;

        if (original_function==NULL){
            return FALSE;}

        return TRUE;
    }

    int Start()
    {
        BYTE JMP_temporary[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3};

        memcpy(JMP_instruction, JMP_temporary, SIZE);

        DWORD JMP_size = ((DWORD)destination_function - (DWORD)original_function - 5);

        VirtualProtect((LPVOID)original_function, SIZE, PAGE_EXECUTE_READWRITE, &original_protection);

        MessageBox(NULL,"Works", ":D",0);

        memcpy(original_bytes,(void*)original_function, SIZE);

        memcpy(&JMP_instruction[1], &JMP_size, 4);

        memcpy((void*)original_function, JMP_instruction, SIZE);

        VirtualProtect((LPVOID)original_function, SIZE, original_protection, NULL);

        return TRUE;
    }

    int Reset(){

        VirtualProtect((LPVOID)original_function, SIZE, new_protection, NULL);

        memcpy((void*)original_function, original_bytes, SIZE);

        return TRUE;
    }

    int Place_Hook(){

        memcpy((void*)original_function, JMP_instruction, SIZE);

        VirtualProtect((LPVOID)original_function, SIZE, original_protection, NULL);

        return TRUE;
    }

};

//...

Hook Firefox; // use chrom library

DWORD PR_Write_H (DWORD *fd,  void *buf,DWORD amount); // this is our overiding-function
typedef DWORD (*prWrite)(DWORD*,void*,DWORD); // defination of our original function

prWrite prw = NULL; // create a orginal function, we later point this to orginal function
                    // address

// example test function
int write_log(char * log, char * data)
{
    ofstream fout("D:\\log2.txt", ios::app);fout << data;fout.close();
    return TRUE;
}

void create_hooks() //this is called when DLL is initialized
{
    // Override PR_Write function in nspr4.dll with our PR_Write_H, 
    // Note nspr4.dll must already be
    // loaded in process space
    Firefox.Initialize("PR_Write", "nspr4.dll", PR_Write_H);

    // Write jump instruction on orginal function address
    Firefox.Start();
}

// our overriding function
DWORD PR_Write_H (DWORD *fd,  void *buf,DWORD amount){
    // reset hooks, this will replace the jump instruction to original data
    Firefox.Reset();
    // point prw(function) to original function
    prw = (prWrite)Firefox.original_function;
    // log the headers
    write_log(log_file, (char*) buf);
    // call the real PR_Write function
    DWORD ret = prw(fd, buf, amount);
    // again place the jump instruction on the original function
    Firefox.Place_Hook();
    return ret;
}

*私は Win8 x64 を使用していますが、フックは Vista/Win7/Win8 32 および 64 ビットで動作する必要があります! また、Win7 x86 ラップトップでもテストしました。Visual Studio 2012 でコンパイルします

4

1 に答える 1

5

dll を挿入するときに使用する基本的な手順は次のとおりです。

1) OpenProcessFirefox のプロセスを取得するために使用しますHANDLE

VirtualAllocEx2) Firefoxのプロセスを使用して、dllのパスにメモリを割り当てます

3)次を使用して、この割り当てられたスペースにdllパスを書き込みますWriteProcessMemory

4)HANDLEを使用して dll kernel32.dll を取得しGetModuleHandleAます。これは、すべてのウィンドウのプロセスに存在する必要があります。kernel32.dll には、ウィンドウのコア API が含まれています。

LoadLibrary5) この kernel32.dll には、dll のロードに役立つ関数があります。でそのアドレスを取得しますGetProcAddress

6) これで、dll を Firefox のプロセスにロードする新しいリモート スレッドを作成するためのすべてのキーが揃いました。アドレスと dll パス文字列を指定してCreateRemoteThreadEx呼び出すだけです。lpStartAddressLoadLibrarylpParameter

7) 挿入された dll をお楽しみください。

dll がプロセス メモリにあるので、フックを開始できます。以下に 2 つの基本的な方法を示します。

- インポート アドレス テーブル (IAT) について: インポート アドレス テーブルは、モジュール/プロセスによって使用される各外部関数のアドレスを含むテーブルです。あなたの場合PR_Write、手動で作成した関数のアドレスでアドレスを変更したいとします。を使用して、IAT のメモリ ページ保護を削除する必要がありますVirtualProtect。これで、アドレスを自分で自由にオーバーライドできます。

- プロセス コードの一部をオーバーライドして、関数内でジャンプさせる: を使用してVirtualProtect、必要なコード部分の保護を一度解除します。次に、関数のオペコードCALLまたはJUMP関数を指すことによって、現在の命令を変更します。オーバーライドされた命令は、実際のフローをそのまま維持するために、関数の先頭で書き直さなければなりません。フック関数の後、オーバーライドされた命令の後に戻る必要があります。

これらすべてのフック トリックには、トランポリンと呼ばれる中間機能が必要になる場合があります。この関数は、レジスタを保存し、後でロードする必要がある場合があります。また、呼び出し規約が尊重されるようにすることもできます。

フックを扱うときは、アセンブリと OllyDbg などのデバッグ ツールの使用方法を学ぶことをお勧めします。

于 2013-08-19T09:54:33.610 に答える