Building Proxy DLL with GCC / MinGW
With the Visual C ++ compiler, you can create a DLL file that can mimic another DLL file and redirect all function calls to the original DLL. Here is an article with a tool that can automatically generate Visual C ++ code.
The generated stub functions work (tested) and look like this:
extern "C" __declspec(naked) void __stdcall __E__0__()
{
__asm
{
jmp p[0]; // p[0] = GetProcAddress(hL,"AcceptEx");
}
}
Now I want to do the same with MinGW / GCC instead of MSVC.
__ declspec (naked) is not supported by GCC on i386, so we need a different way. As suggested here , I could override the functions by writing assembly code in the global scope. Here's my code that should do the trick:
__asm__
(
"jmp *%0"
: /* empty output list */
: "r" (pointer_to_original_function) /* p[0] in the example above */
);
My snippet is using GCC extended ASM . But, unfortunately, this is only allowed inside functions, not globally!
So ... how do I do this? My next approach would be to try it without extended ASM, but how do I get the address of the pointer in the assembly?
Here I am trying to get it from a global variable, but it segfaults on 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");
}
If the pointer is in a global variable, you can simply use its name. Be sure to use any name. Also put your code in the appropriate section of your code and give it a name. Sample code:
#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;
}
If you want to use an array, just add the appropriate offset. Extended sample:
#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;
}