【文章标题】: crackme2简单破解
【软件大小】: 132K
【下载地址】: http://www.fradfire.com/crackme2.rar
【编写语言】: DELPHI
【使用工具】: OLLYDBG,IDA
【难 度】: 简单,适合刚入门的新手
----------------------------------------------------------------------------------------------------------------------------
终于又和大家见面了,这几天由于考网络工程师,忙于复习,所以有好几天都没有发帖子了,终于在今天晚上抽出了一点时间来写点东西,这个CRACKME的确比较简单,只是让我郁闷的是,作者竟然给他加了UPX的壳,好象大多的CRACKME都没有壳,但是为了尊重作者,我还是亲手脱掉
他了,好了不废话了开始吧..
****************************************************************************************************************************
一):用PEID载入,显示UPX 0.89.6 - 1.02 / 1.05 - 1.22 (Delphi) stub -> Markus & Lazlo,很明显是UPX的壳,DELPHI写的。
二):脱壳:先简单说下这个壳吧,等在过几个月真正功壳的时候在仔细研究他.
壳的加载过程:
1)获取壳自己所需要使用的API地址
如果你用PE查看工具看看加壳后的程序文件,会发现未加壳的程序文件和加壳后的程序文件的Import Table不太一样,
加壳后的Import Table一般所引入的DLL和API很少,甚至只有Kernel32.dll以及GetProcAddress这个API。
壳还需要很多其他的API来完成它的工作。
当然他并不想让你知道他想用哪个API,所以一般他只是在壳的代码中动态加载这些API,而只把一些你嗅不出什么味道的几个API放在Import Table中。
当然这其中壳可能会用到一些Anti技术,不过这和本文主旨无关,所以就不说了。
2)解密原程序的各个节区(Section)的数据
壳出于保护原程序代码和数据的目的,一般都会加密原程序文件的各个节区。既然是加密保存,那么在程序执行时你总不能也保持加密状态吧,所以解密是壳必做的工作之一。
一般壳按节区加密的,那么在解密时也按节区解密,并且把解密的节区数据按照节区的定义放在合适的内存位置。
如果加壳时用到了压缩技术,那么在解密之前还有一道工序,当然是解压缩。
这也是一些壳的特色之一,比如说原来的程序文件未加壳时1-2M大小,加壳后反而只有几百K,这种瘦身技术当然会吸引了不少眼球。
3)重定位
我想大家都明白ImageBase吧,即程序的基地址,当然这只是程序文件中声明的,程序运行时能够保证系统一定满足你的要求吗?
对于EXE的程序文件来说,Windows系统会尽量满足你的要求。
比如一般EXE文件的基地址为0x400000,而运行时Windows系统提供给程序的基地址也同样是0x400000。在这种情况下就不需要进行地址"重定位"了。
由于不需要对EXE文件进行"重定位",所以很多壳在加壳时把原程序文件中用于保存重定位信息的节区干脆也去掉了,这样使得加壳后的文件更加小巧。有些工具提供Wipe Reloc的功能,其实就是这个作用。
不过对于DLL的动态链接库文件来说,Windows系统没有办法保证每一次DLL运行时提供相同的基地址。这样"重定位"就很重要了。
此时壳中也需要提供进行"重定位"的代码,否则原程序中的代码是无法正常运行起来的。从这点来说,加壳的DLL比加壳的EXE更难修正。
4)HOOK-API
我们知道程序文件中的Import Table的作用是让Windows系统在程序运行时提供API的实际地址给程序使用。
在程序的第一行代码执行之前,Windows系统就完成了这个工作。
而壳一般都修改了原程序文件的Import Table,那么原程序文件的Import Table由谁来处理呢?
这当然由壳来自己处理了,因此壳不得不模仿Windows系统的工作来填充Import Table中相关的数据。
Import Table结构中与实际运行相关的主要是IAT结构,
这个结构中用于保存API的实际地址,因此壳所需要的就是填充这个结构中的数据。
不过壳不是填充这些实际的API地址,而是填充壳中用来HOOK-API的代码的地址。
这样壳中的代码一旦完成了加载工作,在进入原程序的代码之后,仍然能够间接地获得程序的控制权。
因为程序总是需要与系统打交道,与系统交道的途径是API,而API的地址已经替换成了壳的HOOK-API的地址,那么每一次程序与系统打交道,都会让壳的代码获得一次控制权,一来壳可以进行反跟踪继续保护软件,二来可以完成某些特殊的任务。
其实这就是所谓HOOK技术。
5)最后当然是跳转到程序原入口点。
这个大家比较熟悉,找的就是它。脱壳时大多数也是在这个时候。从这个时候起壳要把控制权交还给原程序了。
以上是一个简单的总结。因为以前研究过一段时间,算是让大家对壳的一个初步了解吧。
三)用OD载入,跳过入口点警告,来分析他的代码.
---------------------------------------------------
00455690 > 60 PUSHAD ---壳的入口
00455691 BE 00604300 MOV ESI,CrackMe2.00436000
00455696 8DBE 00B0FCFF LEA EDI,DWORD PTR DS:[ESI+FFFCB000]
0045569C C787 D0340400 9>MOV DWORD PTR DS:[EDI+434D0],5F46D95
004556A6 57 PUSH EDI
004556A7 83CD FF OR EBP,FFFFFFFF
004556AA EB 0E JMP SHORT CrackMe2.004556BA
004556AC 90 NOP
004556AD 90 NOP
004556AE 90 NOP
004556AF 90 NOP
004556B0 8A06 MOV AL,BYTE PTR DS:[ESI]
004556B2 46 INC ESI
004556B3 8807 MOV BYTE PTR DS:[EDI],AL ---解压后的数据放到00442E44(程序的OEP)
004556B5 47 INC EDI
004556B6 01DB ADD EBX,EBX
004556B8 75 07 JNZ SHORT CrackMe2.004556C1
004556BA 8B1E MOV EBX,DWORD PTR DS:[ESI]
004556BC 83EE FC SUB ESI,-4
004556BF 11DB ADC EBX,EBX
004556C1 ^ 72 ED JB SHORT CrackMe2.004556B0
004556C3 B8 01000000 MOV EAX,1
004556C8 01DB ADD EBX,EBX
004556CA 75 07 JNZ SHORT CrackMe2.004556D3
004556CC 8B1E MOV EBX,DWORD PTR DS:[ESI]
004556CE 83EE FC SUB ESI,-4
004556D1 11DB ADC EBX,EBX
004556D3 11C0 ADC EAX,EAX
004556D5 01DB ADD EBX,EBX
004556D7 ^ 73 EF JNB SHORT CrackMe2.004556C8
004556D9 75 09 JNZ SHORT CrackMe2.004556E4
004556DB 8B1E MOV EBX,DWORD PTR DS:[ESI]
004556DD 83EE FC SUB ESI,-4
004556E0 11DB ADC EBX,EBX
004556E2 ^ 73 E4 JNB SHORT CrackMe2.004556C8
004556E4 31C9 XOR ECX,ECX
004556E6 83E8 03 SUB EAX,3
004556E9 72 0D JB SHORT CrackMe2.004556F8
004556EB C1E0 08 SHL EAX,8
004556EE 8A06 MOV AL,BYTE PTR DS:[ESI]
004556F0 46 INC ESI
004556F1 83F0 FF XOR EAX,FFFFFFFF
004556F4 74 74 JE SHORT CrackMe2.0045576A
004556F6 89C5 MOV EBP,EAX
004556F8 01DB ADD EBX,EBX
004556FA 75 07 JNZ SHORT CrackMe2.00455703
004556FC 8B1E MOV EBX,DWORD PTR DS:[ESI]
004556FE 83EE FC SUB ESI,-4
00455701 11DB ADC EBX,EBX
00455703 11C9 ADC ECX,ECX
00455705 01DB ADD EBX,EBX
00455707 75 07 JNZ SHORT CrackMe2.00455710
00455709 8B1E MOV EBX,DWORD PTR DS:[ESI]
0045570B 83EE FC SUB ESI,-4
0045570E 11DB ADC EBX,EBX
00455710 11C9 ADC ECX,ECX
00455712 75 20 JNZ SHORT CrackMe2.00455734
00455714 41 INC ECX
00455715 01DB ADD EBX,EBX
00455717 75 07 JNZ SHORT CrackMe2.00455720
00455719 8B1E MOV EBX,DWORD PTR DS:[ESI]
0045571B 83EE FC SUB ESI,-4
0045571E 11DB ADC EBX,EBX
00455720 11C9 ADC ECX,ECX
00455722 01DB ADD EBX,EBX
00455724 ^ 73 EF JNB SHORT CrackMe2.00455715
00455726 75 09 JNZ SHORT CrackMe2.00455731
00455728 8B1E MOV EBX,DWORD PTR DS:[ESI]
0045572A 83EE FC SUB ESI,-4
0045572D 11DB ADC EBX,EBX
0045572F ^ 73 E4 JNB SHORT CrackMe2.00455715
00455731 83C1 02 ADD ECX,2
00455734 81FD 00F3FFFF CMP EBP,-0D00
0045573A 83D1 01 ADC ECX,1
0045573D 8D142F LEA EDX,DWORD PTR DS:[EDI+EBP]
00455740 83FD FC CMP EBP,-4
00455743 76 0F JBE SHORT CrackMe2.00455754
00455745 8A02 MOV AL,BYTE PTR DS:[EDX]
00455747 42 INC EDX
00455748 8807 MOV BYTE PTR DS:[EDI],AL
0045574A 47 INC EDI
0045574B 49 DEC ECX
0045574C ^ 75 F7 JNZ SHORT CrackMe2.00455745
0045574E ^ E9 63FFFFFF JMP CrackMe2.004556B6
00455753 90 NOP
00455754 8B02 MOV EAX,DWORD PTR DS:[EDX]
00455756 83C2 04 ADD EDX,4
00455759 8907 MOV DWORD PTR DS:[EDI],EAX
0045575B 83C7 04 ADD EDI,4
0045575E 83E9 04 SUB ECX,4
00455761 ^ 77 F1 JA SHORT CrackMe2.00455754
00455763 01CF ADD EDI,ECX
00455765 ^ E9 4CFFFFFF JMP CrackMe2.004556B6
0045576A 5E POP ESI
0045576B 89F7 MOV EDI,ESI
0045576D B9 25210000 MOV ECX,2125
00455772 8A07 MOV AL,BYTE PTR DS:[EDI]
00455774 47 INC EDI
00455775 2C E8 SUB AL,0E8
00455777 3C 01 CMP AL,1
00455779 ^ 77 F7 JA SHORT CrackMe2.00455772
0045577B 803F 15 CMP BYTE PTR DS:[EDI],15
0045577E ^ 75 F2 JNZ SHORT CrackMe2.00455772
00455780 8B07 MOV EAX,DWORD PTR DS:[EDI]
00455782 8A5F 04 MOV BL,BYTE PTR DS:[EDI+4]
00455785 66:C1E8 08 SHR AX,8
00455789 C1C0 10 ROL EAX,10
0045578C 86C4 XCHG AH,AL
0045578E 29F8 SUB EAX,EDI
00455790 80EB E8 SUB BL,0E8
00455793 01F0 ADD EAX,ESI
00455795 8907 MOV DWORD PTR DS:[EDI],EAX
00455797 83C7 05 ADD EDI,5
0045579A 89D8 MOV EAX,EBX
0045579C ^ E2 D9 LOOPD SHORT CrackMe2.00455777
0045579E 8DBE 00200500 LEA EDI,DWORD PTR DS:[ESI+52000]
004557A4 8B07 MOV EAX,DWORD PTR DS:[EDI]
004557A6 09C0 OR EAX,EAX
004557A8 74 3C JE SHORT CrackMe2.004557E6
004557AA 8B5F 04 MOV EBX,DWORD PTR DS:[EDI+4]
004557AD 8D8430 4C600500 LEA EAX,DWORD PTR DS:[EAX+ESI+5604C]
004557B4 01F3 ADD EBX,ESI
004557B6 50 PUSH EAX
004557B7 83C7 08 ADD EDI,8
004557BA FF96 EC600500 CALL DWORD PTR DS:[ESI+560EC]
004557C0 95 XCHG EAX,EBP
004557C1 8A07 MOV AL,BYTE PTR DS:[EDI]
004557C3 47 INC EDI
004557C4 08C0 OR AL,AL
004557C6 ^ 74 DC JE SHORT CrackMe2.004557A4
004557C8 89F9 MOV ECX,EDI
004557CA 57 PUSH EDI
004557CB 48 DEC EAX
004557CC F2:AE REPNE SCAS BYTE PTR ES:[EDI]
004557CE 55 PUSH EBP
004557CF FF96 F0600500 CALL DWORD PTR DS:[ESI+560F0]
004557D5 09C0 OR EAX,EAX
004557D7 74 07 JE SHORT CrackMe2.004557E0
004557D9 8903 MOV DWORD PTR DS:[EBX],EAX
004557DB 83C3 04 ADD EBX,4
004557DE ^ EB E1 JMP SHORT CrackMe2.004557C1
004557E0 FF96 F4600500 CALL DWORD PTR DS:[ESI+560F4]
004557E6 61 POPAD - --恢复现场
004557E7 ^ E9 58D6FEFF JMP CrackMe2.00442E44 ---跳到入口点00442E44
004557EC 04 58 ADD AL,58
004557EE 45 INC EBP
004557EF 001458 ADD BYTE PTR DS:[EAX+EBX*2],DL
004557F2 45 INC EBP
004557F3 00D0 ADD AL,DL
在00442E44这个地方DUMP之后,用ImportREC 对脱过壳的软件修复之后就可以运行。
其实对大部分压缩壳都是可以采用ESP定律搞点,对与这个壳,可以在单步跟踪到00455691也就是入口的下一行,在观察ESP寄存器的值,此时为0012FFA4,然后在命令筐里面下DD 0012FFA4这个命令,就可以看到0012FFA4早数据窗口中内容,在数据窗口点右键下硬件访问WORD断点,然后运行,便可直接来到004557E7这个地方,他将直接跳到程序的OEP,ESP定律使用的原理当然就是著名的“堆栈平衡”原理,具体的看雪的网站上有.
四)用IDA反汇编脱过壳的CRACKME_2,运行这个CRACKME任意输入几个数字后发现有错误提示--you are a bad cracker!
五)查找这个错误提示,来到如下代码:
---------------------------------------------------------------------------------------------------------------------------
UPX1:00442B2C push ebp ---程序入口,初始化堆栈
UPX1:00442B2D mov ebp, esp
UPX1:00442B2F push 0
UPX1:00442B31 push ebx
UPX1:00442B32 mov ebx, eax
UPX1:00442B34 xor eax, eax ---EAX清0
UPX1:00442B36 push ebp
UPX1:00442B37 push offset loc_442BD5
UPX1:00442B3C push dword ptr fs:[eax]
UPX1:00442B3F mov fs:[eax], esp
UPX1:00442B42 lea edx, [ebp-4]
UPX1:00442B45 mov eax, [ebx+2C4h]
UPX1:00442B4B call sub_4227BC ---返回我们输入的序列号的位数
UPX1:00442B50 mov eax, [ebp-4] ---保存我们输入的序列号
UPX1:00442B53 mov edx, offset a12011982 ; "12011982" ---这个字符串存入EDX中,也许他就是序列号哦
UPX1:00442B58 call sub_403B44 ---算法的核心,一定要跟进去
UPX1:00442B5D jnz short loc_442B79 ---结果不为0就跳向错误
UPX1:00442B5F push 0
UPX1:00442B61 mov ecx, offset aTrialCrackmeCr ; "Trial CrackMe Cracked!"
UPX1:00442B66 mov edx, offset aCongratsYouWer ; "Congrats! You were successful!" ---注册成功的提示
UPX1:00442B6B mov eax, ds:off_443C54
UPX1:00442B70 mov eax, [eax]
UPX1:00442B72 call sub_43EA04 ---调用此函数将告诉我们注册成功
UPX1:00442B77 jmp short loc_442BBF
UPX1:00442B79 ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
UPX1:00442B79
UPX1:00442B79 loc_442B79: ; CODE XREF: UPX1:00442B5Dj
UPX1:00442B79 lea edx, [ebp-4]
UPX1:00442B7C mov eax, [ebx+2C4h]
UPX1:00442B82 call sub_4227BC ---调用此函数返回我们输入的序列号的位数
UPX1:00442B87 cmp dword ptr [ebp-4], 0 ---EBP-4这个局部变量保存仍然是我们输入的序列号
UPX1:00442B8B jnz short loc_442BA7 ---EBP-4不为0就跳,如果为0说明我们没有输入序列号
UPX1:00442B8D push 0
UPX1:00442B8F mov ecx, offset aNothingEntered ; "Nothing entered"
UPX1:00442B94 mov edx, offset aYouHaveToEnter ; "You have to enter a serial" ---没有输入序列号的提示
UPX1:00442B99 mov eax, ds:off_443C54
UPX1:00442B9E mov eax, [eax]
UPX1:00442BA0 call sub_43EA04 ---调用此函数将告诉我们你必须输入内容
UPX1:00442BA5 jmp short loc_442BBF
UPX1:00442BA7 ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
UPX1:00442BA7
UPX1:00442BA7 loc_442BA7: ; CODE XREF: UPX1:00442B8Bj
UPX1:00442BA7 push 0
UPX1:00442BA9 mov ecx, offset aWrongSerial ; "Wrong Serial"
UPX1:00442BAE mov edx, offset aYouAreABadCrac ; "You are a bad cracker!" ---注册错误的提示
UPX1:00442BB3 mov eax, ds:off_443C54
UPX1:00442BB8 mov eax, [eax]
UPX1:00442BBA call sub_43EA04 ---调用此函数将告诉我们注册失败
UPX1:00442BBF
UPX1:00442BBF loc_442BBF: ; CODE XREF: UPX1:00442B77j
UPX1:00442BBF ; UPX1:00442BA5j
UPX1:00442BBF xor eax, eax ---EAX清0
UPX1:00442BC1 pop edx
UPX1:00442BC2 pop ecx
UPX1:00442BC3 pop ecx ---释放堆栈
UPX1:00442BC4 mov fs:[eax], edx
UPX1:00442BC7 push offset loc_442BDC
UPX1:00442BCC
UPX1:00442BCC loc_442BCC: ; CODE XREF: UPX1:00442BDAj
UPX1:00442BCC lea eax, [ebp-4]
UPX1:00442BCF call sub_4037B8
UPX1:00442BD4 retn ---返回
UPX1:00442BD5 ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
UPX1:00442BD5
UPX1:00442BD5 loc_442BD5: ; DATA XREF: UPX1:00442B37o
UPX1:00442BD5 jmp loc_403278
UPX1:00442BDA ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
UPX1:00442BDA jmp short loc_442BCC
UPX1:00442BDC ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
UPX1:00442BDC
UPX1:00442BDC loc_442BDC: ; DATA XREF: UPX1:00442BC7o
UPX1:00442BDC pop ebx
UPX1:00442BDD pop ecx
UPX1:00442BDE pop ebp
UPX1:00442BDF retn
好了现在我们跟进(00442B58 call sub_403B44)这个CALL,看下是怎么判断的,代码如下
---------------------------------------------------------------------------------------------------------
00403B44 53 PUSH EBX
00403B45 56 PUSH ESI
00403B46 57 PUSH EDI
00403B47 89C6 MOV ESI,EAX ---EAX中保存的是我们输入的错误序列号假设为123456
00403B49 89D7 MOV EDI,EDX ---EDX中保存的是12011982这个字符串
00403B4B 39D0 CMP EAX,EDX ---两个字符串进行比较
00403B4D 0F84 8F000000 JE crackme_.00403BE2 ---相等就跳到00403BE2,来到 00403BE2 看下代码
00403B53 85F6 TEST ESI,ESI ---以下就是如果两个字符串不等的时候执行的代码
00403B55 74 68 JE SHORT crackme_.00403BBF
00403B57 85FF TEST EDI,EDI
00403B59 74 6B JE SHORT crackme_.00403BC6
00403B5B 8B46 FC MOV EAX,DWORD PTR DS:[ESI-4] ---序列号的长度送入EAX中
00403B5E 8B57 FC MOV EDX,DWORD PTR DS:[EDI-4] ---字符串的长度送入EAX中
00403B61 29D0 SUB EAX,EDX ---两个长度想减
00403B63 77 02 JA SHORT crackme_.00403B67 --->就跳
00403B65 01C2 ADD EDX,EAX ---两个长度想加
00403B67 52 PUSH EDX ---字符串入栈
00403B68 C1EA 02 SHR EDX,2 ---EDX/(2的平方)
00403B6B 74 26 JE SHORT crackme_.00403B93 ---为0就跳
00403B6D 8B0E MOV ECX,DWORD PTR DS:[ESI] ---序列号送入ECX
00403B6F 8B1F MOV EBX,DWORD PTR DS:[EDI] ---12011982送入EBX
00403B71 39D9 CMP ECX,EBX ---再次对他们进行比较
00403B73 75 58 JNZ SHORT crackme_.00403BCD ---不等就跳
00403B75 4A DEC EDX ---EDX-1
00403B76 74 15 JE SHORT crackme_.00403B8D ---为0就跳
00403B78 8B4E 04 MOV ECX,DWORD PTR DS:[ESI+4]
00403B7B 8B5F 04 MOV EBX,DWORD PTR DS:[EDI+4]
00403B7E 39D9 CMP ECX,EBX ---再次对两个字符串比较
00403B80 75 4B JNZ SHORT crackme_.00403BCD ---很显然看00403BCD的代码后发现,如果两个字符串不相等,那么EAX的值就始终不能为0了
00403B82 83C6 08 ADD ESI,8 ---序列号+8
00403B85 83C7 08 ADD EDI,8 ---12011982+8
00403B88 4A DEC EDX ---EDX―1后必须为0 ,EDX保存的是输入是序列号的位数,基本上可以估算出序列号是8位
00403B89 ^ 75 E2 JNZ SHORT crackme_.00403B6D ---如果EDX不为0就向回跳很明显会失败
00403B8B EB 06 JMP SHORT crackme_.00403B93 ---EDX为0就跳到了00403B93
00403B8D 83C6 04 ADD ESI,4
00403B90 83C7 04 ADD EDI,4
00403B93 5A POP EDX ---EDX出栈
00403B94 83E2 03 AND EDX,3 ---EDX 和3 做AND 运算
00403B97 74 22 JE SHORT crackme_.00403BBB ---为0就跳
00403B99 8B0E MOV ECX,DWORD PTR DS:[ESI]
00403B9B 8B1F MOV EBX,DWORD PTR DS:[EDI]
00403B9D 38D9 CMP CL,BL
00403B9F 75 41 JNZ SHORT crackme_.00403BE2
00403BA1 4A DEC EDX
00403BA2 74 17 JE SHORT crackme_.00403BBB
00403BA4 38FD CMP CH,BH
00403BA6 75 3A JNZ SHORT crackme_.00403BE2
00403BA8 4A DEC EDX
00403BA9 74 10 JE SHORT crackme_.00403BBB
00403BAB 81E3 0000FF00 AND EBX,0FF0000
00403BB1 81E1 0000FF00 AND ECX,0FF0000
00403BB7 39D9 CMP ECX,EBX
00403BB9 75 27 JNZ SHORT crackme_.00403BE2
00403BBB 01C0 ADD EAX,EAX ---EAX是两个序列号的长度差,他们做AND运算,这里的EAX的值将是这个函数最终结果值
00403BBD EB 23 JMP SHORT crackme_.00403BE2 ---跳向 00403BE2
00403BBF 8B57 FC MOV EDX,DWORD PTR DS:[EDI-4]
00403BC2 29D0 SUB EAX,EDX
00403BC4 EB 1C JMP SHORT crackme_.00403BE2
00403BC6 8B46 FC MOV EAX,DWORD PTR DS:[ESI-4]
00403BC9 29D0 SUB EAX,EDX
00403BCB EB 15 JMP SHORT crackme_.00403BE2
00403BCD 5A POP EDX
00403BCE 38D9 CMP CL,BL
00403BD0 75 10 JNZ SHORT crackme_.00403BE2
00403BD2 38FD CMP CH,BH
00403BD4 75 0C JNZ SHORT crackme_.00403BE2
00403BD6 C1E9 10 SHR ECX,10
00403BD9 C1EB 10 SHR EBX,10
00403BDC 38D9 CMP CL,BL
00403BDE 75 02 JNZ SHORT crackme_.00403BE2 ---以上都是对我们输入的序列号和 12011982这个字符串进行的一系列的运算
00403BE0 38FD CMP CH,BH
00403BE2 5F POP EDI ---EDI中的内容出栈
00403BE3 5E POP ESI ---ESI中的内容出栈
00403BE4 5B POP EBX ---EBX中的内容出栈
00403BE5 C3 RETN ---返回到00442B5D处,从此处向下运行就跳向注册成功,因为此函数的返回值放在EAX中为0符合条件
---------------------------------------------------------------------------------------------------------------------
经过上面的分析,其实序列号就是12011982,的确比较简单,主要是对他的代码做一些简单的分析,说了很多的废话,送给刚入门的,连连手.
好了,我要去休息了,下周再见吧!88
fradfire
2006.3.15
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)