本篇文章為大家展示了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è)置反匯編的語法平臺(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的語法字符串。
ud_insn_off(&ud_obj)獲得當(dāng)前的指令地址
ud_insn_asm(&ud_obj)獲取當(dāng)前的反匯編后的字符串。
一下是結(jié)果顯示:
三、符號(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不同的語法風(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à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://m.newbst.com/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)