《加密與解密》筆記四(三)

1:

一般情況下我們的判斷往往都是有跳轉指令的,這個跳轉指令的分類我就不詳細的分了,大的一般分爲6字節(5字節)或是2字節的,具體看下錶瞭解一下就好:
這裏寫圖片描述
這裏要對書上做一個補充:書上的無條件跳轉指令(JMP)只說了兩種類型:
1:目標地址爲0~FF(有符號)
2:目標地址爲0~FFFF(有符號)(通常見到的都是這個)
3(補充):後面直接跟目標地址的

2:

這裏貼一個條件設置的指令吧
這裏寫圖片描述
這些指令都可以用於修改類似於標誌寄存器標誌位的0,1值的,針對於有條件跳轉的修改。
當然,有的時候會遇到優化比較強的此時就會整合我們的代碼從而不直接展現出我們的if,else來,如:

neg eax
sbb eax,eax
and al,0FCH
add eax,5
retn

這裏世界上就是針對一個bool量的0和1的判斷,在上面的彙編程序中我們發現:
如果eax爲0,由neg檢測的爲0就放在標誌寄存器中,此時就會讓CF位爲0,然後sbb就相當於 eax = 0 - 0 此時and 以後同樣爲0,然後加5就爲5,此時eax作爲返回值,所以就是return 5
如果eax爲1,此時CF爲1,然後sbb就是eax = 0 - 1 ,eax = FFFFFFFF,此時and 0FC以後就變成看了FFFFFFFC然後加5,CF爲1,eax 爲 0,此時eax作爲返回值,所以就是return 0
所以這裏對應的語句應該是:

if(bool)
return 0;
else
return 5;

3:

再看看循環
在8086彙編中循環是一個loop 聯合一個FLAG和ecx遞減計數用的
但是在逆向過程中,我們的for循環,while循環的形式一般就不用loop了,具體大概就是:
for(i = 0;i<10;++i:
(我這裏變量都用寄存器代替了吧)

xor eax,eax
jmp 1
0 inc eax 
1 cmp eax,a
jg 2

.....

jmp 0 
2 ...

其實這裏就是一個for 的思路,首先執行第一個分號前的東西,然後判斷中間是否成立,然後執行後面的循環內容,然後執行第三個括號裏面的東西然後判斷中間是否成立。
while的話其實就是相對上面那個少了個初始化的過程
do - while也是一樣的。

4:

數學運算;
在彙編裏面一般見得到的運算命令有:add sub mul div這四個基礎類,後面還擴展到了包含標誌寄存器的類似於上面的sbb之類的,當然還有其他的一系列。。。
這裏要說一些關於編譯器進行特別優化的一些:

printf("%s",a + b + 1);
//mov eax,[a]
//mov ecx,[b]
//lea edx , dword ptr[eax + ecx + 1]
//push edx
//push ...

這裏就只是想說明,在有的編譯器下會直接以類似於lea edx , dword ptr[eax + ecx + 1]的形式進行加減並傳參(速度最快)這裏說一下,lea 和[]就非常類似於C裏面的&和*兩個符號,所以此時edx的值實際上就是eax + ecx + 1
這裏再提一下乘法,乘法一般的話就直接用mul就好,但是有的時候是基數此時如果要以效率優先那麼就會用lea eax[eax +4*eax](這裏是a *= 5)因爲此時以3,4,8之類的二的冪計算實際上就只需要用到位移就行,一次位移就之消耗一個CPU時鐘。
再出發裏面我們一般會用到a/b = a*1/b的算法,或使用到位移
這裏介紹兩個彙編的位移:
shr右位移(除二)shl左位移(乘法)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章