使用GCC/MinGW创建代理DLL

3
使用Visual C++编译器,可以创建一个DLL文件,该文件可以模拟另一个DLL文件并将所有函数调用重定向到原始DLL。这里是一篇文章,介绍了一种可以自动生成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支持,因此我们需要另一种方法。正如这里建议的那样,我可以通过在全局范围内编写汇编代码来覆盖函数。以下是应该起作用的代码:
__asm__
(
    "jmp *%0"
    : /* empty output list */
    : "r" (pointer_to_original_function) /* p[0] in the example above */
);

我的代码片段使用了GCC扩展的ASM。但是不幸的是,这只允许在函数内部使用,而不是在全局范围内使用!
那么...我该怎么办?我的下一个尝试是尝试在没有扩展ASM的情况下进行,但是如何在汇编中获取指针地址呢?
这里我正在尝试从全局变量中获取它,但是它在replace_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");

}

可能指针在某个全局变量中...所以只需使用它的名称。 - Jester
我不太擅长汇编语言,你能给我一个示例代码吗?我猜__asm__("jmp global_variable"); 不会起作用——如果可能的话,我想使用某种数组,因为通常有很多函数。 - John Smith
1个回答

2

如果指针在全局变量中,您可以直接使用其名称。请确保应用任何名称混淆。还要将您的代码放入适用的代码部分并为其命名。示例代码:

#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;
}

1
太棒了!我已经研究了好几个小时,你真的为我节省了很多时间!我想给你点赞,但我还没有足够的声望。 - John Smith
同时,在 x86_64 上编译进行测试时,需要将汇编行中的 4 替换为 8,因为指针在那里的大小是两倍。它可以正常工作! :) - John Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接