# Include "stdafx. h"
 
# Include <stdarg. h>
 
# Include <windows. h>
 
# Include <locale. h>
 
# Include <stdlib. h>
 
 
 
 
 
Const int DC_STADCALL = 0, DC_CDECL = 1, DC_QWORD = 2, DC_NOWORD = 4, DC_RET_OBJ = 8, DC_RET_VAL = 16 + 8;
 
Void * gObjectReturnPtr = NULL; // useless
 
 
 
Void callfn (void * fn, int args [], int argc, void * optr, int flags, void * buff)
 
{
 
Int sz = sizeof (int) * argc;
 
_ Asm {
 
Mov ecx, argc
 
Mov ebx, args
 
// Push the arguments onto the stack, backwards
 
A_loop:
 
Cmp ecx, 0
 
Jz a_out
 
Mov eax, [ebx + 4 * ecx]
 
Push eax
 
Dec ecx
 
Jmp a_loop
 
 
 
A_out:
 
Mov ecx, optr // thiscall calling convention (MS only)
 
Call fn
 
// Cleanup stack ptr if this was a cdecl call
 
Mov ecx, flags
 
Test ecx, DC_CDECL
 
Jz a_over
 
Add esp, sz
 
A_over:
 
Test ecx, DC_RET_OBJ
 
Jz a_again
 
// These cases are peculiar to GCC
 
Cmp ecx, DC_RET_VAL
 
Jl a_skip
 
Mov ebx, gObjectReturnPtr
 
Mov [ebx], eax
 
Mov [ebx + 4], edx
 
Jmp a_finish
 
A_skip:
 
Sub esp, 4
 
A_again:
 
Mov ebx, buff
 
Test ecx, DC_QWORD
 
Jnz a_dbl
 
Mov dword ptr [ebx], eax
 
Jmp a_finish
 
A_dbl:
 
Fstp qword ptr [ebx]
 
A_finish:
 
}
 
}
 
 
 
 
 
Class {
 
Public:
 
Void show (char * msg)
 
{
 
Printf ("msg: % s/n", msg );
 
}
 
};
 
 
 
 
 
Template <class T>
 
Void * addressof (T t)
 
{
 
Void * retValue;
 
_ Asm {
 
Mov eax, t
 
Mov retValue, eax
 
}
 
Return retValue;
 
}
 
 
 
Class DllModule;
 
 
 
Class Function {
 
Private:
 
Void * addr;
 
Int flags;
 
Void * thisPtr;
 
Union CalRet {
 
_ Int64 ll;
 
Struct {
 
Int lo;
 
Int hi;
 
} I2;
 
Char b8 [8];
 
} Ret;
 
Public:
 
Function (void * func, int flag)
 
{
 
This-> addr = func;
 
This-> flags = flag;
 
This-> thisPtr = NULL;
 
}
 
Function (HMODULE hmodule, const char * funcName, int flag)
 
{
 
This-> addr = (void *) GetProcAddress (hmodule, funcName );
 
This-> flags = flag;
 
This-> thisPtr = NULL;
 
}
 
// Function (DllModule & dll, const char * funcName, int flag)
 
//{
 
// This-> addr = dll. get (funcName );
 
// This-> flags = flag;
 
// This-> thisPtr = NULL;
 
//}
 
Function (void * func, void * thisPtr, int flag)
 
{
 
This-> addr = func;
 
This-> thisPtr = thisPtr;
 
This-> flags = flag;
 
}
 
Int operator () (int nargs ,...)
 
{
 
Callfn (addr, & nargs, nargs, thisPtr, flags, ret. b8 );
 
Return ret. i2.lo;
 
}
 
};
 
 
 
Class DllModule {
 
Private:
 
HMODULE hmodule;
 
Char dllName [128];
 
Public:
 
DllModule (const char * name)
 
{
 
Hmodule = LoadLibrary (name );
 
Strncpy (dllName, name, 127 );
 
Printf ("load library % s/n", name );
 
}
 
~ DllModule ()
 
{
 
FreeLibrary (hmodule );
 
Printf ("free library % s/n", dllName );
 
}
 
Void * get (const char * name)
 
{
 
Return GetProcAddress (hmodule, name );
 
}
 
Function cFunc (const char * name, void * thisPtr = NULL)
 
{
 
Return Function (get (name), thisPtr, DC_CDECL );
 
}
 
Function winFunc (const char * name, void * thisPtr = NULL)
 
{
 
Return Function (get (name), thisPtr, DC_STADCALL );
 
}
 
};
 
 
 
Int main (int argc, char * argv [])
 
{
 
Int ret;
 
DllModule cdll ("msvcrt. dll ");
 
Ret = cdll. cFunc ("printf") (2, "Hello, % s/n", "baby ");
 
Printf ("ret % d/n", ret );
 
DllModule user32 ("user32.dll ");
 
Ret = user32.winFunc ("MessageBoxW") (4, 0, L "Hello", L "OK", 0 );
 
Printf ("ret % d/n", ret );
 
Ret = cdll. cFunc ("strstr") (2, "Caller has already cleaned the stack", "has ");
 
Printf ("ret % s/n", ret );
 
A;
 
Ret = Function (addressof (A: show), & a, DC_STADCALL) (1, "Class function call ");
 
Printf ("ret % d/n", ret );
 
Ret = user32.winFunc ("FindWindowW") (2, NULL, L "Google-Google Browser ");
 
Printf ("ret % d/n", ret );
 
Srand (cdll. cFunc ("time") (1, NULL ));
 
Int r = rand ();
 
Ret = user32.winFunc ("ShowWindow") (2, ret, (r % 2) = 0 );
 
Printf ("r = % d, ret % d/n", r, ret );
 
Return 0;
 
}
 
From the lqefn Column