Firefox pr_write hook. DLL инъекция, крючки для окон

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

Я пытаюсь создать хук Firefox, который собирает данные из метода Firefox PR_Write () (он находится в nspr4.dll).
Я много гуглил и пробовал много способов сделать это, но, к сожалению, когда я внедряю хук, 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 работала, я использовал тестовый MessageBox, чтобы проверить это (но я не уверен, правильно ли я указывал последний параметр SetWindowsHookEx ()).

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

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

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

Что я должен делать?

РЕДАКТИРОВАТЬ Я заметил, что на моем компьютере нет 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 для того, чтобы получить процесс Firefox 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, Теперь вы можете свободно изменять адрес самостоятельно.

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

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

При работе с хуками я бы посоветовал изучить ассемблер и методы отладки, такие как OllyDbg.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]