设为首页 加入收藏

TOP

C语言函数动态调用(参考UnderC实现)(一)
2014-11-24 00:33:05 来源: 作者: 【 】 浏览:56
Tags:语言 函数 动态 调用 参考 UnderC 实现

#include "stdafx.h"

#include

#include

#include

#include

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

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, re

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇引入中间变量使程序更易读 下一篇【linux+C】新征程 linux下C编程

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: