#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; // 沒有用的
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 A {
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 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 - 谷歌浏覽器");
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;
}
摘自 lqefn的專欄