马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 playfire 于 2017-5-12 21:06 编辑
--来自15PB
最近几天学习了硬编码,想要按照自己的思路整理一下,有写的不好的地方希望大家指正
ERX -->eax~edi RX-->ax~di Ib是一个字节的立即数, Iw是两个字节的立即数,Id是四个字节的立即数
1.定长 (有一些需要记住)
由于篇幅问题,可以这些指令只是简单描述,也可以作为记忆的关键点,需要了解更多可以找度娘
操作寄存器:0x50~0x5F(push/pop ERX) ;
0x40~0x4F(INC/DEC ERX) ; 0xb0~0xb7(MOV Rb,Ib) ;
0xb8~0xbF(MOV ERX,Id) ; 0x90~0x97(XCHG EAX,ERX)
跳转指令:
0x70 - 0x7F(跳转到 当前指令地址 + 当前指令长度 + Ib);
0x0F 0x80 - 0x0F 0x8F(跳转到 当前指令地址 + 当前指令长度 + Id) ;
0xE0(LOOPNE/LOOPNZ Ib);0xE1(LOOPE/LOOPZ Ib);0xE2(LOOP Ib);0xE3(JRCXZ Ib);
0xE8(CALL Id);0xE9(JMP Id);0xEA(JMP Ap,其中Ap高2位赋给CS,低四位给EIP,实现远跳转);0xEB(JMP Ib);
0xC3(RET);0xC2(RET Iw);0XCB(RETF,相当于POP EIP, POP CS);0xCA(RETF Iw)
2.不定长(强调框架) 这里更多地是尝试将硬编码各个部分串起来,形成一个理解的框架.
整体格式 Intel手册需要查看的章节: Appendix A Opcode Map 2.1.3 ModR/M and SIB Bytes 首先 code可以确定两个操作数的类型(还有大小) 1.操作数是两个寄存器(操作数显示为一个E,一个G),需要到modr/m中查找这两个寄存器,由于两个操作数类型相同,其中纵向(1-2,6-8位)是源(右边的),横向(3-5)是目标(左边的) 2.操作数一个寄存器,一个立即数,就不用查modr/m了,其实也就是上面的定长指令 3.操作数一个内存,一个立即数的情况(操作数显示为一个E, 一个imm):需要到modr/m中查找内存,立即数就是上面写的结构的Imm 4.操作数一个内存,一个寄存器的情况(操作数显示为一个E,一个G):需要在modr/m中查找内存和寄存器,其中表的横向(3-5)位,是表示两个操作数中寄存器是什么,而纵向(1-2,6-8位)则表示内存地址是什么。
对于操作数中有地址的 地址分成两部分:这个信息可以从MOD R/M表中的到,位移就是上面写的结构的Displacement 1.寄存器部分(数量:1个或2个,表现形式:r,r*2,r*4,r*8),2.位移 对于位移:最上面结构中的”位移”即是 对于寄存器部分,怎样才能表示两个寄存器或者他们与2,4,8的乘积呢,很显然还需要一张表SIB SIB是为了解决内存地址表达式中有两个寄存器相加、寄存器乘2或4或8的情况,而SIB表中横纵两个寄存器相加,也就的到了地址表示中的寄存器部分。 注意:SIB中的ebp被写成了,其实当mod不等于0时,它和其他的写法是一样的,也是ebp+纵向上的寄存器,而当mod等于0时,寄存器部分就不用加上ebp了,而是将SIB段后面的8个字节(宽度一定是disp32)作为偏移加到其中。所以你可以看到:8b0405和8b80是一个作用 00401000 > 8B0405 008BC389 MOV EAX,DWORD PTR DS:[EAX+89C38B00] 00401007 8B80 9090906A MOV EAX,DWORD PTR DS:[EAX+6A909090]\
附加: 1.可以使用OD学习这些opcode
2.intel手册 https://software.intel.com/en-us/articles/intel-sdm#combined 下载volume2
下载地址:https://software.intel.com/sites/default/files/managed/a4/60/325383-sdm-vol-2abcd.pdf
求个精华
|