使用GCC / MinGW

时间:2015-05-08 22:32:49

标签: c++ gcc assembly dll dll-injection

使用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做同样的事情。

在i386上GCC不支持

__ declspec(裸),所以我们需要另一种方式。 正如建议here,我可以通过在全局范围内编写汇编代码来覆盖函数。这是我应该做的诀窍代码:

__asm__
(
    "jmp *%0"
    : /* empty output list */
    : "r" (pointer_to_original_function) /* p[0] in the example above */
);

我的代码段使用GCC's extended ASM。但不幸的是,只允许函数中,而不是在全局范围内!

那么......我该怎么做?我的下一个方法是在没有扩展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");

}

1 个答案:

答案 0 :(得分: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;
}