执空法坛

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

此类指令都为6个字节

大致试验结果如下:

第一个字节跟操作类型相关,第二个字节跟寄存器相关,后面四个字节为地址

第二个字节高四位必须为8,9,A,B四个中的一个,低四位必为5和D中的一个,产生8种排列组合,分别代表8个寄存器

第一个能够使用到[EBP+XXXX]的操作数如下:

0X   ADD/OR

1X   ADC/SBB

2X   SUB/ADD

3X   CMP/XOR

8X    ADD/MOV/LEA/POP/XCHG/TEST

CX   ROL/LDS/MOV

DX   ROL/FADD

FX   INC/CALL/TEST

修改方法:

假定OFFSET小于两个字节,则搜索0000串,往前推三个字节和四个字节,使用上述条件判断,如果满足上述条件,则将第二个字节减去0x80h,并将地址加上偏移

修复代码如下:

 

 char *pDoubleNull;
 char *pEnd=(char*)lpBuffer+nBufferSize;
 int nSearchSize=nBufferSize;
 char* lpSearchBuffer=lpBuffer;
 do
 {
  pDoubleNull=(char*)memchr(lpSearchBuffer,'\0',nSearchSize);
  if(NULL==pDoubleNull)
   break;
  nSearchSize=(int)(pEnd-pDoubleNull);
  lpSearchBuffer=pDoubleNull+1;
  if('\0'!=*(pDoubleNull+1))
   continue;
  if(0=*(WORD*)(pDoubleNull+2))//Exclude lea  ecx, ds:0[ecx*8] etc.
  {
   lpSearchBuffer+=3;
   continue;
  }

  lpSearchBuffer++;
  unsigned char bFirHigh,bSecHigh,bSecLow;
  if(NULL==*(pDoubleNull-4)||NULL==*(pDoubleNull-3)||0x850F=*(WORD*)(pDoubleNull-4))//Exclude jnz
   continue;
  bFirHigh=(*(pDoubleNull-4))&0xF0;
  bSecHigh=(unsigned char)((*(pDoubleNull-3))&0xF0)>>4;
  bSecLow=(*(pDoubleNull-3))&0xF;
  if((0x5==bSecLow||0xD==bSecLow)&&(bSecHigh>=0x8&&bSecHigh<=0xB))
   if(0==bFirHigh||0x10==bFirHigh||0x20==bFirHigh||0x30==bFirHigh||0x80==bFirHigh||0xC0==bFirHigh||0xD0==bFirHigh||0xF0==bFirHigh)
   {
    *(pDoubleNull-3)-=0x80;
    *(DWORD*)(pDoubleNull-2)+=nOffsetAddr;
   }

 }while(lpSearchBuffer<=(pEnd-6));

注:1.可能存在个别偏移为单字节的未能修复,需再使用手动修复

  2. 此方法亦可用于把正常CODE修改为重定向

posted on 2008-12-04 16:38  执空法坛  阅读(295)  评论(0编辑  收藏  举报