动态获取汇编指令机器码

     于动态代码加密(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);

 
VC宏展开选项

      定义的宏比较复杂,较难分析时,可以通过一个VC选项控制预处理器将宏展开后的源代码输出到文件,以方便查看,设置方法:

在 “工程属性” ―〉“C/C++”―〉“Project Options” 手工填入/P,然后rebuild,会产生于.cpp同名的.i文件,在这里宏被展开了。

      VC中的宏,#是转义为字符串。如 #define  M1(a)   char * lpc = #a  。  M1(kkk) 展开后 char * lpc = “kkk”;
                      ##为连接转义符号 如 #define M2(b)  int  ab##b = 32;    M2(kkk) 展开后 int abkkk=32;
                      vc中不支持不定参数,gcc倒是支持。遗憾。
 

你可能感兴趣的:(汇编,获取,指令,动态,机器)