《Windows内核编程》---基本汇编指令.pdf

上传人:asd****56 文档编号:70332834 上传时间:2023-01-19 格式:PDF 页数:11 大小:139.79KB
返回 下载 相关 举报
《Windows内核编程》---基本汇编指令.pdf_第1页
第1页 / 共11页
《Windows内核编程》---基本汇编指令.pdf_第2页
第2页 / 共11页
点击查看更多>>
资源描述

《《Windows内核编程》---基本汇编指令.pdf》由会员分享,可在线阅读,更多相关《《Windows内核编程》---基本汇编指令.pdf(11页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、Windows内核编程-基本汇编指令学习各种高级外挂制作技术,马上去百度搜索魔鬼作坊,点击第一个站进入,快速成为做挂达人。1)用 VS2010新建 Win32 Console Application,工程名为 ACECore,工程建立完成后得到打开文件 ACECore.cpp,代码如下:#include stdafx.hint _tmain(int argc,_TCHAR*argv)return 0;2)用 VS2010查看汇编代码的方法:1.VC 必须处于 debug 状态才能看到汇编指令窗口。因此在上面代码 return 0一句上设置断点。2.按下 F5键调试程序,当程序停在断点处时,打开

2、菜单“Debug”下的“Windows”子菜单,选择“Disassembly”。这样就出现反汇编窗口,显示汇编代码:-g:/acecore/acecore/acecore.cpp-/ACECore.cpp:Defines the entry point for the console application./#include stdafx.hint _tmain(int argc,_TCHAR*argv)00411350pushebp00411351movebp,esp00411353subesp,0C0h00411359pushebx0041135Apushesi0041135Bpushe

3、di0041135Cleaedi,ebp-0C0h00411362movecx,30h00411367moveax,0CCCCCCCCh0041136Crep stosdword ptr es:edireturn 0;0041136Exoreax,eax3)相关汇编指令:push:把一个32位的操作数压入堆栈中,这个操作导致 esp 被减4。esp 被称为栈顶,压入堆栈的数据越多,这个堆栈也就越堆越高,esp 地址就越来越小。在32位平台上,esp 每次减少4(字节)。pop:esp 被加4,一个数据出栈。pop 的参数一般是一个寄存器,栈顶数据被弹出到这个寄存器中。某些指令会“自动”地操作堆

4、栈:call 指令会把它的下一条指令的地址压入堆栈中,然后跳转到它调用的函数的开头处;而单纯的 jmp 是不会这样做的。同时,ret 会自动弹出返回地址。call 的本质相当于 push+jmp,ret 的本质相当于 pop+jmp。不但 push、pop、call 和 ret 会操作堆栈,sub 和 add 也可以用于操作堆栈。如果要一次在堆栈中分配4个4字节长整型的空间,那么没有必要4次调用 push,很简单地把 esp 减去4*4=16即可。当然,也可以同样地用 add 指令来恢复它。lea:取得地址(第二个参数)后放入到前面的寄存器(第一个参数)中。实际上,有时候 lea用来做和 mo

5、v 同样的事情,比如赋值:lea edi,ebp 0cch其中,方括弧表示存储器,也就是 ebp-0cch 这个地址所指的存储器内容。但是 lea 语法要求取ebp-0cch的地址,这个地址就是 ebp-0cch,把这个地址放到 edi 中,也就是说,这等同于:mov edi,ebp-0cch但以上的 mov 指令时错误的,因为 mov 不支持后一个操作数写成寄存器减去数字。而 lea支持,因此可以用 lea 来代替它。Stos 指令:mov ecx,30hmov eax,0CCCCCCCChrep stos dword ptr es:edistos 是串存储指令,它的功能是将 eax 中的数

6、据放入 edi 所指的地址中,同时,edi 会增加4(字节数)。rep 时指令重复执行 ecx 中填写的次数。方括弧表示存储器,这个地址实际上就是 edi 的内容所指向的地址。这里的 stos 其实对应的是 stosd,其他还有 stosb、stosw,分别对应于处理4、1、2个字节。上面代码中对堆栈30h*4(=0c0h)个字节初始化为0CCh(也就是 int3指令的机器码),这样发生意外时执行堆栈里面的内容会引发调试中断。=lost 的分割线=C 函数的参数传递过程:1)C 语言程序通过堆栈把参数从函数外部传入到函数内部,同时,在堆栈中划分区域来容纳函数的内部变量。对于 C 语言默认的调用

7、方式,函数调用方把参数反序(从右到左)地压入堆栈中,被调用方把堆栈复原。这些参数对齐到机器字长,16位、32位、64位 CPU 下分别对齐到2、4、8个字节。2)函数调用规则指的是调用者和被调用者函数间传递参数及返回参数的方法,在 Windows 上,常用的有 Pascal 方式、WINAPI 方式(_stdcall)、C 方式(_cdecl)。_cdecl 调用规则:(1)参数从右到左进入堆栈;(2)在函数返回后,调用者要负责清除堆栈,所以这个调用常会生成较大的可执行文件。_stdcall 又称为 WINAPI,其调用规则:(1)参数从右到左入栈;(2)被调用的函数在返回前自行清理堆栈,所以

8、生成的代码比 cdecl 下。Pascal 调用规则:(1)参数从左到右入栈;(2)被调用参数在返回前自行清理堆栈;(3)不支持可变参数的函数调用。此外,在 Windows 内核中还常见有快速调用方式(_fastcall);在 C+编译的代码中有 this call 方式(_thiscall)。3)以如下函数作为例子分析:void ACEFunction(int a,int b)int c=a+b;int _tmain(int argc,_TCHAR*argv)int a=1;int b=2;ACEFunction(a,b);return 0;标准的 C 函数调用方式(_cdecl):(1)调

9、用者把参数反序地压入堆栈中;(2)调用函数;(3)调用者负责把堆栈清理复原。注意:在 Windows 中,不管哪种调用方式都是返回值放在 eax 中,然后返回。外部从 eax 中得到返回值。_cdecl 方式下被调用函数需要做以下的事情:(1)保存 ebp。ebp 总是被我们用来保存这个函数执行之前的 esp的值,执行完毕后,我们用 ebp 恢复 esp;同时,调用此函数的上层函数也用 ebp 做同样的事情,所以先把 ebp 压入堆栈,函数返回之前弹出,避免 ebp 被我们改动。(2)保存 esp 到 ebp 中。上面两步的代码如下:;保存 ebp,并把 esp 放入 ebp 中,此时 ebp

10、 和 esp 同;都是这次函数调用时的栈顶00411360pushebp00411361movebp,esp(3)在堆栈中腾出一个区域用来保存局部变量,这就是常说的所谓局部变量时保存在栈空间中的。方法是:把 esp 减少一个数值,这样就等于压入了一堆变量。恢复时,只有把 esp 恢复成 ebp 中保存的数据就行。(4)保存 ebx、esi、edi 到堆栈中,函数调用完后恢复。上面两步对应代码如下:;把 esp 往下移动一个范围,等于在堆栈中放出一片新;的空间来保存局部变量00411363subesp,0CCh00411369pushebx0041136Apushesi0041136Bpushe

11、di(5)把局部变量区域初始化成全0CCCCCCCCh。0CCh 实际上是 int3指令的机器码,这是一个断点中断指令。因为局部变量不可能被执行,如果执行了,必然程序出错,这时发生中断来提示开发者。这时 VC 编译 Debug 版本的特有操作:0041136Cleaedi,ebp-0CCh00411372movecx,33h00411377moveax,0CCCCCCCCh0041137Crep stosdword ptr es:edi(6)然后做函数里应该做的事情。参数的获取是 ebp+12字节为第二个参数,ebp+8字节为第一个参数(反序入栈),依次增加。最后ebp+4字节处是要返回的地址

12、。(7)恢复 ebx、esi、edi、esp、ebp,最后返回:00411387popedi00411388popesi00411389popebx0041138Amovesp,ebp0041138Cpopebp0041138Dret用 VS2010编译 Debug 版本,完整的反汇编代码如下:-g:/acecore/acecore/acecore.cpp-/ACECore.cpp:Defines the entry point for the console application./#include stdafx.hvoid ACEFunction(int a,int b)00411360

13、pushebp;保存 ebp,并把 esp 放入 ebp 中。此时 ebp 与 esp 相同00411361movebp,esp;都是这次函数调用时的栈顶00411363subesp,0CCh;把 esp 往上移动一个范围,等于在堆栈中放出一片新;的空间用来存储局部变量00411369pushebx;下面保存三个寄存器:ebx、esi、edi0041136Apushesi0041136Bpushedi0041136Cleaedi,ebp-0CCh;原本是想使用“mov edi,ebp-0CCh”,但是 mov 不支持;“-”操作,所以先对 ebp-0CCh取内容(即ebp-0CCh),;再利用

14、 lea 把ebp-0CCh的地址也就是 ebp-0CCh 放到 edi 中;目的是把保存局部变量的区域(即 ebp-0CCh 开始的区域);初始化成全部为0CCCCCCCCh。00411372movecx,33h00411377moveax,0CCCCCCCCh0041137Crep stosdword ptr es:edi;写入0CCh指令(中断)int c=a+b;0041137Emoveax,dword ptr a;加法操作,从堆栈中取得从外部传入的参数。00411381addeax,dword ptr;通过 ida 反汇编可以看到,其实这两天指令是:;mov eax,ebp+8;ad

15、d eax,ebp+0Ch;参数是通过 ebp 从堆栈中取得的。这里看到的是;VC 调试器的显示结果,是为了方便阅读,;直接加上了参数名00411384movdword ptr c,eax00411387popedi;恢复 edi、dsi、ebx00411388popesi00411389popebx0041138Amovesp,ebp;恢复原来的 ebp 和 esp,让上一级调用的0041138Cpopebp;函数可以正常使用0041138Dret主程序中对这个函数的调用方式是:004123DCmoveax,dword ptr;把 b,a 两个参数压入堆栈004123DFpusheax004123E0movecx,dword ptr a004123E3pushecx004123E4callACEFunction(411014h);调用函数 ACEFunction004123E9addesp,8;恢复堆栈

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁