依舊使用的是traceme,相關內容請參考https://blog.51cto.com/181647568/2421560ide
經過反覆的研究traceme的彙編代碼,我經過觀察賦值的值來推測某些命令的做用。測試
我在指令的右邊標註了那些代碼都是幹什麼的,直到最後一行的call命令,這個call命令是接下來跳轉的部分了,下圖中的je也是咱們最一開始爆破nop掉的那個那個命令,因此不管正確的序列號是怎麼出來的,已經就在call TraceMe.00401340中了。spa
點擊call的行按住回車能夠跳轉到這個方法中,爲了方便我在這裏加了斷點,之後我能夠經過F9鍵來快速的跳到這一步。調試
根據查看賦值我很快的發現了上圖結尾幾行爲一個循環部分。orm
循環結束後,程序又作了一個取序列號的操做,而且在下方進行了一次對比(lstrcmpA方法)。由於根據前面的一篇博客(https://blog.51cto.com/181647568/2421560)我已經可以取到正確的驗證碼了,因此在這個地方我分別輸入了正確的和錯誤的驗證碼,查看狀況。結果代表這個程序在運行完成後會有一個寄存器(EAX)保留着一個值,序列號碼錯誤爲0正確爲1。blog
而這個test就是控制je命令的。內存
那麼這樣我能夠確認,序列號就是在那個循環中算出來的。ci
我能夠看到一個0x7的我一開始覺得是循環七次,而後我看着循環反覆的重複着,mov部分,我能夠清楚地看到藍色部分的賦值,get
上圖是第一次循環的結果,我能夠認出這個字符是我輸入的用戶名的第四位,爲了驗證是否和我想的一致,我修改了好幾回用戶名,每次都是第四位。並且被轉換成數字了,我猜想是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明顯是一個內存地址,我右鍵「數據窗口中跟隨」而後查到這個內存地址
對應的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
' 暫停 ()
.判斷循環尾 ()
調試輸出 (sum)