use*_*835 4 c++ firefox hook dll-injection
问题是包含 PR_Write() 的 DLL 不是 npsr4.dll,而是 nss3.dll 和 hooks 无法从不存在的库中找到 GetProcAddress()。
我正在尝试创建 Firefox 钩子,它从 PR_Write() Firefox 方法(它位于 nspr4.dll 中)收集数据。我在谷歌上搜索了很多并尝试了很多方法来做到这一点,但不幸的是,当我注入钩子时,Firefox 崩溃了。
首先,我尝试不使用DLL,使用这种方法http://redkiing.wordpress.com/2012/04/30/firefox-formgrabber-iii-code-injection/(文章开头的来源)Firefox crashed at CreateRemoteProcess()*
我读到 CreateRemoteProcess() 由于安全问题在 Win7 上不起作用。我决定使用这种方法:http : //syprog.blogspot.com/2012/05/createremotethread-bypass-windows.html但它甚至没有加载我的 DLL。(来源在文章开头)
然后我决定用 SetWindowsHookEx() 注入 DLL。DLL 工作,我使用测试 MessageBox 来检查(但我不确定我是否正确指定了 SetWindowsHookEx() 的最后一个参数)。
我找到了带有 Firefox 示例的 Chrom 库(我不能发布超过 2 个链接,但谷歌:“chrom-lib”)。我将代码应用于我的 DLL,但是当我注入它时,Firefox 崩溃了。
我不太了解 ASM、堆栈和内存管理,也不知道出了什么问题以及如何解决。我只知道我应该使用 asm jump hook,但是怎么用呢?我需要一个现成的代码:/
也许有一种方法可以获取 pr_write() 地址,然后获取其调用堆栈(函数参数)并使用它们来调用我自己的函数?或者,也许我应该尝试使用“API Hooking with MS Detours”(同样,我无法发布链接:<)
我该怎么办?
编辑我发现我的电脑上没有 npsr4.dll。那么火狐如何在没有这个库的情况下构建 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;
}
Run Code Online (Sandbox Code Playgroud)
*我使用的是 Win8 x64 但钩子必须在 Vista/Win7/Win8 32 位和 64 位上工作!我还在 Win7 x86 笔记本电脑上进行了测试。我用 Visual Studio 2012 编译
以下是我在注入 dll 时使用的基本步骤:
1) 您OpenProcess为了获取 Firefox 的进程而使用HANDLE
2)您为 dll 的路径分配内存,用于VirtualAllocExFirefox 的进程
3)您使用以下命令将dll路径写入此分配的空间 WriteProcessMemory
4)您HANDLE使用 .dll获取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通过手动创建的函数的地址更改地址。您必须使用VirtualProtect. 现在您可以自由地覆盖您自己的地址。
- 覆盖部分流程代码以使其跳转到您的功能中:
使用VirtualProtect,您一次可以防止取消对您需要的代码部分的保护。然后,您可以通过操作码CALL或JUMP指向您的函数来更改当前指令。重写的指令必须在你的函数开始时重写,以保持真实的流程完整。在你的钩子函数之后,你必须在被覆盖的指令之后跳回去。
所有这些钩子技巧可能需要一个称为蹦床的中间函数。此函数可能必须保存寄存器并稍后加载它们。它还可以确保遵守调用约定。
在处理钩子时,我建议学习汇编以及如何使用 OllyDbg 之类的调试工具。
| 归档时间: |
|
| 查看次数: |
5848 次 |
| 最近记录: |