直接构造汇编指令

发布时间:2014-10-23 23:28:38
来源:分享查询网

      既然我们发现了指令不过就是一些字节的组合,我们可以尝试抛开C语言,自己构造指令执行。我们完全可以分配一段内存,然后将mov指令的机器码填入。但是,如何让CPU执行我们的代码呢?    假定我们构造了一段mov指令,需要用jmp语句跳转到该指令。    如果我们执行完mov指令后就不管了的话,我们就会发现程序会异常退出。比如下面的程序 #include "stdafx.h" #include <iostream>   using namespace std;   int gi = 0; unsigned char *code = 0;   unsigned char* BuildCode() { unsigned char *pCode = new unsigned char[10]; unsigned char *pMov = pCode;   pMov[0] = 0xC7; pMov[1] = 0x05;   unsigned char *pAddress = pMov + 2; *((int *)pAddress) = (int)(&gi);   unsigned char *pImm = pAddress + 4; *((int *)pImm) = 18;   return pCode; }   int _tmain(int argc, _TCHAR* argv[]) { gi = 12; code = BuildCode(); _asm jmp dword ptr [code] return 0; }     我们只是构造了一个mov指令,执行完毕后程序异常退出了。 因为我们执行完mov指令之后,如果不加处理,EIP所指内存的值是不确定的。CPU就会将该不确定的值解释为对应指令,这将导致不可预料的行为,因此,我们再mov指令之后应该放一条指令,让程序回到正常流程。Jmp指令正好可以达到这个目的。   // 1.3.cpp : 定义控制台应用程序的入口点。 //   #include "stdafx.h" #include <iostream>   using namespace std;   int gi = 0; unsigned char *code = 0; unsigned char *pReturnAddress = 0;   unsigned char* BuildCode() { unsigned char *pCode = new unsigned char[16]; unsigned char *pMov = pCode;   pMov[0] = 0xC7; pMov[1] = 0x05;   unsigned char *pAddress = pMov + 2; *((int *)pAddress) = (int)(&gi);   unsigned char *pImm = pAddress + 4; *((int *)pImm) = 18;   unsigned char *pJmp = pImm + 4; pJmp[0] = 0xff; pJmp[1] = 0x25; unsigned char *pJmpAddress = pJmp + 2; *((int *)pJmpAddress) = (int)(&pReturnAddress);   return pCode; }   int _tmain(int argc, _TCHAR* argv[]) { gi = 12;   _asm { mov pReturnAddress, offset l }   code = BuildCode(); _asm jmp dword ptr [code]                                                                                                                                                                                                       l:cout << gi << endl;   return 0; }    mov  指令由三部分构成    两字节的c7 05 代表操作码   四字节的gi地址  四字节的源操作数 jmp指令由6字节构成  2字节的操作码  ff 25   4字节的目的跳转地址   我们通过调试→窗口→寄存器可以看到我们的8个通用寄存器的值 EIP(Extended Instruction Pointer)32位的指令寄存器 是将16位的IP寄存器扩展之后得到的,EIP指向哪里,CPU就将该地址作为执行指令的入口。  

返回顶部
查看电脑版