天天看點

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

一丶除法的優化

1.有符号被除數 / 無符号除數的情況下

進階代碼為:

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

彙編中優化的展現形式

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

相比于昨天,我們發現了的 無符号 / 常量多出了點東西

無符号/常量

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

如果無符号/常量,那麼我們還原的時候

套用公式即可

am >> n

a是被除數  m是設  2n/c   等價于  m == 2n/c

無符号的情況的,n的值是2^33次方  ,n = 33

根據上面得知,  m = 0AAAAAAABh

此時求出C來即可,  C = 除數

公式:

         2n / m = c

套進去得到

2^33次方 / 0AAAAAAABh = 被除數  結果向上取整

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下
逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

向上取整,結果就是3,那麼得出被除數是3了.

2^33次方,也就是n怎麼得出來的,依據上面的彙編代碼n值等于1

也就是shr edx,1  那麼我們知道,算一個除法的時候,必須擴充符号位

也就是 變成了 EDX.EAX 了,現在EDX右移一位,那麼相當于 eax移動了32位+1,也就是33位,是以可以直接省略了.

是以此時EDX >> 1則是 33

此時繼續,有符号 / 常量

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

看彙編代碼,下邊多了幾條語句 顯然與上面不同

此時還原的方法

n得出結果就是32,為什麼?

因為edx直接使用了,我不用移位了.

下方的移動31位,是固定的,這個主要是解決有符号和無符号相除.

在這裡,需要進行大量的數學公式推算,鑒于大家對數學不太明白,是以不再講解.

我們隻需要知道,當一個有符号 / 一個常量的時候,那麼下方如果調整了.不用看.因為m的值如果按照 imul來計算的時候是一個負數.但是此時我們不能讓它變為負數,是以最後進行符号位調整.

還原手法同上.

如果數學公式推導:

我們知道.

a/c的結果可以變為 

m = 2n / c

此時我們要知道,C的結果不會是整數的,是以使用的公式 是上整+1

也可能是小數,也需要上整+1

那麼現在我們可以把符号位提取出來,這樣也就是 移動31位(是以說是在32位系統下是固定死的),這樣如果是負數,那麼負數+1即可.如果是正數,那麼是加0,還原的時候隻看上三句即可.

2.無符号 / 7 和有符号/7的新的優化方式(當然可能不光是7介紹的是這種優化方式)

無符号/7的新方式.

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

又暈了是不是,一個DIV沒用到,很難看到這是一個除法對不對.

先說下還原的公式,以及方法(至于公式怎麼的出來的,那麼可以看下方推導,當然這屬于大數問題,可以不看.不過看了有好處)

2n / (M + 2^32)  = C(除數)即可.(别忘了結果向上取整)

n = 32(本身32起步,看系統,當然n的取值明天會講) + 1 + 2 (指數相加) 結果為2 ^ 35次方

那麼 2^35次方 / (M + 2^32) 結果救贖除數

那麼我們按照數學界的公式去推一下.

推導:

首先得出:

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

得出最後的公式.

那麼根據上面的程式,繼而得到了

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

 一步一步簡化

第一次簡化: 可以把2^32次方拿到上面來

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

 第二次簡化

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

第三次簡化:

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

第四次簡化

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

第五次簡化

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

第六次簡化:

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

第七次簡化:

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

得出了

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

那麼根據以前的除法公式

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

設 m 

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

那麼

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下
逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

進而簡化為公式得出  一個大的M, M的值太大了.變為了一個大數問題,是以我們最終的M要加上1,或者加上2^32次方.(因為進位了)

C =  (2^32 + 指數 + 指數) / (2^32 + M)  故而得出了C

簡化為了

C = 2^n / M (别忘了M是一個大數)

有符号/7

這個和昨天一樣,套用 C = 2^n / M 即可 (M是正常的,不是大數)

在這裡講解一下彙編代碼:

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

請問為什麼要 add一下.

這裡我們就涉及到了有符号和無符号混乘的問題.

比如16位的年代,兩個寄存器相乘,怎麼解決溢出問題了.

A * 8086

A + ~A = FFFF

A + ~A + 1 = 10000 (求補碼)

A * -(10000h - 8086h)

去掉負号

A * (8086h - 10000h )

那麼得出

8086h - 10000h = dx.ax

又因為你減掉了補碼 10000h

那麼 

dx.ax + 10000h = 8086h

那麼此時 10000h的高位變成了1,那麼 dx直接加1即可了.

是以這就是為什麼 add edx,ecx(乘積的高位)

到此,除數為正數的幾種情況講解完畢.

二丶除數為負數

1.除數為  -2的幂的情況下

進階代碼:

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

彙編代碼:

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

 公式還是一樣的,向上取整的公式.也就是昨天的

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

b- 1是3

b是除數, 結果是2 ^2次方.

得出除數是4 隻需要求反即可.

2.除數為-7的時候,有符号除,和無符号除的表現形式

2.1 有符号除

 進階代碼還是上面的,隻不過 -4 變為-7

argc / -7

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

此時,和 有符号 * 無符号問題又沖突了

隻不過,現在的M變為負數了 需要你求補碼了. 而又因為M是一個大數,下面需要調整1F(31)位,是以

還原公式為

2^n / neg(2^32 + M) = C  (向上取整)

也就是說依照上圖,我們的M變為了16DB6DB6D了,此時要對它取反+1變為真正的M 然後用2^n次方去除,然後求出C來(除數)

計算一下得到

2^34 / neg(16DB6DB6D) = 6.99999xxxx 向上取整是7

那麼此時怎麼判斷是否是  ±7那?

可以看彙編代碼,裡面有個 sub edx,ecx(相當于上面舉例子 A * 8086,  那麼此時 EDX隻能減去乘積的高位才會得出真正的8086)

那麼此時,我們判定了m的高位是負數,是求補後的,那麼得出了  M是負數,說明了除數為負數,又因為還原了,M 得出的結果是原除數的絕對值.是以判定為負數.

2.2無符号/-7的優化.

逆向課程第五講逆向中的優化方式,除法原理,以及除法優化下

這個是特殊還原公式

還原公式:

C = 2^n / M   轉為16進制當做有符号解釋即可.

現在的n是29  加上原來的32 = 61 那麼就是2^61次方 / 20000001h  結果轉化為16進制當做有符号解釋.

作者:IBinary