在逆向遇到NEG+SBB指令的組合,不明白原因,上網(wǎng)一查,找到了.嘿嘿!
mov ebx, eax
neg ebx
push esi
sbb bl, bl
注:Intel處理器的文檔中聲明NEG指令除了對(duì)操作數(shù)作符號(hào)取反外,它還要根據(jù)操作數(shù)的值設(shè)置CF標(biāo)志位的值。如果執(zhí)行NEG指令時(shí)操作數(shù)為0,則CF將被置為0。如果操作數(shù)為非零,則CF將被置為1。
NEG是一個(gè)簡單的取反指令,用來對(duì)操作數(shù)的算術(shù)符號(hào)取反——有時(shí)候也稱它為2的補(bǔ)碼(two’s complement。譯注:1的補(bǔ)碼與NOT指令對(duì)應(yīng),是邏輯取反指令)。NEG用C描述的偽代碼:
Result = -(Operand);
SBB是一條帶借位的減法指令,這就是說SBB將第二個(gè)操作數(shù)(即右操作數(shù))加上標(biāo)志位CF,然后將結(jié)果用第一個(gè)操作數(shù)來減。SBB用C描述的偽代碼:
Operand1 = Operand1 - (Operand2 + CF);
在上面的指令中NEG的作用應(yīng)該就是注中的,根據(jù)操作數(shù)來設(shè)置CF標(biāo)志位的值,如果EBX為0,那么CF將被置為0,如果EBX為非零,則CF將被置為1.然后結(jié)合SBB,我們可以將以上4條指令理解為,當(dāng)EBX等于0時(shí),BL將等于0;EBX大于0時(shí),BL將等于-1.
參考:Reversing:逆向工程揭密-附錄A揭密代碼結(jié)構(gòu)(4)
// 對(duì)返回?cái)?shù)進(jìn)行處理,這是編譯器優(yōu)化的結(jié)果,翻譯成C可能是
// if (eax)
// return 1 ;
// else
// return 0 ;
// 求反.執(zhí)行NEG指令時(shí)操作數(shù)為0,則CF將被置為0。如果操作數(shù)為非零,則CF將被置為1
/*41A72D*/ NEG EAX
// 高位借位減法,EAX的值取決于前面的neg指令。對(duì)同一個(gè)操作數(shù)執(zhí)行減運(yùn)算,
// 即用EAX寄存器減去EAX,如果不考慮標(biāo)志位CF的話,這條指令在數(shù)學(xué)上是沒有任何意義的。
// 因?yàn)閷F加到了第二個(gè)操作數(shù)上,所以結(jié)果只取決于CF。如果“CF == 1”,那么EAX將變成-1
/*41A72F*/ SBB EAX,EAX
/*41A731*/ NEG EAX // 如果EAX=0,非0可能是-1了,取反后就返回1