天天看點

通過使用ollydbg彙編語言的代碼逆推序列号的算法

依舊使用的是traceme,相關内容請參考https://blog.51cto.com/181647568/2421560

通過反複的研究traceme的彙編代碼,我通過觀察指派的值來推測某些指令的作用。

通過使用ollydbg彙編語言的代碼逆推序列号的算法

我在指令的右邊标注了那些代碼都是幹什麼的,直到最後一行的call指令,這個call指令是接下來跳轉的部分了,下圖中的je也是我們最一開始爆破nop掉的那個那個指令,是以無論正确的序列号是怎麼出來的,已經就在call TraceMe.00401340中了。

通過使用ollydbg彙編語言的代碼逆推序列号的算法

點選call的行按住回車可以跳轉到這個方法中,為了友善我在這裡加了斷點,以後我可以通過F9鍵來快速的跳到這一步。

通過使用ollydbg彙編語言的代碼逆推序列号的算法

根據檢視指派我很快的發現了上圖結尾幾行為一個循環部分。

通過使用ollydbg彙編語言的代碼逆推序列号的算法

循環結束後,程式又做了一個取序列号的操作,并且在下方進行了一次對比(lstrcmpA方法)。因為根據前面的一篇部落格(https://blog.51cto.com/181647568/2421560)我已經能夠取到正确的驗證碼了,是以在這個地方我分别輸入了正确的和錯誤的驗證碼,檢視情況。結果表明這個程式在運作完成後會有一個寄存器(EAX)保留着一個值,序列号碼錯誤為0正确為1。

而這個test就是控制je指令的。

那麼這樣我可以确認,序列号就是在那個循環中算出來的。

通過使用ollydbg彙編語言的代碼逆推序列号的算法

我可以看到一個0x7的我一開始以為是循環七次,然後我看着循環反複的重複着,mov部分,我可以清楚地看到藍色部分的指派,

通過使用ollydbg彙編語言的代碼逆推序列号的算法

上圖是第一次循環的結果,我可以認出這個字元是我輸入的使用者名的第四位,為了驗證是否和我想的一緻,我修改了好幾次使用者名,每次都是第四位。而且被轉換成數字了,我猜測是ascii碼,在表格上一對應,确實是ASCII碼,不過是16進制的。

而mov粉紅色的一部分是十六進制的C,我沒搞清楚是什麼意思。

然後接下來的操作包含了imul,add,inc三個操作符,我特意百度了一下imul是乘法相當于edx=edx*ebx,數值是前面的使用者名第四位的ASCII碼和C的積。同理add就是esi=esi+edx,這個esi隻在這句話裡出現,而edx正好是前面乘法的結果,是以每次循環的積都會被累加到esi中。

inc ecx則是指ecx=ecx+1這個很像是計數器,是以ecx,eax都是計數器,它們都對應着一個cmp。

最後的那個cmp用ecx和edi,根據我的調試,edi永遠是使用者名的長度,而且這個判斷是控制循環的,這個循環從4開始循環到使用者名長度的那個數。

在每次循環中我反複的觀察兩個MOV指令,藍色部分比較明顯,永遠是使用者名的第N位的ASCII碼,從4開始。粉紅色部分就比較奇怪了,第一個是C,第二次是A第三次是13,都是16位的數字,毫無規律可循。于是我隻能去了解[eax+0x405030]是什麼意思了,首先eax一定指的是寄存器eax,eax的值會由一句inc eax每次都加1,而在循環第一句會判斷這個eax是否會大于7,如果大于7會執行xor eax,eax,這個操作會把eax清零。(而在一開始我把這個7給了解錯了,我以為這個控制循環次數的,循環從4開始,到使用者名長度結束,如果使用者名長度很長的話,也隻會運作七次。但是後來我輸入了一個較長的使用者名,運作七次後并沒有退出程式。)

0x405030明顯是一個記憶體位址,我右鍵“資料視窗中跟随”然後查到這個記憶體位址

通過使用ollydbg彙編語言的代碼逆推序列号的算法

對應的ASCII碼是亂碼,我一開始沒有了解,不過在幾次循環後我發了規律,oc oa 13 09這些數字和粉紅色參數的值是對應的,我立即就猜出了第四次循環的藍色值和粉紅色的值。第四次循環的結果确定了,當時還沒能了解eax和這個記憶體位址的關系。我就用了一個比較長的使用者名不停的測試,粉紅色部分一直到最後的08之後并沒有到D0而是回到了0C。于是我就能了解了,這是八個數字開始循環的。于是整個循環的指令差不多就能模拟出了。

從使用者名的第四個字元開始取ASCII碼乘以C,第五個字元的ASCII碼乘以A,一次類推,第十二個字元又開始乘以C。直到最後一個字元。這些乘積都加起來,轉換成十進制就是序列号。

算碼器用易語言寫是這樣的,其他的語言寫起來應該更加簡單。不過我就不舉例了。

.版本 2

.支援庫 spec

.子程式 子程式1

.局部變量 使用者名, 文本型

.局部變量 序列号, 整數型

.局部變量 使用者名長度, 整數型

.局部變量 計數器, 整數型

.局部變量 第二個數, 整數型, , "0"

.局部變量 sum, 整數型

使用者名 = “traceme”

使用者名長度 = 取文本長度 (使用者名)

第二個數 = { 12, 10, 19, 9, 12, 11, 10, 8 }

計數器 = 1

.判斷循環首 (計數器 + 3 ≤ 使用者名長度)

    sum = sum + 取代碼 (取文本中間 (使用者名, 計數器 + 3, 1), ) × 第二個數 [計數器 % 8]

    計數器 = 計數器 + 1

    ' 暫停 ()

繼續閱讀