现在的位置: 首页 > 综合 > 正文

sizeof_function(函数代码长度)

2013年07月14日 ⁄ 综合 ⁄ 共 1547字 ⁄ 字号 评论关闭
 /*
author: dummyz@126.com
*/
typedef struct _code_block
{
   uint8_t*   code;   // 指令存放位置
   ulong       base;   // 参考处理地址
   size_t       size;   // 指令最大大小
} code_block;

size_t sizeof_function(code_block* block)
{
   vector<uint8_t*> il; // 存放每条指令的地址

   bool bresult = false;
   uint8_t* ip = block->code; // 当前反汇编指示符
   uint8_t* far_ip = ip; // 标识最远的那条指令

   size_t len = 0;
   while ( len < block->size )
   {
       xde_instr instr;
       uint8_t* next_ip;

       // 如果反汇编失败, 将导致解析结束
       if ( 0 == xde_disasm(ip, &instr) )
           break;

       len += instr.len;

       il.push_back(ip); // 保存当前 ip
       next_ip = ip + instr.len; // 默认下一条指令

       // 检查当前指令是否是 jmp imm 类型的指令
       // 如果是则重新计算目标地址。
       if ( instr.opcode == 0xe9 ) // jmp imm32
       {
           next_ip += instr.data_l[0];
       }
       else if ( instr.flag & C_REL ) // 如果是相对跳转
       {
           if ( instr.len == 2 ) // jxx imm8 or loop imm8
               next_ip += instr.data_c[0];
           else if ( instr.len == 6 )
               next_ip += instr.data_l[0];
       }
      
       // 检查下条指令是否超出范围
       if ( next_ip <= block->code || next_ip >= block->code + block->size )
           break;

       // 如果下一条指令是往回跳,则检查其目的地址有效性
       if ( next_ip >= block->code && next_ip <= ip )
       {
           if ( find(il.begin(), il.end(), far_ip) == il.end() )
               break;
       }
      
       // 检查最远的那条指令是否已经处理过
       if ( ip + instr.len > far_ip )
       {
           if ( find(il.begin(), il.end(), far_ip) == il.end() ) // 出现花指令
               break;
       }
      
       // 检测当前指令是否是最远的指令,而且当前这条指令是返回指令
       if ( far_ip == ip && (instr.flag & C_STOP) )
       {
           bresult = true;
           break;
       }
      
       // 检查最远的那条指令是否还是最远
       if ( next_ip > far_ip )
           far_ip = next_ip; // 更新最远的地址

       ip += instr.len; // 顺序性的下条指令
   }

   return bresult ? len : 0; // 判断函数长度有效性,返回其得到的长度
}

抱歉!评论已关闭.