WinAmp V2.11的注册机制分析(三) (15千字)
WinAmp V2.11的注册机制分析(三)(初学者必读)转载本文请注明出处,并保持文章的完整性。本文不得用于任何商业场合,仅供学习和参考。
目的: 分析注册机制
工具: SI 4.05, Wdasm 8.93, Hedit 2.0
下面是CALL 004252D1的核心程序,00401D8D是打开菜单“Nullsoft WinAmp...”(即“关于”)时的调用,第二次是输入注册信息时的调用,第三次我也不清楚。
这段程序负责由RegisterName(Rn)计算出RegisterCode(Rc),放到Eax中。
* Referenced by a CALL at Addresses:
|:00401D8D , :00401F3A , :004254FE
|
:004252D1 55 push ebp
:004252D2 8BEC mov ebp, esp
:004252D4 81EC00010000 sub esp, 00000100
:004252DA 53 push ebx
:004252DB 56 push esi
:004252DC 57 push edi
:004252DD 6A3F push 0000003F
:004252DF 33DB xor ebx, ebx
:004252E1 59 pop ecx <== Ecx=3F
:004252E2 209D00FFFFFF and byte ptr [ebp+FFFFFF00], bl
:004252E8 33C0 xor eax, eax
:004252EA 8DBD01FFFFFF lea edi, dword ptr [ebp+FFFFFF01]
:004252F0 6800010000 push 00000100
:004252F5 F3 repz
:004252F6 AB stosd
:004252F7 FF7508 push [ebp+08]
:004252FA 66AB stosw
:004252FC AA stosb <== 从4252E2到此将 Ebp-100到Ebp处清0
:004252FD 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:00425303 50 push eax
:00425304 E8E7010100 call 004354F0 <== 这次调用将Rn复制到Ebp-100,见分析。
:00425309 83C40C add esp, 0000000C
:0042530C 389D00FFFFFF cmp byte ptr [ebp+FFFFFF00], bl
:00425312 7428 je 0042533C
:00425314 8DB500FFFFFF lea esi, dword ptr [ebp+FFFFFF00]
:0042531A 33FF xor edi, edi
<== 至此,入口: Edi=Ebx=0
* Referenced by a (U)nconditional or (C)onditional Jump at Address: <== !! 这个循环计算中间结果,很关键
|:0042533A(C)
|
:0042531C 56 push esi
:0042531D E861000000 call 00425383 <== 从Esi开始取4字节,作运算,结果在Eax中。请看下面
:00425322 59 pop ecx
:00425323 8BCF mov ecx, edi <== 随着循环,Edi=0、2,4,6,8,A...
:00425325 83E10F and ecx, 0000000F
:00425328 D3E0 shl eax, cl <== 左移位
:0042532A 85C0 test eax, eax
:0042532C 7C04 jl 00425332 <== 是负数则向下跳
:0042532E 03D8 add ebx, eax <== 很少被执行到
:00425330 EB02 jmp 00425334 <== 循环次数为Rn长度
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042532C(C)
|
:00425332 2BD8 sub ebx, eax <== Ebx放累加结果
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425330(U)
|
:00425334 47 inc edi
:00425335 47 inc edi <== Edi=Edi+2
:00425336 46 inc esi <== Esi取Rn的下一个字节
:00425337 803E00 cmp byte ptr [esi], 00 <== 检查是否结束
:0042533A 75E0 jne 0042531C <== 未完则继续,循环次数为Rn长度
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425312(C)
|
:0042533C 8BC3 mov eax, ebx <== 中间结果送 Eax
:0042533E B940420F00 mov ecx, 000F4240 <== Ecx= 1,000,000(Dec)
:00425343 6BC025 imul eax, 00000025 <== Eax= Eax*37(Dec)
:00425346 99 cdq
:00425347 F7F9 idiv ecx
:00425349 8BCA mov ecx, edx <== 余数送Ecx保存,很重要(我跟到下面要返回的语句,向回找了半天才找到)
:0042534B 8BF2 mov esi, edx <== 余数送Esi,到 425352继续处理
:0042534D 6BC964 imul ecx, 00000064 <== Ecx=Ecx*100(Dec)
:00425350 33FF xor edi, edi
* Referenced by a (U)nconditional or (C)onditional Jump at Address: <== 到 425369的这个循环会被执行几次
|:00425369(U)
|
:00425352 85F6 test esi, esi <== Esi是否为0
:00425354 7415 je 0042536B <== 是则跳出这一循环
:00425356 8BC6 mov eax, esi <== Esi->Eax,作处理准备
:00425358 6A64 push 00000064
:0042535A 99 cdq
:0042535B 5B pop ebx
:0042535C F7FB idiv ebx <== 被100(Dec)除
:0042535E 8BC6 mov eax, esi
:00425360 53 push ebx
:00425361 5E pop esi
:00425362 03FA add edi, edx <== Edi放余数累加和
:00425364 99 cdq
:00425365 F7FE idiv esi
:00425367 8BF0 mov esi, eax <== 商被送到Esi
:00425369 EBE7 jmp 00425352
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425354(C)
|
:0042536B 8D047F lea eax, dword ptr [edi+2*edi] <== Eax=Edi*3
|
:0042536E 6A04 push 00000004
:00425370 99 cdq
:00425371 5E pop esi
:00425372 F7FE idiv esi <== 再被4除
|
:00425374 6A64 push 00000064
:00425376 5E pop esi
:00425377 5F pop edi
:00425378 99 cdq
:00425379 F7FE idiv esi <== 再被100除
:0042537B 5E pop esi
:0042537C 5B pop ebx
:0042537D 8BC2 mov eax, edx <== 余数送 Eax
:0042537F 03C1 add eax, ecx <== Eax= Eax+Ecx (看42534D),这是最终结果
:00425381 C9 leave
:00425382 C3 ret
* Referenced by a CALL at Address:
|:0042531D
|
:00425383 55 push ebp
:00425384 8BEC mov ebp, esp
:00425386 51 push ecx
:00425387 8065FC00 and byte ptr [ebp-04], 00
:0042538B 57 push edi
:0042538C 33C0 xor eax, eax
:0042538E 8D7DFD lea edi, dword ptr [ebp-03]
:00425391 66AB stosw
:00425393 6A04 push 00000004
:00425395 FF7508 push [ebp+08] <== 源字符串地址压栈
:00425398 AA stosb <== 从Ebp-04处建立了4字节的临时缓冲区
:00425399 8D45FC lea eax, dword ptr [ebp-04] <==
:0042539C 50 push eax <== 目标区地址压栈
:0042539D E84E010100 call 004354F0 <== 又一次对这个CALL的调用,不过这次是从Esi处取 4 字节到临时缓冲区,我在这里转的头晕,大家可以看一看。
:004253A2 0FB645FE movzx eax, byte ptr [ebp-02] <== 相当于 al=[Esi+2],高位是0,下同
:004253A6 0FB64DFC movzx ecx, byte ptr [ebp-04] <== cl=[Esi]
:004253AA 0FB655FD movzx edx, byte ptr [ebp-03] <== dl=[Esi+1]
:004253AE 33C1 xor eax, ecx <== Al^=Cl
:004253B0 83C40C add esp, 0000000C
:004253B3 0FB64DFF movzx ecx, byte ptr [ebp-01] <== cl=[Esi+3]
:004253B7 F7D1 not ecx <== !Ecx
:004253B9 F7D0 not eax <== !Eax
:004253BB 33CA xor ecx, edx <== Cl^=Dl
:004253BD 5F pop edi
:004253BE 03C1 add eax, ecx <== Eax+=Ecx
:004253C0 C9 leave
:004253C1 C3 ret
call 004354F0,这个CALL是从源字符串区向目标缓冲区复制字串,长度由调用前的压栈决定;出口:将目标缓冲区地址送 Eax。
里面跳转太多,看不明白关系不大,它没有别的功能。
* Referenced by a CALL at Addresses:
|:00403EF8 , :00410333 , :00410517 , :00425304 , :0042539D
|:00425B3F , :00425BF1 , :004294AF , :0042951D , :00439DCA
|
:004354F0 8B4C240C mov ecx, dword ptr [esp+0C] <== 调用此Call前的倒数第三次Push,为100或4
:004354F4 57 push edi
:004354F5 85C9 test ecx, ecx
:004354F7 747A je 00435573 <== 两处调用都不跳
:004354F9 56 push esi
:004354FA 53 push ebx
:004354FB 8BD9 mov ebx, ecx <==
:004354FD 8B742414 mov esi, dword ptr [esp+14] <== !! Esi为源字串地址,注意 @42539D调用时,每次都有Esi=Esi+1
:00435501 F7C603000000 test esi, 00000003 <== Esi低字节是否为03
:00435507 8B7C2410 mov edi, dword ptr [esp+10] <== !! 调用此Call前的最后一次Push,均为Eax,是目标地址
:0043550B 7507 jne 00435514 <== 大多数情况下不会跳
:0043550D C1E902 shr ecx, 02
:00435510 756F jne 00435581 <== 会跳走
:00435512 EB21 jmp 00435535
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0043550B(C), :00435527(C)
|
:00435514 8A06 mov al, byte ptr [esi]
:00435516 46 inc esi
:00435517 8807 mov byte ptr [edi], al
:00435519 47 inc edi
:0043551A 49 dec ecx
:0043551B 7425 je 00435542
:0043551D 84C0 test al, al
:0043551F 7429 je 0043554A
* Possible Reference to String Resource ID=00003: "Uninstall canceled."
|
:00435521 F7C603000000 test esi, 00000003
:00435527 75EB jne 00435514
:00435529 8BD9 mov ebx, ecx
:0043552B C1E902 shr ecx, 02
:0043552E 7551 jne 00435581
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043557F(C)
|
:00435530 83E303 and ebx, 00000003
:00435533 740D je 00435542
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00435512(U), :00435540(C)
|
:00435535 8A06 mov al, byte ptr [esi]
:00435537 46 inc esi
:00435538 8807 mov byte ptr [edi], al
:0043553A 47 inc edi
:0043553B 84C0 test al, al
:0043553D 742F je 0043556E
:0043553F 4B dec ebx
:00435540 75F3 jne 00435535
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0043551B(C), :00435533(C)
|
:00435542 8B442410 mov eax, dword ptr [esp+10]
:00435546 5B pop ebx
:00435547 5E pop esi
:00435548 5F pop edi
:00435549 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043551F(C)
|
:0043554A F7C703000000 test edi, 00000003
:00435550 7412 je 00435564
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00435562(C)
|
:00435552 8807 mov byte ptr [edi], al
:00435554 47 inc edi
:00435555 49 dec ecx
:00435556 0F848A000000 je 004355E6
:0043555C F7C703000000 test edi, 00000003
:00435562 75EE jne 00435552
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00435550(C)
|
:00435564 8BD9 mov ebx, ecx
:00435566 C1E902 shr ecx, 02
:00435569 756C jne 004355D7
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0043556F(C), :004355E4(C)
|
:0043556B 8807 mov byte ptr [edi], al
:0043556D 47 inc edi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043553D(C)
|
:0043556E 4B dec ebx
:0043556F 75FA jne 0043556B
:00435571 5B pop ebx
:00435572 5E pop esi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004354F7(C)
|
:00435573 8B442408 mov eax, dword ptr [esp+08]
:00435577 5F pop edi
:00435578 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00435599(C), :004355B1(C)
|
:00435579 8917 mov dword ptr [edi], edx
:0043557B 83C704 add edi, 00000004
:0043557E 49 dec ecx
:0043557F 74AF je 00435530 <== 处理完成则跳上去
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
<== 从这里到返回处是将字串从[Esi]处复制到[Edi],长度与Ecx有关,不够则在[Edi]后面补0
|:00435510(C), :0043552E(C)
|
:00435581 BAFFFEFE7E mov edx, 7EFEFEFF <--
:00435586 8B06 mov eax, dword ptr [esi] <--
:00435588 03D0 add edx, eax
:0043558A 83F0FF xor eax, FFFFFFFF
:0043558D 33C2 xor eax, edx
:0043558F 8B16 mov edx, dword ptr [esi]
:00435591 83C604 add esi, 00000004
:00435594 A900010181 test eax, 81010100 <-- 检查 Eax取到的是否为0,手法很是怪异?!
:00435599 74DE je 00435579
:0043559B 84D2 test dl, dl
:0043559D 742C je 004355CB
:0043559F 84F6 test dh, dh
:004355A1 741E je 004355C1
:004355A3 F7C20000FF00 test edx, 00FF0000
:004355A9 740C je 004355B7
:004355AB F7C2000000FF test edx, FF000000
:004355B1 75C6 jne 00435579 <== 跳走表示edx取到的各字节均为非0
:004355B3 8917 mov dword ptr [edi], edx
:004355B5 EB18 jmp 004355CF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004355A9(C)
|
:004355B7 81E2FFFF0000 and edx, 0000FFFF
:004355BD 8917 mov dword ptr [edi], edx
:004355BF EB0E jmp 004355CF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004355A1(C)
|
:004355C1 81E2FF000000 and edx, 000000FF
:004355C7 8917 mov dword ptr [edi], edx
:004355C9 EB04 jmp 004355CF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043559D(C)
|
:004355CB 33D2 xor edx, edx
:004355CD 8917 mov dword ptr [edi], edx
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004355B5(U), :004355BF(U), :004355C9(U)
|
:004355CF 83C704 add edi, 00000004
:004355D2 33C0 xor eax, eax
:004355D4 49 dec ecx
:004355D5 740A je 004355E1
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00435569(C)
|
:004355D7 33C0 xor eax, eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004355DF(C)
|
:004355D9 8907 mov dword ptr [edi], eax
:004355DB 83C704 add edi, 00000004
:004355DE 49 dec ecx
:004355DF 75F8 jne 004355D9
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004355D5(C)
|
:004355E1 83E303 and ebx, 00000003
:004355E4 7585 jne 0043556B
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00435556(C)
|
:004355E6 8B442410 mov eax, dword ptr [esp+10]
:004355EA 5B pop ebx
:004355EB 5E pop esi
:004355EC 5F pop edi
:004355ED C3 ret
