首页 WindowsX86-64位汇编语言入门

WindowsX86-64位汇编语言入门

举报
开通vip

WindowsX86-64位汇编语言入门WindowsX86-64位汇编语言入门 Windows X86-64位汇编语言入门 Windows X64汇编入门(1) 最近断断续续接触了些64位汇编的知识,这里小结一下,一是阶段学习的回顾,二是 位汇编新手有所帮助。我也是刚接触这方面知识,文中肯定有错误之处,大家多希望对64 指正。 文章的标题包含了本文的四方面主要内容: (1)Windows:本文是在windows环境下的汇编程序设计,调试环境为Windows Vista 64位版,调用的均为windows API。 (2)X64:本文讨论的是...

WindowsX86-64位汇编语言入门
WindowsX86-64位汇编语言入门 Windows X86-64位汇编语言入门 Windows X64汇编入门(1) 最近断断续续接触了些64位汇编的知识,这里小结一下,一是阶段学习的回顾,二是 位汇编新手有所帮助。我也是刚接触这方面知识,文中肯定有错误之处,大家多希望对64 指正。 文章的标题包含了本文的四方面主要内容: (1)Windows:本文是在windows环境下的汇编程序 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 ,调试环境为Windows Vista 64位版,调用的均为windows API。 (2)X64:本文讨论的是x64汇编,这里的x64表示AMD64和Intel的EM64T,而不包括IA64。至于三者间的区别,可自行搜索。 (3)汇编:顾名思义,本文讨论的编程语言是汇编,其它高级语言的64位编程均不属于讨论范畴。 (4)入门:既是入门,便不会很全。其一,文中有很多知识仅仅点到为止,更深入的学习留待日后努力。其二,便于类似我这样刚接触x64汇编的新手入门。 本文所有代码的调试环境:Windows Vista x64,Intel Core 2 Duo。 1. 建立开发环境 1.1 编译器的选择 对应于不同的x64汇编工具,开发环境也有所不同。最普遍的要算微软的MASM,在x64环境中,相应的编译器已经更名为ml64.exe,随Visual Studio 2005一起发布。因此,如果你是微软的忠实fans,直接安装VS2005既可。运行时,只需打开相应的64位命令行窗口(图1),便可以用ml64进行编译了。 第二个推荐的编译器是GoASM,共包含三个文件:GoASM编译器、GoLINK链接器和GoRC资源编译器,且自带了Include目录。它的最大好外是小,不用为了学习64位汇编安装几个G 的VS。因此,本文的代码就在GoASM下编译。 第三个Yasm,因为不熟,所以不再赘述,感兴趣的朋友自行测试吧。 不同的编译器,语法会有一定差别,这在下面再说。 1.2 IDE的选择 搜遍了Internet也没有找到支持asm64的IDE,甚至连个Editor都没有。因此,最简单的 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 是自行修改EditPlus的masm语法文件,这也是我采用的方法,至少可以得到语法高亮。当然,如果你懒得动手,那就用notepad吧。 没有IDE,每次编译时都要手动输入不少参数和选项,做个批处理就行了。 1.3 硬件与操作系统 硬件要求就是64位的CPU。操作系统也必须是64位的,如果在64位的CPU上安装了 32位的操作系统,就算编译成功也无法运行程序。 2. 寄存器的改变 汇编是直接与寄存器打交道的语言,因此硬件对语言影响很大。先来看看x64与x32相比在硬件上多了什么,变了什么(图2)。 X64多了8个通用寄存器:R8、R9、R10、R11、R12、R13、R14、R15,当然,它们都是64位的。另外还增加了8个128位XMM寄存器,不过通常用不着。 X32中原有的寄存器在X64中均为扩展为64位,且名称的第一个字母从E改为R。不过我们还是可以在64位程序中调用32位的寄存器,如RAX(64位)、EAX(低32)、AX(低16位)、AL(低8位)、AH(8到15位),相应的有R8、R8D、R8W和R8B。不过不要在程序中使用如AH之类的寄存器,因为在AMD的CPU上这种用法会与某些指令产生冲突。 3. 第一个x64汇编程序 本节,我们开始编写自己的第一个x64汇编程序。在这之前,先讲一下calling convention的改变。 3.1 API调用方式 把Calling convention放在第一个讲,代表它的重要性。在32位汇编中,我们调用一个API时,采用的是stdcall,它有两个特点:一是所有参数入栈,通过椎栈传递;二是被调用的API负责栈指针(ESP)的恢复,我们在调用MessageBox后不用add esp,14h,因为MessageBox已经恢复过了。 而在x64汇编中,两方面都发生了变化。一是前四个参数分析通过四个寄存器传递:RCX、 RDX、R8、R9,如果还有更多的参数,才通过椎栈传递。二是调用者负责椎栈空间的分配与 回收。 下面给出一段代码,功能是显示一个简单的MessageBox,注意对RSP的操作: 代码: ;示例代码1.asm ;语法:GoASM DATA SECTION text db 'Hello x64!', 0 caption db 'My First x64 Application', 0 CODE SECTION START: sub rsp,28h xor r9d,r9d lea r8, caption lea rdx, text xor rcx,rcx call MessageBoxA add rsp,28h ret 这段代码是在GoASM中编译,指令部分GoASM与ML64差不多,关键是一些宏的定义有差 别。比如masm中的.code,在这里就成了CODE SECTION。下面再说区别,先编译。GoASM中 编译分两步: (1) 编译:goasm /x64 1.asm (2) 链接:golink 1.obj user32.dll 如果一些正常,命令行中应显示图3的内容。 运行一下,我们的第一个64位windows程序就运行了。 GoASM还有一个特点是支持宏:ARG和INVOKE,使用这两个宏可以免除程序员自己对椎 栈进行操作。不过初学吗,还是从基础掌握比较好。下面的一段代码相同的功能的MASM代 码,注意看看区别。ML64至今仍不支持宏,所以每一步工作都要自己做。 代码: ;示例代码2.asm ;语法:ML64 extrn MessageBoxA: proc .data text db 'Hello x64!', 0 caption db 'My First x64 Application', 0 .code Main proc sub rsp,28h xor r9d,r9d lea r8, caption lea rdx, text xor rcx,rcx call MessageBoxA add rsp,28h ret Main ENDP end 编译这段代码的命令行是:ml64 2.asm /link /subsystem:windows /entry:Main user32.lib。如果正常,应该如图5显示那样。 很有意思吧,在64位系统下,我们仍然调用user32的API。可能是名称用习惯了,微软自己都懒得改了吧。 3.2 64位的椎栈 代码中还有一处值得注意,那就是sub rsp,28h和add rsp,28h。28h这个数值是怎么来的呢, 首先,x64中椎栈被扩展为64位;其次,我们在调用MessageBoxA时,要给四个参数外加一个返回地址留空间,因此8(位)*5=40=28h。 另外一些小问题要注意,AMD64不支持push 32bit寄存器的指令,最好的方法就是push和pop都用64位寄存器。EM64T如何,看了下Intel的开发手册,各个指令都分三种情况:纯32位、纯64位和32与64位混合。下面是手册的片段: Opcode* Instruction 64-Bit Mode Compat/Leg Mode Description FF /6 PUSH r/m16 Valid Valid Push r /m16. FF /6 PUSH r/m32 N.E. Valid Push r /m32. FF /6 PUSH r/m64 Valid N.E. Push r/ m64. Default operand size 64-bits. 没别的好方法,使用中多注意,尽量在64位程序中保用64位寄存器。 4. 一些参考资料 写完了第一个hello world,本文就此打住。本还想写一些内容,但掌握不深,留待下回吧。感觉有些资料不得不在第一篇文章中放出来,因为它们是现有学习x64汇编的最好教材了,文中很多代码和 知识点 高中化学知识点免费下载体育概论知识点下载名人传知识点免费下载线性代数知识点汇总下载高中化学知识点免费下载 也来自于这些资料。 (1)《Moving to Windows x64》,出自:.com/Files/vista_x64.htm (2)GoASM的帮助文档,目前最好的64位汇编教程。出自:www.jorgon.freeserve.co.uk (3)《开始进行 64 位 Windows 系统编程之前需要了解的所有信息》,出自:oft.com/china/MSDN/library/Windev/64bit/issuesx64.mspx (4)来自CodeGurus的两篇文章 《Assembler & Win64》, rus.be/codegurus/Programming/assembler&win64_en.htm 《bout RIP relative addressing》 rus.be/codegurus/Programming/riprelativeaddressing_en.htm (5)AMD开发手册 (6)Intel开发手册,注意是新的《ntel? 64 and IA-32 Architectures software Developer’s Manual》 Windows X64汇编入门(2) 五一长假就要结束了,总算有时间好好睡了几个懒觉。今天醒来后想到的第一件事就是,该写第二篇了。 64位技术现在还不成熟,没有好调试器,但是我们搞技术的总是对新东西充满了好奇和热情。这个理由就足够我们现在开始学习64位汇编了~OK,Let’s go on。 1. 再说Calling convention 关于API的调用方式,在入门(1)中说了一些,不过感觉有必要再讲两点。一是在调用API时椎栈的框架,也就是Stack Frame,二是利用反汇编64位C/C++程序来研究calling convention。 先说Stack Frame。图1是一个通用的椎栈框架。 在一个使用STDCALL的32位程序中,stack frame的四项工作: (1) 传入参数的调用; (2) 在返回caller时,callee要负责平衡椎栈; (3) 给局部变量提供空间; (4) 保证ebx、esi、edi和ebp四个寄存器的值不变(这种寄存器被称为non-volatile)。 在64位环境中,少了一个平衡椎栈的任务,因为平衡椎栈的工作由caller负责了,因此callee的stack frame只剩下三项工作: (1) 将寄存器传入的参数和其它超过4个以上的参数在椎栈上保存(入栈); (2) 给局部变量提供空间; (3) 保证non-volatile寄存器的值不变,包括ebp、ebx、rdi、rsi、r12到r15,xmm6到xmm15。 所以,在一个函数的开始往往有如下代码: MOV [RSP+8h],RCX MOV [RSP+10h],RDX MOV [RSP+18h],R8 MOV [RSP+20h],R9 PUSH RBP MOV RBP,RSP 而在返回时会有如下代码: LEA RSP,[RBP] POP RBP RET 图2摘自GoASM的帮助文档,上文描述的情况在图中一目了然。 如果能在VC中编译64位C/C++程序,再用IDA反汇编,不是挺好的吗,正确,这正是我们玩儿逆向 工程 路基工程安全技术交底工程项目施工成本控制工程量增项单年度零星工程技术标正投影法基本原理 的人喜欢的方法。Visual Studio 2005的64位开发环境设置网上有,这里不多说了。以一个C/C++的代码为例: 代码: // Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; } 这段代码是一个地球人都知道的窗口消息处理代码,在编译为64位程序后,用ida64看一下它的反汇编。这样,熟悉而又有点陌生的64位汇编代码就出来了,包括消息的判断,EndDialog的调用等,确实很方便。 2. 第二个汇编例子:SMC 在入门(1)中我们写了第一个64位的汇编程序,这里我们开始写第二个。当然,代码本身还是有点意思的,这就是Self Modify Code。让我们试一试SMC在64位下进行的如何,这还牵涉到vista的特性。代码来自修改过的参考资料《About RIP relative addressing》。 DATA SECTION testzero db 'eax值为0', 0 testnonzero db 'eax值不为0!', 0 testtitle db '测试or eax,eax指令', 0 oldprotect dd ? CODE SECTION Start: ;改变当前内存页的保护为可写 sub rsp,28h lea r9, oldprotect ; R9 = lpflOldProtect mov r8d, 40h ; R8D = flNewProtect mov rdx, 1 ; RDX = dwSize lea rcx, modifyhere ; RCX = lpAddress call VirtualProtect add rsp,28h lea rax,modifyhere inc B[rax] xor eax,eax or eax,eax ;如果eax为0,则or指令会使jz跳转 lea rax, testzero modifyhere: jz >.skip ;这个是GoASM的语法,>号表示后面代码中的label lea rax, testnonzero .skip ;GoASM中的label这样定义 ; 显示结果 sub rsp,28h mov r9d, 0 ; R9D = UINT uType lea r8, testtitle ; R8 = LPCTSTR lpCaption mov rdx, rax ; RDX = LPCSTR lpText mov rcx, 0 ; RCX = HWND hWnd call MessageBoxA mov ecx, eax ; ECX = UINT uExitCode call ExitProcess add rsp,28h ret 代码的执行流程如下:将eax赋0,然后进行or eax,eax,如果不修改代码,则jz处 会跳转,结果会显示“eax值为0”。我们的任务就是把jz改为jnz。jz的十六进制编码为 74,jnz为75。 编译一下: GoASM /x64 “2.1.asm” GoLink “2.1.obj” kernel32.dll user32.dll 因为我们加入了下面两句代码: lea rax,modifyhere inc B[rax] 所以jz为in为jnz了。结果显示如下图所示。注意,GoASM中byte ptr简写为B。当然,你可以把上面两句指令删除,那出来的就完全是另一个结果了。 3. 资源文件 本文的最后一节来讲下带资源的程序编译。由于GoASM有自己的编译器GoRC,而visua l studio中是rc,因此我们将分别用两种语法编写,看一下两个编译器中的相同与不同。 先按下面的代码建立MainDlg.rc,这个rc文件是两个例子通用的,代码来自RadASM的32位默认模板代码,其实就是一个对话框,没有添加任何控件: 代码: #define IDD_DLG1 1000 IDD_DLG1 DIALOGEX 6,6,194,106 CAPTION "我的第一个DialogBox" FONT 8,"MS Sans Serif" STYLE 0x10CF0000 EXSTYLE 0x00000000 BEGIN END 来看一下GoASM语法的文件,其中用了很多GoASM的宏语法,不熟悉的可以看下帮助文件。我们把它保存为2.2.asm。 ;################################################################## ; DIALOGAPP ;################################################################## ;暂时没有完整的include文件,我们把要用的自己添加进来 #Define WM_INITDIALOG 00110H #Define WM_DESTROY 00002H #Define WM_COMMAND 00111H #Define WM_CLOSE 00010H #IFNDEF FALSE #Define FALSE 0 #ENDIF #IFNDEF TRUE #Define TRUE 1 #ENDIF CONST SECTION IDD_DLG1 equ 1000 DATA SECTION hInstance DQ ? CODE SECTION Start: ;invoke是GoASM调用API的宏,用不着我们自己进行stack frame了 invoke GetModuleHandleA, 0 mov [hInstance],rax invoke InitCommonControls invoke DialogBoxParamA,[hInstance],IDD_DLG1,0,ADDR DlgProc,0 invoke ExitProcess,0 ;FRAME是GoASM的宏 DlgProc FRAME hwnd,uMsg,wParam,lParam mov eax,[uMsg] cmp eax,WM_INITDIALOG jne >.WMCOMMAND jmp >.EXIT .WMCOMMAND cmp eax,WM_COMMAND jne >.WMCLOSE jmp >.EXIT .WMCLOSE cmp eax,WM_CLOSE jne >.DEFPROC INVOKE EndDialog,[hwnd],0 .DEFPROC mov eax,FALSE ret .EXIT mov eax, TRUE ret ENDF 编译时有个很奇怪的问题,就是要把资源文件编译成.obj格式才能顺利链接。命令行如下: GoRC /machine x64 /o maindlg.rc GoASM /x64 2.2.asm GoLink “2.2.obj” maindlg.obj kernel32.dll user32.dll comctl32.dll 生成了2.2.exe后,运行,如下图所示: 下面,看一下ml64的编译过程。rc文件不变,把下面的代码保存为2.3.asm。 ;################################################################## ; DIALOGAPP ;################################################################## extrn GetModuleHandleA : proc extrn MessageBoxA : proc extrn InitCommonControls : proc extrn DialogBoxParamA : proc extrn DestroyWindow : proc extrn ExitProcess : proc extrn EndDialog : proc .const WM_INITDIALOG equ 00110H WM_DESTROY equ 00002H WM_COMMAND equ 00111H WM_CLOSE equ 00010H FALSE equ 0 TRUE equ 1 IDD_DLG1 equ 1000 .data? hInstance qword ? .code Main proc ;invode是GoASM调用API的宏,用不着我们自己进行stack frame了 sub rsp,30h xor rcx,rcx call GetModuleHandleA mov [hInstance],rax call InitCommonControls mov rcx,[hInstance] mov rdx,IDD_DLG1 xor r8,r8 lea r9,DlgProc push 0 call DialogBoxParamA xor rcx,rcx call ExitProcess add rsp,30h ret Main endp ;DlgProc FRAME hwnd,uMsg,wParam,lParam DlgProc: mov [rsp+8],rcx mov [rsp+10h],rdx mov [rsp+18h],r8 mov [rsp+20h],r9 push rbp mov rbp,rsp mov eax,edx cmp eax,WM_INITDIALOG jne WMCOMMAND jmp EXIT WMCOMMAND: cmp eax,WM_COMMAND jne WMCLOSE jmp EXIT WMCLOSE: cmp eax,WM_CLOSE jne DEFPROC sub rsp,18h xor rdx,rdx ;注意,这里第一个参数rcx未变。按理应该是由rbp定位 mov rcx,[rbp+10h] call EndDialog add rsp,18h DEFPROC: pop rbp mov eax,FALSE ret EXIT: pop rbp mov eax, TRUE ret end 编译命令行为: rc maindlg.rc ml64 2.3.asm /link /subsystem:windows /entry:Main kernel32.lib user32 .lib comctl32.lib maindlg.res 如果你编译正确了,应该和2.2.exe的运行结果一样。 和GoASM的宏比起来,ml64的语法显得更低级,也更基础。不过要注意的是,在 2.3.asm中,很多语法我并没有写得很 规范 编程规范下载gsp规范下载钢格栅规范下载警徽规范下载建设厅规范下载 ,要想知道最规范的代码,便是逆向高级语言或GoASM 生成的exe文件。 OK,第二篇就到这里了。五一长假将在今晚结束,明天上班喽。 备注: 标 题: 【原创】Windows X64汇编入门(1) tankaiha 作 者: 时 间: 2007-05-05,23:31 链 接: ;read.php?t=43967
本文档为【WindowsX86-64位汇编语言入门】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_721103
暂无简介~
格式:doc
大小:207KB
软件:Word
页数:21
分类:企业经营
上传时间:2017-11-07
浏览量:136