用内嵌汇编来解决运行时参数不确定的函数的调用问题

原创 2007年09月12日 02:04:00
 

问题的描述:
1.有一个test.dll库,其中有一些函数,但是我们并不知道其中的函数名和参数表;
2.当我们的程序在运行时会得到需要调用的函数名和其参数表,我们用这些信息来调用test.dll中相应的函数。
比如在运行时获得了调用 int Add(int i,intj)函数的命令,我们需要首先装载dll文件,然后查找相应的函数是否存在,如果存在则获得函数的入口地址并希望通过函数指针调用该函数。问题产生了:在编译时我们并不清楚被调用的函数的返回值和参数表,我们如何定义这个函数指针呢?
用汇编代码直接把参数push到堆栈中,然后再调用函数,最后恢复堆栈,这样就能解决这些问题了,具体的实现方法如下:
我们调用函数的方式是__stdcall,在调用函数时是以从右至左的顺序将参数依次压栈,与C/C++默认的__cdecl方式不同,__stdcall在函数返回时会自动恢复堆栈,而__cdecl需要显式的恢复堆栈;__stdcall函数如有返回值,则会把值保存在寄存器eax中。
我们获得了函数名_Add@8存储在字符串变量procName中;参数从左至右为int型的i,int型的j;返回值为int
首先定义一个参数的结构体:
 typedef struct{
  int tag;//代表参数的类型;其中1为int,2为char,3为float
  value val;
 }parameter;
其中的value是一个union:
 typedef union{
  int intVal;
  char chVal;
  float fltVal;
 }value;


在程序中我们定义了vector<parameter> v ,将参数按从左至右的顺序push_back。然后就可以进行调用了:
#define PUSH_INT(var) __asm  push var
#define PUSH_CHAR(var) __asm  push var
#define PUSH_FLOAT(var) __asm  push var
 


 HINSTANCE hdll = LoadLibrary("Test.dll");
 if (hdll!=NULL)
 {
  FARPROC proc = (FARPROC)GetProcAddress(hdll,procName);
  if(proc != NULL)
  {
   for(int i=v.size()-1;i>=0;i-)
   {
    parameter p = v.at(i);
    switch(p.tag){
     case 1:
      PUSH_INT(p.val.intVal)
      break;
     case 2:
      PUSH_CHAR(p.val.chVal)
     case 3:
      PUSH_FLOAT(p.val.fltVal)
      break;
    }
   }
   __asm call proc
   int retVal;
   __asm mov  dword ptr[retVal],eax
  }
 
 }

这样就完成了不确定参数的函数的调用

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

ATPCS和内嵌汇编:arm处理器上函数调用寄存器的使用规则

为了优化 arm cpu做deinterlace,学习arm的汇编,对于arm汇编的传参规则不了解,特此记录。 原文链接: http://lli_njupt.0fees.net/ar01s05.ht...
  • yypony
  • yypony
  • 2013-12-28 16:03
  • 2629

va_start、va_end、va_list的使用 函数参数个数不确定的情况

1:当无法列出传递函数的所有实参的类型和数目时,可用省略号指定参数表 void foo(...); void foo(parm_list,...);   2:函数参数的传递原理 函数参数...

C语言中实现参数个数不确定的函数

C语言中有一种长度不确定的参数,形如:"…",它主要用在参数个数不确定的函数中,我们最容易想到的例子是printf函数。(注意:在C++中有函数重载(overload)可以用来区别不同函数参数的调用,...

不确定参数个数的函数的实现

某些情况下希望函数的参数个数可以根据需要确定。典型的例子有大家熟悉的函数printf()、scanf()和系统调用execl()等。那么它们是怎样实现的呢?C编译器通常提供了一系列处理这种情况的宏,以...

python 函数不确定的参数

先说说函数定义,我们都知道,下面的代码定义了一个函数funcA def funcA():   pass      显然,函数funcA没有参数(同时啥也不干:D)。 下面这个函数fu...

Linux系统调用(C内嵌汇编)

Linux下对文件操作有两种方式:系统调用(systemcall)和库函数调用(Library functions)。可以参考《Linux程序设计》(英文原版为《Beginning LinuxProg...

Microsoft VBScript 运行时错误 '800a0005'无效的过程调用或参数: 'Instr'

从后台上传软件时出现这个报警,麻烦帮忙解决一下!报警内容:Microsoft VBScript 运行时错误 '800a0005' 无效的过程调用或参数: 'Instr' /upload.asp, li...

运行时的问题提示

  • 2008-06-02 11:08
  • 1000KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)