【天书笔记】C函数传参过程

十二月 13th, 2009 by shyandsy
1

一.C函数调用与堆栈的关系

C语言通过堆栈将参数传入函数内部

push和pop的时候esp用于指向栈顶——栈顶总是栈中地址最小的位置。push则esp减少,pop则esp增加。

二.函数调用规则

定义:函数调用规则是指调用者和被调用函数之间传递参数及返回参数的方法。

Windows上常用的有Pascal方式,WINAPI(_stdcall)方式以及C方式(_cdecl)。

1._cdecl方式

参数入栈:参数从右到左依次入栈

清理方式:函数返回后,调用者负责清理堆栈。这种调用会生成较大的可执行程序。

2._stdcall方式(WINAPI方式)

参数入栈:参数从右到左依次入栈

清理方式:被调用函数在返回前自行清理堆栈。生成代码比_cdecl方式小。

3.Pascal方式

入栈方式:参数从左到右依次入栈

清理方式:被调用函数在返回前自行清理堆栈

不支持可变参数的函数调用

此外Windows内核中还有常见的_fastcall快速调用;c++中有_thiscall方式。

任何调用方式,最终返回值都是写入eax,然后返回。外部从eax中取得返回值。

一.C函数调用与堆栈的关系

C语言通过堆栈将参数传入函数内部

push和pop的时候esp用于指向栈顶——栈顶总是栈中地址最小的位置。push则esp减少,pop则esp增加。

二.函数调用规则

定义:函数调用规则是指调用者和被调用函数之间传递参数及返回参数的方法。

Windows上常用的有Pascal方式,WINAPI(_stdcall)方式以及C方式(_cdecl)。

1._cdecl方式

参数入栈:参数从右到左依次入栈

清理方式:函数返回后,调用者负责清理堆栈。这种调用会生成较大的可执行程序。

2._stdcall方式(WINAPI方式)

参数入栈:参数从右到左依次入栈

清理方式:被调用函数在返回前自行清理堆栈。生成代码比_cdecl方式小。

3.Pascal方式

入栈方式:参数从左到右依次入栈

清理方式:被调用函数在返回前自行清理堆栈

不支持可变参数的函数调用

此外Windows内核中还有常见的_fastcall快速调用;c++中有_thiscall方式。

任何调用方式,最终返回值都是写入eax,然后返回。外部从eax中取得返回值。

三.技术细节

1. 标准C的_cdecl调用方式

调用者把参数反序压入堆栈中

调用函数

调用者把堆栈清理复原

2._cdecl被调用函数

a.保存ebp。ebp总是被用来保存当前函数执行前的esp,执行完毕后我们用ebp回复esp。上层函数也用ebp作同样的事。所以先把ebp压入堆栈,返回之前弹出,避免ebp被我们改动。

b.保存esp到ebp

push     ebp                                      ;保存ebp

move     ebp,    esp                         ;把esp放入ebp     此时esp=ebp         都是这次函数调用时的栈顶

c.在堆栈中腾出一个区域用来保存局部变量。esp减去一个值,这样就等于压入了一堆变量。回复的时候只要把esp恢复成ebp中保存的值即可。

d.保存ebx,esi,edi到堆栈中,函数调用完了以后恢复。

sub       esp,         0cch                   ;esp向下移动一个范围,等同于在堆栈中放入一片新空间来存放局部变量

push     ebx                                      ;保存 ebx,esi,edi 三个寄存器

push     esi

push     edi

e.局部变量区域初始化成全0xCCCCCCCC。0cch实际上是int 3指令的机器码,这是一个断点中断指令。因为局部变量不可能被执行,执行了必然有错,这时发生中断来提示开发者。这是VC编译debug版本的特有操作。

lea         edi,         [ebp-0cch]           ; 即 edi = ebp-0xcc

mov       ecx,         33h                       ;总长cch,每次stos操作时4h,所以操作次数=CCh/4h=33h

mov       eax,         0cccccccch          ;将被写入的内容

rep stos dword ptr [edi]                    ;串写入。stos将eax数据写入edi同时edi加4,rep则是重复执行ecx次

f.做函数该做的事情ebp+12字节为第二个参数ebp+8为第一个参数,ebp+4是返回地址

&nbs
p;g.恢复ebx,esi,edi,esp,ebp

pop        edi                                        ;回复 edi, esi, ebx

pop        esi

pop        ebx

mov        esp,         ebp                        ;恢复上层函数原有的ebp和esp

pop        ebp

ret

四.实例

void    myfunction(int a, int b)

{

int   c = a+b;

}

我自己用VS2005反汇编了一下

void function(int a, int b)

{

00411390  push        ebp                        ;保存上一级函数的ebp,作为返回地址

00411391  mov         ebp,esp                 ;保存当前栈顶

00411393  sub          esp,0CCh              ;esp  = esp – 0cch

00411399  push        ebx                         ;压栈ebx, esi, edi

0041139A  push        esi

0041139B  push        edi

0041139C  lea         edi,[ebp-0CCh]       ;edi = ebp-0cch

004113A2  mov         ecx,33h                    ;串指令执行次数

004113A7  mov         eax,0CCCCCCCCh  ; 串指令填充的内容

004113AC  rep stos    dword ptr es:[edi]    ;重复执行33h次,将eax写入edi并且edi加4 (ebp-0cch到ebp)

int c = a+b;

004113AE  mov         eax,dword ptr [a]          ; eax = a

004113B1  add         eax,dword ptr [b]           ;eax  += b

004113B4  mov         dword ptr [c],eax           ; c  = eax

}

004113B7  pop         edi                                            ; 恢复 edi,esi,ebx

004113B8  pop         esi

004113B9  pop         ebx

;当前esp位于ebp-0cch

004113BA  mov         esp,ebp                                   ;恢复esp到当前函数的栈顶ebp,即可跳过局部变量区

004113BC  pop         ebp                                           ;恢复ebp为上一级函数ebp

004113BD  ret
>

Posted in 汇编与逆向

One Response to “【天书笔记】C函数传参过程”

  1. Yahoouj 说:

    Really good work about this website was done. Keep trying more – thanks!

Leave a Reply

վ:Ħ Ϻgay ŰĦ Ϻ տ ɽ ɽ ŰĦ Ϻ˹˾ ŰĦ ϺŰĦ ˹˾ ݰĦ ŰĦ Ħ ϺĦ ͬ־ Ѽ˹˾ ŰĦ ϺѼ ɳ᳡ shenzhen massage ŰĦ ͬ־ Ϸʿյά ϲŰĦ 人˿ఴĦ ɽ˹˾ Ϻ Ѽ˿ Ħ ֣ŰĦ ˹˾ ݼѼ Ϻ ǿ Ϻ ڰ᳡۸ °˾
ӣǵɽǵݸǵ麣ǵɽǵɳǵɽǵǵǵǵϺǵǵǵǵݸǵɽǵ麣ǵǵɽǵɽǵǵǵǵǵǵǵǵϺǵŰĦϺǵɽanĦൺǵӰװϷϺǵϾŰĦϾŰĦϾŰĦ㶫huλ㽭huңhuң
ӣҸĻȾ,ɾӹȫ.
ugg boots cheap UGG Boots UGG Boots Sale UGG Bailey Button Triplet ugg australia uk mens ugg boots new ghd hair straighteners coach handbags outlet
ӣվĶ٣ÿ쿴ɾ, ұ˫Ϊ˴Ǯ;ãӲҪɾҾɾվɾipҲ㡣
ɹͷ Ҹ θ Ƽʪõķ ҸƷ ƾõҽԺ 򾲶ʮζ ƹɹͷҩ θҩ ҽԺ ɹͷô ƹɹͷõҽԺ θҽԺ ̿۸ lovegreen californianews
ӣǵάɽǵάݸǵά麣ǵάɽǵάɳǵάɽǵάǵάǵάǵάϺǵάǵάǵάǵάݸǵάɽǵά麣ǵάǵάɽǵάɽǵάǵάǵάǵάǵάǵάǵάǵάϺװ˿㰴ĦϺǵάɽСlaohujiϷǵӰװϾСϾСϾС㽭huϷɽǵά˿㰴Ħ