playfire 发表于 2017-5-12 20:23:21

OPCODE思路整理!!

本帖最后由 playfire 于 2017-5-12 21:06 编辑

--来自15PB
最近几天学习了硬编码,想要按照自己的思路整理一下,有写的不好的地方希望大家指正

ERX-->eax~ediRX-->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 Map2.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中查找内存,立即数就是上面写的结构的Imm4.操作数一个内存,一个寄存器的情况(操作数显示为一个E,一个G):需要在modr/m中查找内存和寄存器,其中表的横向(3-5)位,是表示两个操作数中寄存器是什么,而纵向(1-2,6-8位)则表示内存地址是什么。

对于操作数中有地址的地址分成两部分:这个信息可以从MOD R/M表中的到,位移就是上面写的结构的Displacement1.寄存器部分(数量:1个或2个,表现形式:r,r*2,r*4,r*8),2.位移对于位移:最上面结构中的”位移”即是对于寄存器部分,怎样才能表示两个寄存器或者他们与2,4,8的乘积呢,很显然还需要一张表SIBSIB是为了解决内存地址表达式中有两个寄存器相加、寄存器乘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:00401007      8B80 9090906A         MOV EAX,DWORD PTR DS:\
附加: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

求个精华



页: [1]
查看完整版本: OPCODE思路整理!!