返回> 网站首页
[转载]动态获取汇编指令机器码
yoours2011-07-08 17:35:39
简介一边听听音乐,一边写写文章。
对于动态代码加密(SMC)、api hook、以及thunk技术,都需要插入机器指令,一般情况下,都是事先查好指令的机器码,然后赋值到数组或结构体,最后再跳转到数组或结构体的首地址执行。如果你曾实际写一段这样的代码,一定会发现非常麻烦。逐个查找汇编指令的机器码,相信不会是一件愉快的事情,因此应该避免直接写机器码,下面一小段代码示范了如何动态的获取指令段机器码。 |
首先定义一个辅助宏: |
#define LABEL_ITEM(x)\ const char * lpsz##x = #x; \ __asm \ { \ __asm push lpsz##x \ __asm push lpszLable \ __asm call strcmp \ __asm add esp, 8 \ __asm test eax, eax \ __asm jnz LABEL_FIND_NEXT_##x \ __asm lea eax, x \ __asm mov lpCode, eax \ __asm jmp LABEL_RET \ __asm LABEL_FIND_NEXT_##x: \ } |
一般的,可以用一个函数把需要硬编码指令段包含起来,每一个指令段均以两个LABEL标记,代表其开始和结尾地址,为每个LABEL执行前面定义的宏,如下所示: |
unsigned char * __stdcall hard_code_DisableGetDC(LPCSTR lpszLable) { unsigned char * lpCode = 0; LABEL_ITEM(BEGIN_GETDC) LABEL_ITEM(END_GETDC) LABEL_ITEM(BEGIN_GETDCEX) LABEL_ITEM(END_GETDCEX) assert(0); LABEL_RET: return lpCode; _asm { BEGIN_GETDC: mov eax, 0 ret 4 END_GETDC: } _asm { BEGIN_GETDCEX: mov eax, 0 ret 12 END_GETDCEX: } } |
通过上面的函数可以简单的获取里面定义的每个指令段的机器编码: unsigned char szCode[1024]; unsigned char *pBegin = hard_code_DisableGetDC("BEGIN_GETDC"); unsigned char *pEnd = hard_code_DisableGetDC("END_GETDC"); memcpy(szCode, pBegin, pEnd - pBegin); |