C++ 汇编 动态函数调用 自定义参数数量 动态改变参数数量 并且能够获取返回值 可以传递字符串

本文为原创,汇编写吐了,点个赞吧

众所周知,C++调用函数的实质就是将参数从右往左一个个push,接着Call,返回值存储在eax中,这样的一个汇编实现过程。

知道原理就很简单了,由于我们需要动态传参,所以我们需要建一个结构体以方便我们读取参数

#include <Windows.h>
struct MyArg {
	size_t  size; // 数据长度
	void* bytes; // 开头指针
	DWORD32 ToPtr; // 是否传递指针
};

我定义了一个名为MyArg的结构体,它是怎么工作的?(在内联汇编中,我是使用结构体指针+N的形式以读取各个数据的)

  • size (Ptr+0):保留参数,由于在我的实际开发中没有用到,我才意识到这其实是一个无用的参数,但是内存地址已经确定,不方便修改,所以没有删除。
  • bytes(Ptr+4):数据指针参数,它是这样使用的
    const char a[] = "Hello";
    bytes = &a; // 获取a[0]的指针存储到bytes中
    就像这样,他不一定一定是一个字符串的指针,他甚至可以是一个int变量的指针
  • ToPtr(Ptr+8):这其实是一个Bool变量。当它为1时,他将会传递bytes变量的值;当他为0时,它会传递*byte的值 

至此,参数结构体已经处理完毕,接下来就是如何调用函数了
 

bool TyPfunBegin(FARPROC pFun, MyArg* args, DWORD32 len, void* pret) {

    if (IsBadCodePtr(pFun)) {
        return false;
    }
    DWORD32 NOWARG = (DWORD32)args + (len>0?len-1 : 0) * sizeof(MyArg);
    DWORD32 MAXARG =  (DWORD32)args - (len>0? 1 : 0) * sizeof(MyArg);
    DWORD32 SIZEARG = sizeof(MyArg);
	DWORD32 DW32PRET = (DWORD32)pret;
    __asm {
        mov eax, MAXARG;
        mov ebx, NOWARG;
    table_forbegin:
        cmp eax, ebx;
        je table_beginbegin;
        cmp [ebx + 8], 0;
        jne table_truetop;
        mov ecx, dword ptr[ebx + 4];
        mov ecx, dword ptr[ecx]
        push ecx;
        jmp table_nortop;
    table_truetop:
        mov ecx, dword ptr[ebx + 4];
        push ecx;
    table_nortop:
        sub ebx, SIZEARG;
        jmp table_forbegin;
	table_ret:
		mov ecx, DW32PRET;
		mov dword ptr[ecx], eax;
		jmp table_end;
    table_beginbegin:
        call pFun;
		cmp DW32PRET, 0;
		jne table_ret;
    }
table_end:
	return true;
}

 我写出了一个函数,他可以调用其他任意一个函数,无论参数数量(似乎参数数量只能在8及以下?我并没有测试过)

  • pFun 函数地址,比如这样
    void add(int a, int b) {
        std::cout << a + b << endl;
    }
    pFun = &add;
  •  args  参数列表,比如MyArg a[25]; args = &a;

  • len 参数数量

  • pret 返回值接收位置,可为NULL(也就是不获取返回值),这会把返回值存储到*pret

代码原理非常简单,就是使用汇编进行遍历MyArgs,然后读取数据,push,最后call,写入返回值 ,汇编不方便解释,自行查看

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值