2013-08-19 2 views
3

Проблема была в том, что DLL, содержащая PR_Write(), называется не npsr4.dll, но nss3.dll и hooks не смогли найти GetProcAddress() из несуществующей библиотеки.Firefox pr_write hook. dll injection, windows hooks

Я пытаюсь создать Firefox-крючок, который собирает данные из метода PR_Write() Firefox (он находится в nspr4.dll). Я много искал Google и много раз пытался это сделать, но, к сожалению, когда я вставляю крючок, Firefox падает.

  • Во-первых, я старался не использовать DLL, используя этот метод http://redkiing.wordpress.com/2012/04/30/firefox-formgrabber-iii-code-injection/ (источник в начале статьи) Firefox разбился на CreateRemoteProcess() *

  • Я читал, что CreateRemoteProcess() не работайте над Win7 из-за проблем с безопасностью. Я решил использовать этот метод: http://syprog.blogspot.com/2012/05/createremotethread-bypass-windows.html Но он даже не загрузил мою DLL. (источник в начале статьи)

  • Затем я решил вставить DLL с помощью SetWindowsHookEx(). DLL работал, я использовал test MessageBox, чтобы проверить это (но я не уверен, правильно ли задал последний параметр SetWindowsHookEx()).

  • Я нашел библиотеку Chrom с примером Firefox (я не могу опубликовать более двух ссылок, но google: «chrom-lib»). Я применил код к своей DLL, но когда я его ввожу, Firefox сбой.

Я не знаю, как управлять ASM, стек и памятью, и я понятия не имею, что не так и как его исправить. Я знаю только, что я должен использовать прыжок для прыжка, но как ?. Мне нужен готовый к использованию код:/

Возможно, есть способ получить адрес pr_write(), затем получить его стек вызовов (аргументы функции) и использовать их для вызова моей собственной функции? Или, может быть, я должен попробовать с «API Hooking with MS Detours» (снова я не могу отправить ссылку: <)

Что мне делать?

EDIT Я nocticed, что на моем компьютере нет npsr4.dll. Итак, как Firefox создает HTTP-запрос без этой библиотеки?

Текущий код DLL (Chrom основе с VirtualProtect() использования)

#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

ответ

3

Вот основные шаги, которые я использую, когда нагнетание DLL:

1) Вы используете OpenProcess для того, чтобы получает процесс Фирефокса HANDLE

2) Вы выделяете памяти для пути вашей dll с использованием VirtualAllocEx в процесс firefox

3) Вы записываете путь dll в это выделенное пространство, используя WriteProcessMemory

4) Вы получаете HANDLE dll kernel32.dll с помощью GetModuleHandleA. Этот должен присутствовать в процессе каждого окна. kernel32.dll содержит основные элементы API ядра.

5) В этом файле kernel32.dll вы найдете функцию LoadLibrary, которая поможет вам загрузить вашу DLL. Получите его адрес с GetProcAddress.

6) Теперь у вас есть все ключи для создания нового удаленного потока, который будет загружать вашу DLL в процесс Firefox. Вы только что позвонили CreateRemoteThreadEx с lpStartAddress, указав адрес LoadLibrary и lpParameter на вашу строку пути dll.

7) Наслаждайтесь инъекцией dll.

Теперь, когда ваша dll находится в памяти процесса, вы можете начать подключаться. Вот два основных способа:

- на импорт таблицы адресов (IAT): В таблице импорта адрес является таблица, которая содержит адрес каждого внешних функций с помощью вашего модуля/процесса. В вашем случае вы хотите изменить адрес PR_Write по адресу вашей созданной вручную функции. Вы должны удалить защиту страницы памяти IAT с помощью VirtualProtect. Теперь вы можете свободно переопределить адрес самостоятельно.

- Override части кода процесса, чтобы сделать его прыгать в ваши функции: Использование VirtualProtect, вы когда-то против снятия защиты от частей кода вам нужно. Затем вы изменяете текущие инструкции по коду операции CALL или JUMP в соответствии с вашими функциями. Переопределенные инструкции ДОЛЖНЫ быть переписаны при начале вашей функции, чтобы сохранить реальный поток неповрежденным. После вашей функции перехвата вы должны вернуться назад после переопределенной инструкции.

Все эти крюковые трюки могут нуждаться в промежуточной функции, называемой батутом. Эта функция, возможно, придется сохранять регистры и загружать их позже. Он также может обеспечить соблюдение соглашений о вызовах.

Имея дело с крючками, я бы предложил изучить сборку и как использовать инструменты для отладки, такие как OllyDbg.

+0

Я сделал что-то simillar, но Firefox сработал при выполнении DLL-кода с подключенным PR_write() – user2693835

+0

Можете ли вы подключить OllyDbg или даже отладчик VS и показать нам сбой? – Jiwan

+0

Я добавил DLL-код. Crash - это только окно отправки отчета Mozilla. Он сбой при одном вызове VirtualProtect() – user2693835