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

原创 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
  }
 
 }

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

相关文章推荐

gcc内嵌汇编调用C函数

C样式的函数使用堆栈传递输入值;C库函数也是如此;所有输入参数都要放入堆栈中,顺序和函数中提到的顺序相反;汇编中压入栈中函数参数的顺序,和参数列表中函数出现的顺序相反; 代码如下所示: C中函数p...

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

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

详解CUDA核函数及运行时参数

版权声明:本文为博主原创文章,未经博主允许不得转载。 核函数是GPU每个thread上运行的程序。必须通过__gloabl__函数类型限定符定义。形式如下:  ...
  • csshuke
  • csshuke
  • 2017年08月04日 03:06
  • 91

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

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

关于函数中不确定参数的使用方法

1.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表 void foo(...); void foo(parm_list,...); 这种方式和我们以前...

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

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

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

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

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

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

python 函数不确定的参数

先说说函数定义,我们都知道,下面的代码定义了一个函数funcA def funcA():   pass      显然,函数funcA没有参数(同时啥也不干:D)。 下面这个函数fu...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用内嵌汇编来解决运行时参数不确定的函数的调用问题
举报原因:
原因补充:

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