先跑一下,這個程序應該是有定時器,多久之後自動開啓,測試一下輸入,序列號以字母方式輸入會出現類型不匹配,之後程序自動退出
但是如果以數字方式輸入序列號,則會出現,Try Again,所以這裏序列號應該是一個數字
直接找Try Again這個字符串的位置,同上一題,在IDA中還是找不到,所以看Ollydbg,在地址4086f9處,這裏是前一部分的標號爲
004086DB loc_4086DB
應該是從下面這句跳轉過來的
.text:00408677 jz short loc_4086DB
驗證一下,將00408677處的jz改成jnz,74改75,然後輸入序列號111,則可以發現成功了
剩下的就是算法了。
從這個位置往前找,標誌位應該是下面這句設置的
.text:00408665 test si, si
再往前找,有下面兩句影響了si的值
.text:0040862E xor esi, esi
.text:00408653 neg esi
xor的操作由下面這段代碼決定
.text:0040860A fnstsw ax .text:0040860C test al, 0Dh ;低位爲0Dh .text:0040860E jnz loc_4087BF .text:00408614 call ds:__vbaFpR8 .text:0040861A fcomp ds:dbl_401028 .text:00408620 fnstsw ax .text:00408622 test ah, 40h ;也就是說ah不能爲40h .text:00408625 jz short loc_40862E .text:00408627 mov esi, 1 .text:0040862C jmp short loc_408630 .text:0040862E ; --------------------------------------------------------------------------- .text:0040862E .text:0040862E loc_40862E: ; CODE XREF: .text:00408625↑j .text:0040862E xor esi, esi ;不能走到這裏,esi被清零後就會跳到錯誤路徑 .text:00408630 .text:00408630 loc_408630: ; CODE XREF: .text:0040862C↑j
往前找到判斷函數爲__vbaFpR8的返回值,它的高16位不能爲40h,
__vbar8Str 將一個字符串轉爲雙精度單精度浮點型(8個字節)的數值形式
.text:004085CE mov eax, [ebp-18h] ;可以看出函數局部變量值ebp-18h表示的是序列號字符串 .text:004085D1 push eax .text:004085D2 call ds:__vbaR8Str ;此時參數爲unicode編碼字符串"111",也就是輸入的序列號字符串 .text:004085D8 mov ecx, [ebp-1Ch] ;根據下面這個值又可以推測出這個地方局部變量的值 .text:004085DB fstp qword ptr [ebp-0E4h] .text:004085E1 push ecx .text:004085E2 call ds:__vbaR8Str ;此時參數爲unicode編碼字符串"4533559" .text:004085E8 cmp dword_409000, 0 .text:004085EF jnz short loc_4085F9 .text:004085F1 fdivr qword ptr [ebp-0E4h] .text:004085F7 jmp short loc_40860A
向上追到這裏就可以分析出ebp-18h和ebp-1ch這兩個局部變量的值,後面的浮點運算就是比較這兩個值,只不過換了形式而已。直接將4533559作爲序列號輸入,發現直接就可以輸出正確結果了。
關於字符串"4533559"的來源就是計算序列號的算法的結果。
從這個函數的開頭開始看起,直到發現了之前見過的函數,求出字符串的長度,然後進行乘15B38,再加上第一個字符的ascll碼
.text:004081E9 mov edx, [ebp-0B0h] .text:004081EF mov eax, [ebp-1Ch] .text:004081F2 push eax .text:004081F3 mov ebx, [edx] .text:004081F5 call ds:__vbaLenBstr .text:004081FB mov edi, eax .text:004081FD mov ecx, [ebp-18h] .text:00408200 imul edi, 15B38h .text:00408206 push ecx .text:00408207 jo loc_4087C4 .text:0040820D call ds:rtcAnsiValueBstr .text:00408213 movsx edx, ax .text:00408216 add edi, edx .text:00408218 jo loc_4087C4 .text:0040821E push edi .text:0040821F call ds:__vbaStrI4 .text:00408225 mov edx, eax
然後根據這個數值一步一步跟蹤下去,下面又對這個值進行了乘3,再減二的操作,這部分都是使用浮點數來進行操作的,
.text:004083E9 mov ecx, [ebp-0A8h] .text:004083EF mov edx, [ebp-18h] .text:004083F2 push edx .text:004083F3 mov ebx, [ecx] .text:004083F5 call ds:__vbaR8Str .text:004083FB fmul ds:dbl_401010 .text:00408401 sub esp, 8 .text:00408404 fsub ds:dbl_401018 .text:0040840A fnstsw ax .text:0040840C test al, 0Dh .text:0040840E jnz loc_4087BF .text:00408414 fstp qword ptr [esp] .text:00408417 call ds:__vbaStrR8 .text:0040841D mov edx, eax .text:0040841F lea ecx, [ebp-1Ch]
在最後,又進行了減0x15的操作
.text:004084D3 mov ecx, [ebp-0A8h] .text:004084D9 mov edx, [ebp-18h] .text:004084DC push edx .text:004084DD mov ebx, [ecx] .text:004084DF call ds:__vbaR8Str .text:004084E5 fsub ds:dbl_401020 .text:004084EB sub esp, 8 .text:004084EE fnstsw ax .text:004084F0 test al, 0Dh .text:004084F2 jnz loc_4087BF .text:004084F8 fstp qword ptr [esp] .text:004084FB call ds:__vbaStrR8 .text:00408501 mov edx, eax
再往後就是判斷條件了,所以最終的算法就是(name的長度)*0x15B38+第一個字符的ASCII碼值)轉成10進制字符串算出serial,然後serial*3-0x2+0x15。