Create a proxy DLL with GCC/MinGW - c++

With the Visual C++ compiler, it is possible to create a DLL file, that can imitate another DLL file and redirect all function calls to the original DLL. Here is an article with a tool that can generate Visual C++ code automatically.
The generated function-stubs 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 thing with MinGW/GCC instead of MSVC.
__declspec(naked) isn't supported by GCC on i386, so we need another way.
As suggested here, I could override 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 uses GCC's extended ASM. But unfortunatelly this is only allowed inside of functions, not in the global scope!
So... how do I do that? My next approach would be to try it without extended ASM, but how do I get the pointer address in assembly then?
Here i'm trying to get it from a global variable, but it segfaults at 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 just use its name. Be sure to apply any name mangling. Also put your code in the applicable code section 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 displacement. 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;
}

Related

Call a function in C++ by its address without knowing the return type

I want to call a C function from a C++ dll by its address.
I know how to do it where the return type is known from this separate question: Calling a function through its address in memory in c / c++.
However, if I do not know the return type, what can I do? I've tried "typedef auto", but it seems you cannot use auto like that.
If the returning type is really unknown or it doesn't matter, you can use void in your function definition, or if it is any pointer you can use void *, but if the function is in a C coded DLL, and you'll use it in a C++ code, then you can utilize and share almost every type defined in your C code, because C++ it's a superset of C.
That said, I prepared a small example with a structure called PyObject shared in C and C++ codes.
To do this, is better creating a header with the shared types/definitions:
#ifndef PYOBJECT_DLL_H
#define PYOBJECT_DLL_H
#ifdef __cplusplus
extern "C" {
#endif
// Common structure definition
typedef struct PyObject{
int field1;
char *field2;
} PyObject;
// Public function pointer type declaration
typedef PyObject *(*__stdcall getPyObject_t)(int arg1, const char *arg2);
#ifdef __cplusplus
}
#endif
#endif // PYOBJECT_DLL_H
Let's suppose that the C code with the exported function is something like:
#include "pyobject.h"
#include <stdlib.h>
#ifdef __cplusplus
extern "C"
#endif
__declspec(dllexport) PyObject * getPyObject(int arg1, char *arg2);
PyObject *getPyObject(int arg1, char *arg2){
PyObject *obj = (PyObject *)malloc(sizeof(PyObject));
obj->field1 = arg1;
obj->field2 = arg2;
return obj;
}
Finally the C++ code using the function and data created in the library would be:
#include "pyobject.h"
#include <iostream>
#include <windows.h>
int main() {
HINSTANCE dll = LoadLibrary("pyobject.dll");
if (dll == NULL) {
std::cerr << "Cannot open pyobject.dll. Error: " << GetLastError() << "\n";
return 1;
}
getPyObject_t getPyObject = (getPyObject_t) GetProcAddress(dll, "getPyObject");
if (getPyObject == NULL) {
std::cerr << "Cannot locate 'getPyObject' function in dll. Error: " << GetLastError() << "\n";
FreeLibrary(dll);
return 2;
}
PyObject *obj = getPyObject(3, "test");
std::cout << "PyObject == { field1: " << obj->field1 << ", field2: \"" << obj->field2 << "\"}\n";
FreeLibrary(dll);
return 0;
}
Edit
As #raymondchen pointed in his comment, ignoring the return type when the C function returns a large aggregate (e.g. struct) it's not a good idea, because the C function expects that the caller already has had reserved stack space to store the returned aggregate, but if the caller treats the function as void or anything else, then compiler will not reserve that space, causing unpredictable effects (probably ending with Segmentation fault error).
To avoid it, it's always better to define the correct type in both C and C++ codes (or in the common header), especially when the C function returns an aggregate.

Including C-DLL from C++

This feels like a noob question, so if it's a dupe, please point me to the right location :)
I tried including a DLL written in C into a C++ program. It didn't work; gcc said
test.cpp: xxx: error: too many arguments to function.
Here's a minimal working example:
Wrapper for DLL functions:
/* myWrapper.h */
#ifndef _MYWRAPPER_H
#define _MYWRAPPER_H
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
extern FARPROC EXPORTED_functionNameP;
int GetDLLpointers();
#ifdef __cplusplus
}
#endif
#endif
Implementation thereof:
/* myWrapper.c */
#include <windows.h>
#include "myHeader.h"
#ifdef __cplusplus
extern "C" {
#endif
HINSTANCE drvsHANDLE;
extern FARPROC EXPORTED_functionNameP;
int GetDLLpointers()
{
static int result;
drvsHANDLE = LoadLibrary("myLibrary.dll");
if (drvsHANDLE == NULL) return (result=0);
EXPORTED_functionNameP = GetProcAddress(
drvsHANDLE, "originalFunctionName");
if (EXPORTED_functionNameP == NULL) return (result = 0);
return (result = 1);
}
#ifdef __cplusplus
}
#endif
Naturally, I haven't written these nor the library myself, and preferably, they should all stay untouched. I did however add the extern "C" lines.
Then, my main file:
// my Main
#include <windows.h>
#include "myHeader.h"
int main(int argc, char **argv)
{
int arg = 1;
EXPORTED_functionNameP(arg);
return 0;
}
Build commands:
gcc -I. -c -o myHeader.o myHeader.c -L. -lmyLibrary
g++ -I. -o main.exe myMain.cpp myHeader.o -L. -lmyLibrary
It works fine if I rewrite my main.cpp into valid C and compile with gcc instead of g++.
I tried changing extern "C" into extern "C++" to no avail, I tried all permutations or gcc and g++ for the two build commands, nothing.
I know it's something to do with name mangling, but I thought gcc would take care of that when you include the extern "C" lines...Can someone please explain what I'm missing here?
In case it matters --
Windows XP Pro (will be Win7 later on)
(MinGW) gcc 4.6.2
I know this is a very old question, but I am having exactly the same issues but in relation to writing a generic wrapper template for wrapping calls to LoadLibrary() and GetProcAddress()
Taking https://blog.benoitblanchon.fr/getprocaddress-like-a-boss/ as inspiration, it looks like he is taking FARPROC as a kind of "void* for Windows functions" and then casting it to the correct type subsequently.
I needed to tweak that code a little to work for me, and reproduce it here:
class ProcPtr
{
public:
explicit ProcPtr(FARPROC ptr) : m_ptr(ptr) {}
template <typename T>
operator T* () const { return reinterpret_cast<T*>(m_ptr); }
private:
FARPROC m_ptr;
};
class DllHelper
{
public:
explicit DllHelper(LPCTSTR filename) : m_module(LoadLibrary(filename)) {}
~DllHelper() { FreeLibrary(m_module); }
ProcPtr operator[](LPCSTR proc_name) const
{
return ProcPtr(::GetProcAddress(m_module, proc_name));
}
private:
HMODULE m_module;
};
So, with that helper code now available we can use it to write a wrapper class that encapsulates several functions in the Advapi32 library:
class Advapi32
{
public:
Advapi32() : m_dll(TEXT("Advapi32"))
{
getUserName = m_dll["GetUserNameA"];
openSCManager = m_dll["OpenSCManagerA"];
bogusFunction = m_dll["BogusFunctionThatDoesNotExist"];
}
decltype(GetUserNameA)* getUserName;
decltype(OpenSCManagerA)* openSCManager;
decltype(GetWindowsDirectoryA)* bogusFunction;
private:
DllHelper m_dll;
};
bogusFunction is a function with the same signature as GetWindowsDirectoryA but which doesn't exist in Advapi32. This is what I was trying to achieve - graceful fallback on an older OS which might not have a certain function.
So, finally a test app...
int main()
{
Advapi32 advapi32;
auto func1 = advapi32.getUserName;
if (func1)
{
TCHAR infoBuf[256];
DWORD bufCharCount = sizeof(infoBuf);
if (func1(infoBuf, &bufCharCount))
{
std::cout << "Username: " << infoBuf << std::endl;
}
}
auto func2 = advapi32.openSCManager;
if (func2)
{
SC_HANDLE handle = func2(NULL, NULL, SC_MANAGER_CONNECT);
if (handle)
{
std::cout << "opened SC Manager" << std::endl;
}
}
auto func3 = advapi32.bogusFunction;
if (func3)
{
std::cerr << "This should not happen!" << std::endl;
}
else
{
std::cout << "Function not supported" << std::endl;
}
}
Output:
Username: TestAccount
opened SC Manager
Function not supported
Note: This was compiled as a Windows 32-bit console application with MBCS rather than Unicode, under VS2019 with the VS2015_XP toolset, since that is what I am needing to target (don't ask).
The FARPROC type is a function pointer for a function that takes no parameters. You should declare EXPORTED_functionNameP like so (replacing void with whatever the function really returns):
extern void (*EXPORTED_functionNameP)(int);
And initialize it like so (the returned value from GetProcAddress() pretty much always needs to be cast to the correct type):
EXPORTED_functionNameP = (void (*)(int)) GetProcAddress(drvsHANDLE, "originalFunctionName");
A typedef for the funciton type might make things a bit more readable.
There is a difference between C and C++.
int (FAR WINAPI * FARPROC) ()
In C, the FARPROC declaration indicates a callback function that has an unspecified parameter list. In C++, however, the empty parameter list in the declaration indicates that a function has no parameters.
The MSDN page on CallWindowProc explains a bit more.
After a quick Google search, it seems that FARPROC is defined as this:
typedef int (FAR WINAPI *FARPROC)();
That is, FARPROC is a function that returns an int and takes no arguments. So you can't use it for any other case.
Instead declare EXPORTED_functionNameP like this:
extern void (*EXPORTED_functionNameP)(int);
Now EXPORTED_functionNameP is a pointer to a function that takes an int argument and returns no value.
It is because of FARPROC is defined as:
int (FAR WINAPI * FARPROC) ()
So you can not pass any parameters to such function in C++. For fix it you should define EXPORTED_functionNameP as pointer to function with equal semantics as defined in DLL-library. For example:
typedef (void* EXPORTED_functionNameP)(int value);
EXPORTED_functionNameP ExportedFns;
...
ExportedFns = GetProcAddress(drvsHANDLE, "originalFunctionName");
FARPROC is defined as
typedef int (FAR WINAPI *FARPROC)();
When you pass an additional argument although the argument list of the prototype is empty you get the error.
You need a proper prototype definition for PORTED_functionNameP and cas the result from GetProcAddress to that type in your GetDLLPopinters functions.

Determine whether caller is called from EXE or DLL

I need to determine the caller code whether is coming from EXE or DLL.
DLL
#ifdef DLL_EXPORTS
__declspec(dllexport) void say_hello();
__declspec(dllexport) void getCurrentModuleName();
#else
__declspec(dllimport) void say_hello();
__declspec(dllexport) void getCurrentModuleName();
#endif
#include <cstdio>
#include <windows.h>
#include <Dbghelp.h>
#include <iostream>
#include <tchar.h>
#include "dll.h"
#include "Psapi.h"
__declspec(naked) void *GetStackPointer()
{
__asm
{
mov eax, esp
ret
}
}
void getCurrentModuleName()
{
BOOL result = SymInitialize(GetCurrentProcess(), NULL , TRUE);
DWORD64 dwBaseAddress = SymGetModuleBase64(GetCurrentProcess(), (DWORD64)GetStackPointer());
TCHAR szBuffer[50];
GetModuleBaseName(GetCurrentProcess(), (HMODULE) dwBaseAddress, szBuffer, sizeof(szBuffer));
std::wcout << _T("--->") << szBuffer << std::endl;
}
void say_hello() {
getCurrentModuleName();
}
EXE
#include <windows.h>
#include <cstdio>
#include "dll.h"
int main() {
printf ("ENTERING EXE CODE...\n");
getCurrentModuleName();
printf ("ENTERING DLL CODE...\n");
say_hello();
getchar();
}
Here is the output.
ENTERING EXE CODE...
--->exe.exe
ENTERING DLL CODE...
--->exe.exe
I wish I can get
ENTERING EXE CODE...
--->exe.exe
ENTERING DLL CODE...
--->dll.dll
As the last caller code are from DLL itself (say_hello in DLL)
Is there any way I can achieve this?
GetStackAddress is returning the value of ESP, which is a reference to the stack. The stack is allocated per thread, independently of any modules loaded in the process.
What you need to do is extract from the stack, the value of the return address - which will be an address in the calling module.
Given that the usual prefix code in a function is:
push ebp
mov ebp,esp
sub esp, bytes_of_local_variables
esp is going to be somewhat random, but [ebp] should be pointing at the previous ebp, and [ebp+4] should be pointing at the current frames return address.
So, you could try this:
__declspec(naked) void *GetReturnAddressAssumingStandardFramePointers()
{
__asm
{
mov eax, [ebp+4]
ret
}
}
Just make sure that functions that call that arn't compiled with /Oy
In that case use the return address of the function, which you can figure out by looking directly at the stack. The rest of the answer still applies.
You get stack pointer inside getCurrentModuleName() which is in DLL, but you need to get returning address from stack at the beginning of getCurrentModuleName() which shows you where getCurrentModuleName() was called from.
Use EnumProcessModules(). For each one call GetModuleInformation(). Compare the address of the function that you're executing (using a function pointer) to the lpBaseOfDll and SizeOfImage members of the MODULEINFO struct. If it falls within the range, you know that's the current module. If so, use GetModuleBaseName to retrieve the name of the module.
Here is the solution. The limitation is that, it is only able to trace up to 62 frames.
// Must have in order for us to turned address into module name.
SymInitialize(GetCurrentProcess(), NULL , TRUE);
// Limitation of RtlCaptureStackBackTrace.
const int kMaxCallers = 62;
void* callers[kMaxCallers];
int count = RtlCaptureStackBackTrace(0, kMaxCallers, callers, NULL);
for (int i = 0; i < count; i++) {
TCHAR szBuffer[50];
DWORD64 dwBaseAddress = SymGetModuleBase64(GetCurrentProcess(), (DWORD64)callers[i]);
GetModuleBaseName(GetCurrentProcess(), (HMODULE) dwBaseAddress, szBuffer, sizeof(szBuffer));
std::wcout << _T("--->") << szBuffer << std::endl;
}

Using DYLD interposing to interpose class functions

I have succesfully using dyld -macosx- to interpose standard C functions to a third party application, getting important information about the workarounds it does. But what I really need is to replace a certain function of a certain class.
The function I want to override is QString::append(..., ..., ...), so each time a string is appended to another -the whole application uses qstring-, i find out.
Is there a way? Here's the code I already have.
// libinterposers.c
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <stdlib.h>
typedef struct interpose_s {
void *new_func;
void *orig_func;
} interpose_t;
int my_open(const char *, int, mode_t);
int my_close(int);
void* my_malloc(size_t);
static const interpose_t interposers[] \
__attribute__ ((section("__DATA, __interpose"))) = {
{ (void *)my_open, (void *)open },
{ (void *)my_close, (void *)close },
{ (void *)my_malloc, (void *)malloc },
};
int
my_open(const char *path, int flags, mode_t mode)
{
int ret = open(path, flags, mode);
printf("--> %d = open(%s, %x, %x)\n", ret, path, flags, mode);
return ret;
}
int
my_close(int d)
{
int ret = close(d);
printf("--> %d = close(%d)\n", ret, d);
return ret;
}
void*
my_malloc(size_t size)
{
void *ret = malloc(size);
//fprintf(stderr, "Reserva de memoria");
return ret;
}
Thank you very much
C++ does name mangling. This means member function QString::mid() looks something like __ZNK7QString3midEii to the linker. Run the nm(1) command on the library you are interposing on to see the symbols.
It is going to be much easier that this. QString uses memcpy to concatenate and work with Strings, and I can easily override memcpy, and apply a regular expression to the result, logging only the strings I want. Piece of cake. No need for magic voodo-hoodo :)

Is there STDCALL in Linux?

I'm trying to port a Windows app to Linux. This appplication marks some functions with the __stdcall attribute. However, I was told by a friend that stdcall is used only on Windows and has no meaning in Linux (but DOES exist in Windows GCC).
Searching Google - some results state that there IS stdcall in Linux.
Is there a stdcall in Linux?
Additionally, GCC indicates that:
__attribute__((__stdcall__)) and __attribute__((stdcall)) (without the underscores near stdcall).
Which one is preferred (if applied to Linux at all)?
The simplest solution is to just define __stdcall to nothing conditionally on Linux.
Here's a link to __stdcall description on MSDN:
http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.80).aspx
It's only used to call WinAPI functions. To port such a Windows application to Linux, you need much more than just defining __stdcall to nothing:
#ifndef WIN32 // or something like that...
#define __stdcall
#endif
You would also need to call the Linux-specific API functions instead of Win32 API ones. Depending on the particular part of Win32 API and the size of the application (amount of code), it can be anywhere between moderately difficult and daunting.
Which specific functions are marked by the app as __stdcall?
Indeed, Windows port of GCC has to have __stdcall, because it's supposed to be able to generate conforming code for the Win32 platform. But since under Linux there is only one standard calling convention and it coincides with the default compiler output, this statement is not needed.
The reason your application is not compiling under Linux is almost certainly due to the fact, that it references Win32 API functions that are not defined under Linux -- you need to find appropriate Linux counterparts. Win32 API and Linux GLibc API-s are very much different and cannot be substituted easily.
Probably the easiest way to port your app to Linux would be to use Wine, i.e. modifying the Windows code in such a way, that it runs smoothly under Wine in Linux. This is the way even the most complex applications, like modern computer games, have been made to run under Linux.
Of course, if you really want it to be running natively under Linux, then porting is the only way to go.
stdcall is NOT just a calling convention; in addition to being a calling convention, it allows an isomorphism between C and C++ objects. Here's an example:
#define _CRT_SECURE_NO_WARNINGS // disable marking use of strcpy as error.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class ICdeclGreeter {
public:
virtual ~ICdeclGreeter(){}
virtual void setGreeting(const char *greeting) = 0;
virtual void greet() = 0;
};
class IStdcallGreeter {
public:
virtual __stdcall ~IStdcallGreeter(){}
virtual void __stdcall setGreeting(const char *greeting) = 0;
virtual void __stdcall greet() = 0;
};
class CdeclGreeter : public ICdeclGreeter {
public:
char *greeting;
~CdeclGreeter() {
if (greeting != nullptr) {
free(greeting);
puts("[CdeclGreeter] destroyed");
}
}
void setGreeting(const char *greeting) {
this->greeting = (char *)malloc(strlen(greeting) + 1);
strcpy(this->greeting, greeting);
}
void greet() {
puts(greeting);
}
};
class StdcallGreeter : public IStdcallGreeter {
public:
char *greeting;
__stdcall ~StdcallGreeter() {
if (greeting != nullptr) {
free(greeting);
puts("[StdcallGreeter] destroyed");
}
}
void __stdcall setGreeting(const char *greeting) {
this->greeting = (char *)malloc(strlen(greeting) + 1);
strcpy(this->greeting, greeting);
}
void __stdcall greet() {
puts(greeting);
}
};
typedef struct pureC_StdcallGreeter pureC_StdcallGreeter;
typedef struct pureC_StdcallGreeterVtbl {
void (__stdcall *dtor)(pureC_StdcallGreeter *This);
void (__stdcall *setGreeting)(pureC_StdcallGreeter *This, const char *greeting);
void (__stdcall *greet)(pureC_StdcallGreeter *This);
} pureC_IStdcallGreeterVtbl;
struct pureC_StdcallGreeter {
pureC_IStdcallGreeterVtbl *lpVtbl;
char *greeting;
int length;
};
/* naive attempt at porting a c++ class to C;
on x86, thiscall passes This via ecx register rather than
first argument; this register cannot be accessed in C without
inline assembly or calling a reinterpretation of byte array
as a function. there is no "This" argument in any of below. */
typedef struct pureC_CdeclGreeter pureC_CdeclGreeter;
typedef struct pureC_CdeclGreeterVtbl {
void (*dtor)(pureC_CdeclGreeter *This);
void (*setGreeting)(pureC_CdeclGreeter *This, const char *greeting);
void (*greet)(pureC_CdeclGreeter *This);
} pureC_CdeclGreeterVtbl;
struct pureC_CdeclGreeter {
pureC_CdeclGreeterVtbl *lpVtbl;
char *greeting;
int length;
};
void test() {
ICdeclGreeter *g = new CdeclGreeter;
g->setGreeting("hi");
g->greet();
IStdcallGreeter *g2 = new StdcallGreeter;
g2->setGreeting("hi");
g2->greet();
// we can pass pointers to our object to pure C using this interface,
// and it can still use it without doing anything to it.
pureC_StdcallGreeter *g3 = (pureC_StdcallGreeter *)g2;
g3->lpVtbl->setGreeting(g3, "hello, world!");
g3->lpVtbl->greet(g3);
g3->lpVtbl->dtor(g3);
free(g2);
/*
// cdecl passes this via ecx in x86, and not as the first argument;
// this means that this argument cannot be accessed in C without
// inline assembly or equivelent. Trying to run code below will cause a runtime error.
pureC_CdeclGreeter *g4 = (pureC_CdeclGreeter *)g;
g4->lpVtbl->setGreeting(g4, "hello, world!");
g4->lpVtbl->greet(g4);
g4->lpVtbl->dtor(g4);
free(g);
*/
delete g;
}
int main(int argc, char **argv)
{
test();
system("pause");
return 0;
}
TLDR; it's not the same as cdecl makes C++ classes not usable from C on platforms using this convention because in order to send "This" to a method, you must set ecx register to address of "This" rather than just pushing it, and likewise if you want to implement a class in C that C++ can recognize, the method will need to get This pointer from ecx register which is not accessible to C without inline assemby or equivelent.
stdcall has this nice property that classes that use stdcall can easily be simultaneously usable from C or C++ without doing anything to them.
So you can only #define __stdcall as long as you don't deal with __thiscall; although there might be some other subtle distinctions.