使用 GCC/MinGW 创建代理 DLL
Create a proxy DLL with GCC/MinGW
使用 Visual C++ 编译器,可以创建一个 DLL 文件,该文件可以模仿另一个 DLL 文件并将所有函数调用重定向到原始 DLL。 Here 是一篇有自动生成Visual C++代码的工具的文章。
生成的函数存根可以正常工作(已测试),如下所示:
extern "C" __declspec(naked) void __stdcall __E__0__()
{
__asm
{
jmp p[0]; // p[0] = GetProcAddress(hL,"AcceptEx");
}
}
现在我想用 MinGW/GCC 而不是 MSVC 做同样的事情。
__declspec(naked) 在 i386 上不受 GCC 支持,因此我们需要另一种方式。
正如建议 here,我可以通过在全局范围内编写汇编代码来覆盖函数。这是我的代码,应该可以解决问题:
__asm__
(
"jmp *%0"
: /* empty output list */
: "r" (pointer_to_original_function) /* p[0] in the example above */
);
我的代码片段使用 GCC's extended ASM。但不幸的是,这只允许 inside 函数,而不是全局范围!
所以...我该怎么做?我的下一个方法是在没有扩展 ASM 的情况下尝试它,但是我如何在汇编中获取指针地址?
这里我试图从全局变量中获取它,但它在 repace_this_stub():
处出现段错误
#include <stdio.h>
void try_to_jump_to_me()
{
printf("you made the jump\n");
}
void* target_pointer = try_to_jump_to_me;
__asm__ (
"replace_this_stub:"
"jmp target_pointer"
);
void replace_this_stub();
int main(int argc, char** argv)
{
printf("starting in main. \n");
replace_this_stub();
printf("back in main?\n");
}
如果指针在全局变量中,你可以直接使用它的名字。请务必应用任何名称修改。还将您的代码放在适用的代码部分并为其命名。示例代码:
#include <stdio.h>
void* p = printf;
asm(
".section .text\n\t"
"proxy: jmp *p\n\t"
".previous\n\t");
extern void proxy();
int main()
{
proxy("Hello world!\n");
return 0;
}
如果要使用数组,只需添加适当的位移即可。扩展示例:
#include <stdio.h>
#include <string.h>
void* p[] = { printf, strcpy };
#define str(x) #x
#define PROXY(name, index) asm( \
".section .text\n\t" \
str(proxy_##name) ": jmp *p + " str(index) " * 4\n\t" \
".previous\n\t"); \
extern void proxy_##name()
PROXY(printf, 0);
PROXY(strcpy, 1);
int main()
{
char buf[128];
proxy_strcpy(buf, "Hello world!\n");
proxy_printf(buf);
return 0;
}
使用 Visual C++ 编译器,可以创建一个 DLL 文件,该文件可以模仿另一个 DLL 文件并将所有函数调用重定向到原始 DLL。 Here 是一篇有自动生成Visual C++代码的工具的文章。
生成的函数存根可以正常工作(已测试),如下所示:
extern "C" __declspec(naked) void __stdcall __E__0__()
{
__asm
{
jmp p[0]; // p[0] = GetProcAddress(hL,"AcceptEx");
}
}
现在我想用 MinGW/GCC 而不是 MSVC 做同样的事情。
__declspec(naked) 在 i386 上不受 GCC 支持,因此我们需要另一种方式。 正如建议 here,我可以通过在全局范围内编写汇编代码来覆盖函数。这是我的代码,应该可以解决问题:
__asm__
(
"jmp *%0"
: /* empty output list */
: "r" (pointer_to_original_function) /* p[0] in the example above */
);
我的代码片段使用 GCC's extended ASM。但不幸的是,这只允许 inside 函数,而不是全局范围!
所以...我该怎么做?我的下一个方法是在没有扩展 ASM 的情况下尝试它,但是我如何在汇编中获取指针地址?
这里我试图从全局变量中获取它,但它在 repace_this_stub():
处出现段错误#include <stdio.h>
void try_to_jump_to_me()
{
printf("you made the jump\n");
}
void* target_pointer = try_to_jump_to_me;
__asm__ (
"replace_this_stub:"
"jmp target_pointer"
);
void replace_this_stub();
int main(int argc, char** argv)
{
printf("starting in main. \n");
replace_this_stub();
printf("back in main?\n");
}
如果指针在全局变量中,你可以直接使用它的名字。请务必应用任何名称修改。还将您的代码放在适用的代码部分并为其命名。示例代码:
#include <stdio.h>
void* p = printf;
asm(
".section .text\n\t"
"proxy: jmp *p\n\t"
".previous\n\t");
extern void proxy();
int main()
{
proxy("Hello world!\n");
return 0;
}
如果要使用数组,只需添加适当的位移即可。扩展示例:
#include <stdio.h>
#include <string.h>
void* p[] = { printf, strcpy };
#define str(x) #x
#define PROXY(name, index) asm( \
".section .text\n\t" \
str(proxy_##name) ": jmp *p + " str(index) " * 4\n\t" \
".previous\n\t"); \
extern void proxy_##name()
PROXY(printf, 0);
PROXY(strcpy, 1);
int main()
{
char buf[128];
proxy_strcpy(buf, "Hello world!\n");
proxy_printf(buf);
return 0;
}