如何用汇编实现C语言函数调用

如何用汇编实现C语言函数调用,第1张

1。对于“汇编调用”:

我知道你要调用func,而不是它本身,但如果这个函数比较复杂时是必须用逆向先分析func这个函数,然后再确定参数列表和返回值的……

2。对于你的内联汇编的代码:

这里到底要不要用add %3, %%rsp;还是一个问题,因为要看函数使用的是什么调用标准,有标准C的,VB的,Pascal的,包括fastcall,stdcall,cdecl等……

3。对于“知道函数参数的起始地址和长度”:

这个的话,除了参数中有字符数组和直接结构体什么的,所有的基本变量基本都是每8字节(64位)一个,并且Intel一般都用bigendian的,也就是说,在内存中 01 02 03 04 05 06 07 08 读入寄存器后会变为: 0x0807060504030201

所以说对于简单的函数,用8字节一个参数来做就好了……

而对于有字符数组什么的就必须用逆向分析了……

这个……只能进行逆向分析了……

反正你知道了函数的地址和长度……

就是你把编译为机器码的程序用反编译工具翻译成汇编,然后分析一下就好了,C语言的汇编还是比较简单……

比如这个函数:

int func(int a, int b) {

// float要用到CPU的FPU,指令记不得,要查下

// 为了简单就改为int

printf("a = %d, b = %d\n", a, b);

return a;

}

编译成机器码后,反编译,如果不加优化,一般都会这样:

(假设函数入口地址为0400000h)

sub_0400000:

push rbp

mov rbp,rsp ; C函数参数度取使用堆栈

; 参数在内存中这样: || a | b | |

; 由于是64位,故8字节对齐

mov rax,[rbp+8] ; rax = (rbp+8) // 这里就是 rax = a

push rsi

mov rsi,[rbp+16] ; rsi = (rbp+16) // rsi = b

; 调用C函数都是这样堆栈式,最后一个参数最先入栈

push [rsi]

push rax

push "a = %d, b = %d\n" ; 这里是便于理解,实际上是push这个字符串常量的指针

call printf ; printf("a = %d, b = %d\n",rax,rsi)

add rsp,24 ; 平衡堆栈,用了3个参数,要还原38=24字节,但根据函数类型的不同去平衡,像调用VB的函数就不需要平衡堆栈……

; 还原数据

mov rsp,rbp

pop rsi

pop rbp

; 一般返回数据都用rax装载

mov rax,[rbp+8] ;rax=a

ret ; return rax

想调用未知参数列表的函数就是把以上过程倒过来,看着汇编把C的代码写出来……

破解注册码什么也是这样玩的……

实际上你可以直接用反编译的软件,比如IDA,直接自动分析,它反编译的虽然是汇编,但参数列表还是大部分都显示的……

但是,当编译器加优化大部分情况就必须自己分析了,因为:

int func(int a, int b) {

printf("a = %d, b = %d\n", a, b);

return a;

}

在优化情况下可能为(直接用寄存器传递数据):

sub_040000:

push rdx

mov rdx,rax

push rax

push rbx

push "a = %d, b = %d\n"

call printf

mov rax,rdx

pop rdx

ret

其实像wwwpediycom看雪学院有不少这方面的教程……

不可以

以下来自msdn:

The drawing mode is for raster devices only; it does not apply to vector devices Drawing modes are binary raster-operation codes representing all possible Boolean combinations of two variables, using the binary operators AND, OR, and XOR (exclusive OR), and the unary operation NOT

既然是用ADO连接,就是把EXCEL的SHEET看成数据表,EXCEL的列就是数据表的字段。单元格的计算值就是记录字段的内容。所以已经无法取出单元格的原始内容,只能取出计算值。你可以把数据集结果先存放到一个2维数组中

A[1,1]的值就等于$A$1的计算结果。

如果要想取单元格的内容,直接用OLE获取

TypeGetMethod可以得到一个MethodInfo对象,MethodInfo对象有一个方法是GetParameters即得到ParameterInfo数组,ParameterInfo对象有一个属性是IsOut。

已知foo的函数原型么?如果已知的话可以用GetMethod(string, Type[])这个重载。

比如你提到的有这样一个类:

class a

{

public void foo(string value);

public void foo(out string value);

}

如果想获得上面那一个方法,用这个语句:

1

typeGetMethod("foo", new Type[] { typeof(string) });

如果想获得下面那一个方法,用这个语句:

1

typeGetMethod("foo", new Type[] { typeof(string)MakeByRefType() });

1 class Program

2 {

3 static void Main(string[] args)

4 {

5

string content = "main"; //#1 variable

6 MethodInfo testMethod = typeof(Program)GetMethod("TestMethod",

7 BindingFlagsStatic | BindingFlagsNonPublic);

8 if (testMethod != null)

9 {

10 // Following way can not take content back

11 //

12 testMethodInvoke(null, new object[] { content / #1 variable / });

13 ConsoleWriteLine(content); // #1 variable, Output is: main

14 //

15

16

17 object[] invokeArgs = new object[] { content / #1 variable / };

18 testMethodInvoke(null, invokeArgs);

19 content = (string)invokeArgs[0]; // #2 variable, bypass from invoke, set to content

20 ConsoleWriteLine(content); // #2 variable, Output is: test

21 }

22 }

23

24 static void TestMethod(ref string arg)

25 {

26 arg = "test"; // #2 variable, wanna bypass to main process

27 }

28 }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12188445.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存