ollydbg調(diào)試器中反匯編引擎的選擇與改造是怎樣的

本篇文章為大家展示了ollydbg調(diào)試器中反匯編引擎的選擇與改造是怎樣的,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

成都創(chuàng)新互聯(lián)公司專注于東勝企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,商城網(wǎng)站建設(shè)。東勝網(wǎng)站建設(shè)公司,為東勝等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)

小編選擇的是udis86,od的反匯編引擎ODDisassm雖然簡(jiǎn)潔,但是只支持x86intel的匯編指令,不支持x64,指令集也很陳舊,BeaEngine雖然也不錯(cuò)支持新指令集也多,但是代碼風(fēng)格看起來不爽,capstone 雖然支持指令集比較多,也支持移動(dòng)arm指令,但是整體代碼比較復(fù)雜,龐大臃腫,改造成本太高,最后還是選擇了udis86,代碼和接口都非常簡(jiǎn)潔只有幾個(gè)cpp/h文件,支持支持MMX, FPU (x87), AMD 3DNow, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES, AMD-V, INTEL-VMX, SMX,支持x86/x64的Intel/AT&A的指令平臺(tái),還有一個(gè)最大的特點(diǎn)就是解碼速度非???。

1.    udis86的使用

udis86的接口很簡(jiǎn)單,使用也很簡(jiǎn)單

                 一、第一步是初始化

                 ud_t ud_obj;

   ud_init(&ud_obj); 

   ud_set_mode(&ud_obj,16); 設(shè)置反匯編系統(tǒng)16/32/64位      

          ud_set_pc(u, 0); 設(shè)置內(nèi)存的段的基址,相當(dāng)于PE文件的基址。

          ud_set_asm_buffer(u,u->asm_buf_int,sizeof(u->asm_buf_int)); 設(shè)置反匯編的數(shù)據(jù)原始地址和數(shù)據(jù)長(zhǎng)度

          ud_set_syntax(&ud_obj, UD_SYN_INTEL);設(shè)置反匯編的語(yǔ)法平臺(tái)

               二、第二步反匯編調(diào)用

     代碼示例: 

          while (ud_disassemble(&ud_obj)) { 

          if (o_do_off)

                printf("%016"FMT64 "x", ud_insn_off(&ud_obj));

          if (o_do_hex) {

              const char* hex1, *hex2;

              hex1 = ud_insn_hex(&ud_obj);

                hex2 = hex1 + 16;

                printf("%-16.16s%-24s", hex1, ud_insn_asm(&ud_obj));

                if (strlen(hex1) > 16) {

                //printf("\n");

                if (o_do_off)

                   printf("%15s-", "");

                printf("%-16s",hex2);

                }

             }

            else printf(" %-24s", ud_insn_asm(&ud_obj));

          printf("\n");

          } 

       ud_disassemble(&ud_obj)反匯編解析指令

       ud_disassemble里調(diào)用ud_decode函數(shù)來實(shí)現(xiàn)解碼分析操作,然后使用translator函數(shù)對(duì)解碼的結(jié)果做指令翻譯操作翻譯成可讀的     intel或者AT&T的語(yǔ)法字符串。

       ud_insn_off(&ud_obj)獲得當(dāng)前的指令地址

       ud_insn_asm(&ud_obj)獲取當(dāng)前的反匯編后的字符串。

     一下是結(jié)果顯示:

      ollydbg調(diào)試器中反匯編引擎的選擇與改造是怎樣的

三、符號(hào)的設(shè)置

 udis86還提供了一個(gè)設(shè)置解析符號(hào)的函數(shù)接口

ud_set_sym_resolver(&ud_obj,resolver);

resolver的接口定義:

const char* (*resolver)(struct ud*,

                                   uint64_t addr,

                                  int64_t *offset)

我們可以看到代碼里

void

ud_syn_print_addr(struct ud *u, uint64_t addr,char operand_asm_buf[64],int*index)

{

  const char *name = NULL;

  if (u->sym_resolver) {

    int64_t offset =0;

    name = u->sym_resolver(u, addr, &offset);

    if (name) {

      if (offset) {

        ud_asmprintf(u, "%s%+" FMT64"d", name,offset);

        ud_asmprintf2(operand_asm_buf,index,"%s%+"FMT64 "d",name, offset);

      } else {

        ud_asmprintf(u, "%s", name);

        ud_asmprintf2(operand_asm_buf,index, "%s",name);

      }

      return;

    }

  }

  ud_asmprintf(u, "%" FMT64"X", addr);

  ud_asmprintf2(operand_asm_buf,index, "%"FMT64 "X",addr);

}

如果設(shè)置了sym_resolver接口,就會(huì)調(diào)用這個(gè)接口反匯的符號(hào)字符串來替代地址值的反匯編字符串。

縱觀以上udis86提供不少的功能但是在冒些情況下有很多不足之處,比如在一塊很大的內(nèi)存進(jìn)行反匯編解碼時(shí)沒有預(yù)解碼的函數(shù)接口,會(huì)導(dǎo)致使用者誤認(rèn)為效率不高,還有其他情況與我們使用ollydbg不同的語(yǔ)法風(fēng)格也需要我們?nèi)ジ脑臁?/p>

 2. udis86改造

 一、增加預(yù)分析接口。

unsigned int ud_predecode(struct ud* u)

{

    int len;

    if (u->inp_end) {

        return 0;

    } 

    len = ud_decode(u);

    return len;

這個(gè)函數(shù)在分析解析過程速度非???,效率非常高,這個(gè)函數(shù)用處主要在預(yù)分析,確定當(dāng)前內(nèi)存數(shù)據(jù)能反匯編出多少行指令,方便后續(xù)界面顯示時(shí)分頁(yè)顯示,因?yàn)樗倭藅ranslator過程,預(yù)分析過程效率提高了幾百上千倍。

二.地址前綴顯示的改造

udis86在地址取址的前綴結(jié)果顯示與ollydbg不同,例如

static void
opr_cast(struct ud* u, struct ud_operand* op)
{
  if (u->br_far) {
    ud_asmprintf(u, "far ");
  }
  switch(op->size) {
  case  8: ud_asmprintf(u, "byte " ); break;
  case 16: ud_asmprintf(u, "word "); break;
  case 32: ud_asmprintf(u, "dword ");break;
  case 64: ud_asmprintf(u, "qword ");break;
  case 80: ud_asmprintf(u, "tword ");break;
  default: break;
  }
}
為了保持了ollydbg一直我們需要改成:
switch(op->size) {
      case  8: ud_asmprintf(u, "BYTE PTR ");ud_asmprintf2(operand_asm_buf,index,"BYTE PTR"); break;
      case 16: ud_asmprintf(u, "WORD PTR " );ud_asmprintf2(operand_asm_buf,index,"WORD PTR "); break;
      case 32: ud_asmprintf(u, "DWORD PTR ");ud_asmprintf2(operand_asm_buf,index,"DWORD PTR "); break;
      case 64: ud_asmprintf(u, "QWORD PTR ");ud_asmprintf2(operand_asm_buf,index,"QWORD PTR "); break;
      case 80: ud_asmprintf(u, "TWORD PTR ");ud_asmprintf2(operand_asm_buf,index,"TWORD PTR "); break;
      default: break;
      }

三、X64 RIP call指令不能顯示符號(hào)地址

這個(gè)應(yīng)該屬于bug顯示問題,所以我們需要做以下修改,問題主要在ud_syn_print_mem_disp

函數(shù),原是函數(shù)代碼為:

void
ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *op, int sign,char operand_asm_buf[64], int*index)
{
  UD_ASSERT(op->offset != 0);
 if (op->base == UD_NONE&& op->index== UD_NONE) {
    uint64_t v;
    UD_ASSERT(op->scale == UD_NONE&& op->offset!= 8);
    /* unsigned mem-offset */
    switch (op->offset) {
    case 16: v = op->lval.uword;  break;
    case 32: v = op->lval.udword; break;
    case 64: v = op->lval.uqword; break;
    default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
    }
    ud_asmprintf(u, "%" FMT64"X", v);
    ud_asmprintf2(operand_asm_buf,index, "%"FMT64 "X",v);
  } else {
    int64_t v;
    UD_ASSERT(op->offset != 64);
    switch (op->offset) {
    case 8 : v = op->lval.sbyte;  break;
    case 16: v = op->lval.sword;  break;
    case 32: v = op->lval.sdword; break;
    default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
    }
    if (v < 0) {
      ud_asmprintf(u, "-%" FMT64"X", -v);
      ud_asmprintf2(operand_asm_buf,index,"-%" FMT64"X", -v);
    } else if (v > 0) {
      ud_asmprintf(u, "%s%" FMT64"X", sign?"+" : "",v);
      ud_asmprintf2(operand_asm_buf,index,"%s%" FMT64"X", sign?"+" : "",v);
    }
  }
}
修復(fù)主要在后面加一個(gè)RIP指令判斷
void ud_syn_print_mem_disp(
                    struct ud* u,
                    struct ud_operand *op,
                    int sign)
{
  UD_ASSERT(op->offset != 0);
 if (op->base == UD_NONE&& op->index== UD_NONE)
 {
    uint64_t v;
    UD_ASSERT(op->scale == UD_NONE&& op->offset!= 8);
    /* unsigned mem-offset */
    switch (op->offset)
    {
    case 16: v = op->lval.uword;  break;
    case 32: v = op->lval.udword; break;
    case 64: v = op->lval.uqword; break;
    default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
    }
    if (u->sym_resolver)
    {
        LPTSTR name = NULL;
        int64_t offset =0;       
        name = u->sym_resolver(u, v, &offset);
        if (name)
        {
            if (offset)
            {
                op->_legacy = offset;
                ud_asmprintf(u,0, _T("%s.%")FMT64 _T("X"), name,offset);
            }
            else
            {
                op->_legacy = v;
                ud_asmprintf(u,0, _T("%s"),name);
            }
            return;
        }
    }   
    ud_asmprintf(u,1, _T("%")FMT64 _T("X"), v);   
  }
 else
 {
     int64_tv;
    UD_ASSERT(op->offset != 64); 
     switch (op->offset)
     {
     case 8 : v = op->lval.sbyte;  break;
     case 16: v = op->lval.sword;  break;
     case 32: v = op->lval.sdword; break;
     default: UD_ASSERT(!"invalidoffset"); v = 0; /* keep cc happy */
     }
//這里為添加專門處理RIP的指令
     if (op->base == UD_R_RIP)
     {
         v += (u->inp_ctr + u->insn_offset); 
         if (u->sym_resolver)
         {
             LPTSTR name = NULL;
             int64_toffset = 0;
             name = u->sym_resolver(u, v, &offset);
             if (name)
             {
                 if (offset)
                 {
                     op->_legacy = offset;
                     ud_asmprintf(u,0, _T("%s.%") FMT64_T("X"),name, offset);
                 }
                 else
                 {
                     op->_legacy = v;
                     ud_asmprintf(u,0, _T("%s"), name);
                 } 
                 return;
             }
         }
     }
     if (v < 0)
     {
         ud_asmprintf(u,1, _T("-%") FMT64_T("X"),-v);
     }
     else if (v > 0)
     {
         if (op->base == UD_R_RIP)
         {
             ud_asmprintf(u,1, _T("%s%") FMT64_T("X"),sign? _T("") : _T(""), v);
         }else
         {
           ud_asmprintf(u,1, _T("%s%") FMT64_T("X"),sign? _T("+") : _T(""), v);
         }         
     }
 }
}

其他還有一些小的細(xì)節(jié)和ollydbg有細(xì)微差別,這里就不再贅述了,讀者可以自行去發(fā)現(xiàn),經(jīng)過一些改造與加工我們就能得到一個(gè)性能與結(jié)果完美的反匯編引擎,后面的一些界面顯示的速度性能等等一些調(diào)試器的交互工作就會(huì)事半功倍了。

上述內(nèi)容就是ollydbg調(diào)試器中反匯編引擎的選擇與改造是怎樣的,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站標(biāo)題:ollydbg調(diào)試器中反匯編引擎的選擇與改造是怎樣的
網(wǎng)站網(wǎng)址:http://muchs.cn/article32/gcecpc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、網(wǎng)站維護(hù)商城網(wǎng)站、品牌網(wǎng)站建設(shè)外貿(mào)建站、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)