能力值:
( LV2,RANK:10 )
2 楼
NO1: 作者:RoBa
教菜鸟写注册机
目标程序下载地址:
http://opencrackmes.crackmes.de/opencrackmes/Collections/keygenning4newbies/Crackmes/k4n.zip
到一些黑客站点上转转,发现那些最受欢迎、点击次数最多的文章都是一些“教菜鸟使用木马”“入侵初级教程”之类文章,而“Outlook Express HTML邮件超长字节href值缓冲溢出缺陷”“PHP fopen()函数易遭到CRLF Injection攻击”这种文章却乏人问津,尽管这或许才是真正高手所关心的。
现在看雪论坛上后一种文章逐渐增多,当然是因为大家的水平都提高了,但也给刚入门的菜鸟带来了麻烦,来了之后什么也看不懂,在高手看来不是问题的问题常常困扰新手们很长时间:为什么这里是关键跳转,那边是重要CALL?为什么有的CALL要跟进,有的CALL只需带过?我按照高手所写的一步步做下去成功了,可为什么要这样做呢?我想更有不少人好不容易破了一个明码比较的软件,想贴出来又怕为高手所不屑而做罢。
因此我找了一个非常简单的CrackMe(如果你是高手,只静态调试应该就可以搞定了:)),从头到尾仔仔细细地写出了分析过程,在里面加入了些我认为应该注意的地方,希望能对刚入门的朋友有些帮助。我不是什么高手,最多算是破解得熟练一点儿了而已,也许这样才更能了解新手们的难处吧。
这里我用W32Dasm作为静态反汇编的工具,各位可能有用C32Asm或者其他的,基本功能其实应该差不多。
先胡乱输入用户名和注册码,点"Check the Serial",看看错误信息是什么(如果出现“注册码正确”的话就别在这儿看了,赶紧买彩票去:D)好出来了,“This serial is *NOT* Valid!! Try again... : UNREGISTERED”。
好了运行W32Dasm把它反汇编,在串式参考(string reference)中找吧,注意当字串较长时有时不能完全显示,这时只要找前面一段就行了,比如这次就是,找到"This serial is *NOT* Valid!! Try ",就是它了,双击来到引用该字串的地方。(PS:有时错误信息在代码中会不止一次出现,这时只要多次双击就能找到其他的地方。)
下面我要引用代码了(这是在W32DASM里的形式,如果你用OD或SI动态跟踪时形式会略有不同)。不要被这么多代码搞晕了,建议先跳过代码看我的后面的说明,再从代码中对照。
代码:--------------------------------------------------------------------------------
* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0066, ""
|
:00401085 6A66 push 00000066 ;输入用户名的文本框ID
:00401087 53 push ebx ;对话框句柄
* Reference To: USER32.GetDlgItem, Ord:0000h
|
:00401088 E8159C0000 Call 0040ACA2 ;得到文本框句柄
:0040108D 6A64 push 00000064 ;得到字符串的最大长度
:0040108F 8D9548FFFFFF lea edx, dword ptr [ebp+FFFFFF48]
:00401095 52 push edx ;EDX是存取字符串的地址
:00401096 50 push eax ;EAX是上面得到的文本框句柄
* Reference To: USER32.GetWindowTextA, Ord:0000h
|
:00401097 E8129C0000 Call 0040ACAE ;得到用户名,在[ebp+FFFFFF48]
* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0068, ""
|
:0040109C 6A68 push 00000068 ;同样的操作,输入注册码的文本框ID
:0040109E 53 push ebx
* Reference To: USER32.GetDlgItem, Ord:0000h
|
:0040109F E8FE9B0000 Call 0040ACA2
:004010A4 6A64 push 00000064
:004010A6 8D8DE4FEFFFF lea ecx, dword ptr [ebp+FFFFFEE4]
:004010AC 51 push ecx
:004010AD 50 push eax
* Reference To: USER32.GetWindowTextA, Ord:0000h
|
:004010AE E8FB9B0000 Call 0040ACAE ;得到注册码,在[ebp+FFFFFEE4]
* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0067, ""
|
:004010B3 6A67 push 00000067 ;这个是最下面的提示的文本框的ID
:004010B5 53 push ebx
7
* Reference To: USER32.GetDlgItem, Ord:0000h
|
:004010B6 E8E79B0000 Call 0040ACA2 ;得到句柄
:004010BB 8BF0 mov esi, eax ;放在ESI备用
:004010BD 8D8548FFFFFF lea eax, dword ptr [ebp+FFFFFF48]
:004010C3 50 push eax ;指向用户名
:004010C4 E867050000 call 00401630 ;得到用户名长度
:004010C9 59 pop ecx
:004010CA 8945D8 mov dword ptr [ebp-28], eax ;长度放在[ebp-28]
:004010CD 8D95E4FEFFFF lea edx, dword ptr [ebp+FFFFFEE4]
:004010D3 52 push edx ;指向注册码
:004010D4 E857050000 call 00401630 ;得到注册码长度
:004010D9 59 pop ecx
:004010DA 68EAB04000 push 0040B0EA
:004010DF E84C050000 call 00401630
:004010E4 59 pop ecx
:004010E5 680EB14000 push 0040B10E
:004010EA E841050000 call 00401630
:004010EF 59 pop ecx
:004010F0 837DD803 cmp dword ptr [ebp-28], 00000003
:004010F4 7E7B jle 00401171 ;用户名长度不能小于等于3
:004010F6 90 nop
:004010F7 90 nop
:004010F8 90 nop
:004010F9 90 nop
:004010FA 33C9 xor ecx, ecx
:004010FC 33D2 xor edx, edx
:004010FE 33DB xor ebx, ebx
:00401100 33C0 xor eax, eax
:00401102 837DD832 cmp dword ptr [ebp-28], 00000032
:00401106 7D69 jge 00401171 ;用户名长度不能大于等于32h
:00401108 90 nop
:00401109 90 nop
:0040110A 90 nop
:0040110B 90 nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040111C(C)
|
:0040110C 0FBE840D48FFFFFF movsx eax, byte ptr [ebp+ecx-000000B8];依次取用户名的字符
:00401114 41 inc ecx ;ECX为循环变量
:00401115 33C1 xor eax, ecx ;取的字符与循环变量XOR
:00401117 03D8 add ebx, eax ;把结果累加到EBX
:00401119 3B4DD8 cmp ecx, dword ptr [ebp-28] ;循环变量与用户名长度相比
:0040111C 75EE jne 0040110C ;如果未取完就跳回继续
:0040111E 6BC006 imul eax, 00000006 ;最后一轮计算的结果在EAX, 乘6
:00401121 C1E307 shl ebx, 07 ;前面累加结果左移7位
:00401124 03C3 add eax, ebx ;相加
:00401126 8945C8 mov dword ptr [ebp-38], eax
:00401129 FF75C8 push [ebp-38] ;把上面结果压栈
* Possible StringData Ref from Data Obj ->"%lX"
|
:0040112C 6838B44000 push 0040B438 ;一个转换的标识
:00401131 8D8D80FEFFFF lea ecx, dword ptr [ebp+FFFFFE80]
:00401137 51 push ecx ;存放转换结果的地址
:00401138 E8873D0000 call 00404EC4 ;数字转为十六进制字串
:0040113D 83C40C add esp, 0000000C
:00401140 8D8580FEFFFF lea eax, dword ptr [ebp+FFFFFE80]
:00401146 50 push eax ;上面转换的字串
:00401147 8D95E4FEFFFF lea edx, dword ptr [ebp+FFFFFEE4]
:0040114D 52 push edx ;假注册码
* Reference To: KERNEL32.lstrcmpA, Ord:0000h
|
:0040114E E8339C0000 Call 0040AD86 ;比较
:00401153 85C0 test eax, eax
:00401155 750D jne 00401164 ;这里就是关键的跳转
* Possible StringData Ref from Data Obj ->"Congratulations! IF this number "
->"comes *FROM YOUR* keygen, Write "
->"a tutorial dude ;)."
|
:00401157 683CB44000 push 0040B43C ;指向表示成功的字符串
:0040115C 56 push esi ;ESI还记得么?那个提示文本框的句柄
* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0040115D E8289B0000 Call 0040AC8A ;显示出来
:00401162 EB18 jmp 0040117C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401155(C)
|
* Possible StringData Ref from Data Obj ->"This serial is *NOT* Valid!! Try "
->"again... : UNREGISTERED"
|
:00401164 6890B44000 push 0040B490 ;开始时停在这句,向上找跳转
:00401169 56 push esi ;ESI提示文本框的句柄
* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0040116A E81B9B0000 Call 0040AC8A
:0040116F EB0B jmp 0040117C
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004010F4(C), :00401106(C)
|
* Possible StringData Ref from Data Obj ->"Name must contain more than 4 "
->"chars and less than 50 chars !!"
|
:00401171 68C9B44000 push 0040B4C9 ;用户名不符合要求跳到这里
:00401176 56 push esi ;ESI提示文本框的句柄
* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:00401177 E80E9B0000 Call 0040AC8A
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401162(U), :0040116F(U)
|
:0040117C 5F pop edi
:0040117D 5E pop esi
:0040117E 5B pop ebx
:0040117F 8BE5 mov esp, ebp
:00401181 5D pop ebp ;整理一下返回了
:00401182 C3 ret
--------------------------------------------------------------------------------
双击后光标停在401164这一句。很明显,如果我们来到这句时我们就死翘翘了,而如果我们的注册码正确的话当然不会来到这一句(废话太多了:p)那么这一句上面就肯定会有一个条件跳转的指令。(这是找爆破点时的基本思想)向上找找看,找到了:
:00401155 750D jne 00401164
正好跳到401164错误信息那一句。呵呵,如果你想爆破的话,只要把750D改成740D(je,把条件反过来,注册码错误就显示正确信息:D)或者改成EB0D(jmp,无条件跳转,不管三七二十一就正确)。
OK,我们不能满足于此啊,咱们看看它的算法是怎样的,也像那些神秘兮兮的高手似的写一个注册机出来。:D
我先给各位补一点课,就是对函数的调用。除了一些DELPHI程序之外,对函数参数的传递大都用堆栈来完成,简单地说就是把函数的各个参数先PUSH进去,然后再CALL这个函数。在函数内部呢,一般[ebp+8]是第一个参数,[ebp+C]是第二个参数,每次多加4依此类推。而函数内部的局部变量常用[ebp-4][ebp-8]...等等。(原因讲起来有点复杂,先记住就行了)函数的返回值在EAX里。
一般来说,软件的判断注册部分都是一个函数,在函数开头最经典的两句就是
push ebp
mov ebp,esp
这和堆栈处理有关,我们菜鸟先不用太明白,知道这通常是一个函数的开始就行了。向上找找有没有丫,找到了没有,在最上面哪(我上面没有列出来)。如果你想完整地判断它的算法的话,一般从这里开始就行了。在这个程序中前面都是一些初始化之类的东东,所以我把前面一部分省略了。(这也是破解时的原则,不要在无关紧要的地方费功夫,在高级语言中,代码有很大部分是机器自动生成的,电脑一行行写代码不知道累,人脑一行行读代码怎么受得了?你的脑袋是几GHz的CPU?常见有些没有破解经验的汇编高手,完全懂得每行代码的意思,就是找不到关键的地方,原来他跟了半天都是在API里转,白做无用功了。)
好了,现在可以动态调试了。我们在开头这里下个断点,一步步向下看,出现了一个CALL GetDlgItem,我们来看一看函数说明(手头一份这个是必需的)
HWND GetDlgItem(
HWND hDlg, // handle of dialog box
int nIDDlgItem // identifier of control
);
呵呵,简单的说这个函数就是让程序确定一个对话框上的控件,第一个参数是对话框的句柄,第二个参数是对话框上某个控件的ID,函数会返回该控件的句柄,这样在下面就可以用这个句柄来操作了。看程序:
代码:--------------------------------------------------------------------------------
* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0066, ""
|
:00401085 6A66 push 00000066 ;控件ID
:00401087 53 push ebx ;对话框句柄
* Reference To: USER32.GetDlgItem, Ord:0000h
|
:00401088 E8159C0000 Call 0040ACA2
--------------------------------------------------------------------------------
看见第一行没有,DialogID_0001,CONTROL_ID:0066,压进去了一个66作为第二个参数:控件ID(注意API调用是从右至左,也就是最后面一个参数先PUSH),用 资源查看工具 看看ID为66的是甚么呀,呵呵就是那个输入用户名的文本框嘛。好了,现在我们有文本框的句柄了,存在EAX里。接着向下看,又一个API,是GetWindowText。看看说明:
int GetWindowText(
HWND hWnd, // handle of window or control with text
LPTSTR lpString, // address of buffer for text
int nMaxCount // maximum number of characters to copy
);
从名字也能猜出来了,这个函数就是得到一个窗口类控件的文本。第一个参数是该控件的句柄,第二个是存放得到的文本的缓冲区的地址,第三个参数设定取文本的最大长度。看程序:
代码:--------------------------------------------------------------------------------
:0040108D 6A64 push 00000064 ;最大长度
:0040108F 8D9548FFFFFF lea edx, dword ptr [ebp+FFFFFF48];把[ebp+FFFFFF48]先放在EDX里
:00401095 52 push edx ;缓冲区地址[ebp+FFFFFF48]
:00401096 50 push eax ;EAX?是上面那个API的返回值呀,控件句柄
* Reference To: USER32.GetWindowTextA, Ord:0000h
|
:00401097 E8129C0000 Call 0040ACAE
--------------------------------------------------------------------------------
好了,现在 D ebp+FFFFFF48 看看,是不是输入的用户名?(说明,在OLLY或SICE里这个是[ebp-B8]的形式,其实是一样的)
下面有类似的操作,只是控件ID成了68,可想而知就是得到注册码了,注册码放在[ebp+FFFFFEE4]。
呵呵,继续,到了这么几句:
代码:--------------------------------------------------------------------------------
:004010BD 8D8548FFFFFF lea eax, dword ptr [ebp+FFFFFF48]
:004010C3 50 push eax
:004010C4 E867050000 call 00401630
--------------------------------------------------------------------------------
这是干甚么牙?要不要进4010C4这个CALL 401630看看?且慢!我前面说过了,不要在无关紧要的地方费力,(啪!一个鸡蛋扔上来:谁知道这里是不是重要啊?)别急嘛,一般来说,先粗略地跟一遍,试着猜猜CALL的作用。如果发现返回值很可疑,再跟进细看也不迟。(这就需要一定的“直觉”了,英文叫“Sence”,台湾老大叫“触机”或者“先死:D”,别担心,破解得多了自然会有这种感觉,这种感觉很难说出来,有时候一见那种阵势就知道关键地方到了)
又扯远了,我们回来看代码。一个CALL,前面有PUSH EAX,很明显是CALL的参数了。(见我前面的说明)看看EAX:lea eax,dword ptr [ebp+FFFFFF48]。[ebp+FFFFFF48]还有没有印象?对了,就是前面API调用中放用户名的地址呀。过了这里后D eax,呵呵不就是咱们的用户名吗,我输入的是“RoBa”,带过这个CALL后看看EAX是什么,嗯~~~~是4。想到什么了?没有?没关系咱们继续看下面:
代码:--------------------------------------------------------------------------------
:004010C9 59 pop ecx
:004010CA 8945D8 mov dword ptr [ebp-28], eax ;记住,上面的返回结果在[ebp-28]
:004010CD 8D95E4FEFFFF lea edx, dword ptr [ebp+FFFFFEE4]
:004010D3 52 push edx
:004010D4 E857050000 call 00401630
--------------------------------------------------------------------------------
又是一个CALL 401630,和上面一样的。看看它的参数EDX,[ebp+FFFFFEE4]呵就是假注册码呀,我输的是'87654321',返回值EAX=8,发现什么没有?对,这个CALL就是求一个字符串的长度嘛,要是跟进去又给费不少时间。向下:
代码:--------------------------------------------------------------------------------
:004010F0 837DD803 cmp dword ptr [ebp-28], 00000003
:004010F4 7E7B jle 00401171
:00401102 837DD832 cmp dword ptr [ebp-28], 00000032
:00401106 7D69 jge 00401171
--------------------------------------------------------------------------------
还记得[ebp-28]是什么吗?对,就是用户名的长度,这几句的意思就很明显了,用户名的长度必须大于3小于32h,不然就跳到401171去了,你可以跟过去看看是什么,呵呵是用户名不符合要求之类的提示。
好了我们来到关键地方喽:
代码:--------------------------------------------------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040111C(C)
|
:0040110C 0FBE840D48FFFFFF movsx eax, byte ptr [ebp+ecx-000000B8]
:00401114 41 inc ecx
:00401115 33C1 xor eax, ecx
:00401117 03D8 add ebx, eax
:00401119 3B4DD8 cmp ecx, dword ptr [ebp-28]
:0040111C 75EE jne 0040110C
--------------------------------------------------------------------------------
呵呵,是不是又晕了?[ebp+ecx-B8]这是啥呀?别着急,车到山前必有路。先 d ebp+ecx-B8看看,哟,不还是咱们的用户名吗?:D 怎么回事?好好想想,ecx现在是0,[ebp-B8]和[ebp+FFFFFF48](记得不?放用户名的地址)不是一回事嘛!(不明白的去补习一下负数的表示方法,我也不知道为什么W32DASM有时候非把-B8写成FFFFFF48)
再仔细看看,movsx eax,byte ptr [ebp+ecx-000000B8],注意是byte ptr,即以字节的方式读取(就是说每次读出一个字符),而且又加上了个ecx。如果你破解多了的话,应该立刻就明白:关键的地方到了。
这是一个很典型的循环结构,看出来没?ecx就是循环变量了,每执行一次会从用户名中取一个字符,然后ecx加1,这样[ebp+ecx-B8]就指向用户名的下一个字符了。对取出来的字符与循环变量进行XOR运算,把结果累加到EBX。然后循环变量与[ebp-28]也就是用户名长度比较,如果不等于的话也就是还没取完,就返回上去继续取用户名的下一个字符。这样直到取完为止。
代码:--------------------------------------------------------------------------------
:0040111E 6BC006 imul eax, 00000006 ;EAX其实是上面最后一轮计算的结果,乘6
:00401121 C1E307 shl ebx, 07 ;EBX是几轮计算累加起来的结果,左移7位
:00401124 03C3 add eax, ebx ;加起来
:00401126 8945C8 mov dword ptr [ebp-38], eax
:00401129 FF75C8 push [ebp-38] ;上面的结果,作为一个参数
* Possible StringData Ref from Data Obj ->"%lX"
|
:0040112C 6838B44000 push 0040B438 ;"%lX"有点眼熟哟
:00401131 8D8D80FEFFFF lea ecx, dword ptr [ebp+FFFFFE80]
:00401137 51 push ecx ;这是什么呢?
:00401138 E8873D0000 call 00404EC4
:0040113D 83C40C add esp, 0000000C
--------------------------------------------------------------------------------
前面几句是继续上面的计算,把EAX*6和EBX左移7位的值加进来,然后结果复制到[ebp-38]这个局部变量里作为下面CALL的一个参数,接着[ebp+FFFFFE80]作第二个参数,然后又一个CALL,还是那样,先别着急跟进去,前后看看有没有可疑之处:
第一个参数[ebp-38],没什么好说的,上面计算的结果。第二个参数指向"%lX",这个字串写过C语言的都有印象吧,就是在printf里把一个数字按照大写的16进制方式显示出来所用的标识符,比方说把一个数字255转换成字串“FF”。(在WinAPI里叫wsprintf)第三个参数是什么呢?前面这种形式见多了吧,猜猜!
我们验证一下前面猜想是否正确,我用"RoBa"上面算出来的结果是46430,也就是16进制的B55E,我们跟过这个CALL看看结果如何?什么,结果在哪?聪明的你还没想到吗,上面那第三个参数[ebp+FFFFFE80]就是结果的地址呀。怎么样不出所料吧。
(其实从40113D这一句add esp,C也能看出来,因为在函数外平衡堆栈的只有这个一个参数数目不定的函数。引申一下,看不懂没关系啦:D )
接着看啦:
代码:--------------------------------------------------------------------------------
:00401140 8D8580FEFFFF lea eax, dword ptr [ebp+FFFFFE80];眼熟吗,刚才的转换结果呀
:00401146 50 push eax ;EAX指向上面转换得到的字符串
:00401147 8D95E4FEFFFF lea edx, dword ptr [ebp+FFFFFEE4];这个很早了,向前面找找是啥
:0040114D 52 push edx ;EDX指向我们输入的假注册码
* Reference To: KERNEL32.lstrcmpA, Ord:0000h
|
:0040114E E8339C0000 Call 0040AD86
:00401153 85C0 test eax, eax
:00401155 750D jne 00401164 ;关键跳转哟
--------------------------------------------------------------------------------
哈哈,lstrcmp,什么意思不用我说了吧,当然是STRingCoMPare字符串比较啦。把计算的结果与前面输入的假码比较,相等就OK了。好了,现在把上面的完整的代码过一遍,怎么样,写个注册机不难吧?
代码:--------------------------------------------------------------------------------
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
int EAX=0,EBX=0,len;
char name[50]={0};
char password[50]={0};
printf("Please input your name:");
scanf("%s",name);
len=strlen(name);
for (int i=0;i<len;i++)
{
EAX=name[i]^(i+1);
EBX+=EAX;
}
EAX*=6;
EBX<<=7;
EAX+=EBX;
printf("Your password is: %lX\n",EAX);
printf("KeyGen by RoBa Enjoy Cracking,Newbies!\n");
}
--------------------------------------------------------------------------------
简单的C程序哟,你也可以用你熟悉的语言写一个。
后记:
这是一个简单的CRACKME,本来三言两语就能解决的,被我??嗦嗦说了这么一大堆,就是希望能把问题真正地说明白了,希望通过这篇文章让你发现,破解软件乃至写注册机并不是多么困难的事,只要坚持下去,谁都有成为高手的那一天,也希望高手们能够抽时间发一些适合较低水平的文章或者至少对发这种文章的新手多多鼓励。Enjoy Cracking,Newbies!
能力值:
( LV2,RANK:10 )
3 楼
NO2: 作者:RoBa
教菜鸟写注册机――中级篇
上次那篇破文(不是破解文章,是破烂文章)丢了,我补在这贴的后面。这次说是中级,其实只难了一点点而已,cmp You,高手 jz offset NextPage。
好了,再来一篇。还是那个系列的,下载地址:
http://opencrackmes.crackmes.de/opencrackmes/Collections/keygenning4newbies/Crackmes/k4n2.zip
运行一下,呵呵,外观一模一样。反汇编,前面的部分几乎完全一样,GetDlgItem,GetWindowText,我都不写了,直接看下面,注意[ebp-2C]是用户名的长度。(可以先跳过去看后面的说明。)
代码:--------------------------------------------------------------------------------
:004010ED 837DD403 cmp dword ptr [ebp-2C], 00000003
:004010F1 0F8E38010000 jle 0040122F ;用户名必须大于3位
:004010F7 33D2 xor edx, edx
:004010F9 33DB xor ebx, ebx
:004010FB 8B55D4 mov edx, dword ptr [ebp-2C]
:004010FE 0155C4 add dword ptr [ebp-3C], edx
:00401101 0155C4 add dword ptr [ebp-3C], edx ;算出[EBP-3C]
:00401104 8BC2 mov eax, edx
:00401106 83C005 add eax, 00000005
:00401109 8945B8 mov dword ptr [ebp-48], eax ;算出[EBP-48]
:0040110C 33C0 xor eax, eax
:0040110E 8BCF mov ecx, edi
:00401110 83C104 add ecx, 00000004
:00401113 894DB4 mov dword ptr [ebp-4C], ecx ;算出[EBP-4C]
:00401116 33C9 xor ecx, ecx
:00401118 0155BC add dword ptr [ebp-44], edx
:0040111B 017DBC add dword ptr [ebp-44], edi ;算出[EBP-44]
:0040111E 6BFF03 imul edi, 00000003
:00401121 897DC0 mov dword ptr [ebp-40], edi ;算出[EBP-40]
:00401124 33FF xor edi, edi
:00401126 0FBE8C0544FFFFFF movsx ecx, byte ptr [ebp+eax-000000BC]
:0040112E 83F961 cmp ecx, 00000061
:00401131 7C07 jl 0040113A
:00401133 90 nop
:00401134 90 nop
:00401135 90 nop
:00401136 90 nop
:00401137 83E920 sub ecx, 00000020
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401131(C)
|
:0040113A 8BF1 mov esi, ecx
:0040113C 03DE add ebx, esi
:0040113E 0FAFD9 imul ebx, ecx
:00401141 4A dec edx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401178(C)
|
:00401142 0FBE8C2F44FFFFFF movsx ecx, byte ptr [edi+ebp-000000BC]
:0040114A 0FBEB42F45FFFFFF movsx esi, byte ptr [edi+ebp-000000BB]
:00401152 83F961 cmp ecx, 00000061
:00401155 7D12 jge 00401169
:00401157 90 nop
:00401158 90 nop
:00401159 90 nop
:0040115A 90 nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040116C(U)
|
:0040115B 83FE61 cmp esi, 00000061
:0040115E 7D0E jge 0040116E
:00401160 90 nop
:00401161 90 nop
:00401162 90 nop
:00401163 90 nop
:00401164 EB0B jmp 00401171
:00401166 90 nop
:00401167 90 nop
:00401168 90 nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401155(C)
|
:00401169 83E920 sub ecx, 00000020
:0040116C EBED jmp 0040115B
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040115E(C)
|
:0040116E 83EE20 sub esi, 00000020
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401164(U)
|
:00401171 47 inc edi
:00401172 03DE add ebx, esi
:00401174 0FAFD9 imul ebx, ecx
:00401177 4A dec edx
:00401178 75C8 jne 00401142
:0040117A 895DC8 mov dword ptr [ebp-38], ebx ;算出[EBP-38]
:0040117D 33C9 xor ecx, ecx
:0040117F 33D2 xor edx, edx
:00401181 33DB xor ebx, ebx
:00401183 33C0 xor eax, eax
:00401185 837DD432 cmp dword ptr [ebp-2C], 00000032
:00401189 0F8DA0000000 jnl 0040122F
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040119F(C)
|
:0040118F 0FBE840D44FFFFFF movsx eax, byte ptr [ebp+ecx-000000BC]
:00401197 03C1 add eax, ecx
:00401199 03D8 add ebx, eax
:0040119B 41 inc ecx
:0040119C 3B4DD4 cmp ecx, dword ptr [ebp-2C]
:0040119F 75EE jne 0040118F
:004011A1 D1C0 rol eax, 1
:004011A3 3540E20100 xor eax, 0001E240
:004011A8 8945B0 mov dword ptr [ebp-50], eax ;算出[EBP-50]
:004011AB 33C9 xor ecx, ecx
:004011AD 33D2 xor edx, edx
:004011AF 33DB xor ebx, ebx
:004011B1 33C0 xor eax, eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011C6(C)
|
:004011B3 0FBE840D44FFFFFF movsx eax, byte ptr [ebp+ecx-000000BC]
:004011BB 6BD006 imul edx, eax, 00000006
:004011BE 33C2 xor eax, edx
:004011C0 03D8 add ebx, eax
:004011C2 41 inc ecx
:004011C3 3B4DD4 cmp ecx, dword ptr [ebp-2C]
:004011C6 75EB jne 004011B3
:004011C8 035DB0 add ebx, dword ptr [ebp-50]
:004011CB 895DAC mov dword ptr [ebp-54], ebx ;算出[EBP-54]
:004011CE FF75C0 push [ebp-40]
:004011D1 FF75C4 push [ebp-3C]
:004011D4 FF75BC push [ebp-44]
:004011D7 FF75C8 push [ebp-38]
:004011DA FF75B4 push [ebp-4C]
:004011DD FF75B8 push [ebp-48]
:004011E0 FF75AC push [ebp-54]
:004011E3 FF75B0 push [ebp-50]
* Possible StringData Ref from Data Obj ->"%lX%lu-%lu%lX-%lu%lu-%lX%lX"
|
:004011E6 6838B44000 push 0040B438
:004011EB 8D857CFEFFFF lea eax, dword ptr [ebp+FFFFFE7C]
:004011F1 50 push eax
:004011F2 E88D3D0000 call 00404F84 ;wsprinf()
:004011F7 83C428 add esp, 00000028
:004011FA 8D957CFEFFFF lea edx, dword ptr [ebp+FFFFFE7C]
:00401200 52 push edx
:00401201 8D8DE0FEFFFF lea ecx, dword ptr [ebp+FFFFFEE0]
:00401207 51 push ecx
* Reference To: KERNEL32.lstrcmpA, Ord:0000h
|
:00401208 E8399C0000 Call 0040AE46 ;比较
:0040120D 85C0 test eax, eax
:0040120F 750F jne 00401220 ;关键跳转
--------------------------------------------------------------------------------
用我上篇文章介绍的方法找串式参考,然后向上找关键跳转。具体过程不说了,看看你是不是找的到。对了,就是40120F这个地方了。向上看看,有一个lstrcmp,上次已经说了,这个就是字符串比较。可以看到它的前面有两个PUSH作为比较的字符串,在这里下断点,看看两个字串是什么?D ecx,是我们输入的假注册码,D edx,是一个长长的字符串,当然就是真正的注册码啦。嗯,再向上看这个注册码是咋来的:
代码:--------------------------------------------------------------------------------
:004011CE FF75C0 push [ebp-40]
:004011D1 FF75C4 push [ebp-3C]
:004011D4 FF75BC push [ebp-44]
:004011D7 FF75C8 push [ebp-38]
:004011DA FF75B4 push [ebp-4C]
:004011DD FF75B8 push [ebp-48]
:004011E0 FF75AC push [ebp-54]
:004011E3 FF75B0 push [ebp-50]
* Possible StringData Ref from Data Obj ->"%lX%lu-%lu%lX-%lu%lu-%lX%lX"
|
:004011E6 6838B44000 push 0040B438
:004011EB 8D857CFEFFFF lea eax, dword ptr [ebp+FFFFFE7C]
:004011F1 50 push eax ;结果存在[ebp+FFFFFE7C]
:004011F2 E88D3D0000 call 00404F84 ;这个CALL其实是wsprinf
:004011F7 83C428 add esp, 00000028
--------------------------------------------------------------------------------
呵呵,一个"%lX%lu-%lu%lX-%lu%lu-%lX%lX"。还记得上次的例子吗,那回是一个"%lX",这回复杂了一些哟。别担心,还是很简单的。上次说了,"%lX"是十六进制的大写形式,那么"%lu"呢,就是普通的十进制形式啦。再看前面PUSH进了一堆参数,这些[ebp-xx]的形式都是函数里面的局部变量,在这里把它们以不同的形式表示出来再组合好,就是真正的注册码了。下一步的目标,当然就是看这8个变量是如何计算出的啦。记住这几个变量都是什么.从头看:
代码:--------------------------------------------------------------------------------
:004010FB 8B55D4 mov edx, dword ptr [ebp-2C] ;edx=[ebp-2C]是用户名的长度n
:004010FE 0155C4 add dword ptr [ebp-3C], edx ;[ebp-3C]可是一个重要变量,
:00401101 0155C4 add dword ptr [ebp-3C], edx ;[ebp-3C]=2n,看出来没有
:00401104 8BC2 mov eax, edx
:00401106 83C005 add eax, 00000005
:00401109 8945B8 mov dword ptr [ebp-48], eax ;[ebp-48]=n+5,也是一个重要变量
:0040110C 33C0 xor eax, eax
:0040110E 8BCF mov ecx, edi ;edi是一个常数64F4F0
:00401110 83C104 add ecx, 00000004
:00401113 894DB4 mov dword ptr [ebp-4C], ecx ;[ebp-4C]=64f4f4
:00401116 33C9 xor ecx, ecx
:00401118 0155BC add dword ptr [ebp-44], edx
:0040111B 017DBC add dword ptr [ebp-44], edi ;[ebp-44]=64f4f0+n
:0040111E 6BFF03 imul edi, 00000003
:00401121 897DC0 mov dword ptr [ebp-40], edi ;[ebp-40]=64f4f0*3
--------------------------------------------------------------------------------
这几个计算都比较简单的,有5个变量已经被搞定了。其中那个EDI我实在没看明白和我们的输入有什么关系,我改动用户名和注册码它也不会变化,因此我认为这是一个常量,如果不对请高手指正。
代码:--------------------------------------------------------------------------------
:00401126 0FBE8C0544FFFFFF movsx ecx, byte ptr [ebp+eax-BC];[EBP-BC]是用户名,EAX作为指针
:0040112E 83F961 cmp ecx, 00000061
:00401131 7C07 jl 0040113A ;如果小于61即'a'就跳转
:00401137 83E920 sub ecx, 00000020 ;如果大于就减20,对于字母来说是小写转大写
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401131(C)
|
:0040113A 8BF1 mov esi, ecx ;ECX为用户名第一个字符
:0040113C 03DE add ebx, esi ;EBX=ECX
:0040113E 0FAFD9 imul ebx, ecx ;实际上EBX=ECX*ECX
:00401141 4A dec edx ;EDX为循环变量减1
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401178(C)
|
:00401142 0FBE8C2F44FFFFFF movsx ecx, byte ptr [edi+ebp-000000BC];前一个字符
:0040114A 0FBEB42F45FFFFFF movsx esi, byte ptr [edi+ebp-000000BB];后一个字符
;EDI也是控制取字符的指针,这里相当于每次取出两个字符,前一个放在ECX,后一个放在ESI
:00401152 83F961 cmp ecx, 00000061
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040116C(U)
|
:0040115B 83FE61 cmp esi, 00000061
:0040115E 7D0E jge 0040116E ;这里对字符进行同样的转换
:00401164 EB0B jmp 00401171
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401155(C)
|
:00401169 83E920 sub ecx, 00000020
:0040116C EBED jmp 0040115B
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040115E(C)
|
:0040116E 83EE20 sub esi, 00000020
:00401171 47 inc edi ;EDI这个指针+1
:00401172 03DE add ebx, esi ;EBX是累加的结果,再加上后一个字符
:00401174 0FAFD9 imul ebx, ecx ;再乘上前一个字符
:00401177 4A dec edx
:00401178 75C8 jne 00401142 ;是否取完?
:0040117A 895DC8 mov dword ptr [ebp-38], ebx ;累加结果存在[ebp-38]
--------------------------------------------------------------------------------
这段麻烦一些,看不明白的话看我的注册机代码就清楚了.来看下面一段:
代码:--------------------------------------------------------------------------------
:0040118F 0FBE840D44FFFFFF movsx eax, byte ptr [ebp+ecx-000000BC];循环取字符
:00401197 03C1 add eax, ecx ;EAX=每位字符+ECX
:00401199 03D8 add ebx, eax ;累加到EBX
:0040119B 41 inc ecx ;循环变量递增
:0040119C 3B4DD4 cmp ecx, dword ptr [ebp-2C]
:0040119F 75EE jne 0040118F ;如果未取完则继续
:004011A1 D1C0 rol eax, 1 ;EAX左移1位
:004011A3 3540E20100 xor eax, 0001E240 ;EAX XOR 1E240
:004011A8 8945B0 mov dword ptr [ebp-50], eax
--------------------------------------------------------------------------------
相信你已经对这个形式很熟悉了吧,[EBP-BC]这是用户名,然后用一个ECX循环递增来取每个字符,再看看:add eax,ecx / add ebx,eax 好像是把每位字符的值再和字符的位置(ECX)累加起来的,呵呵,作者开了个小玩笑。看看下面的操作,都是对EAX进行的,可是累加的结果是放在EBX中呀,其实EAX是用户名的最后一个字符加上用户的长度。要说下的是ROL,这个本来是“滚动”,但因为EAX肯定很小,最高位为0,所以在注册机中我简单的用左移SHL代替了。计算结果放在[ebp-50]。
代码:--------------------------------------------------------------------------------
:004011B3 0FBE840D44FFFFFF movsx eax, byte ptr [ebp+ecx-000000BC]
:004011BB 6BD006 imul edx, eax, 00000006
:004011BE 33C2 xor eax, edx
:004011C0 03D8 add ebx, eax
:004011C2 41 inc ecx
:004011C3 3B4DD4 cmp ecx, dword ptr [ebp-2C]
:004011C6 75EB jne 004011B3
:004011C8 035DB0 add ebx, dword ptr [ebp-50]
:004011CB 895DAC mov dword ptr [ebp-54], ebx
--------------------------------------------------------------------------------
这一段不写说明了,当作测验,应该看懂了吧,算出结果放在[ebp-54]。
至此八个变量都出来了,注册机也容易了吧。
代码:--------------------------------------------------------------------------------
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
int len,i;
int EBP_40,EBP_3C,EBP_44,EBP_38,EBP_4C,EBP_48,EBP_54,EBP_50;
int EDI=0x64F4F0;
char name[50]={0};
printf("Please input your name:");
scanf("%s",name);
len=strlen(name);
EBP_3C=len*2;
EBP_48=len+5;
EBP_4C=EDI+4;
EBP_44=EDI+len;
EBP_40=EDI*3;
EBP_50=((len-1+name[len-1])<<1);
EBP_50^=0x1E240;
EBP_54=0;
for (i=0;i<len;i++)
EBP_54+=((name[i]*6)^name[i]);
EBP_54+=EBP_50;
for (i=0;i<len;i++)
if (name[i]>='a') name[i]-=0x20;
EBP_38=name[0]*name[0];
for (i=1;i<len;i++)
EBP_38=(EBP_38+name[i])*name[i-1];
printf("Your password is: %lX%lu-%lu%lX-%lu%lu-%lX%lX\n",
EBP_50,EBP_54,EBP_48,EBP_4C,EBP_38,EBP_44,EBP_3C,EBP_40);
printf("KeyGen by RoBa Enjoy Cracking!\n");
}
--------------------------------------------------------------------------------
一个可用的注册码:
Name: RoBa
Serial: 1E288125744-964F4F4-29089574586616308-812EDED0
_____________________________@
能力值:
( LV2,RANK:10 )
4 楼
NO3: 作者:RoBa
教菜鸟写注册机――高级篇(注意我这里说的高级只是对偶辈菜鸟来说是难一些)
HEYA,我又来灌喽!还是那个系列的第3位CRACKME。下载:
http://opencrackmes.crackmes.de/opencrackmes/Collections/keygenning4newbies/Crackmes/k4n3.zip
用W32DASM来反,(可以先看后面说明) 代码:--------------------------------------------------------------------------------
:004011BF 6A45 push 00000045
:004011C1 50 push eax
:004011C2 A4 movsb
* Reference To: USER32.GetDlgItemTextA, Ord:0104h
|
:004011C3 8B3DA8404000 mov edi, dword ptr [004040A8] ;注意这里把地址放在EDI
* Possible Reference to Dialog: DialogID_0065, CONTROL_ID:03E8, ""
|
:004011C9 68E8030000 push 000003E8
:004011CE 51 push ecx
:004011CF FFD7 call edi ;实际是CALL GetDlgItemTextA,得到用户名
:004011D1 8BF0 mov esi, eax
:004011D3 85F6 test esi, esi
:004011D5 0F844B010000 je 00401326
:004011DB 83FE40 cmp esi, 00000040
:004011DE 0F8742010000 ja 00401326
:004011E4 8B4508 mov eax, dword ptr [ebp+08]
:004011E7 8D5594 lea edx, dword ptr [ebp-6C]
:004011EA 6A13 push 00000013
:004011EC 52 push edx
* Possible Reference to Dialog: DialogID_0065, CONTROL_ID:03E9, ""
|
:004011ED 68E9030000 push 000003E9
:004011F2 50 push eax
:004011F3 FFD7 call edi ;再次调用GetDlgItemText,得到注册码
:004011F5 6BC003 imul eax, 00000003 ;EAX是注册码的长度
:004011F8 C1E002 shl eax, 02 ;左移二位
:004011FB 05CD000000 add eax, 000000CD ;加上0CD
:00401200 8945FC mov dword ptr [ebp-04], eax
:00401203 817DFCA5010000 cmp dword ptr [ebp-04], 000001A5;看看计算结果是不是1A5
:0040120A 0F85BC000000 jne 004012CC ;不是就死,可以逆算出(1A5-0CD)>>2=12
:00401210 33C0 xor eax, eax ;即注册码不能小于12h位
:00401212 8A4594 mov al, byte ptr [ebp-6C]
:00401215 84C0 test al, al
:00401217 7413 je 0040122C
:00401219 8D4D94 lea ecx, dword ptr [ebp-6C]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040122A(C)
|
:0040121C 3C30 cmp al, 30
:0040121E 0F82C6000000 jb 004012EA ;注册码每位不能小于30h,即'0'
:00401224 8A4101 mov al, byte ptr [ecx+01]
:00401227 41 inc ecx
:00401228 84C0 test al, al
:0040122A 75F0 jne 0040121C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401217(C)
|
:0040122C E8CFFDFFFF call 00401000 ;这是什么呀?好像很重要哟,进去看看!
:00401231 8D852CFFFFFF lea eax, dword ptr [ebp+FFFFFF2C]
:00401237 50 push eax
:00401238 E843FEFFFF call 00401080 ;转换过程一,跟进
:0040123D 8945FC mov dword ptr [ebp-04], eax
:00401240 E8BBFDFFFF call 00401000 ;还进去不?呀....别打我!
:00401245 8D8D2CFFFFFF lea ecx, dword ptr [ebp+FFFFFF2C]
:0040124B 56 push esi
:0040124C 51 push ecx
:0040124D E8BEFDFFFF call 00401010
:00401252 83C40C add esp, 0000000C
:00401255 33C9 xor ecx, ecx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401284(C)
|
:00401257 8B45FC mov eax, dword ptr [ebp-04] \
:0040125A 33D2 xor edx, edx |
:0040125C BE1A000000 mov esi, 0000001A |
:00401261 F7F6 div esi |
:00401263 8A941510FFFFFF mov dl, byte ptr [ebp+edx-000000F0]
:0040126A 88540DC8 mov byte ptr [ebp+ecx-38], dl|
:0040126E 8B45FC mov eax, dword ptr [ebp-04] |
:00401271 C1E003 shl eax, 03 |---转换过程二
:00401274 BA45230100 mov edx, 00012345 |
:00401279 F7E8 imul eax |
:0040127B 03C2 add eax, edx |
:0040127D 8945FC mov dword ptr [ebp-04], eax |
:00401280 41 inc ecx |
:00401281 83F912 cmp ecx, 00000012 |
:00401284 72D1 jb 00401257 /
:00401286 E875FDFFFF call 00401000
:0040128B 33C0 xor eax, eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004012A2(C)
|
:0040128D 8A4C0594 mov cl, byte ptr [ebp+eax-6C] \
:00401291 8A5405C8 mov dl, byte ptr [ebp+eax-38] |
:00401295 80E930 sub cl, 30 |
:00401298 32D1 xor dl, cl |---转换过程三
:0040129A 885405C8 mov byte ptr [ebp+eax-38], dl |
:0040129E 40 inc eax |
:0040129F 83F812 cmp eax, 00000012 |
:004012A2 72E9 jb 0040128D /
:004012A4 E857FDFFFF call 00401000
:004012A9 8D55C8 lea edx, dword ptr [ebp-38]
:004012AC 52 push edx
:004012AD E85EFEFFFF call 00401110 ;转换过程四
:004012B2 E849FDFFFF call 00401000
:004012B7 8D45C8 lea eax, dword ptr [ebp-38]
* Possible StringData Ref from Data Obj ->"KEYGENNING4NEWBIES"
|
:004012BA 6814514000 push 00405114 ;固定字串"KEYGENNING4NEWBIES"
:004012BF 50 push eax ;上面转换而来的字串
:004012C0 E86BFEFFFF call 00401130 ;进行比较
:004012C5 83C40C add esp, 0000000C
:004012C8 85C0 test eax, eax
:004012CA 753C jne 00401308 ;关键跳转
--------------------------------------------------------------------------------
找串式参考,然后向上很容易找到关键跳转。可以发现是对EAX进行判断,在一般情况下这EAX就是上面CALL的返回值了。再看CALL上面有两个PUSH,猜猜是什么?应该是对字符串比较吧。在上面就可以看出405114是一个固定的字串"KEYGENNIG4NEWBIES",动态跟一跟看EAX是啥,果然,也是一个同样长度的字符串。这时几乎可以肯定这个EAX就是我们的用户名和注册码进行某种运算产生的结果。那么我们就跟一跟看:
从前面的方法找到这个函数的开头,开头还是一些初始化的东东,向下看,可以找到一个API:GetDlgItemText这个API从名字猜猜看,就是我们介绍过的GetDlgItem和GetWindowText和“合体” 具体说明请查资料,我不写了。值得一提的是程序把这个CALL的地址先放在EDI里,以后每次调用时只用CALL EDI就行了,这是多次调用同一API时翻译器的优化方法,注意!
调用这个API后返回值是得到的文本的长度,然后在后面对注册码的长度进行一些计算(注释在上面),我们可以反算出注册码的长度为12h位(多于12h位也可以,因为只取前12h位)。
然后就是一个CALL 401000,我直觉感到这是一个重要的CALL,结果跟进去一看:!@#$%,只是把几个寄存器清零了,这告诉我们:直觉会有出错的时候,代码才是检验真理的唯一标准。
下面一个CALL 401080,在它前面压入了一个参数正是我们的用户名,我直觉感到这个CALL有问题。跟进看看,这回对了啦:
代码:--------------------------------------------------------------------------------
* Referenced by a CALL at Address:
|:00401238
|
:00401080 55 push ebp
:00401081 8BEC mov ebp, esp
:00401083 51 push ecx
:00401084 53 push ebx
:00401085 56 push esi
:00401086 57 push edi
* Possible StringData Ref from Data Obj ->"eheh"
|
:00401087 6880504000 push 00405080
:0040108C 6A00 push 00000000
:0040108E E8ADFFFFFF call 00401040 ;这个CALL有问题
:00401093 83C408 add esp, 00000008
:00401096 8BD8 mov ebx, eax
:00401098 E863FFFFFF call 00401000
* Possible StringData Ref from Data Obj ->" is a whore."
|
:0040109D BF70504000 mov edi, 00405070
:004010A2 83C9FF or ecx, FFFFFFFF
:004010A5 33C0 xor eax, eax
:004010A7 F2 repnz
:004010A8 AE scasb
:004010A9 F7D1 not ecx
:004010AB 2BF9 sub edi, ecx
:004010AD 8BF7 mov esi, edi
:004010AF 8B7D08 mov edi, dword ptr [ebp+08]
:004010B2 8BD1 mov edx, ecx
:004010B4 83C9FF or ecx, FFFFFFFF
:004010B7 F2 repnz
:004010B8 AE scasb
:004010B9 8BCA mov ecx, edx
:004010BB 4F dec edi
:004010BC C1E902 shr ecx, 02
:004010BF F3 repz
:004010C0 A5 movsd
:004010C1 8BCA mov ecx, edx
:004010C3 83E103 and ecx, 00000003
:004010C6 F3 repz
:004010C7 A4 movsb
:004010C8 33FF xor edi, edi
:004010CA 33F6 xor esi, esi ;上面这一段是不是有点晕,没关系,只看结果
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004010F6(C)
|
:004010CC 8B4508 mov eax, dword ptr [ebp+08]
:004010CF 50 push eax ;在这里D eax看看是什么,RoBa is a whore.
:004010D0 56 push esi ;ESI每次加4,从第ESI个字符开始取值
:004010D1 E86AFFFFFF call 00401040 ;还是上面的CALL
:004010D6 8B8E30504000 mov ecx, dword ptr [esi+00405030];这也是一个表,从里面取值
:004010DC 83C408 add esp, 00000008
:004010DF 33CF xor ecx, edi
:004010E1 03C1 add eax, ecx
:004010E3 8945FC mov dword ptr [ebp-04], eax
:004010E6 C145FC07 rol dword ptr [ebp-04], 07 ;ROL是一个“滚动”移位
:004010EA 8B45FC mov eax, dword ptr [ebp-04]
:004010ED 83C604 add esi, 00000004
:004010F0 33D8 xor ebx, eax ;进行一些运算,EBX最初是"eheh"=68656865
:004010F2 47 inc edi
:004010F3 83FE40 cmp esi, 00000040 ;ESI每次加4,所以这是计算10H=16次
:004010F6 7CD4 jl 004010CC ;这里是循环计算
:004010F8 5F pop edi
:004010F9 8BC3 mov eax, ebx
:004010FB 5E pop esi
:004010FC 5B pop ebx
:004010FD 8BE5 mov esp, ebp
:004010FF 5D pop ebp
:00401100 C3 ret
--------------------------------------------------------------------------------
呵呵,别害怕,这是整个程序最复杂的一处运算,过了这儿就简单了
一上来压入了一个"eheh",一个0,然后一个CALL 401040,我跟进。。。。别着急,先带过看返回值是什么?嗯,EAX=68656865。作了这么多练习了,你的“先死”练出来了么?这个EAX怎么这么别扭,就是"eheh"倒过来了呀。'e'=65h,'h'=68h。当然如果没有看出来,跟进一下更保险了。
再向下,一个字串" is a whore."(whore什么意思牙,我英语太菜)接下来就是倒来倒去。记住repnz scasb/ repnz movsd这样的计算经常是字符串的计算。我们不算三七二十一先走过这一段看看结果如何。走到4010CF时下D eax。呵呵,是"RoBa is a whore."(到底是什么意思?不是骂我的吧)。可见上面那一段就是把用户名接上一个" is a whore." 所以,看不懂的计算不妨先跳过去,往往结果却非常明了。
接下来就是一个循环。又用了CALL 401040。这次是从字串"RoBa is a whore."里取值,而第二个参数ESI每次加4,可以看出它是控制从第几个字符开始取。从循环的最后可以看出要算10h次。
每次从字串中取出四个字符放在EAX中后,再从[405030]这个表里从一个值,进行一些计算,把结果与EBX进行XOR,(EBX最初是上面得到的68656865)。这个CALL返回的值就是10H次计算后的EBX。(这一段较乱,也不太好说明,亲自跟一下就会明白,有疑问请看我的注册机是如何实现的。或者直接找我啦)
好了,我们出来喽,往下走,把返回放在[EBP-4],清空一些寄存器,又来到一个循环。(过程二)
代码:--------------------------------------------------------------------------------
:00401257 8B45FC mov eax, dword ptr [ebp-04] ;最初这里是上面过程一的结果
:0040125A 33D2 xor edx, edx
:0040125C BE1A000000 mov esi, 0000001A
:00401261 F7F6 div esi ;除以1Ah=26
:00401263 8A941510FFFFFF mov dl, byte ptr [ebp+edx-000000F0];根据余数从表中取值
:0040126A 88540DC8 mov byte ptr [ebp+ecx-38], dl ;把取得的值组成一个字串
:0040126E 8B45FC mov eax, dword ptr [ebp-04]
:00401271 C1E003 shl eax, 03
:00401274 BA45230100 mov edx, 00012345
:00401279 F7E8 imul eax
:0040127B 03C2 add eax, edx ;进行一些计算,准备下次再取
:0040127D 8945FC mov dword ptr [ebp-04], eax
:00401280 41 inc ecx ;ECX是循环变量
:00401281 83F912 cmp ecx, 00000012 ;共计算12h=18次
:00401284 72D1 jb 00401257
--------------------------------------------------------------------------------
先讲下DIV除法运算。它把商放在EAX,余数放在EDX。在这里我们可以看到除以1Ah即26。[ebp-F0]看看是啥,哈哈是一个字符表"ABCDEFGHIJKLMNOPQRSTUVWXYZ"。根据除得的余数从这个表中取出一个字符,(恰好除以26)。然后把取出的字符放在[ebp+ecx-38]这个地方,因为ECX是递增的,这样就形成了一个新串。对后面的计算也有一点要说明。imul eax这句,是两个32位的数相乘,这样结果会是64位,结果的高32位放在EDX,低32放入EAX,一定要注意!
下面我们来到过程三:
代码:--------------------------------------------------------------------------------
:0040128D 8A4C0594 mov cl, byte ptr [ebp+eax-6C] ;循环取假注册码
:00401291 8A5405C8 mov dl, byte ptr [ebp+eax-38] ;循环取过程二的结果字串
:00401295 80E930 sub cl, 30
:00401298 32D1 xor dl, cl
:0040129A 885405C8 mov byte ptr [ebp+eax-38], dl
:0040129E 40 inc eax ;EAX是循环变量
:0040129F 83F812 cmp eax, 00000012 ;还是18位
:004012A2 72E9 jb 0040128D
--------------------------------------------------------------------------------
又一个循环,EAX是循环变量,[EBP-38]记得是什么,就是过程二得到的那个新串。[EBP-6C]呢,在很远的上面,就是我们的假注册码。用EAX控制每次取一个字符,然后(假码的字符-30h) XOR 新串的字符,生成的新的新串还放在[EBP-38].
好了,先别晕,下面还有:
lea edx,[EBP-38]。这时EDX是过程三产生的新串了,又压进去,然后CALL 401110。跟进过程四:
代码:--------------------------------------------------------------------------------
:00401110 8B4C2404 mov ecx, dword ptr [esp+04] ;[ESP+4]就是上面PUSH来的字串啦
:00401114 33C0 xor eax, eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401122(C)
|
:00401116 8A1408 mov dl, byte ptr [eax+ecx] ;依次取过程三产生的新串
:00401119 32D0 xor dl, al ;与循环变量XOR
:0040111B 881408 mov byte ptr [eax+ecx], dl ;放好结果
:0040111E 40 inc eax
:0040111F 83F812 cmp eax, 00000012 ;EAX为循环变量,计算12H=18次
:00401122 72F2 jb 00401116
:00401124 C3 ret
--------------------------------------------------------------------------------
这个比较简单吧。CHEERS!最终结果终于出来了,然后判断这个最终结果是不是一个固定字串。当然我们的胡乱输入得不到字串"KEYGENNING4NEWBIES"的。那么应该怎么办呢?过程一和过程二都是对用户名的计算,这两步是不可逆的。也就是说从用户名N算出一个新串K,我们不能从K算出N来(我以为是这样,即使可逆应该也十分复杂)可以表示成 F12(N)=K。然后新串K和注册码S都参考计算,又得出一个新串K'。这是过程三,这个计算可逆(不明白?我在最后有说明)。F3(K,S)=K'。再从K'得到一个K''(过程四,也是可逆的)。最后判断这个K''是不是等于固定字串,即判断是否F4(K')=K''="KEYGENNING4NEWBIES"。
我们写注册机时呢,既然过程一和二(F12)不可逆,我们把它照抄下来得到K,然后可以从"KEYGENNING4NEWBIES"反算(过程四的逆运算)F4'("KEYGENNING4NEWBIES")=K''。最后F2可逆,所以可以求出F3'(K,K')=S。这样就根据用户名求出了注册码S。
(不知各位看懂没有,我自己都说晕了,这种符号表示真麻烦。其实只要想一想就发现很简单的。)
注册机:(C,写得很烂,各位将就)
代码:--------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
unsigned int iEAX,iEBX,i;
char st[]="KEYGENNING4NEWBIES";
char alpha[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //过程二用到的表
char name[70]={0};
int st1[]={
0x12,0x5C,0x34,0x22,0xAB,0x9D,0x54,0x00,
0xDD,0x84,0xAE,0x66,0x31,0x78,0x73,0xCF //过程一用到的表
};
char st2[20]={0};
char password[20]={0};
printf("Please input your name:");
scanf("%s",name);
strcat(name," is a whore.");
iEBX=0x68656865;
for (i=0;i<16;i++)
{
iEAX=(name[i*4])|(name[i*4+1]<<8)|
(name[i*4+2]<<16)|(name[i*4+3]<<24);
iEAX+=(st1[i]^i);
iEAX=(iEAX<<7)|(iEAX>>25); //我用这个表示ROL
iEBX^=iEAX;
} //过程一
iEAX=iEBX;
for (i=0;i<0x12;i++)
{
int k=iEAX%26;
st2[i]=alpha[k];
__asm
{
mov eax,iEAX
shl eax,3
mov edx,12345h
imul eax
add eax,edx
mov iEAX,eax
} //用了汇编
} //过程二
for (i=0;i<18;i++)
st[i]=st[i]^i; //过程四的逆运算
for (i=0;i<18;i++)
{
password[i]=st2[i]^st[i];
password[i]+=0x30;
} //过程三的逆运算,得到注册码
printf("Your Serial number is:\n%s\n",password);
printf("Keygen by RoBa\nEnjoy Cracking!\n");
}
--------------------------------------------------------------------------------
一个可用的用户名:RoBa
注册码::98D34M<N9?:AH85F
这个CRACKME设计有点缺陷,算出的注册码有可能是不可显示字符。开始我以为是我注册机错了,可把字符串粘贴过去以后是正确的。
一点说明:过程二的那个乘法我前面说了,其实结果是64位的,而高级语言里表示64位真的很麻烦,我只知道C里面有一个__int64,但程序老是出错,不得已加进了一段汇编,简单几句就解决了,可见汇编决不能丢掉
还有过程三和过程四为什么可逆,我想各位菜鸟同胞搞不清的可能就是异或。我可以明确的告诉大家,XOR运算是可逆的,逆运算仍然是XOR。下面我来证明:因为XOR是按位计算,所以只要一个二进制位的XOR可逆,那么整个数的计算也就可逆。来看
当A=0,B=0时,C=A XOR B=0,那么A=C XOR B=0,B=C XOR A=0
当A=0,B=1时,C=A XOR B=1,那么A=C XOR B=0,B=C XOR A=1
当A=1,B=0时,C=A XOR B=1,那么A=C XOR B=1,B=C XOR A=0
当A=1,B=1时,C=A XOR B=0,那么A=C XOR B=1,B=C XOR A=1
我说的对吧?
后记:这个CRACKME单从注册算法来说算是比较复杂的了,能够达到大部分共享软件的水平(某些采用密码学算法的BT除外)。对于新手来说可能会有些吃力(写破文更费劲),但如果能够弄明白的话,相信你已经能够搞定很大一部分软件的算法了。
当然,在具体的软件保护中不光是要解开算法,PE文件知识、壳的知识等也非常重要。(我正学脱壳,已经能脱UPX,ASPack了,呵呵,是不是很白痴。。。)让我们一起努力吧。 由 RoBa 于 2004-10-15 20:45 最后编辑
能力值:
( LV2,RANK:10 )
5 楼
NO4: 作者:RoBa
教菜鸟写注册机――实战篇
呵呵,再灌一篇,等再过两天开学就没得灌喽
前面我们折腾了半天都是在跟CRACKME过不去,可能有人觉得没意思了,这次咱们来个有实际意义的,呵呵,一个发布不久的软件――麻将拼图V1.04,这里来下:
http://skycn.softreg.com.cn/product.asp?id=/E5DCF286-05EE-4AA8-8ABE-9524013EFADA
用W32DASM反下,找串式参考“注册失败!”到下面:(分析见后)
代码:--------------------------------------------------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402E16(C)
|
:00402E3F 8B3D88974000 mov edi, dword ptr [00409788]
:00402E45 B940000000 mov ecx, 00000040
:00402E4A 33C0 xor eax, eax
:00402E4C 8B6C2414 mov ebp, dword ptr [esp+14]
:00402E50 F3 repz
:00402E51 AB stosd
:00402E52 8B3D7C974000 mov edi, dword ptr [0040977C]
:00402E58 B940000000 mov ecx, 00000040
:00402E5D F3 repz
:00402E5E AB stosd
:00402E5F 8B0D88974000 mov ecx, dword ptr [00409788]
* Reference To: USER32.SendDlgItemMessageA, Ord:020Fh
|
:00402E65 8B1D38714000 mov ebx, dword ptr [00407138] ;注意
:00402E6B 51 push ecx ;用户名存放地址[409788]
:00402E6C 6A10 push 00000010
:00402E6E 6A0D push 0000000D ;WM_GETTEXT
* Possible Reference to Dialog: DialogID_0070, CONTROL_ID:03E8, ""
|
:00402E70 68E8030000 push 000003E8 ;控件ID
:00402E75 55 push ebp
:00402E76 FFD3 call ebx ;得到用户名
:00402E78 8B157C974000 mov edx, dword ptr [0040977C]
:00402E7E 52 push edx ;注册码地址[40977C]
:00402E7F 6A10 push 00000010
:00402E81 6A0D push 0000000D ;WM_GETTEXT
* Possible Reference to Dialog: DialogID_0070, CONTROL_ID:03E9, ""
|
:00402E83 68E9030000 push 000003E9 ;控件ID
:00402E88 55 push ebp
:00402E89 FFD3 call ebx ;得到注册码
:00402E8B A188974000 mov eax, dword ptr [00409788]
:00402E90 803800 cmp byte ptr [eax], 00
:00402E93 0F8438010000 je 00402FD1
:00402E99 8B0D7C974000 mov ecx, dword ptr [0040977C]
:00402E9F 803900 cmp byte ptr [ecx], 00
:00402EA2 0F8429010000 je 00402FD1
:00402EA8 50 push eax ;压入用户名
:00402EA9 E822FEFFFF call 00402CD0 ;关键CALL
:00402EAE 8B3D7C974000 mov edi, dword ptr [0040977C] ;假码
:00402EB4 A188974000 mov eax, dword ptr [00409788] ;真码
:00402EB9 83C404 add esp, 00000004
:00402EBC 8BF7 mov esi, edi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402EDC(C)
|
:00402EBE 8A10 mov dl, byte ptr [eax]
:00402EC0 8ACA mov cl, dl
:00402EC2 3A16 cmp dl, byte ptr [esi]
:00402EC4 751C jne 00402EE2
:00402EC6 84C9 test cl, cl
:00402EC8 7414 je 00402EDE
:00402ECA 8A5001 mov dl, byte ptr [eax+01]
:00402ECD 8ACA mov cl, dl
:00402ECF 3A5601 cmp dl, byte ptr [esi+01]
:00402ED2 750E jne 00402EE2
:00402ED4 83C002 add eax, 00000002
:00402ED7 83C602 add esi, 00000002
:00402EDA 84C9 test cl, cl
:00402EDC 75E0 jne 00402EBE
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402EC8(C)
|
:00402EDE 33C0 xor eax, eax
:00402EE0 EB05 jmp 00402EE7
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402EC4(C), :00402ED2(C)
|
:00402EE2 1BC0 sbb eax, eax
:00402EE4 83D8FF sbb eax, FFFFFFFF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402EE0(U)
|
:00402EE7 85C0 test eax, eax
:00402EE9 0F848D000000 je 00402F7C
* Possible StringData Ref from Data Obj ->"52341546" ;骗人的
|
:00402EEF BEA4904000 mov esi, 004090A4
:00402EF4 8BC7 mov eax, edi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402F14(C)
|
:00402EF6 8A10 mov dl, byte ptr [eax]
:00402EF8 8ACA mov cl, dl
:00402EFA 3A16 cmp dl, byte ptr [esi]
:00402EFC 751C jne 00402F1A
:00402EFE 84C9 test cl, cl
:00402F00 7414 je 00402F16
:00402F02 8A5001 mov dl, byte ptr [eax+01]
:00402F05 8ACA mov cl, dl
:00402F07 3A5601 cmp dl, byte ptr [esi+01]
:00402F0A 750E jne 00402F1A
:00402F0C 83C002 add eax, 00000002
:00402F0F 83C602 add esi, 00000002
:00402F12 84C9 test cl, cl
:00402F14 75E0 jne 00402EF6
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402F00(C)
|
:00402F16 33C0 xor eax, eax
:00402F18 EB05 jmp 00402F1F
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402EFC(C), :00402F0A(C)
|
:00402F1A 1BC0 sbb eax, eax
:00402F1C 83D8FF sbb eax, FFFFFFFF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402F18(U)
|
:00402F1F 85C0 test eax, eax
:00402F21 7459 je 00402F7C
:00402F23 A180974000 mov eax, dword ptr [00409780]
:00402F28 6A00 push 00000000
:00402F2A 83F803 cmp eax, 00000003
* Possible StringData Ref from Data Obj ->"用户注册"
|
:00402F2D 6898904000 push 00409098
:00402F32 7D23 jge 00402F57
* Possible StringData Ref from Data Obj ->"注册码错误!请重新输入!"
|
:00402F34 687C904000 push 0040907C
:00402F39 55 push ebp
* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:00402F3A FF1534714000 Call dword ptr [00407134]
:00402F40 A180974000 mov eax, dword ptr [00409780]
:00402F45 5F pop edi
:00402F46 40 inc eax
:00402F47 5E pop esi
:00402F48 A380974000 mov dword ptr [00409780], eax
:00402F4D 5D pop ebp
:00402F4E B801000000 mov eax, 00000001
:00402F53 5B pop ebx
:00402F54 C21000 ret 0010
--------------------------------------------------------------------------------
根据错误错息找串式参考,很容易找到上面这些。然后从这个函数的开头开始分析。
首先值得一提的是程序取得文本框文本的方法。在这个程序中如果你下GetWindowText,GetDlgItemText这些断点都不能断到,那么它是靠的什么方法呢?我们可以在402E65这一句看到把一个API函数SendDlgItemMessage的地址给了EBX,然后下面两次调用EBX。可以想到这就是取用户名和注册码了,具体说明见下:
LONG SendDlgItemMessage(
HWND hDlg, // 对话框句柄
int nIDDlgItem, // 控件的ID
UINT Msg, // 要发送的消息
WPARAM wParam, // 消息的第一个附加值
LPARAM lParam // 消息的第二个附加值
;
对照上面的程序,可以发现它向ID为3E8h即1000的控件(用资源编辑工具可以发现这就是用户名的输入框)发送一个编号为0D的消息,这个消息表示什么呢?在winuser.h里有定义:
#define WM_SETTEXT 0x000C
#define WM_GETTEXT 0x000D
#define WM_GETTEXTLENGTH 0x000E
呵呵,不出所料是WM_GETTEXT。再来看WM_GETTEXT的附加值有什么意义
WM_GETTEXT
wParam = (WPARAM) cchTextMax; // number of characters to copy 得到的字串长度
lParam = (LPARAM) lpszText; // address of buffer for text 字串存放的地址
再看上面的程序就很明显了,第一个CALL的wParam为10,字串长度,lParam为[409788],这是用户名的位置,记好。第二个CALL得到假注册码放在[40977C]。
很不错的方式,躲开了常见的API,让我想起了DELPHI。
接下去是判断是否为空。然后把用户名PUSH进了,接着CALL。呵呵~~~~还不快跟进:
代码:--------------------------------------------------------------------------------
* Referenced by a CALL at Addresses:
|:00402EA9 , :004030ED
|
:00402CD0 53 push ebx
:00402CD1 56 push esi
:00402CD2 57 push edi
:00402CD3 8B7C2410 mov edi, dword ptr [esp+10] ;EDI指向用户名
:00402CD7 32DB xor bl, bl
:00402CD9 8BCF mov ecx, edi
:00402CDB 8A07 mov al, byte ptr [edi]
:00402CDD 84C0 test al, al
:00402CDF 740A je 00402CEB
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402CE9(C)
|
:00402CE1 02D8 add bl, al ;各字符累加起来
:00402CE3 8A4101 mov al, byte ptr [ecx+01] ;循环取字符
:00402CE6 41 inc ecx
:00402CE7 84C0 test al, al ;是否取完
:00402CE9 75F6 jne 00402CE1 ;这是一个循环
;注意参与计算的是AL,BL,即只取累加结果的低8位放在BL
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402CDF(C)
|
:00402CEB A178974000 mov eax, dword ptr [00409778]
:00402CF0 33F6 xor esi, esi
:00402CF2 A384974000 mov dword ptr [00409784], eax
:00402CF7 A174974000 mov eax, dword ptr [00409774]
:00402CFC 85C0 test eax, eax
:00402CFE 7E2D jle 00402D2D
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402D2B(C)
|
:00402D00 8A0C3E mov cl, byte ptr [esi+edi] ;EDI指向用户名,ESI循环变量,取字符
:00402D03 32CB xor cl, bl ;每次取的字符与上面累加结果BL异或
:00402D05 51 push ecx ;把异或所得结果压入
:00402D06 E895FFFFFF call 00402CA0 ;关键CALL,跟进
{
:00402CA0 0FBE442404 movsx eax, byte ptr [esp+04] ;EAX=上面压入的结果
:00402CA5 030584974000 add eax, dword ptr [00409784] ;[409784]最初是989681h
:00402CAB 69C0697DAE42 imul eax, 42AE7D69
:00402CB1 0531D40000 add eax, 0000D431 ; D431h=54321
:00402CB6 A384974000 mov dword ptr [00409784], eax ;把结果放回,下次计算要用
:00402CBB C1F810 sar eax, 10 ;右移10位
:00402CBE 83E00F and eax, 0000000F ;只取最低4位(见后)
:00402CC1 C3 ret
}
:00402D0B 83C404 add esp, 00000004
:00402D0E 88043E mov byte ptr [esi+edi], al ;AL是上面CALL返回的结果
:00402D11 3C0A cmp al, 0A
:00402D13 0FBEC0 movsx eax, al
:00402D16 7D05 jge 00402D1D ;如果AL>=0A就跳
:00402D18 83C030 add eax, 00000030 ;如果AL<0A就加30h
:00402D1B EB03 jmp 00402D20
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402D16(C)
|
:00402D1D 83C041 add eax, 00000041 ;如果AL>=0A就加41h
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402D1B(U)
|
:00402D20 88043E mov byte ptr [esi+edi], al ;把结果放好,这可是最后注册码哟
:00402D23 A174974000 mov eax, dword ptr [00409774] ;[409774]是常量8
:00402D28 46 inc esi ;ESI是循环变量
:00402D29 3BF0 cmp esi, eax
:00402D2B 7CD3 jl 00402D00 ;这里是一个循环
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402CFE(C)
|
:00402D2D C6043800 mov byte ptr [eax+edi], 00
:00402D31 5F pop edi
:00402D32 5E pop esi
:00402D33 5B pop ebx
:00402D34 C3 ret
--------------------------------------------------------------------------------
先说说关于位操作的事。上面有一个SAR,这个和SHR有一些区别,就在最高位的处理上。我也说不太明白,举个例子 11011100 shr 4 = 00001101 而 11011100 sar 4 = 11111101。不过这里右移10位,我们只取最后4位,所以高10位的变化是影响不到的,可以简单的用右移(>> )来取代。还有要说的就是AND,有一个AND 0000000F,我说是只取最低4位,可能有菜鸟不明白,其实AND只要有一个操作数为0,结果肯定为0,如果一个操作数是1,结果肯定等于另一个操作数。比方说我们如果想“屏蔽”一个八位数的第三四位,只要让它AND 11110011就行了。同理,因为0F=1111,所以AND 0000000F等于只取出了最后面的四位。
可以发现经过这个CALL后形成的一个新的字串,仍然放在原用户名的位置。接下来的代码把它们取出,逐位比较,不等就跳。。。自己看看吧,练习一下,很简单的。
最后要说的是它还设了个陷阱,后面有一个固定字串"52341546",输入这个会提示成功注册,但其实下次启动又成未注册了。
整理下思路,先把用户名累加,把结果再和用户名的每位进行一些计算,就得到正确的注册码了。很简单的是不是?
代码:--------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char name[20]={0};
char password[20]={0};
unsigned int s=0,k=0,i;
printf("Please input your name:");
scanf("%s",name);
int len=strlen(name);
for (i=0;i<len;i++)
{
s+=name[i];
s%=0x100; //取低8位
}
int LOCAL=0x989681;
for (i=0;i<8;i++)
{
k=s^name[i];
k=(k+LOCAL)*0x42AE7D69+0xD431;
LOCAL=k;
k>>=0x10; //SAR
k%=0x10; //取最低4位
if (k>=0xA) k+=0x41;
else k+=0x30;
password[i]=k;
}
printf("Your password is : %s\n",password);
printf("Keygen by RoBa\nEnjoy Cracking!\n");
}
--------------------------------------------------------------------------------
一个可用的用户名:RoBa
注册码:0P6N0089
能力值:
( LV2,RANK:10 )
6 楼
NO5: 作者:subtway+0
network spy eval 1.6破解教程【原创】
【软件名称】network spy eval 1.6
【下载地址】网上搜索
【应用平台】Win9x
【软件大小】未知
【软件限制】未知
【破解声明】破解只是感兴趣,无其它目的。失误之处敬请诸位大侠赐教!
【破解工具】trw2000, peid, W32Dasm
【软件简介】功能很全,ping,traceroute hostlookup,finger,listener,scanner,whois,winsock.....,总之上网必备
========================================================================================
【分析过程】
先用peid查看一下,还好,vc++编写的软件,没有加壳。
运行该程序 ,加载trw2000 ,输入注册姓名:subtway , 序列号:78787878 ,
CTRL+M呼入TRW2000 ,输入bpx hmemcpy ,按F5返回程序,点击register按钮,TRW拦截,
下pmodule命令,然后按F10一步步来到
.......
0167:004051AD 8D542448 LEA EDX,[ESP+48] //下dedx 显示:78787878
0167:004051B1 8D442408 LEA EAX,[ESP+08] //下deax 显示:subtway
0167:004051B5 52 PUSH EDX
0167:004051B6 50 PUSH EAX
0167:004051B7 E8142E0000 CALL 00407FD0 //关键call ,按F8进入
0167:004051BC 83C408 ADD ESP,BYTE +08
0167:004051BF 85C0 TEST EAX,EAX
0167:004051C1 744A JZ 0040520D // 注册码不对则跳,game over!
0167:004051C3 8B3D28104100 MOV EDI,[00411028]
0167:004051C9 8D4C2408 LEA ECX,[ESP+08]
0167:004051CD 6820024300 PUSH DWORD 00430220
0167:004051D2 51 PUSH ECX
0167:004051D3 6824344100 PUSH DWORD 00413424
0167:004051D8 6884314100 PUSH DWORD 00413184
0167:004051DD FFD7 CALL EDI
0167:004051DF 8D542448 LEA EDX,[ESP+48]
0167:004051E3 6820024300 PUSH DWORD 00430220
0167:004051E8 52 PUSH EDX
0167:004051E9 6838344100 PUSH DWORD 00413438
0167:004051EE 6884314100 PUSH DWORD 00413184
0167:004051F3 FFD7 CALL EDI
0167:004051F5 6A40 PUSH BYTE +40
0167:004051F7 6804364100 PUSH DWORD 00413604
0167:004051FC 68C4354100 PUSH DWORD 004135C4
0167:00405201 56 PUSH ESI
0167:00405202 FF1554114100 CALL `USER32!MessageBoxA` //注册码正确的欢迎窗口
0167:00405208 6A01 PUSH BYTE +01
0167:0040520A 56 PUSH ESI
0167:0040520B EB39 JMP SHORT 00405246
0167:0040520D 6A10 PUSH BYTE +10
0167:0040520F 68B8354100 PUSH DWORD 004135B8
0167:00405214 6898354100 PUSH DWORD 00413598
0167:00405219 56 PUSH ESI
0167:0040521A FF1554114100 CALL `USER32!MessageBoxA` // 注册码错误的欢迎窗口
0167:00405220 5F POP EDI
0167:00405221 B801000000 MOV EAX,01
0167:00405226 5E POP ESI
0167:00405227 81C480000000 ADD ESP,80
..... 追入call后, 0167:00407FD0 83EC20 SUB ESP,BYTE +20
:00407FD3 56 PUSH ESI
:00407FD4 8B742428 MOV ESI,[ESP+28]
:00407FD8 56 PUSH ESI
:00407FD9 FF1560104100 Call dword ptr [00411060]
:00407FDF 83F804 cmp eax, 00000004 //比较注册姓名位数,小于4则跳,game over
:00407FE2 7D07 jge 00407FEB
:00407FE4 33C0 xor eax, eax
:00407FE6 5E pop esi
:00407FE7 83C420 add esp, 00000020
:00407FEA C3 ret * Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407FE2(C)
|
:00407FEB 0FBE4601 movsx eax, byte ptr [esi+01] //取姓名第2位u的ASC码0x75 放入eax
:00407FEF 0FBE4E02 movsx ecx, byte ptr [esi+02] //取姓名第3位b的ASC码0x62 放入ecx
:00407FF3 D1E0 shl eax, 1 //eax=eax*2=0x75*2=0xea(十进制234)
:00407FF5 50 push eax
:00407FF6 0FBE4603 movsx eax, byte ptr [esi+03] //取姓名第4位t的ASC码0x74 放入eax
:00407FFA C1E102 shl ecx, 02 //ecx=ecx*4=0x62*4=0x188(十进制392)
:00407FFD 51 push ecx
:00407FFE B90A000000 mov ecx, 0000000A //ecx=a(十进制10)
:00408003 99 cdq
:00408004 F7F9 idiv ecx //用eax的值(0x74)和ecx的值(a)做除法运算,商为b(十进制11) ,放在eax中,余数为6(十进制6) ,放在edx
:00408006 B8A0C634FA mov eax, FA34C6A0 //eax=0xfa34c6a0(十进制4197762720)
:0040800B 8BCA mov ecx, edx //ecx=edx=6
:0040800D D3E0 shl eax, cl //eax=eax*(2^ecx)=0x8d31a800(十进制2368841728)
:0040800F 8D4C240C lea ecx, dword ptr [esp+0C]
:00408013 50 push eax * Possible StringData Ref from Data Obj ->"%010u-%d%d"
|
:00408014 68383B4100 push 00413B38
:00408019 51 push ecx * Reference To: USER32.wsprintfA, Ord:02B3h
|
:0040801A FF1544114100 Call dword ptr [00411144] //将上述计算的值合成最后的注册码 ->2368841728-392234
:00408020 8B542440 mov edx, dword ptr [esp+40]
:00408024 83C414 add esp, 00000014
:00408027 8D442404 lea eax, dword ptr [esp+04]
:0040802B 52 push edx //下dedx,显示:78787878 ->输入的注册码
:0040802C 50 push eax //下deax,显示:2368841728-392234 ->正确的注册码 * Reference To: KERNEL32.lstrcmpA, Ord:0329h
|
:0040802D FF1544104100 Call dword ptr [00411044] //比较eax和edx,不等则game over!
:00408033 F7D8 neg eax
:00408035 1BC0 sbb eax, eax
:00408037 5E pop esi
:00408038 40 inc eax
:00408039 83C420 add esp, 00000020
:0040803C C3 ret
========================================================================================
【分析总结】
注册码只和姓名的前四位有关,注册机如下:
//this is a keymaker program of network spy eval 1.6!
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main()
{
cout<<"the keymaker of network spy eval 1.6"<<endl;
cout<<"========================"<<endl;
cout<<"made by subtway+0"<<endl;
cout<<"========================"<<endl;
cout<<endl;
char s1[20];
cout<<"please input your name:";
cin>>s1;
int len=strlen(s1);
if(len<4)
{cout<<"please input again!your name must has at lease 4 chars!"<<endl;
return 0;
}
else
{
int m1,m2,m3,m4;
unsigned long m5;
m1=s1[1]*2;
m2=s1[2]*4;
m3=s1[3]/10;
m4=s1[3]%10;
m5=0xfa34c6a0*pow(2,m4);
cout<<"your password is: "<<m5<<"-"<<m2<<m1<<endl;
system ("PAUSE");
return 0;
}
}
========================================================================================
【版权信息】
copyright subtway+0 all rights reserved!
能力值:
( LV2,RANK:10 )
7 楼
NO6: 作者:lzqgj
圣诞到了,发一个缘分测试软件的分析。
圣诞闲来无聊,拿个缘分测试软件测试了自己与女孩子的缘分,结果竟然有98分,评语是“千年等一回”,真的有这么神吗?于是产生了看看它计算过程的冲动。
软件名称:缘分测试
下载地址:http://www.skycn.net/soft/21402.html 天空软件的东西,可以放心的。
调试工具:OD
开工。首先用OD插件Ultra String Reference查找“千年等一回”,在
0040195A push 200401.00429068 “千年等一回”
在该过程的起始处401780下断,开始调试。
00401780 push -1
00401782 push 200401.00420E18
00401787 mov eax,dword ptr fs:[0]
0040178D push eax
0040178E mov dword ptr fs:[0],esp
00401795 sub esp,0C
00401798 push ebx
00401799 push ebp
0040179A push esi
0040179B push edi
0040179C mov esi,ecx
0040179E push 1
004017A0 call <jmp.&MFC42.#6334>
004017A5 mov edx,dword ptr ds:[esi+60]
004017A8 xor edi,edi
004017AA xor ebx,ebx
004017AC xor eax,eax
004017AE mov ecx,dword ptr ds:[edx-8]
004017B1 mov dword ptr ss:[esp+14],edi
004017B5 test ecx,ecx
004017B7 mov dword ptr ss:[esp+18],ebx
004017BB jle short 200401.004017CC
004017BD movsx ebp,byte ptr ds:[edx+eax] ; 循环计算boy name
004017C1 add edi,ebp ; 累和
004017C3 inc eax ; 计数器
004017C4 cmp eax,ecx
004017C6 jl short 200401.004017BD ; 循环
004017C8 mov dword ptr ss:[esp+14],edi ; 保存结果在[esp+14]
004017CC mov ecx,dword ptr ds:[esi+64]
004017CF xor eax,eax
004017D1 mov edi,dword ptr ds:[ecx-8]
004017D4 test edi,edi
004017D6 jle short 200401.004017E7
004017D8 movsx ebp,byte ptr ds:[ecx+eax] ; 循环计算girl name
004017DC add ebx,ebp
004017DE inc eax
004017DF cmp eax,edi
004017E1 jl short 200401.004017D8
004017E3 mov dword ptr ss:[esp+18],ebx ; 保存结果在[esp+18]
004017E7 mov edi,dword ptr ds:[<&MSVCRT._mbscmp>] ; MSVCRT._mbscmp
004017ED push 200401.004297E4 ;
004017F2 push edx ;
004017F3 call edi ;
004017F5 add esp,8
004017F8 test eax,eax
004017FA je 200401.0040198C
00401800 mov eax,dword ptr ds:[esi+64]
00401803 push 200401.004297E4
00401808 push eax ; girl name
00401809 call edi
0040180B add esp,8
0040180E test eax,eax
00401810 je 200401.0040198C
00401816 fild dword ptr ss:[esp+14] ; boy name 结果入栈 (-167)
0040181A fadd qword ptr ds:[4228D8] ; 加3.76793
00401820 fimul dword ptr ss:[esp+18] ; 与girl name相乘 (-182)
00401824 fsin ; 取正弦值,结果介于-1到1之间
00401826 fadd qword ptr ds:[4228D0] ; 加1,结果介于0-2
0040182C fmul qword ptr ds:[4228C8] ; 乘50,结果介于0-100
00401832 call <jmp.&MSVCRT._ftol> ; 结果出栈
00401837 mov ebx,eax ; 得分
00401839 mov eax,dword ptr ds:[esi+60]
0040183C push 200401.00429248 ; ASCII "Romeo"
00401841 push eax ; boy name
00401842 call edi 是否是Romeo
00401844 add esp,8
00401847 test eax,eax
00401849 jnz short 200401.00401864
0040184B mov eax,dword ptr ds:[esi+64]
0040184E push 200401.00429240 ; ASCII "Julia"
00401853 push eax
00401854 call edi 是否是Julia
00401856 add esp,8
00401859 test eax,eax
0040185B jnz short 200401.00401864
0040185D mov ebx,64 ; 分数为100
00401862 jmp short 200401.004018B8
00401864 mov eax,dword ptr ds:[esi+60]
00401867 push 200401.00429238 ; ASCII "romeo"
0040186C push eax ; boy name
0040186D call edi
0040186F add esp,8
00401872 test eax,eax
00401874 jnz short 200401.0040188F
00401876 mov eax,dword ptr ds:[esi+64]
00401879 push 200401.00429230 ; ASCII "julia"
0040187E push eax
0040187F call edi
00401881 add esp,8
00401884 test eax,eax
00401886 jnz short 200401.0040188F
00401888 mov ebx,64
0040188D jmp short 200401.004018B8
0040188F mov eax,dword ptr ds:[esi+60]
00401892 push 200401.00429228 ; 梁山伯
00401897 push eax
00401898 call edi
0040189A add esp,8
0040189D test eax,eax
0040189F jnz short 200401.004018B8
004018A1 mov eax,dword ptr ds:[esi+64]
004018A4 push 200401.00429220 祝英台
004018A9 push eax
004018AA call edi
004018AC add esp,8
004018AF test eax,eax
004018B1 jnz short 200401.004018B8
004018B3 mov ebx,63
004018B8 push ebx
004018B9 lea eax,dword ptr ds:[esi+68]
004018BC push 200401.0042921C ;
004018C1 push eax
004018C2 call <jmp.&MFC42.#2818>
004018C7 add esp,0C
004018CA mov ecx,esi
004018CC push 0
004018CE call <jmp.&MFC42.#6334>
004018D3 mov ecx,dword ptr ds:[esi+20]
004018D6 push 1 ;
004018D8 push 0 ;
004018DA push ecx ;
004018DB call dword ptr ds:[<&USER32.InvalidateRect>] ; \InvalidateRect
004018E1 lea ecx,dword ptr ds:[ebx+5] ; 以下计算分数分级,分数+5
004018E4 mov eax,66666667 ; 应该是四舍五入计算,但不知为什么代码这样。
004018E9 imul ecx
004018EB sar edx,2
004018EE mov eax,edx
004018F0 lea ecx,dword ptr ss:[esp+10]
004018F4 shr eax,1F
004018F7 add edx,eax
004018F9 mov edi,edx ; 等级保存在EDI,11个等级,0-4,5-14,类推。
004018FB call <jmp.&MFC42.#540>
00401900 cmp edi,0A ; 等级是否大于A,Switch (cases 0..A)
00401903 mov dword ptr ss:[esp+24],0
0040190B ja short 200401.00401968
0040190D jmp dword ptr ds:[edi*4+4019A0]
00401914 push 200401.00429204 ; Case 0 of switch 00401900
00401919 jmp short 200401.0040195F
0040191B push 200401.004291F0 ; Case 1 of switch 00401900
00401920 jmp short 200401.0040195F
00401922 push 200401.004291D8 ; Case 2 of switch 00401900
00401927 jmp short 200401.0040195F
00401929 push 200401.004291C0 ; Case 3 of switch 00401900
0040192E jmp short 200401.0040195F
00401930 push 200401.00429178 ; Case 4 of switch 00401900
00401935 jmp short 200401.0040195F
00401937 push 200401.00429150 ; Case 5 of switch 00401900
0040193C jmp short 200401.0040195F
0040193E push 200401.00429110 ; Case 6 of switch 00401900
00401943 jmp short 200401.0040195F
00401945 push 200401.004290E0 ; Case 7 of switch 00401900
0040194A jmp short 200401.0040195F
0040194C push 200401.004290B0 ; Case 8 of switch 00401900
00401951 jmp short 200401.0040195F
00401953 push 200401.00429078 ; Case 9 of switch 00401900
00401958 jmp short 200401.0040195F
0040195A push 200401.00429068 ; Case A of switch 00401900,千年等一回啊!
0040195F lea ecx,dword ptr ss:[esp+14]
00401963 call <jmp.&MFC42.#860>
00401968 mov ecx,dword ptr ss:[esp+10] ; Default case of switch 00401900
0040196C push 0
0040196E push 200401.0042905C
00401973 push ecx
00401974 mov ecx,esi
00401976 call <jmp.&MFC42.#4224>
0040197B lea ecx,dword ptr ss:[esp+10]
0040197F mov dword ptr ss:[esp+24],-1
00401987 call <jmp.&MFC42.#800>
0040198C mov ecx,dword ptr ss:[esp+1C]
00401990 pop edi
00401991 pop esi
00401992 pop ebp
00401993 pop ebx
00401994 mov dword ptr fs:[0],ecx
0040199B add esp,18
0040199E retn
0040199F nop
004019A0 dd 200401.00401914 ; Switch table used at 0040190D, 等级表
004019A4 dd 200401.0040191B
004019A8 dd 200401.00401922
004019AC dd 200401.00401929
004019B0 dd 200401.00401930
004019B4 dd 200401.00401937
004019B8 dd 200401.0040193E
004019BC dd 200401.00401945
004019C0 dd 200401.0040194C
004019C4 dd 200401.00401953
004019C8 dd 200401.0040195A
004019CC nop
004019CD nop
004019CE nop
004019CF nop
004019D0 jmp 200401.00401780
总结:其实软件是取男孩名字的每个字节相加,结果为A;女孩名字的每个字节相加,结果为B,
{Sin[(A+3.76793)*B]+1}*50即为最终分数(取正弦后加1是为了保证结果在0-100之间)
然后分数四舍五入获得等级(11个等级,对应0-A),不同等级有不同评语。
想哄女孩子的赶紧拿去玩玩吧。 由 lzqgj 于 2004-12-25 20:23 最后编辑
能力值:
( LV2,RANK:10 )
8 楼
NO7: 作者:80x86
屏幕录像专家 v5.0 注册码破解
【破文标题】 屏幕录像专家 v5.0 注册码破解分析
【破文作者】 80x86
【作者邮箱】 80x86@sohu.com
【使用工具】 Ollydbg,IDA
【破解平台】 XP
【软件名称】 屏幕录像专家
【下载地址】 http://download.enet.com.cn/html/040312003020601.html
【破解内容】
00437D20 /. 55 push ebp
00437D21 |. 8BEC mov ebp,esp
00437D23 |. 81C4 CCFEFFFF add esp,-134
00437D29 |. 53 push ebx
00437D2A |. 8995 44FFFFFF mov dword ptr ss:[ebp-BC],edx
00437D30 |. 8985 48FFFFFF mov dword ptr ss:[ebp-B8],eax
00437D36 |. B8 FCBA5000 mov eax,屏录专家.0050BAFC
00437D3B |. E8 60440A00 call <屏录专家.@__InitExceptBlockLDTC>
00437D40 |. 66:C785 5CFFFFFF 0800 mov word ptr ss:[ebp-A4],8
00437D49 |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
00437D4C |. E8 BF9BFCFF call <屏录专家.unknown_libname_37>
00437D51 |. 8BD0 mov edx,eax
00437D53 |. FF85 68FFFFFF inc dword ptr ss:[ebp-98]
00437D59 |. 8B8D 48FFFFFF mov ecx,dword ptr ss:[ebp-B8]
00437D5F |. 8B81 E4020000 mov eax,dword ptr ds:[ecx+2E4]
00437D65 |. E8 1E860500 call <屏录专家.@TControl@GetText$qqrv> ;取注册码
00437D6A |. 8D55 FC lea edx,dword ptr ss:[ebp-4] ;**edx->注册码
00437D6D |. FF32 push dword ptr ds:[edx]
00437D6F |. 8D45 F8 lea eax,dword ptr ss:[ebp-8]
00437D72 |. E8 999BFCFF call <屏录专家.unknown_libname_37>
00437D77 |. 8BD0 mov edx,eax
00437D79 |. FF85 68FFFFFF inc dword ptr ss:[ebp-98]
00437D7F |. 8B8D 48FFFFFF mov ecx,dword ptr ss:[ebp-B8]
00437D85 |. 8B81 DC020000 mov eax,dword ptr ds:[ecx+2DC]
00437D8B |. E8 F8850500 call <屏录专家.@TControl@GetText$qqrv> ;取注册名
00437D90 |. 8D55 F8 lea edx,dword ptr ss:[ebp-8] ;**edx->注册名
00437D93 |. FF32 push dword ptr ds:[edx]
00437D95 |. FFB5 48FFFFFF push dword ptr ss:[ebp-B8]
00437D9B |. E8 180C0000 call <屏录专家.old_ver> ;关于老版本
00437DA0 |. 83C4 0C add esp,0C
00437DA3 |. 3C 01 cmp al,1
00437DA5 |. 0F94C1 sete cl
00437DA8 |. 83E1 01 and ecx,1
00437DAB |. 51 push ecx
00437DAC |. FF8D 68FFFFFF dec dword ptr ss:[ebp-98]
00437DB2 |. 8D45 F8 lea eax,dword ptr ss:[ebp-8]
00437DB5 |. BA 02000000 mov edx,2
00437DBA |. E8 11F70A00 call <屏录专家.@System@AnsiString@$bdtr$qqrv>
00437DBF |. FF8D 68FFFFFF dec dword ptr ss:[ebp-98]
00437DC5 |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
00437DC8 |. BA 02000000 mov edx,2
00437DCD |. E8 FEF60A00 call <屏录专家.@System@AnsiString@$bdtr$qqrv>
00437DD2 |. 59 pop ecx
00437DD3 |. 84C9 test cl,cl
00437DD5 |. 74 48 je short 屏录专家.00437E1F ;不是老版本
00437DD7 |. 66:C785 5CFFFFFF 1400 mov word ptr ss:[ebp-A4],14 ;注册码是老版本
00437DE0 |. BA DCB75000 mov edx,屏录专家.0050B7DC
00437DE5 |. 8D45 F4 lea eax,dword ptr ss:[ebp-C]
00437DE8 |. E8 ABF40A00 call <屏录专家.sub_4E7298>
00437DED |. FF85 68FFFFFF inc dword ptr ss:[ebp-98]
00437DF3 |. 8B00 mov eax,dword ptr ds:[eax]
00437DF5 |. E8 46310500 call <屏录专家.@Dialogs@ShowMessage$qqrx17System@AnsiString>
00437DFA |. FF8D 68FFFFFF dec dword ptr ss:[ebp-98]
00437E00 |. 8D45 F4 lea eax,dword ptr ss:[ebp-C]
00437E03 |. BA 02000000 mov edx,2
00437E08 |. E8 C3F60A00 call <屏录专家.@System@AnsiString@$bdtr$qqrv>
00437E0D |. 8B8D 4CFFFFFF mov ecx,dword ptr ss:[ebp-B4]
00437E13 |. 64:890D 00000000 mov dword ptr fs:[0],ecx
00437E1A |. E9 7E0B0000 jmp 屏录专家.0043899D ;返回
不是老版本:
00437E1F |> 6A 14 push 14
00437E21 |. 6A 00 push 0
00437E23 |. 8D85 00FFFFFF lea eax,dword ptr ss:[ebp-100]
00437E29 |. 50 push eax
00437E2A |. E8 A13F0A00 call <屏录专家._memset>
00437E2F |. 83C4 0C add esp,0C
00437E32 |. 33D2 xor edx,edx
00437E34 |. 8995 40FFFFFF mov dword ptr ss:[ebp-C0],edx
00437E3A |. 6A 14 push 14
00437E3C |. 6A 00 push 0
00437E3E |. 8D8D 18FFFFFF lea ecx,dword ptr ss:[ebp-E8]
00437E44 |. 51 push ecx
00437E45 |. E8 863F0A00 call <屏录专家._memset>
00437E4A |. 83C4 0C add esp,0C
00437E4D |. 6A 14 push 14
00437E4F |. 6A 00 push 0
00437E51 |. 8D85 E8FEFFFF lea eax,dword ptr ss:[ebp-118]
00437E57 |. 50 push eax
00437E58 |. E8 733F0A00 call <屏录专家._memset>
00437E5D |. 83C4 0C add esp,0C
00437E60 |. 66:C785 5CFFFFFF 2000 mov word ptr ss:[ebp-A4],20
00437E69 |. 8D45 F0 lea eax,dword ptr ss:[ebp-10]
00437E6C |. E8 9F9AFCFF call <屏录专家.unknown_libname_37>
00437E71 |. 8BD0 mov edx,eax
00437E73 |. FF85 68FFFFFF inc dword ptr ss:[ebp-98]
00437E79 |. 8B8D 48FFFFFF mov ecx,dword ptr ss:[ebp-B8]
00437E7F |. 8B81 DC020000 mov eax,dword ptr ds:[ecx+2DC]
00437E85 |. E8 FE840500 call <屏录专家.@TControl@GetText$qqrv> ;取注册名
00437E8A |. 8D45 F0 lea eax,dword ptr ss:[ebp-10]
**eax->取注册名
00437E8D |. E8 46DEFCFF call <屏录专家.@System@AnsiString@c_str$xqqrv>
00437E92 |. 50 push eax
00437E93 |. 8D95 E8FEFFFF lea edx,dword ptr ss:[ebp-118]
00437E99 |. 52 push edx
00437E9A |. E8 5D400A00 call <屏录专家._strcpy> ;copy 注册名
00437E9F |. 83C4 08 add esp,8
00437EA2 |. FF8D 68FFFFFF dec dword ptr ss:[ebp-98]
00437EA8 |. 8D45 F0 lea eax,dword ptr ss:[ebp-10]
00437EAB |. BA 02000000 mov edx,2
00437EB0 |. E8 1BF60A00 call <屏录专家.@System@AnsiString@$bdtr$qqrv>
00437EB5 |. 66:C785 5CFFFFFF 2C00 mov word ptr ss:[ebp-A4],2C
00437EBE |. 8D45 EC lea eax,dword ptr ss:[ebp-14]
00437EC1 |. E8 4A9AFCFF call <屏录专家.unknown_libname_37>
00437EC6 |. 8BD0 mov edx,eax
00437EC8 |. FF85 68FFFFFF inc dword ptr ss:[ebp-98]
00437ECE |. 8B8D 48FFFFFF mov ecx,dword ptr ss:[ebp-B8]
00437ED4 |. 8B81 F0020000 mov eax,dword ptr ds:[ecx+2F0]
00437EDA |. E8 A9840500 call <屏录专家.@TControl@GetText$qqrv> ;取机器码
00437EDF |. 8D45 EC lea eax,dword ptr ss:[ebp-14]
;**eax->机器码
00437EE2 |. E8 F1DDFCFF call <屏录专家.@System@AnsiString@c_str$xqqrv>
00437EE7 |. 50 push eax
00437EE8 |. 8D95 00FFFFFF lea edx,dword ptr ss:[ebp-100]
00437EEE |. 52 push edx
00437EEF |. E8 08400A00 call <屏录专家._strcpy> ;copy 机器码
00437EF4 |. 83C4 08 add esp,8
00437EF7 |. FF8D 68FFFFFF dec dword ptr ss:[ebp-98]
00437EFD |. 8D45 EC lea eax,dword ptr ss:[ebp-14]
00437F00 |. BA 02000000 mov edx,2
00437F05 |. E8 C6F50A00 call <屏录专家.@System@AnsiString@$bdtr$qqrv>
00437F0A |. 33C9 xor ecx,ecx
00437F0C |. 898D 3CFFFFFF mov dword ptr ss:[ebp-C4],ecx
;*********************************************************************************************************
00437F12 |> 8B85 3CFFFFFF /mov eax,dword ptr ss:[ebp-C4]
00437F18 |. 8A9405 E8FEFFFF |mov dl,byte ptr ss:[ebp+eax-118] ;[ebp+eax-118]=注册名
00437F1F |. 8B8D 3CFFFFFF |mov ecx,dword ptr ss:[ebp-C4]
00437F25 |. 32940D 00FFFFFF |xor dl,byte ptr ss:[ebp+ecx-100] ;[ebp+ecx-100h]=机器码
00437F2C |. 8B85 3CFFFFFF |mov eax,dword ptr ss:[ebp-C4]
00437F32 |. 889405 18FFFFFF |mov byte ptr ss:[ebp+eax-E8],dl
00437F39 |. 8B95 3CFFFFFF |mov edx,dword ptr ss:[ebp-C4]
00437F3F |. 0FBE8C15 18FFFFFF |movsx ecx,byte ptr ss:[ebp+edx-E8]
00437F47 |. 898D CCFEFFFF |mov dword ptr ss:[ebp-134],ecx
00437F4D |. DB85 CCFEFFFF |fild dword ptr ss:[ebp-134]
00437F53 |. 83C4 F8 |add esp,-8
00437F56 |. DD1C24 |fstp qword ptr ss:[esp]
00437F59 |. E8 02840A00 |call <屏录专家._fabs> ;st=|[ebp-134h]|
00437F5E |. 83C4 08 |add esp,8
00437F61 |. DB85 3CFFFFFF |fild dword ptr ss:[ebp-C4] ;st=[ebp-0C4h]
00437F67 |. DEC9 |fmulp st(1),st ; st=|[ebp-134h]|*[ebp-0C4h]
00437F69 |. DB85 40FFFFFF |fild dword ptr ss:[ebp-C0] ;st=[ebp-0C0h]
00437F6F |. DEC1 |faddp st(1),st ; st=|[ebp-134h]|*[ebp-0C4h]+[ebp-0C0h]
00437F71 |. E8 12840A00 |call <屏录专家.@_ftol$qv> ; eax=st
00437F76 |. 8985 40FFFFFF |mov dword ptr ss:[ebp-C0],eax
00437F7C |. FF85 3CFFFFFF |inc dword ptr ss:[ebp-C4]
00437F82 |. 83BD 3CFFFFFF 14 |cmp dword ptr ss:[ebp-C4],14 ;20位
00437F89 |.^ 7C 87 \jl short 屏录专家.00437F12
;假设这段程序输出为temp_H
static char n[14]="ABABABAB"//注册名
static char m[14]="92388863"//机器码
int count;
int temp_H;
temp_H=0;
for count=0 to 14h do
{
temp_H=|n[count] xor m[count]|*count+temp_H
}
;*********************************************************************************************************
00437F8B |. 8185 40FFFFFF 39300000 add dword ptr ss:[ebp-C0],3039
00437F95 |. FFB5 40FFFFFF push dword ptr ss:[ebp-C0]
00437F9B |. 68 57B85000 push 屏录专家.0050B857
00437FA0 |. 8D95 18FFFFFF lea edx,dword ptr ss:[ebp-E8]
00437FA6 |. 52 push edx
00437FA7 |. E8 F8690A00 call <屏录专家._sprintf> ;把temp_H转为十进制temp_D (十六进)temp_H------->(十进制)temp_D
;*********************************************************************************************************
00437FAC |. 83C4 0C add esp,0C
00437FAF |. 66:C785 5CFFFFFF 3800 mov word ptr ss:[ebp-A4],38
00437FB8 |. 8D45 E8 lea eax,dword ptr ss:[ebp-18]
00437FBB |. E8 5099FCFF call <屏录专家.unknown_libname_37>
00437FC0 |. 8BD0 mov edx,eax
00437FC2 |. FF85 68FFFFFF inc dword ptr ss:[ebp-98]
00437FC8 |. 8B8D 48FFFFFF mov ecx,dword ptr ss:[ebp-B8]
00437FCE |. 8B81 E4020000 mov eax,dword ptr ds:[ecx+2E4]
00437FD4 |. E8 AF830500 call <屏录专家.@TControl@GetText$qqrv> ;取注册码
00437FD9 |. 8D45 E8 lea eax,dword ptr ss:[ebp-18]
;**EAX-> 注册码
00437FDC |. E8 F7DCFCFF call <屏录专家.@System@AnsiString@c_str$xqqrv>
00437FE1 |. 50 push eax
00437FE2 |. 8D95 D0FEFFFF lea edx,dword ptr ss:[ebp-130]
00437FE8 |. 52 push edx
00437FE9 |. E8 0E3F0A00 call <屏录专家._strcpy> ;COPY 取注册码
00437FEE |. 83C4 08 add esp,8
00437FF1 |. FF8D 68FFFFFF dec dword ptr ss:[ebp-98]
00437FF7 |. 8D45 E8 lea eax,dword ptr ss:[ebp-18]
00437FFA |. BA 02000000 mov edx,2
00437FFF |. E8 CCF40A00 call <屏录专家.@System@AnsiString@$bdtr$qqrv>
00438004 |. 33C9 xor ecx,ecx
00438006 |. 898D 3CFFFFFF mov dword ptr ss:[ebp-C4],ecx 0043800C |> 8B85 3CFFFFFF /mov eax,dword ptr ss:[ebp-C4]
00438012 |. 0FBE9405 18FFFFFF |movsx edx,byte ptr ss:[ebp+eax-E8];[ebp+eax-0E8h]=temp_D
0043801A |. 8B8D 3CFFFFFF |mov ecx,dword ptr ss:[ebp-C4]
00438020 |. 0FBE840D D0FEFFFF |movsx eax,byte ptr ss:[ebp+ecx-130];[ebp+ecx-130]=注册码
00438028 |. 83C0 EC |add eax,-14
0043802B |. 3BD0 |cmp edx,eax
0043802D |. 75 5D |jnz short 屏录专家.0043808C
| |
0043802F |. 83BD 3CFFFFFF 03 |cmp dword ptr ss:[ebp-C4],3;是不是第5位
00438036 |. 75 45 |jnz short 屏录专家.0043807D;不是第5位
| |
00438038 |. 8B95 40FFFFFF |mov edx,dword ptr ss:[ebp-C0];[ebp-C0]=temp_H
0043803E |. 81C2 444D0000 |add edx,4D44
00438044 |. 8995 CCFEFFFF |mov dword ptr ss:[ebp-134],edx
0043804A |. DB85 CCFEFFFF |fild dword ptr ss:[ebp-134]
00438050 |. DC0D A4894300 |fmul qword ptr ds:[4389A4] ;3.14
00438056 |. DB2D AC894300 |fld tbyte ptr ds:[4389AC] ;1.59489633173843711e-1
0043805C |. DEC9 |fmulp st(1),st
0043805E |. E8 25830A00 |call <屏录专家.@_ftol$qv> ;eax=st
00438063 |. 8985 40FFFFFF |mov dword ptr ss:[ebp-C0],eax
00438069 |. 8B85 40FFFFFF |mov eax,dword ptr ss:[ebp-C0]
0043806F |. B9 A0860100 |mov ecx,186A0
00438074 |. 99 |cdq
00438075 |. F7F9 |idiv ecx
00438077 |. 8995 40FFFFFF |mov dword ptr ss:[ebp-C0],edx ;edx:余数
| |
0043807D |> FF85 3CFFFFFF |inc dword ptr ss:[ebp-C4]
00438083 |. 83BD 3CFFFFFF 05 |cmp dword ptr ss:[ebp-C4],5 ;loop 5 次
0043808A |.^ 7C 80 \jl short 屏录专家.0043800C 0043808C |> 83BD 3CFFFFFF 05 cmp dword ptr ss:[ebp-C4],5 ;是不是第5位
00438093 |. 0F8C AD080000 jl 屏录专家.00438946 ;小于5失败
以下检查第5位:
00438099 |. 8B85 40FFFFFF mov eax,dword ptr ss:[ebp-C0]
0043809F |. B9 0A000000 mov ecx,0A
004380A4 |. 99 cdq
004380A5 |. F7F9 idiv ecx
004380A7 |. 8B85 3CFFFFFF mov eax,dword ptr ss:[ebp-C4]
004380AD |. 0FBE8C05 D0FEFFFF movsx ecx,byte ptr ss:[ebp+eax-130];[ebp+eax-130]=第5位注册码
004380B5 |. 83C1 BF add ecx,-41
004380B8 |. 2BCA sub ecx,edx ;edx通过对temp_H计算得到
004380BA |. 898D 38FFFFFF mov dword ptr ss:[ebp-C8],ecx
004380C0 |. 83BD 38FFFFFF 00 cmp dword ptr ss:[ebp-C8],0
004380C7 |. 74 0D je short 屏录专家.004380D6 ;成功
004380C9 |. 83BD 38FFFFFF 05 cmp dword ptr ss:[ebp-C8],5
004380D0 |. 0F85 25080000 jnz 屏录专家.004388FB ;失败 static char s[14]="xxxxxx"//注册码
int count
int buffer
for count=0 to 5 do
{ cmp temp_D[count],(s[count]-14)
jnz fail
if count=3 do {
buffer=mod(((temp_H+4d44h)*3.14*1.59489633173843711e-1)/186a0h)
}
}
buffer=s[count]-41-mod(buffer/0ah)
if buffer=0 or buffer=5 jmp succeed
fail:
succeed:
;************************************************************************************************************
成功:
004380D6 |> 66:C785 5CFFFFFF 4400 mov word ptr ss:[ebp-A4],44
004380DF |. BA 5AB85000 mov edx,屏录专家.0050B85A
004380E4 |. 8D45 E4 lea eax,dword ptr ss:[ebp-1C]
004380E7 |. E8 ACF10A00 call <屏录专家.sub_4E7298>
004380EC |. FF85 68FFFFFF inc dword ptr ss:[ebp-98]
004380F2 |. 8B00 mov eax,dword ptr ds:[eax]
004380F4 |. E8 472E0500 call <屏录专家.@Dialogs@ShowMessage$qqrx17System@AnsiString>
004380F9 |. FF8D 68FFFFFF dec dword ptr ss:[ebp-98]
004380FF |. 8D45 E4 lea eax,dword ptr ss:[ebp-1C]
00438102 |. BA 02000000 mov edx,2
【破解总结】
不能爆破,因为通过注册后他会把注册明肯注册码保存在pmlxzj.dll文件里,再次起动时会再检查,
我的机器码为"92388863",输入注册名为“ABABABAB"
下断点在:
0043800C |> 8B85 3CFFFFFF /mov eax,dword ptr ss:[ebp-C4]
00438012 |. 0FBE9405 18FFFFFF |movsx edx,byte ptr ss:[ebp+eax-E8];[ebp+eax-0E8h]=temp_D
可见[ebp+eax-E8]指向"31 35 36 35 30 00"
可得:
31h+14h=45h->"E"
35h+14h=49h->"I"
36h+14h=4Ah->"J"
35h+14h=49h->"I"
30h+14h=44h->"D"
"EIJID"为前5位注册码
再下断点在:
004380AD |. 0FBE8C05 D0FEFFFF movsx ecx,byte ptr ss:[ebp+eax-130];[ebp+eax-130]=第5位注册码
004380B5 |. 83C1 BF add ecx,-41
004380B8 |. 2BCA sub ecx,edx
可得到edx=3
所以第5位注册码为:3+41h=44h->"D" 或3+41h+5=49h->"I" 我的注册码为"EIJIDD"或"EIJIDI"
通过上面输入注册名与注册码后将通过注册,所有限制都取消,生成*.avi已没有未注册字样,
但生成*.exe时还是有未注册字样,通过重新跟踪发现程序重新运行时又读取注册名与注册码,进行了新的计算,
没能跟出来,但我用了另外一种方法来解决这个问题,就是把"play.dat"里未注册字样改为空格,
这样使用起来还没有发现有什么问题。
能力值:
( LV2,RANK:10 )
9 楼
NO8: 作者: icytear
EditPlus v2.12en破解全过程
第一篇破文,还望大家多多指教!!!!
【破解作者】icytear
【作者邮箱】icytear@126.com
【使用工具】SoftIce4.3.1,IDA4.5,PEiD0.92
【破解平台】WindowsXP Pro SP1.
【破解日期】2004.12.7 - 2004.12.22
【软件名称】EditPlus v2.12en
【软件大小】913,408 Byte
【加壳方式】无
【下载地址】
【软件简介】
EditPlus是Internet时代的32位文本编辑程序,HTML编辑及程序员的Windows平台编辑器。它可以充分的替换记事本,它也提供网页作家及程序设计师许多强悍的功能。对于HTML、CSS、PHP、ASP、Perl、C/C++、Java、JavaScript及VBScript的语法突显。当然,它也可以在自定义语法文件后扩充其他的程序语言。嵌合网页浏览器作HTML页的预览,及FTP命令做本地文件上传到FTP服务器。其他功能还包含HTML工具栏、用户工具、列号、标尺、URL突显。自动完成、剪贴文本、行列选择、强大的搜索与替换、多重撤消/重做、拼写检测、自定义键盘快捷键、以及更多。
【破解声明】本文仅供技术交流、学习之用。
【破解内容】
1. 用PEiD打开editplus发现无壳。
2. 打开程序出现注册对话框,点击输入注册码,Username输入"icytear",Regcode输入"280060443",下断点
addr editplus
bpx GetWindowTextA
单击注册按钮,程序被中断,按F12退出GetWindowTextA函数,到如下位置 001B:004BFC91 PUSH DWORD PTR [ESP+08]
001B:004BFC95 PUSH DWORD PTR [ESP+08]
001B:004BFC99 PUSH DWORD PTR [ECX+1C]
001B:004BFC9C CALL [USER32!GetWindowTextA]
001B:004BFCA2 JMP 004BFCB6 ;---->按F12后到这里,goto #exit
...
001B:004BFCB6 RET 0008 ;#exit
按2次F10执行代码,程序返回到#R01
001B:0047C850 MOV EAX,[ESP+0C]
001B:0047C854 MOV ECX,[ESP+04]
001B:0047C858 PUSH ESI
001B:0047C859 MOV ESI,[ESP+0C]
001B:0047C85D PUSH EAX
001B:0047C85E PUSH ESI
001B:0047C85F CALL 004BFC8A
001B:0047C864 MOV AL,[ESI] ;#R01---->程序返回到这里
001B:0047C866 CMP AL,20 ;---->从前向后比较字符是否为空格
001B:0047C868 JZ 0047C86E ;---->为空格则跳转,继续比较下一个字符
001B:0047C86A CMP AL,09 ;---->比较这个字符是否为制表符
001B:0047C86C JNZ 0047C871 ;---->如果不为空格也不是制表符则跳转到#J01↓
001B:0047C86E INC ESI ;---->如果字符为空格或制表符则删除
001B:0047C86F JMP 0047C864 ;---->继续比较下一个字符(跳转到#R01↑)
===>:0047C871 PUSH ESI ;↑#J01---->用户名入栈
001B:0047C872 CALL [KERNEL32!lstrlen] ;---->不用说了吧,得到用户名长度
001B:0047C878 MOV ECX,[ESP+14]
001B:0047C87C TEST EAX,EAX ;---->检查是否输入了用户名
001B:0047C87E MOV [ECX],EAX ;---->把结果保存起来
001B:0047C880 JLE 0047C899
001B:0047C882 MOV EAX,[ECX]
001B:0047C884 MOV DL,[ESI+EAX-01] ;---->取出最后一个字符
001B:0047C888 CMP DL,20 ;---->比较是否为空格
001B:0047C88B JZ 0047C892
001B:0047C88D CMP DL,09
001B:0047C890 JNZ 0047C899
001B:0047C892 DEC EAX ;---->继续向前比较
001B:0047C893 TEST EAX,EAX
001B:0047C895 MOV [ECX],EAX
001B:0047C897 JG 0047C882
001B:0047C899 MOV EDX,[ECX]
001B:0047C89B MOV BYTE PTR [ESI+EDX],00 ;---->删除末尾的空格和制表符
001B:0047C89F MOV EAX,[ECX]
001B:0047C8A1 TEST EAX,EAX ;
001B:0047C8A3 JNZ 0047C8AD
001B:0047C8A5 PUSH 40
001B:0047C8A7 CALL [USER32!MessageBeep]
001B:0047C8AD MOV EAX,ESI
001B:0047C8AF POP ESI
001B:0047C8B0 RET
上面的代码大概的意思就是:检查输入的用户名开始和末尾是否为有效字符(非空格和制表符)。
然后返回到#R02:
...
001B:0047C8E1 CALL 0047C850 ;---->取输入的用户名
001B:0047C8E6 MOV EBX,EAX ;#R02---->D EAX;EAX指向的就是输入的用户名icytear
001B:0047C8E8 MOV EAX,[ESP+20] ;---->[esp+20]存的是用户名的长度
001B:0047C8EC ADD ESP,10 ;---->平衡堆栈
001B:0047C8EF TEST EAX,EAX ;---->检查输入的用用户名是否有效
001B:0047C8F1 JZ 0047C9B1
001B:0047C8F7 LEA EAX,[ESP+0C] ;---->SS:[ESP+0C] = 00000034
001B:0047C8FB LEA ECX,[ESP+14] ;---->SS:[ESP+14] = 0
001B:0047C8FF PUSH EAX
001B:0047C900 PUSH 31
001B:0047C902 LEA EDX,[ESI+5C]
001B:0047C905 PUSH ECX
001B:0047C906 PUSH EDX
001B:0047C907 CALL 0047C850 ;---->用上面同样的方法得到输入的注册码
001B:0047C90C MOV ECX,[ESP+1C] ;---->[ESP+1C]输入的注册码长度
001B:0047C910 ADD ESP,10 ;---->平衡堆栈
001B:0047C913 TEST ECX,ECX ;---->检查有效注册码长度
001B:0047C915 MOV EDI,EAX
001B:0047C917 JZ 0047C9B1
001B:0047C91D XOR EAX,EAX
001B:0047C91F TEST ECX,ECX
001B:0047C921 JLE 0047C93B
001B:0047C923 XOR ECX,ECX
001B:0047C925 MOV CL,[EDI+EAX] ;---->从输入的注册码取一个字符
001B:0047C928 INC EAX ;---->移动指针指向下一个字符
001B:0047C929 MOV DL,[ECX+00522C90] ;---->查表,把小写转换成大写
001B:0047C92F MOV [EDI+EAX-01],DL
001B:0047C933 MOV ECX,[ESP+0C]
001B:0047C937 CMP EAX,ECX
001B:0047C939 JL 0047C923
001B:0047C93B PUSH EDI ;---->把输入的注册码入栈
001B:0047C93C PUSH EBX ;---->输入的用户名入栈
001B:0047C93D CALL 0047CA60 ;#C01---->关键调用
001B:0047C942 ADD ESP,08
001B:0047C945 TEST EAX,EAX
001B:0047C947 JNZ 0047C961 ;---->注册成功的关键
001B:0047C949 PUSH FF
001B:0047C94B PUSH 10
001B:0047C94D PUSH 00005F81
001B:0047C952 CALL 004C7E94 ;---->这里就弹出错误对话框了
001B:0047C957 POP EDI
001B:0047C958 POP ESI
001B:0047C959 POP EBX
001B:0047C95A ADD ESP,00000230
001B:0047C960 RET
001B:0047C961 PUSH EDI
001B:0047C962 PUSH EBX
001B:0047C963 CALL 0047C3B0
...
进入#C01 (CALL 0047CA60)继续跟踪
001B:0047CA60 SUB ESP,0C
001B:0047CA63 PUSH EBX ;---->用户名入栈
001B:0047CA64 MOV EBX,[KERNEL32!lstrlen]
001B:0047CA6A PUSH ESI
001B:0047CA6B PUSH EDI
001B:0047CA6C MOV EDI,[ESP+1C] ;---->edi指向了用户名
001B:0047CA70 PUSH EDI
001B:0047CA71 CALL EBX ;---->call [lstrlen],得到用户名长度
001B:0047CA73 MOV ESI,EAX
001B:0047CA75 TEST ESI,ESI ;---->
001B:0047CA77 JNZ 0047CA80 ;---->跳到#C01.C1
001B:0047CA79 POP EDI
001B:0047CA7A POP ESI
001B:0047CA7B POP EBX
001B:0047CA7C ADD ESP,0C
001B:0047CA7F RET
001B:0047CA80 CALL 0047C9C0 ;#C01.C1---->跟进去
001B:0047CA85 PUSH ESI
001B:0047CA86 PUSH EDI
001B:0047CA87 PUSH 00
001B:0047CA89 CALL 0047CA10 ;#C01.C2---->
001B:0047CA8E ADD ESP,0C
001B:0047CA91 AND EAX,0000FFFF
001B:0047CA96 PUSH EAX
001B:0047CA97 LEA EAX,[ESP+10]
001B:0047CA9B PUSH 0051824C
001B:0047CAA0 PUSH EAX
001B:0047CAA1 CALL 004AEABC ;#C01.C3---->sprintf
001B:0047CAA6 MOV ESI,[ESP+2C]
001B:0047CAAA MOV AL,[ESP+18]
...
进入#C01.C1 (CALL 0047C9C0).
001B:0047C9C0 PUSH ESI
001B:0047C9C1 PUSH EDI
001B:0047C9C2 MOV ECX,00000080 ;---->计数 0x80
001B:0047C9C7 XOR EAX,EAX ;---->EAX清零
001B:0047C9C9 MOV EDI,00523410
001B:0047C9CE XOR ESI,ESI
001B:0047C9D0 REPZ STOSD ;---->从00523410~00523610清零
001B:0047C9D2 MOV EDX,00523410
001B:0047C9D7 MOV EAX,0000C0C1 ;#loop1--->第一层循环
001B:0047C9DC MOV ECX,00000001
001B:0047C9E1 TEST ESI,ECX ;#loop2--->第二层循环
001B:0047C9E3 JZ 0047C9E8
001B:0047C9E5 XOR [EDX],AX
001B:0047C9E8 ADD EAX,EAX
001B:0047C9EA SHL ECX,1
001B:0047C9EC XOR EAX,00004003
001B:0047C9F1 CMP ECX,00000100
001B:0047C9F7 JL 0047C9E1 ;---->跳转到#loop2
001B:0047C9F9 ADD EDX,02
001B:0047C9FC INC ESI
001B:0047C9FD CMP EDX,00523610
001B:0047CA03 JL 0047C9D7 ;---->跳转到#loop1
001B:0047CA05 POP EDI
001B:0047CA06 POP ESI
001B:0047CA07 RET
以上代码用C语言表示如下:
WORD list[0x80*2];
void sub_0047C9C0()
{
int i,j=0;
DWORD ieax,iecx,iesi=0;
WORD temp;
for(i=0;i<0x80*2;i++)
list[i] = 0;
do{
ieax = 0x0C0C1; //ieax = 49345
iecx = 1;
do{
if ((iesi&iecx)!=0)
{
temp = (WORD)(ieax&0x0FFFF);
list[j] = list[j]^temp;
}
ieax*=2;
iecx*=2;
ieax = ieax^0x04003;
}while(iecx<0x100);
j++;
iesi++;
}while(j<0x80*2);
}
从#C01.C1 CALL 出来
...
001B:0047CA85 PUSH ESI ;---->用户名长度
001B:0047CA86 PUSH EDI ;---->用户名指针入栈
001B:0047CA87 PUSH 00
001B:0047CA89 CALL 0047CA10 ;#C01.C2--->跟进去..
001B:0047CA8E ADD ESP,0C
...
进入#C01.C2 (CALL 0047CA10).
001B:0047CA10 MOV ECX,[ESP+08] ;---->ECX指向用户名'icytear'
001B:0047CA14 MOV EAX,[ESP+0C] ;---->EAX存用户名长度,
001B:0047CA18 PUSH ESI
001B:0047CA19 LEA ESI,[EAX+ECX] ;---->ESI指向了用户名的末尾'\0'
001B:0047CA1C CMP ECX,ESI
001B:0047CA1E JAE 0047CA4A ;---->如果大于等于则跳转#exit.
001B:0047CA20 MOV EAX,[ESP+08]
001B:0047CA24 PUSH EBX
001B:0047CA25 MOV EDX,EAX ;#loop3
001B:0047CA27 XOR EBX,EBX
001B:0047CA29 MOV BL,[ECX] ;---->开始逐个字符取用户名
001B:0047CA2B AND EDX,000000FF
001B:0047CA31 XOR EDX,EBX
001B:0047CA33 XOR EBX,EBX
001B:0047CA35 MOV BL,AH
001B:0047CA37 MOV AX,[EDX*2+00523410] ;---->(00523410~00523610) #C01.C1 CALL 生成的东东
001B:0047CA3F XOR AX,BX
001B:0047CA42 INC ECX
001B:0047CA43 CMP ECX,ESI
001B:0047CA45 JB 0047CA25 ;---->如果小于跳转倒#loop3↑
001B:0047CA47 POP EBX
001B:0047CA48 POP ESI
001B:0047CA49 RET
001B:0047CA4A MOV AX,[ESP+08] ;#exit.
001B:0047CA4F POP ESI
001B:0047CA50 RET
##C01.C2 (CALL 0047CA10) C语言代码如下:
char username[]="icytear";
int sub_0047CA10(int n,char *pname,int unamelen)
{
DWORD ieax,iebx,iedx,temp;
char *iecx;
iecx = pname;
ieax = unamelen;
if(*iecx == '\0')
return 0;
ieax = n;
do{
//MOV EDX,EAX
iedx = ieax;
//XOR EBX,EBX
iebx = 0;
//MOV BL,[ECX]
temp = *iecx;
iebx = iebx & 0xFFFFFF00;
iebx = iebx ^ temp;
//AND EDX,000000FF
iedx = iedx & 0x000000FF;
//XOR EDX,EBX
iedx = iedx ^ iebx;
//XOR EBX,EBX
iebx = 0;
//MOV BL,AH
temp = ieax;
temp = temp>>8;
temp = temp & 0x000000FF;
iebx = iebx & 0xFFFFFF00;
iebx = iebx ^ temp;
//MOV AX,[EDX*2+00523410]
temp = list[iedx];
ieax = ieax & 0xFFFF0000;
ieax = ieax ^ temp;
//XOR AX,BX
temp = iebx;
temp = temp & 0x0000FFFF;
ieax = ieax ^ temp;
iecx++;
}while(*iecx != '\0');
return ieax;
}
从#C01.C2 CALL 出来到 #C01CALL
...
001B:0047CA8E ADD ESP,0C ;---->#C01.C2 CALL 出来到这里
001B:0047CA91 AND EAX,0000FFFF ;---->AX是用用户名算出的结果
001B:0047CA96 PUSH EAX
001B:0047CA97 LEA EAX,[ESP+10]
001B:0047CA9B PUSH 0051824C ;---->;"%02X"
001B:0047CAA0 PUSH EAX ;
001B:0047CAA1 CALL 004AEABC ;---->sprintf,把用户名算出的16进制结果以字符形式保存
001B:0047CAA6 MOV ESI,[ESP+2C]
001B:0047CAAA MOV AL,[ESP+18] ;---->[ESP+18] = "5CF",由"icytear"算出的值
001B:0047CAAE ADD ESP,0C
001B:0047CAB1 MOV CL,[ESI+02] ;---->[ESI+02] 注册码的第三个字符
001B:0047CAB4 LEA EDI,[ESI+02]
001B:0047CAB7 CMP CL,AL ;---->比较,在这里比较注册码第三个字符是否为'5'
001B:0047CAB9 JZ 0047CAC4
001B:0047CABB POP EDI
001B:0047CABC POP ESI
001B:0047CABD XOR EAX,EAX
001B:0047CABF POP EBX
001B:0047CAC0 ADD ESP,0C
001B:0047CAC3 RET
001B:0047CAC4 MOV DL,[ESI+03] ;---->注册码第四个字符
001B:0047CAC7 MOV AL,[ESP+0D] ;---->"5CF"的第二个字符
001B:0047CACB CMP DL,AL ;---->比较注册码的第四个字符是否为'C'
001B:0047CACD JZ 0047CAD8
001B:0047CACF POP EDI
001B:0047CAD0 POP ESI
001B:0047CAD1 XOR EAX,EAX
001B:0047CAD3 POP EBX
001B:0047CAD4 ADD ESP,0C
001B:0047CAD7 RET
001B:0047CAD8 PUSH ESI ;---->注册码
001B:0047CAD9 CALL EBX ;---->KERNEL!lstrlen
001B:0047CADB SUB EAX,02
001B:0047CADE PUSH EAX ;---->EAX == 注册码长度 - 2;
001B:0047CADF PUSH EDI ;---->第三位以后的注册码
001B:0047CAE0 PUSH 00
001B:0047CAE2 CALL 0047CA10 ;---->前面出现过这个函数,用注册码第三为以后的字符计算出一个值
001B:0047CAE7 ADD ESP,0C
001B:0047CAEA AND EAX,0000FFFF
001B:0047CAEF PUSH EAX
001B:0047CAF0 LEA EAX,[ESP+10]
001B:0047CAF4 PUSH 0051824C ;---->"%02X"
001B:0047CAF9 PUSH EAX
001B:0047CAFA CALL 004AEABC ;---->sprintf
001B:0047CAFF MOV CL,[ESI] ;---->取注册码的第一个字符
001B:0047CB01 MOV AL,[ESP+18] ;---->由第三位以后的注册码计算出的值(第一个字符)
001B:0047CB05 ADD ESP,0C
001B:0047CB08 CMP CL,AL ;---->比较注册码的第一位
001B:0047CB0A JZ 0047CB15
001B:0047CB0C POP EDI
001B:0047CB0D POP ESI
001B:0047CB0E XOR EAX,EAX
001B:0047CB10 POP EBX
001B:0047CB11 ADD ESP,0C
001B:0047CB14 RET
001B:0047CB15 MOV DL,[ESI+01] ;---->取注册码的第二个字符
001B:0047CB18 MOV CL,[ESP+0D] ;---->由第三位以后的注册码计算出的值(第二个字符)
001B:0047CB1C XOR EAX,EAX
001B:0047CB1E CMP DL,CL ;---->比较注册码的第二位
001B:0047CB20 POP EDI
001B:0047CB21 POP ESI
001B:0047CB22 SETZ AL
001B:0047CB25 POP EBX
001B:0047CB26 ADD ESP,0C
001B:0047CB29 RET ;---->出#C01 CALL 3. 以上代码,验证了注册码的前四位,以上可知注册码的第3、4位是由用户名用sub_0047CA10(int,char*,int)函数计算出的值16进制码的字符格式的前两位, 在这里为"5C"; 注册码的第1、2位是由注册码第三位以后的字符用sub_0047CA10函数计算出的16进制码的字符格式的前两位,用"5C60443"计算的结果为"EF",所以在这时注册码应为"ef5c60443".
回到注册对话框重新输入注册码"ef5c60443",提示需要重启EditPlus激活注册码,看来第一步验证通过了.
4. 重启EditPlus,提示"Invalid registration code.",看来其它的地方还有注册码的验证过程,好我们回到程序继续跟踪...
这次跟踪注册码用"EF5C60443".
出#C01 CALL 到...
001B:0047C942 ADD ESP,08 ;---->返回到这里
001B:0047C945 TEST EAX,EAX ;---->
001B:0047C947 JNZ 0047C961 ;---->跳转则第一步注册成功
001B:0047C949 PUSH FF
001B:0047C94B PUSH 10
001B:0047C94D PUSH 00005F81
001B:0047C952 CALL 004C7E94 ;---->出错对话框,
001B:0047C957 POP EDI
001B:0047C958 POP ESI
001B:0047C959 POP EBX
001B:0047C95A ADD ESP,00000230
001B:0047C960 RET
===>:0047C961 PUSH EDI ;---->注册码
001B:0047C962 PUSH EBX ;---->用户名
001B:0047C963 CALL 0047C3B0 ;#C02---->关于注册表的动作????,跟进去看看..
001B:0047C968 ADD ESP,08
001B:0047C96B TEST EAX,EAX
001B:0047C96D JNZ 0047C986 ;--->输入"ef5c60443"时,在这里我们跳转了..
001B:0047C96F PUSH FF
001B:0047C971 PUSH EAX
001B:0047C972 PUSH 00004E7F
001B:0047C977 CALL 004C7E94 ;--->注册失败!!
001B:0047C97C POP EDI
001B:0047C97D POP ESI
001B:0047C97E POP EBX
001B:0047C97F ADD ESP,00000230
001B:0047C985 RET
===>:0047C986 MOV ECX,[ESI+000000D8]
001B:0047C98C PUSH EBX ;---->用户名
001B:0047C98D CALL 004C0367 ;---->CString::=
001B:0047C992 MOV ECX,[ESI+000000DC]
001B:0047C998 PUSH EDI ;---->注册码"EF5C60443"
001B:0047C999 CALL 004C0367 ;---->CString::=
001B:0047C99E MOV EAX,[ESI+000000E4]
001B:0047C9A4 MOV ECX,ESI
001B:0047C9A6 MOV DWORD PTR [EAX],00000000
001B:0047C9AC CALL 004BF482 ;---->CDialog::0nOK(void)
001B:0047C9B1 POP EDI
001B:0047C9B2 POP ESI
001B:0047C9B3 POP EBX
001B:0047C9B4 ADD ESP,00000230
001B:0047C9BA RET
001B:0047C9BB NOP
... 进入#C02 ...
001B:0047C3B0 SUB ESP,000000E0
001B:0047C3B6 PUSH EBX ;---->用户名(保护现场)
001B:0047C3B7 PUSH EBP
001B:0047C3B8 PUSH ESI
001B:0047C3B9 MOV ESI,[ESP+000000F0] ;---->让ESI指向用户名
001B:0047C3C0 PUSH EDI ;---->注册码(保护现场)
001B:0047C3C1 MOV EDI,[KERNEL32!lstrlen]
001B:0047C3C7 PUSH ESI ;---->用户名入栈了
001B:0047C3C8 CALL EDI ;---->得到用户名长度
001B:0047C3CA MOV EBX,EAX
001B:0047C3CC MOV EAX,[ESP+000000F8]
001B:0047C3D3 PUSH EAX ;---->EAX指向注册码
001B:0047C3D4 CALL EDI ;---->注册码长度
001B:0047C3D6 LEA EBP,[EBX+EAX+02] ;---->ebp = name_len+sn_len+2;
001B:0047C3DA MOV [ESP+14],EAX
001B:0047C3DE PUSH EBP
001B:0047C3DF CALL 004AD84D ;---->malloc(size_t)分配内存
001B:0047C3E4 MOV ECX,EBX
001B:0047C3E6 LEA EDI,[EAX+01]
001B:0047C3E9 MOV EDX,ECX
001B:0047C3EB MOV [EAX],BL ;---->把bl(用户名长度)存到新分配的空间中的第一个字节
001B:0047C3ED SHR ECX,02
001B:0047C3F0 REPZ MOVSD ;---->把用户名存到分配的空间中
001B:0047C3F2 MOV ECX,EDX
001B:0047C3F4 MOV [ESP+1C],EAX
001B:0047C3F8 AND ECX,03
001B:0047C3FB REPZ MOVSB ;---->把用户名存到分配的空间中
001B:0047C3FD MOV ECX,[ESP+18] ;---->注册码长度
001B:0047C401 MOV ESI,[ESP+000000FC] ;---->ESI指向注册码
001B:0047C408 MOV [EAX+EBX+01],CL ;---->把cl(注册码长度)存到分配的空间中
001B:0047C40C LEA EDI,[EAX+EBX+02]
001B:0047C410 MOV EAX,ECX
001B:0047C412 SHR ECX,02
001B:0047C415 REPZ MOVSD ;---->存注册码
001B:0047C417 MOV ECX,EAX
001B:0047C419 MOV EAX,51EB851F
001B:0047C41E IMUL EBP ;---->EDX:EAX=0x51eb851f * 0x12 = 5C28F5C2E
001B:0047C420 AND ECX,03
001B:0047C423 REPZ MOVSB ;---->存注册码,此时内存中的数据为"\x07icytear\x09EF5C60443"
001B:0047C425 SAR EDX,05 ;---->移位操作
001B:0047C428 MOV ECX,EDX
001B:0047C42A SHR ECX,1F
001B:0047C42D ADD EDX,ECX
001B:0047C42F LEA EDX,[EBP+EDX+0C] ;---->计算要下一个操作要分配多少空间n
001B:0047C433 PUSH EDX
001B:0047C434 MOV [ESP+18],EDX ;---->把n存下来
001B:0047C438 CALL 004AD84D ;---->malloc(size_t)分配内存
001B:0047C43D MOV EDI,[ESP+20] ;---->EDI指向"\x07icytear\x09EF5C60443"
001B:0047C441 PUSH EBP
001B:0047C442 LEA EDX,[ESP+1C] ;---->EDX指向上次分配空间大小n
001B:0047C446 MOV ESI,EAX ;---->让ESI指向最近分配的内存空间
001B:0047C448 PUSH EDI ;---->EDI指向"\x07icytear\x09EF5C60443",
001B:0047C449 PUSH EDX
001B:0047C44A PUSH ESI
001B:0047C44B MOV [ESP+38],ESI
001B:0047C44F CALL 0049F820 ;#C1---->关键,计算出一段值(size:1E),要写入注册表License,在此处按F9下一个断点
001B:0047C454 ADD ESP,18
001B:0047C457 TEST EAX,EAX
001B:0047C459 JZ 0047C477 ;---->跳转到#J1
001B:0047C45B PUSH EDI
001B:0047C45C CALL 004AD764 ;---->call????
001B:0047C461 PUSH ESI
001B:0047C462 CALL 004AD764 ;---->call????
001B:0047C467 ADD ESP,08
001B:0047C46A XOR EAX,EAX
001B:0047C46C POP EDI
001B:0047C46D POP ESI
001B:0047C46E POP EBP
001B:0047C46F POP EBX
001B:0047C470 ADD ESP,0E0
001B:0047C476 RET
===>:0047C477 MOV EAX,[ESP+10] ;#J1---->
001B:0047C47B ADD EAX,08
001B:0047C47E PUSH EAX
001B:0047C47F MOV [ESP+18],EAX
001B:0047C483 CALL 004AD84D ;---->malloc(size_t)分配内存
001B:0047C488 MOV ECX,[0051A58] ;---->[0051A58]==DWORD 0x182989DB 定值
001B:0047C48E MOV EBX,EAX
001B:0047C490 MOV [EBX],ECX ;---->write memory...
001B:0047C492 MOV EDX,[00518A58]
001B:0047C498 PUSH EDX
001B:0047C499 CALL 004AD987 ;---->void _cdecl srand(unsigned int)
001B:0047C49E CALL 004AD994 ;---->int rand(void)产生一个伪随机数
001B:0047C4A3 ADD EAX,EBP ;---->ebp == name_len+sn_len+2
001B:0047C4A5 MOV [EBX+04],AX ;---->write memory... to [ebx+4]
001B:0047C4A9 MOV EAX,[00518A58]
001B:0047C4AE INC EAX
001B:0047C4AF PUSH EAX
001B:0047C4B0 CALL 004A987 ;---->srand
001B:0047C4B5 ADD ESP,0C
001B:0047C4B8 CALL 004AD994 ;---->rand() 产生一个伪随机数
001B:0047C4BD MOV ECX,[ESP+10]
001B:0047C4C1 LEA EDI,[EBX+08]
001B:0047C4C4 ADD EAX,ECX
001B:0047C4C6 MOV [EBX+06],AX ;---->write memory... to [ebx+6] = 0xb78188+6
001B:0047C4CA MOV ECX,[ESP+10]
001B:0047C4CE MOV EDX,ECX
001B:0047C4D0 SHR ECX,02
001B:0047C4D3 REPZ MOVSD
001B:0047C4D5 MOV ECX,EDX
001B:0047C4D7 AND ECX,03
001B:0047C4DA REPZ MOVSB
...
把刚才生成的16进制码写注册表...
...
按F5运行程序,又提示重启editplus,退出程序..在这里程序被上面按F9下的那个断点中断(在#C02.#C1,001B:0047C44B),看来程序在关闭时又调用了一次#C02 Call,也就是又写了一次注册表,好我们用D edi命令查看edi指向的内存为"\x07icytear\x090F5C60443",看到区别了吗,前面我们看到的是"\x07icytear\x09EF5C60443",看来是被程序修改了,用这个再一次计算出16进制代码写入注册表,重启editplus时和第一次写得当然就不一样了,看来程序是在这里做了手脚..
我们按F12退出此次调用(CALL 0047C3B0)
...
001B:0042E691 CALL 0047C3B0
001B:0042E696 ADD ESP,08 ;---->到这里
...
我们向上查看代码,看到
...
001B:0042E661 TEST EAX,EAX
001B:0042E663 JZ 0042E69A ;---->这里有个跳转,如果跳就不能执行CALL 0047C3B0了,按F9在这里下个断点(把其它得断点可以先禁掉),如果跳转我们就可以注册成功..
重新输入注册码后退出editplus程序被中断,单步执行看看
...
001B:0042E653 MOV EAX,[ESI+B44]
001B:0042E659 MOV DWORD PTR [ESP+10],08
001B:0042E661 TEST EAX,EAX
001B:0042E663 JZ 0042E69A
001B:0042E665 MOV EAX,[ESI+0B30] ;---->D EAX,发现eax指向的还是"EF5C60443",由此判断可能是由于下面的代码改变了此字符串,我们保持此内存的窗口,继续往下执行
001B:0042E66B PUSH EDI
001B:0042E66C LEA EDI,[ESI+0B30]
001B:0042E672 MOV AL,[EAX]
001B:0042E674 CMP AL,30
001B:0042E676 JNZ 0042E67C
001B:0042E678 PUSH 31
001B:0042E67A JMP 0042E67E
001B:0042E67C PUSH 30
001B:0042E67E PUSH 00
001B:0042E680 MOV ECX,EDI
001B:0042E682 CALL 004C069E ;#C03---->执行此调用后,"EF5C60443"被改为"0F5C60443",看来我们的判断是真确的.
001B:0042E687 MOV EDI,[EDI]
001B:0042E689 MOV EAX,[ESI+B2C]
001B:0042E68F PUSH EDI
001B:0042E690 PUSH EAX
001B:0042E691 CALL 0047C3B0
...
我们再看看TEST EAX,EAX 中的EAX从那来的,向上看到MOV EAX,[ESI+B44],用D ESI+B44查看内存,显示如下
...
0023:00B7590C 01 00 00 00 .....
0023:00B7591C .......
...
那我们下一个内存断点试试,BPMD 0B7590C,再次输入注册码点击注册,OK,程序被中断在..
...
001B:0047C9A6 MOV DWORD PTR [EAX],0 ;---->这里改变内存,赋值0
001B:0047C9AC CALL 004BF482 ;---->中断在此
...
MOV DWORD PTR [EAX],0;把内存B7590C赋值0,我们要看看在那里把其改为1的,按F5执行程序,再次中断
...
001B:0047C718 MOV DWORD PTR [ECX],01 ;---->改变内存,赋值1
001B:0047C71E LEA ECX,[EDI+98] ;---->中断在此
...
我们向上看程序
001B:0047C707 MOV AL,[EAX,04] ;---->把第5位注册码存入AL
001B:0047C70A MOV CL,[ESP+10] ;---->那[esp+10]存的是什么呢?我们继续向上看程序 001B:0047C670 PUSH FF
001B:0047C672 PUSH 004E6183
001B:0047C677 MOV EAX,FS:[00000000]
001B:0047C67D PUSH EAX
001B:0047C67E MOV FS:[0],ESP
001B:0047C685 SUB ESP,10
001B:0047C688 PUSH EBP
001B:0047C689 PUSH ESI
001B:0047C68A PUSH EDI
001B:0047C68B MOV EDI,ECX
001B:0047C691 MOV DWORD PTR [EDI],004F41E0
001B:0047C697 MOV EAX,[EDI+D8]
001B:0047C69D MOV DWORD PTR [ESP+24],01
001B:0047C6A5 MOV EBP,[EAX] ;---->让EBP指向用户名"icytear"
001B:0047C6A7 MOV ESI,[EBP-08] ;---->ESI存用户名长度
001B:0047C6AA TEST ESI,ESI
001B:0047C6AC JLE 0047C71E ;---->跳过赋值1的那个指令
001B:0047C6AE XOR EAX,EAX
001B:0047C6B0 MOV ECX,01 ;---->ECX赋值1
001B:0047C6B5 TEST ESI,ESI
001B:0047C6B7 JLE 0047C6C5
===>:0047C6B9 XOR EDX,EDX ;#LOOP
001B:0047C6BB MOV DL,[EBP+EAX]
001B:0047C6BE ADD ECX,EDX
001B:0047C6C0 INC EAX
001B:0047C6C1 CMP EAX,ESI
001B:0047C6C3 JL 0047C6B9 ;---->跳到#LOOP,用户名每一位的值相加再加1;
001B:0047C6C5 LEA ECX,[ECX*8+ECX+0A]
001B:0047C6C9 MOV EAX,55555556
001B:0047C6CE IMUL ECX
001B:0047C6D0 MOV EAX,EDX
001B:0047C6D2 SHR EAX,1F
001B:0047C6D5 LEA ECX,[EAX+EDX+24]
001B:0047C6D9 AND ECX,8000000F
001B:0047C6DF JNS 0047C6E6
001B:0047C6E1 DEC ECX
001B:0047C6E2 OR ECX,-10
001B:0047C6E5 INC ECX
===>:0047C6E6 PUSH ECX
001B:0047C6E7 LEA EDX,[ESP+14]
001B:0047C6EB PUSH 0051700C ;---->"%1X"
001B:0047C6F0 PUSH EDX
001B:0047C6F1 CALL 004AEABC ;---->sprintf
001B:0047C6F6 MOV EAX,[EDI+DC]
001B:0047C6FC ADD ESP,0C
001B:0047C6FF MOV EAX,[EAX] ;---->EAX指向注册码
001B:0047C701 CMP DWORD PTR[EAX-8],05 ;---->[EAX-8]存着注册码长度,也就是说注册码长度应该大于5
001B:0047C605 JL 0047C712
001B:0047C607 MOV AL,[EAX,04] ;---->注册码第5位
001B:0047C60A MOV CL,[ESP+10] ;---->很显然是我们用用户名算出的那个值
001B:0047C60E CMP AL,CL ;---->验证第5位注册码,在这里我们计算出的是'D'
001B:0047C610 JZ 0047C71E ;---->第二次验证通过则注册成功..^_^,胜利!!
001B:0047C612 MOV ECX,[EDI+E4]
001B:0047C618 MOV DWORD PTR[ECX],01
...
5. 用我得用户名'icytear'计算出的值是'D'所以我的第5位注册码应为'D',前2位应用'5CD0443'由sub_0047CA10重新计算为'E4',重新输入注册码'E45CD0443',哈哈,注册成功!!
6. 好累,注册机大家写吧,别忘了给我发一份!! ###############
username: icytear
Regcode: E45CD0443
###############
能力值:
( LV2,RANK:10 )
10 楼
NO9: 作者:kyc
系统优化大师V2004 build 12.10 破解教程
【破解作者】 kyc[dfcg][czg]
【作者邮箱】 [email]muyang008@163.com[/email]
【使用工具】 FLYold1.10c
【破解平台】 win2003
【软件名称】 系统优化大师V2004 build 12.10
【下载地址】
http://www.skycn.com/soft/12317.html
【软件简介】〖系统优化大师〗软件是一个电脑性能优化软件。软件全面、高效、安全地提高系统性能,使用简单,傻瓜式操作。
使用本软件可能迅速达到系统优化目的。包括桌面优化、菜单优化、网络优化、软件优化、系统优化以及禁用设置、选择设置、
更改设置等一系列个性化优化及设置选项。软件可以进行高速的注册表清理及高速的硬盘垃圾文件清理,清理全面、安全、
不影响任何运行性能。软件绿色、环保、小巧、功能强大、可完全卸载,放心使用。软件由澄海市夫子电脑工作室推荐,软件随时升级。
【软件大小】 1743 KB
【加壳方式】 无壳
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】这个软件的注册码是重启验证的,注册码保存在注册表里
用OLD分析后很容易得到以下代码,具体下断点分析过程我就忽略了。
0052A8C0 /. 55 push ebp ; f2
0052A8C1 |. 8BEC mov ebp,esp
0052A8C3 |. B9 17000000 mov ecx,17
0052A8C8 |> 6A 00 /push 0
0052A8CA |. 6A 00 |push 0
0052A8CC |. 49 |dec ecx
0052A8CD |.^ 75 F9 \jnz short yhds.0052A8C8
0052A8CF |. 51 push ecx ; f4
0052A8D0 |. 53 push ebx
0052A8D1 |. 56 push esi
0052A8D2 |. 57 push edi
0052A8D3 |. 8BD8 mov ebx,eax
0052A8D5 |. 33C0 xor eax,eax
0052A8D7 |. 55 push ebp
0052A8D8 |. 68 89AB5200 push yhds.0052AB89
0052A8DD |. 64:FF30 push dword ptr fs:[eax]
0052A8E0 |. 64:8920 mov dword ptr fs:[eax],esp
0052A8E3 |. B2 01 mov dl,1
0052A8E5 |. A1 446B4700 mov eax,dword ptr ds:[476B44]
0052A8EA |. E8 C1C3F4FF call yhds.00476CB0
0052A8EF |. 8B15 80725900 mov edx,dword ptr ds:[597280] ; yhds.00599948
0052A8F5 |. 8902 mov dword ptr ds:[edx],eax
0052A8F7 |. A1 80725900 mov eax,dword ptr ds:[597280]
0052A8FC |. 8B00 mov eax,dword ptr ds:[eax]
0052A8FE |. BA 02000080 mov edx,80000002
0052A903 |. E8 84C4F4FF call yhds.00476D8C
0052A908 |. A1 80725900 mov eax,dword ptr ds:[597280]
0052A90D |. 8B00 mov eax,dword ptr ds:[eax]
0052A90F |. B1 01 mov cl,1
0052A911 |. BA A0AB5200 mov edx,yhds.0052ABA0 ; ASCII "SOFTWARE\Microsoft\Yhds"
0052A916 |. E8 B5C5F4FF call yhds.00476ED0 ;这是注册码保存在注册表位置
0052A91B |. 68 80000000 push 80 ; /BufSize = 80 (128.)
0052A920 |. 8D85 7BFFFFFF lea eax,dword ptr ss:[ebp-85] ; |
0052A926 |. 50 push eax ; |Buffer
0052A927 |. E8 78CCEDFF call <jmp.&kernel32.GetSystemDirectoryA> ; \GetSystemDirectoryA
0052A92C |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
0052A92F |. 8D95 7BFFFFFF lea edx,dword ptr ss:[ebp-85]
0052A935 |. B9 81000000 mov ecx,81
0052A93A |. E8 C5A3EDFF call yhds.00404D04
0052A93F |. 8D95 74FFFFFF lea edx,dword ptr ss:[ebp-8C]
0052A945 |. 8B83 14030000 mov eax,dword ptr ds:[ebx+314]
0052A94B |. E8 9816F2FF call yhds.0044BFE8
0052A950 |. 83BD 74FFFFFF>cmp dword ptr ss:[ebp-8C],0 ; 确认码不能为空
0052A957 |. 74 1A je short yhds.0052A973
0052A959 |. 8D95 70FFFFFF lea edx,dword ptr ss:[ebp-90]
0052A95F |. 8B83 08030000 mov eax,dword ptr ds:[ebx+308]
0052A965 |. E8 7E16F2FF call yhds.0044BFE8
0052A96A |. 83BD 70FFFFFF>cmp dword ptr ss:[ebp-90],0 ; 注册码不能为空
0052A971 |. 75 0F jnz short yhds.0052A982
0052A973 |> B8 C0AB5200 mov eax,yhds.0052ABC0
0052A978 |. E8 9BA7F1FF call yhds.00445118
0052A97D |. E9 85010000 jmp yhds.0052AB07
0052A982 |> 8D95 6CFFFFFF lea edx,dword ptr ss:[ebp-94]
0052A988 |. 8B83 08030000 mov eax,dword ptr ds:[ebx+308]
0052A98E |. E8 5516F2FF call yhds.0044BFE8
0052A993 |. 8B85 6CFFFFFF mov eax,dword ptr ss:[ebp-94]
0052A999 |. 50 push eax
0052A99A |. 8D95 64FFFFFF lea edx,dword ptr ss:[ebp-9C]
0052A9A0 |. 8B83 14030000 mov eax,dword ptr ds:[ebx+314]
0052A9A6 |. E8 3D16F2FF call yhds.0044BFE8
0052A9AB |. 8B85 64FFFFFF mov eax,dword ptr ss:[ebp-9C]
0052A9B1 |. E8 8EEFEDFF call yhds.00409944 ; EAX=确认码
0052A9B6 |. B9 A1030000 mov ecx,3A1 ; ECX=3A1
0052A9BB |. 99 cdq
0052A9BC |. F7F9 idiv ecx ; EAX/3A1
0052A9BE |. 8BC2 mov eax,edx ; EAX=EAX%3A1 重要记住
0052A9C0 |. 8D95 68FFFFFF lea edx,dword ptr ss:[ebp-98]
0052A9C6 |. E8 99EEEDFF call yhds.00409864
0052A9CB |. 8D85 68FFFFFF lea eax,dword ptr ss:[ebp-98]
0052A9D1 |. 50 push eax
0052A9D2 |. 8D95 58FFFFFF lea edx,dword ptr ss:[ebp-A8]
0052A9D8 |. 8B83 14030000 mov eax,dword ptr ds:[ebx+314]
0052A9DE |. E8 0516F2FF call yhds.0044BFE8
0052A9E3 |. 8B85 58FFFFFF mov eax,dword ptr ss:[ebp-A8]
0052A9E9 |. E8 56EFEDFF call yhds.00409944
0052A9EE |. 8D95 5CFFFFFF lea edx,dword ptr ss:[ebp-A4]
0052A9F4 |. E8 17FCFFFF call yhds.0052A610 ; F7 关键算法
0052A9F9 |. 8B85 5CFFFFFF mov eax,dword ptr ss:[ebp-A4]
0052A9FF |. E8 40EFEDFF call yhds.00409944
0052AA04 |. 8D95 60FFFFFF lea edx,dword ptr ss:[ebp-A0]
0052AA0A |. E8 E1FCFFFF call yhds.0052A6F0 ; F7 关键算法
0052AA0F |. 8B95 60FFFFFF mov edx,dword ptr ss:[ebp-A0]
0052AA15 |. 58 pop eax
0052AA16 |. E8 41A3EDFF call yhds.00404D5C ; f7 **关键算法连接上面算好的数字
0052AA1B |. 8B95 68FFFFFF mov edx,dword ptr ss:[ebp-98]
0052AA21 |. 58 pop eax
0052AA22 |. E8 71A4EDFF call yhds.00404E98 ; F7
0052AA27 |. 0F85 CD000000 jnz yhds.0052AAFA
0052AA2D |. 8D95 54FFFFFF lea edx,dword ptr ss:[ebp-AC]
0052AA33 |. 8B83 08030000 mov eax,dword ptr ds:[ebx+308]
0052AA39 |. E8 AA15F2FF call yhds.0044BFE8
0052AA3E |. 8B8D 54FFFFFF mov ecx,dword ptr ss:[ebp-AC]
0052AA44 |. A1 80725900 mov eax,dword ptr ds:[597280]
0052AA49 |. 8B00 mov eax,dword ptr ds:[eax]
0052AA4B |. BA E0AB5200 mov edx,yhds.0052ABE0 ; ASCII "yhdsger"
0052AA50 |. E8 A7C9F4FF call yhds.004773FC
0052AA55 |. 8D85 50FFFFFF lea eax,dword ptr ss:[ebp-B0]
0052AA5B |. B9 F0AB5200 mov ecx,yhds.0052ABF0 ; ASCII "\i1l00.sys"
=============================================================================call yhds.0052A610
0052A610 /$ 55 push ebp
0052A611 |. 8BEC mov ebp,esp
0052A613 |. 33C9 xor ecx,ecx
0052A615 |. 51 push ecx
0052A616 |. 51 push ecx
0052A617 |. 51 push ecx
0052A618 |. 51 push ecx
0052A619 |. 53 push ebx
0052A61A |. 56 push esi
0052A61B |. 8BF2 mov esi,edx
0052A61D |. 8BD8 mov ebx,eax ; ebx=eax=确认码
0052A61F |. 33C0 xor eax,eax ; eax=0
0052A621 |. 55 push ebp
0052A622 |. 68 E0A65200 push yhds.0052A6E0
0052A627 |. 64:FF30 push dword ptr fs:[eax]
0052A62A |. 64:8920 mov dword ptr fs:[eax],esp
0052A62D |. 81F3 F1250B00 xor ebx,0B25F1 ; ebx=0B25F1
0052A633 |. 8BC3 mov eax,ebx ; eax=ebx
0052A635 |. 33D2 xor edx,edx ; edx=0
0052A637 |. 52 push edx ; /Arg2 => 00000000
0052A638 |. 50 push eax ; |Arg1
0052A639 |. 8D45 FC lea eax,dword ptr ss:[ebp-4] ; |
0052A63C |. E8 53F2EDFF call yhds.00409894 ; \yhds.00409894
0052A641 |. 8B45 FC mov eax,dword ptr ss:[ebp-4] ; 确认码和0B25F1 异或结果转成10进制
0052A644 |. 0FB600 movzx eax,byte ptr ds:[eax] ; eax=[eax]第1个数值
0052A647 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A64A |. 0FB652 01 movzx edx,byte ptr ds:[edx+1] ; edx=[eax+1]第2个数值
0052A64E |. 03C2 add eax,edx ; EAX=eax+edx
0052A650 |. B9 05000000 mov ecx,5 ; ecx=5
0052A655 |. 99 cdq
0052A656 |. F7F9 idiv ecx ; eax/ecx
0052A658 |. 80C2 34 add dl,34 ; DL=eax%ecx+34
0052A65B |. 8855 F8 mov byte ptr ss:[ebp-8],dl ; [EBP-8]=DL
0052A65E |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0052A661 |. 0FB640 02 movzx eax,byte ptr ds:[eax+2] ; eax=[eax+2]第3个数值
0052A665 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A668 |. 0FB652 03 movzx edx,byte ptr ds:[edx+3] ; edx=[eax+3]第4个数值
0052A66C |. 03C2 add eax,edx ; EAX=eax+edx
0052A66E |. B9 05000000 mov ecx,5 ; ecx=5
0052A673 |. 99 cdq
0052A674 |. F7F9 idiv ecx ; eax/ecx
0052A676 |. 8BDA mov ebx,edx
0052A678 |. 80C3 33 add bl,33 ; BL=bl+33
0052A67B |. 885D F9 mov byte ptr ss:[ebp-7],bl ; [EBP-7]=BL
0052A67E |. 8D45 F4 lea eax,dword ptr ss:[ebp-C]
0052A681 |. 8A55 F8 mov dl,byte ptr ss:[ebp-8]
0052A684 |. E8 F3A5EDFF call yhds.00404C7C
0052A689 |. 8B45 F4 mov eax,dword ptr ss:[ebp-C]
0052A68C |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
0052A68F |. B9 1B000000 mov ecx,1B
0052A694 |. E8 9BA9EDFF call yhds.00405034
0052A699 |. 8D45 F0 lea eax,dword ptr ss:[ebp-10]
0052A69C |. 8BD3 mov edx,ebx
0052A69E |. E8 D9A5EDFF call yhds.00404C7C
0052A6A3 |. 8B45 F0 mov eax,dword ptr ss:[ebp-10]
0052A6A6 |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
0052A6A9 |. B9 19000000 mov ecx,19
0052A6AE |. E8 81A9EDFF call yhds.00405034 ; 把两个值连接到异或后的10进制数组后面
0052A6B3 |. 8BC6 mov eax,esi
0052A6B5 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A6B8 |. E8 33A4EDFF call yhds.00404AF0
0052A6BD |. 33C0 xor eax,eax
0052A6BF |. 5A pop edx
0052A6C0 |. 59 pop ecx
0052A6C1 |. 59 pop ecx
0052A6C2 |. 64:8910 mov dword ptr fs:[eax],edx
0052A6C5 |. 68 E7A65200 push yhds.0052A6E7
0052A6CA |> 8D45 F0 lea eax,dword ptr ss:[ebp-10]
0052A6CD |. BA 02000000 mov edx,2
0052A6D2 |. E8 E9A3EDFF call yhds.00404AC0
0052A6D7 |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
0052A6DA |. E8 BDA3EDFF call yhds.00404A9C
====================================================================================call yhds.0052A6F0
0052A6F0 /$ 55 push ebp
0052A6F1 |. 8BEC mov ebp,esp
0052A6F3 |. 33C9 xor ecx,ecx
0052A6F5 |. 51 push ecx
0052A6F6 |. 51 push ecx
0052A6F7 |. 51 push ecx
0052A6F8 |. 51 push ecx
0052A6F9 |. 51 push ecx
0052A6FA |. 51 push ecx
0052A6FB |. 53 push ebx
0052A6FC |. 56 push esi
0052A6FD |. 8BF2 mov esi,edx
0052A6FF |. 8BD8 mov ebx,eax ; EBX=EAX=刚形成的数值
0052A701 |. 33C0 xor eax,eax
0052A703 |. 55 push ebp
0052A704 |. 68 3CA85200 push yhds.0052A83C
0052A709 |. 64:FF30 push dword ptr fs:[eax]
0052A70C |. 64:8920 mov dword ptr fs:[eax],esp
0052A70F |. 81F3 8776FBDD xor ebx,DDFB7687 ; EBX^DDFB7687
0052A715 |. 8BC3 mov eax,ebx ; EAX=EBX
0052A717 |. 33D2 xor edx,edx ; EDX=0
0052A719 |. 52 push edx ; /Arg2 => 00000000
0052A71A |. 50 push eax ; |Arg1
0052A71B |. 8D45 FC lea eax,dword ptr ss:[ebp-4] ; |
0052A71E |. E8 71F1EDFF call yhds.00409894 ; \结果转换为10进制
0052A723 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0052A726 |. 0FB600 movzx eax,byte ptr ds:[eax] ; EAX=第1位数值
0052A729 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A72C |. 0FB652 01 movzx edx,byte ptr ds:[edx+1] ; EDX=第2位数值
0052A730 |. 03C2 add eax,edx ; EAX=EAX+EDX
0052A732 |. B9 05000000 mov ecx,5
0052A737 |. 99 cdq
0052A738 |. F7F9 idiv ecx ; EAX/5
0052A73A |. 80C2 66 add dl,66 ; DL=EAX%5+66
0052A73D |. 8855 F8 mov byte ptr ss:[ebp-8],dl ; [EBP-8]=DL
0052A740 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0052A743 |. 0FB640 02 movzx eax,byte ptr ds:[eax+2] ; EAX=第3位数值
0052A747 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A74A |. 0FB652 03 movzx edx,byte ptr ds:[edx+3] ; EDX=第4位数值
0052A74E |. 03C2 add eax,edx ; EAX=EAX+EDX
0052A750 |. B9 05000000 mov ecx,5
0052A755 |. 99 cdq
0052A756 |. F7F9 idiv ecx ; EAX/5
0052A758 |. 80C2 75 add dl,75 ; DL=EAX%5+75
0052A75B |. 8855 F9 mov byte ptr ss:[ebp-7],dl
0052A75E |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0052A761 |. 0FB640 04 movzx eax,byte ptr ds:[eax+4] ; EAX=第5位数值
0052A765 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A768 |. 0FB652 05 movzx edx,byte ptr ds:[edx+5] ; EDX=第6位数值
0052A76C |. 03C2 add eax,edx ; EAX=EAX+EDX
0052A76E |. B9 05000000 mov ecx,5
0052A773 |. 99 cdq
0052A774 |. F7F9 idiv ecx ; EAX/5
0052A776 |. 80C2 7A add dl,7A ; DL=EAX%5+7A
0052A779 |. 8855 FA mov byte ptr ss:[ebp-6],dl
0052A77C |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0052A77F |. 0FB640 06 movzx eax,byte ptr ds:[eax+6] ; EAX=第7位数值
0052A783 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A786 |. 0FB652 07 movzx edx,byte ptr ds:[edx+7] ; EDX=第8位数值
0052A78A |. 03C2 add eax,edx ; EAX=EAX+EDX
0052A78C |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A78F |. 0FB652 08 movzx edx,byte ptr ds:[edx+8] ; EDX=第9位数值
0052A793 |. 03C2 add eax,edx ; EAX=EAX+EDX
0052A795 |. B9 05000000 mov ecx,5
0052A79A |. 99 cdq
0052A79B |. F7F9 idiv ecx ; EAX/5
0052A79D |. 80C2 69 add dl,69
0052A7A0 |. 8855 FB mov byte ptr ss:[ebp-5],dl
0052A7A3 |. 8D45 F4 lea eax,dword ptr ss:[ebp-C]
0052A7A6 |. 8A55 F8 mov dl,byte ptr ss:[ebp-8]
0052A7A9 |. E8 CEA4EDFF call yhds.00404C7C
0052A7AE |. 8B45 F4 mov eax,dword ptr ss:[ebp-C]
0052A7B1 |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
0052A7B4 |. B9 07000000 mov ecx,7
0052A7B9 |. E8 76A8EDFF call yhds.00405034 ;F7 把第1个字符插入到第7位
0052A7BE |. 8D45 F0 lea eax,dword ptr ss:[ebp-10]
0052A7C1 |. 8A55 FB mov dl,byte ptr ss:[ebp-5]
0052A7C4 |. E8 B3A4EDFF call yhds.00404C7C
0052A7C9 |. 8B45 F0 mov eax,dword ptr ss:[ebp-10]
0052A7CC |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
0052A7CF |. B9 03000000 mov ecx,3
0052A7D4 |. E8 5BA8EDFF call yhds.00405034 ; f7把第4个字符插入到第3位
0052A7D9 |. 8D45 EC lea eax,dword ptr ss:[ebp-14]
0052A7DC |. 8A55 F9 mov dl,byte ptr ss:[ebp-7]
0052A7DF |. E8 98A4EDFF call yhds.00404C7C
0052A7E4 |. 8B45 EC mov eax,dword ptr ss:[ebp-14]
0052A7E7 |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
0052A7EA |. B9 05000000 mov ecx,5
0052A7EF |. E8 40A8EDFF call yhds.00405034 ; f7把第2个字符插入到第5位
0052A7F4 |. 8D45 E8 lea eax,dword ptr ss:[ebp-18]
0052A7F7 |. 8A55 FA mov dl,byte ptr ss:[ebp-6]
0052A7FA |. E8 7DA4EDFF call yhds.00404C7C
0052A7FF |. 8B45 E8 mov eax,dword ptr ss:[ebp-18]
0052A802 |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
0052A805 |. B9 09000000 mov ecx,9
0052A80A |. E8 25A8EDFF call yhds.00405034 ; f7把第3个字符插入到第9位
0052A80F |. 8BC6 mov eax,esi
0052A811 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0052A814 |. E8 D7A2EDFF call yhds.00404AF0
0052A819 |. 33C0 xor eax,eax
0052A81B |. 5A pop edx
0052A81C |. 59 pop ecx
0052A81D |. 59 pop ecx
0052A81E |. 64:8910 mov dword ptr fs:[eax],edx
0052A821 |. 68 43A85200 push yhds.0052A843
0052A826 |> 8D45 E8 lea eax,dword ptr ss:[ebp-18]
0052A829 |. BA 04000000 mov edx,4
0052A82E |. E8 8DA2EDFF call yhds.00404AC0
0052A833 |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
0052A836 |. E8 61A2EDFF call yhds.00404A9C
0052A83B \. C3 retn
为了节省空间省略其他代码。。。。。。。。。。。。。。。。。。。。。。
==============================================================================
总结:根据上述分析过程能得到以下C++代码。
写的很烂请各位大虾指点指点…^_^
///////////////////////////////////////////////////
/////////系统优化大师V2004 build 12.10/////////////
//////////////// key.cpp //////////////////////////
#include<iostream>
#include<string>
#include <stdlib.h>
using namespace std;
char output[256],sn[256],str1[256];
char str[20];
unsigned long stmp1;
//插入函数
void InsertSort(char* pData,unsigned long Count,int pos)
{
for(int i=strlen(pData);i>pos;i--)
{
pData[i]=pData[i-1];
}
pData[pos]=Count;
}
//主函数
void main()
{
unsigned long qrm,tmp;
unsigned long s1,s2,s3,s4;
cout<<"请输入确认码(必须是数字):"<<endl;
cin>>qrm;
cout<<"您输入的确认码是:"<<qrm<<endl;
tmp=qrm;
qrm%=0x3a1;//这是注册码的前部分
_ui64toa(qrm,output,10);
tmp^=0x0B25F1;
_ui64toa(tmp,str1,10);
s1=str1[0]+str1[1];
str[0]=s1%5+0x34;
s1=str1[2]+str1[3];
str[1]=s1%5+0x33;
strcat(str1,str);
strcpy(sn,str1);
tmp=atol(str1 );
tmp^=0xDDFB7687;
_ui64toa(tmp,str1,10);
s1=str1[0]+str1[1];
str[0]=s1%5+0x66;
s2=str1[2]+str1[3];
str[1]=s2%5+0x75;
s3=str1[4]+str1[5];
str[2]=s3%5+0x7A;
s4=str1[6]+str1[7]+str1[8];
str[3]=s4%5+0x69;
/////////////////////////////////////
InsertSort(str1,str[0],6) ;//插入第1个
InsertSort(str1,str[3],2) ;//插入第4个
InsertSort(str1,str[1],4) ;//插入第2个
InsertSort(str1,str[2],8) ;//插入第3个
//////////////////////////////////
strcat(output,str1);//连接上面算好的数字
strcpy(sn,output);
cout<<"您的注册码是:";
cout<<sn<<endl;
}
//////////////////////////////////////////////////////////////////////
能力值:
( LV2,RANK:10 )
11 楼
NO10: 作者:Pr0Zel
贯通词典破解过程
这是我写的第一篇破解的文章,也是我第一次成功地破解软件(成功破解是指能写出注册机),若有错的话请大家提出来,指导一下我这只菜鸟 ;)
目标:贯通词典V2.1
简介:一个日语字典
原因:自己正在自学日语,听说这个词典还算可以,就下载下来试试,发现是要注册的
先用PEID看看
UPX 0.89.6 - 1.02 / 1.05 - 1.24 (Delphi) stub -> Markus & Laszlo
嗯,是用UPX加壳,用upx -d就可以解壳了,手动解壳也可
解壳后是1.23MB的
OK了,用C32ASM反汇编吧
::004E65A7:: BA 01000000 MOV EDX,1
::004E65AC:: 59 POP ECX
::004E65AD:: E8 4EE6F1FF CALL 00404C00
::004E65B2:: 8B45 E4 MOV EAX,[EBP-1C]
::004E65B5:: E8 E6E5F1FF CALL 00404BA0
::004E65BA:: 8D55 E8 LEA EDX,[EBP-18]
::004E65BD:: E8 BAE2FFFF CALL 004E487C
::004E65C2:: 8B55 E8 MOV EDX,[EBP-18]
::004E65C5:: B8 64F64E00 MOV EAX,4EF664
::004E65CA:: E8 65E1F1FF CALL 00404734
::004E65CF:: 8D4D D8 LEA ECX,[EBP-28]
::004E65D2:: BA E46E4E00 MOV EDX,4E6EE4 \->: yasha
::004E65D7:: A1 64F64E00 MOV EAX,[4EF664]
::004E65DC:: E8 13E1FFFF CALL 004E46F4 ->关键:注册码生成过程
::004E65E1:: 8B45 D8 MOV EAX,[EBP-28]
::004E65E4:: 8D55 F4 LEA EDX,[EBP-C]
::004E65E7:: E8 F8E1FFFF CALL 004E47E4
::004E65EC:: C705 3CF64E00 705E4E00 MOV DWORD PTR [4EF63C],4E5E70
::004E65F6:: 8D45 D4 LEA EAX,[EBP-2C]
::004E65F9:: BA 6CF64E00 MOV EDX,4EF66C
::004E65FE:: B9 80000000 MOV ECX,80
进去4E46F4里面看看是怎样生成注册码的吧
::004E46F4:: 55 PUSH EBP \:BYCALL CallBy:004E65DC,
::004E46F5:: 8BEC MOV EBP,ESP
::004E46F7:: 83C4 E8 ADD ESP,-18
::004E46FA:: 53 PUSH EBX
::004E46FB:: 56 PUSH ESI
::004E46FC:: 57 PUSH EDI
::004E46FD:: 33DB XOR EBX,EBX
::004E46FF:: 895D E8 MOV [EBP-18],EBX
::004E4702:: 895D F0 MOV [EBP-10],EBX
::004E4705:: 895D EC MOV [EBP-14],EBX
::004E4708:: 894D F4 MOV [EBP-C],ECX
::004E470B:: 8955 F8 MOV [EBP-8],EDX
::004E470E:: 8945 FC MOV [EBP-4],EAX
::004E4711:: 8B45 FC MOV EAX,[EBP-4]
::004E4714:: E8 7704F2FF CALL 00404B90 \:JMPUP
::004E4719:: 8B45 F8 MOV EAX,[EBP-8]
::004E471C:: E8 6F04F2FF CALL 00404B90 \:JMPUP
::004E4721:: 33C0 XOR EAX,EAX
::004E4723:: 55 PUSH EBP
::004E4724:: 68 D3474E00 PUSH 4E47D3
::004E4729:: 64:FF30 PUSH DWORD PTR FS:[EAX]
::004E472C:: 64:8920 MOV FS:[EAX],ESP
::004E472F:: 8B45 FC MOV EAX,[EBP-4] 把序列号送入EAX
::004E4732:: E8 7102F2FF CALL 004049A8 序列号ASCII码的位数(9个)
::004E4737:: 50 PUSH EAX EAX入栈
::004E4738:: 8B45 F8 MOV EAX,[EBP-8] 字符串"yasha"送到EAX里
::004E473B:: E8 6802F2FF CALL 004049A8 "yasha"ASCII码的位数(5个)
::004E4740:: 5A POP EDX 栈的数据弹到EDX里 (EDX==9 EAX==5)
::004E4741:: 92 XCHG EAX,EDX 交换EAX与EDX (EDX==5 EAX==9)
::004E4742:: 8BCA MOV ECX,EDX EDX数据送入ECX (ECX=EDX=5)
::004E4744:: 99 CDQ
::004E4745:: F7F9 IDIV ECX ECX执行除法 (EAX==1 EDX==4)
::004E4747:: 8BF8 MOV EDI,EAX EAX数据送到EDI里
::004E4749:: 66:85FF TEST DI,DI
::004E474C:: 7C 11 JL SHORT 004E475F
::004E474E:: 47 INC EDI EDI++
::004E474F:: 8D45 F0 LEA EAX,[EBP-10]
::004E4752:: 8B55 F8 MOV EDX,[EBP-8] "yasha"送入EDX
::004E4755:: E8 5602F2FF CALL 004049B0 把"yasha"累加,变成"yashayasha"
::004E475A:: 66:FFCF DEC DI
::004E475D:: 75 F0 JNZ SHORT 004E474F
::004E475F:: 8B45 FC MOV EAX,[EBP-4] 序列号送到EAX
::004E4762:: E8 4102F2FF CALL 004049A8 得到序列号长度(9)
::004E4767:: 8BF8 MOV EDI,EAX
::004E4769:: 66:85FF TEST DI,DI
::004E476C:: 7E 32 JLE SHORT 004E47A0
::004E476E:: 66:BE 0100 MOV SI,1
::004E4772:: 0FBFC6 MOVSX EAX,SI
::004E4775:: 8B55 FC MOV EDX,[EBP-4] 序列号送到EDX
::004E4778:: 8A5C02 FF MOV BL,[EDX+EAX-1] 序列号的第一个字符送到BL
::004E477C:: 8B55 F0 MOV EDX,[EBP-10] 字符串"yashayasha"送到EDX
::004E477F:: 8A4402 FF MOV AL,[EDX+EAX-1] 字符串"yashayasha"第一个字符送去AL
::004E4783:: 32D8 XOR BL,AL 异或BL与AL,结果送回BL
::004E4785:: 8D45 E8 LEA EAX,[EBP-18]
::004E4788:: 8BD3 MOV EDX,EBX
::004E478A:: E8 3101F2FF CALL 004048C0 \:JMPUP
::004E478F:: 8B55 E8 MOV EDX,[EBP-18]
::004E4792:: 8D45 EC LEA EAX,[EBP-14]
::004E4795:: E8 1602F2FF CALL 004049B0 \:JMPUP
::004E479A:: 46 INC ESI
::004E479B:: 66:FFCF DEC DI
::004E479E:: 75 D2 JNZ SHORT 004E4772 \:JMPUP
::004E47A0:: 8B45 F4 MOV EAX,[EBP-C] \:BYJMP JmpBy:004E476C,
::004E47A3:: 8B55 EC MOV EDX,[EBP-14]
::004E47A6:: E8 89FFF1FF CALL 00404734 \:JMPUP
::004E47AB:: 33C0 XOR EAX,EAX
::004E47AD:: 5A POP EDX
::004E47AE:: 59 POP ECX
::004E47AF:: 59 POP ECX
::004E47B0:: 64:8910 MOV FS:[EAX],EDX
::004E47B3:: 68 DA474E00 PUSH 4E47DA
::004E47B8:: 8D45 E8 LEA EAX,[EBP-18] \:BYJMP JmpBy:004E47D8,
::004E47BB:: BA 03000000 MOV EDX,3
::004E47C0:: E8 3FFFF1FF CALL 00404704 \:JMPUP
::004E47C5:: 8D45 F8 LEA EAX,[EBP-8]
::004E47C8:: BA 02000000 MOV EDX,2
::004E47CD:: E8 32FFF1FF CALL 00404704 \:JMPUP
::004E47D2:: C3 RETN
::004E47D3:: E9 30F9F1FF JMP 00404108 \:JMPUP
::004E47D8:: EB DE JMP SHORT 004E47B8 \:JMPUP
::004E47DA:: 5F POP EDI
::004E47DB:: 5E POP ESI
::004E47DC:: 5B POP EBX
::004E47DD:: 8BE5 MOV ESP,EBP
::004E47DF:: 5D POP EBP
::004E47E0:: C3 RETN
经过这个CALL以后,因为我的序列号是8C0D-DB4C,与yashayash异或后的字符串就是A"C,L=#G+
最后一步还要留意这个CALL:
::004E6603:: E8 50E3F1FF CALL 00404958
它把异或后的字符串转为ASCII码的十进制值, A"C,L=#G+的十进制ASCII码值就是65 34 67 44 76 61 35 71 43 把空格去掉,就是653467447661357143,这就是注册码了,开始写注册机吧
void CRegDlg::OnButton1()
{
// TODO: Add your control notification handler code here
int tmp,cst,cst2,res;
char buff[20];
CString ori="yashayasha";
UpdateData(true);
m_CS2="";
int stlen=strlen(m_CS1);
if(stlen!=9) MessageBox("申请注册码是XXXX-XXXX的型式的");
else
{
for(tmp=0;tmp<stlen;tmp++)
{
cst=int(m_CS1.GetAt(tmp));
cst2=int(ori.GetAt(tmp));
res=cst^cst2;
_itoa(res,buff,10);
m_CS2=m_CS2+buff;
}
}
UpdateData(false);
}
完成,收工.
另外一个: 序列号是根据C盘序列号算出来的,但我始终搞不清是如何算出来的,请高手帮我看看吧
有不对的地方请提出来,谢谢.
能力值:
( LV2,RANK:10 )
12 楼
NO11: 作者:cracklover
desksaver 破解教程
【破解作者】 cracklover
【作者邮箱】 cracklover@126.com
【使用工具】 W32dasm ds2.7
【破解平台】 Win9x/NT/2000/XP
【软件名称】 Easy Desktop Keeper
【下载地址】 http://www.softheap.com/desksaver.html
或 http://www.softheap.com/download/desksaver.zip
【软件简介】 此软件是英文的,兄弟也看不太懂,意思好象是管理桌面的,几乎囊括了桌面的所有功能设置,并且能按你老大的意思,保存几种不同的桌面!
【软件大小】 1,161K
【加壳方式】 无壳
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】
根据注册错误信息提示,很容易找到如下代码: :0049026C 6A00 push 00000000
:0049026E 6A00 push 00000000
:00490270 49 dec ecx
:00490271 75F9 jne 0049026C
:00490273 51 push ecx
:00490274 53 push ebx
:00490275 56 push esi
:00490276 8BF0 mov esi, eax
:00490278 33C0 xor eax, eax
:0049027A 55 push ebp
:0049027B 68E9034900 push 004903E9
:00490280 64FF30 push dword ptr fs:[eax]
:00490283 648920 mov dword ptr fs:[eax], esp
:00490286 8D55F4 lea edx, dword ptr [ebp-0C]
:00490289 8B8644030000 mov eax, dword ptr [esi+00000344]
:0049028F E8FC4DFCFF call 00455090
:00490294 8B45F4 mov eax, dword ptr [ebp-0C]
:00490297 8D55F8 lea edx, dword ptr [ebp-08]
:0049029A E8B5CDFEFF call 0047D054
:0049029F 8B55F8 mov edx, dword ptr [ebp-08]
:004902A2 B824914900 mov eax, 00499124
:004902A7 E8303FF7FF call 004041DC
:004902AC E8DBFDFFFF call 0049008C
{
:0049008C 53 push ebx
:0049008D 56 push esi
:0049008E 57 push edi
:0049008F BF24914900 mov edi, 00499124
:00490094 33F6 xor esi, esi //ESI清零!下面用到!
:00490096 33DB xor ebx, ebx
:00490098 8B07 mov eax, dword ptr [edi] //EAX指向注册码!
:0049009A E8A943F7FF call 00404448 //取注册码长度
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049002E(C)
|
:0049009F 83F80E cmp eax, 0000000E //长度是否为14,否则OVER!
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049002C(C)
|
:004900A2 7567 jne 0049010B
:004900A4 8B07 mov eax, dword ptr [edi] //EAX指向注册码!
:004900A6 803833 cmp byte ptr [eax], 33 //第一位是否为3
:004900A9 0F94C0 sete al //上面相等则设置AL为1
:004900AC 83E07F and eax, 0000007F //7F也就是二进制的1111111
:004900AF 03F0 add esi, eax //将得到的结果加到ESI,表示一个条件满足
:004900B1 8B07 mov eax, dword ptr [edi]
:004900B3 80780233 cmp byte ptr [eax+02], 33 //第三位是否为3
:004900B7 0F94C0 sete al
:004900BA 83E07F and eax, 0000007F
:004900BD 03F0 add esi, eax
:004900BF 8B07 mov eax, dword ptr [edi]
:004900C1 80780339 cmp byte ptr [eax+03], 39 //第四位是否为9
:004900C5 0F94C0 sete al
:004900C8 83E07F and eax, 0000007F
:004900CB 03F0 add esi, eax
:004900CD 8B07 mov eax, dword ptr [edi]
:004900CF 80780430 cmp byte ptr [eax+04], 30 //第五位是否为0
:004900D3 0F94C0 sete al
:004900D6 83E07F and eax, 0000007F
:004900D9 03F0 add esi, eax
:004900DB 8B07 mov eax, dword ptr [edi]
:004900DD 80780738 cmp byte ptr [eax+07], 38 //第八位是否为8
:004900E1 0F94C0 sete al
:004900E4 83E07F and eax, 0000007F
:004900E7 03F0 add esi, eax
:004900E9 8B07 mov eax, dword ptr [edi]
:004900EB 80780838 cmp byte ptr [eax+08], 38 //第九位是否为8
:004900EF 0F94C0 sete al
:004900F2 83E07F and eax, 0000007F
:004900F5 03F0 add esi, eax
:004900F7 8B07 mov eax, dword ptr [edi]
:004900F9 80780A32 cmp byte ptr [eax+0A], 32 //第十一位是否为2
:004900FD 0F94C0 sete al
:00490100 83E07F and eax, 0000007F
:00490103 03F0 add esi, eax
:00490105 83FE07 cmp esi, 00000007 //以上7个条件全满足的话,ESI=7
:00490108 0F94C3 sete bl //ESI=7则设置BL为1,则注册成功!
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004900A2(C)
|
:0049010B 8BC3 mov eax, ebx //将EBX传入EAX,准备返回!
:0049010D 5F pop edi
:0049010E 5E pop esi
:0049010F 5B pop ebx
:00490110 C3 ret
}
:004902B1 8BD8 mov ebx, eax
:004902B3 84DB test bl, bl
:004902B5 0F84DC000000 je 00490397
此处跳往出错框!BL为比较旗!那上面的两个CALL肯定有问题,得追进看看,
经分析,第二个CALL有问题,将其内容列到上面。
下面的几个字符串把我着实吓了一跳,以为又是什么RSA防破解的呢,后来一分析,
此处的跳转若不跳的话,后面程序怎么执行都会经过注册成功的地方,所以往下就不用分析了!
:004902BB C6866403000001 mov byte ptr [esi+00000364], 01
:004902C2 8D45FC lea eax, dword ptr [ebp-04]
:004902C5 50 push eax
:004902C6 8D55F0 lea edx, dword ptr [ebp-10]
* Possible StringData Ref from Code Obj ->"AC95829F829D9994ABAABF8A8BBF82838982A895"
|
:004902C9 B800044900 mov eax, 00490400
:004902CE E89D44FFFF call 00484770
:004902D3 8B45F0 mov eax, dword ptr [ebp-10]
:004902D6 50 push eax
:004902D7 8D55EC lea edx, dword ptr [ebp-14]
* Possible StringData Ref from Code Obj ->"BE828B999A8C9F88B1A0848E9F829E828B99B1A9BFA0BF"
->"BEB5"
|
:004902DA B834044900 mov eax, 00490434
:004902DF E88C44FFFF call 00484770
:004902E4 8B55EC mov edx, dword ptr [ebp-14]
:004902E7 A12C914900 mov eax, dword ptr [0049912C]
:004902EC 59 pop ecx
:004902ED E8865AFFFF call 00485D78
:004902F2 8D55E8 lea edx, dword ptr [ebp-18]
:004902F5 A124914900 mov eax, dword ptr [00499124]
:004902FA E8D543FFFF call 004846D4
:004902FF 8B45E8 mov eax, dword ptr [ebp-18]
:00490302 50 push eax
:00490303 8D55E4 lea edx, dword ptr [ebp-1C]
* Possible StringData Ref from Code Obj ->"BE9E95A99F95AFAFBC8E95BEBEBF"
|
:00490306 B870044900 mov eax, 00490470
:0049030B E86044FFFF call 00484770
:00490310 8B45E4 mov eax, dword ptr [ebp-1C]
:00490313 50 push eax
:00490314 8D45E0 lea eax, dword ptr [ebp-20]
:00490317 50 push eax
* Possible StringData Ref from Code Obj ->"BE828B999A8C9F88B1A0848E9F829E828B99B1A9BFA0BF"
->"BEB5"
|
:00490318 B834044900 mov eax, 00490434
:0049031D 5A pop edx
:0049031E E84D44FFFF call 00484770
:00490323 8B55E0 mov edx, dword ptr [ebp-20]
:00490326 A12C914900 mov eax, dword ptr [0049912C]
:0049032B 59 pop ecx
:0049032C E8EB5AFFFF call 00485E1C
:00490331 837DFC00 cmp dword ptr [ebp-04], 00000000
:00490335 7546 jne 0049037D
:00490337 E808A4F7FF call 0040A744
:0049033C 83C4F4 add esp, FFFFFFF4
:0049033F DB3C24 fstp tbyte ptr [esp]
:00490342 9B wait
:00490343 8D45DC lea eax, dword ptr [ebp-24]
:00490346 E8B59EF7FF call 0040A200
:0049034B 8B45DC mov eax, dword ptr [ebp-24]
:0049034E 50 push eax
:0049034F 8D55D8 lea edx, dword ptr [ebp-28]
* Possible StringData Ref from Code Obj ->"AC95829F829D9994ABAABF8A8BBF82838982A895"
|
:00490352 B800044900 mov eax, 00490400
:00490357 E81444FFFF call 00484770
:0049035C 8B45D8 mov eax, dword ptr [ebp-28]
:0049035F 50 push eax
:00490360 8D45D4 lea eax, dword ptr [ebp-2C]
:00490363 50 push eax
* Possible StringData Ref from Code Obj ->"BE828B999A8C9F88B1A0848E9F829E828B99B1A9BFA0BF"
->"BEB5"
|
:00490364 B834044900 mov eax, 00490434
:00490369 5A pop edx
:0049036A E80144FFFF call 00484770
:0049036F 8B55D4 mov edx, dword ptr [ebp-2C]
:00490372 A12C914900 mov eax, dword ptr [0049912C]
:00490377 59 pop ecx
:00490378 E89F5AFFFF call 00485E1C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00490335(C)
|
:0049037D 6A40 push 00000040
* Possible StringData Ref from Code Obj ->"Information"
|
:0049037F B990044900 mov ecx, 00490490
* Possible StringData Ref from Code Obj ->"Registration has been completed "
->"successfully!"
|
:00490384 BA9C044900 mov edx, 0049049C
:00490389 A1F8744900 mov eax, dword ptr [004974F8]
:0049038E 8B00 mov eax, dword ptr [eax]
:00490390 E81B55FEFF call 004758B0
:00490395 EB22 jmp 004903B9
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004902B5(C)
|
:00490397 B824914900 mov eax, 00499124
:0049039C E8E73DF7FF call 00404188
:004903A1 6A10 push 00000010
* Possible StringData Ref from Code Obj ->"Error" //错误信息框出现!
|
:004903A3 B9CC044900 mov ecx, 004904CC
* Possible StringData Ref from Code Obj ->"Registration code is invalid!"
|
:004903A8 BAD4044900 mov edx, 004904D4
:004903AD A1F8744900 mov eax, dword ptr [004974F8]
:004903B2 8B00 mov eax, dword ptr [eax]
:004903B4 E8F754FEFF call 004758B0
--------------------------------------------------------------------------------
【破解总结】
注册码必须为14位,其中:
并且第一、三、四、五位分别必须为3,3,9,0;
第八、九、十一位分别必须为8,8,2;其余的随便,补齐14位就可!
即:3X3390X88X2XXX,X可为任一字母或数字。
这应该是我等菜鸟的学习的经典破解软件,注册码比对简单,流程清晰。
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
能力值:
( LV2,RANK:10 )
13 楼
NO12: 作者:kyc
卸载精灵 V4.1 破解教程
【破解作者】 kyc[dfcg][czg]
【作者邮箱】 muyang008@163.com
【使用工具】 old1.10c
【破解平台】 win2003
【软件名称】 卸载精灵 V4.1
【下载地址】 http://www.skycn.com/soft/4502.html
【软件简介】 您的电脑里面有很多软件、游戏无法卸载?已经厌倦了WINDOWS控制面板那个功能很弱的“添加/删除程序”了吗?
卸载精灵的智能卸载功能可以干净彻底地卸载软件,包括那些无法正常卸载的程序它都可以帮您卸载。2.0版新增加了清除垃圾文件的功能。
2.3版的智能卸载更强大,可以卸载桌面快捷方式及菜单。3.0以上版本增加了IE浏览器修复功能。
这个软件特别适合网吧做系统维护,清除系统中的垃圾软件,优化系统的运行速度。它操作方便,界面友好,安全可靠。
【软件大小】 3210 KB
【加壳方式】 无壳
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】
这两天破了几个小软件下载了不少共享软件,我的电脑几乎装满了于是下载了卸载精灵 V4.1。
觉得好用就开始破解了。
根据序列号错误
00405E93 /. 55 push ebp
00405E94 |. 8BEC mov ebp,esp
00405E96 |. 83EC 14 sub esp,14
00405E99 |. 894D F4 mov dword ptr ss:[ebp-C],ecx
00405E9C |. 68 4C5A4100 push Cleaner.00415A4C
00405EA1 |. 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
00405EA4 |. 81C1 A0000000 add ecx,0A0
00405EAA |. E8 79570000 call <jmp.&MFC42.#3874_CWnd::GetWindowTextA> ; 取用户名
00405EAF |. 68 485A4100 push Cleaner.00415A48
00405EB4 |. 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
00405EB7 |. 83C1 60 add ecx,60
00405EBA |. E8 69570000 call <jmp.&MFC42.#3874_CWnd::GetWindowTextA> ; 取注册码
00405EBF |. 51 push ecx
00405EC0 |. 8BCC mov ecx,esp
00405EC2 |. 8965 F8 mov dword ptr ss:[ebp-8],esp
00405EC5 |. 68 485A4100 push Cleaner.00415A48
00405ECA |. E8 ED530000 call <jmp.&MFC42.#535_CString::CString>
00405ECF |. 8945 F0 mov dword ptr ss:[ebp-10],eax ; |
00405ED2 |. E8 66BBFFFF call Cleaner.00401A3D ; \f7 关键算法
00405ED7 |. 83C4 04 add esp,4
00405EDA |. 8845 EC mov byte ptr ss:[ebp-14],al
00405EDD |. 8B45 EC mov eax,dword ptr ss:[ebp-14]
00405EE0 |. 25 FF000000 and eax,0FF
00405EE5 |. 85C0 test eax,eax
00405EE7 |. 0F84 DD000000 je Cleaner.00405FCA ; 跳就失败
================================================================================call Cleaner.00401A3D
00401A3D /$ 55 push ebp
00401A3E |. 8BEC mov ebp,esp
00401A40 |. 6A FF push -1
00401A42 |. 68 27C04000 push Cleaner.0040C027 ; SE handler installation
00401A47 |. 64:A1 0000000>mov eax,dword ptr fs:[0]
00401A4D |. 50 push eax
00401A4E |. 64:8925 00000>mov dword ptr fs:[0],esp
00401A55 |. 83EC 1C sub esp,1C
00401A58 |. 56 push esi
00401A59 |. C745 FC 00000>mov dword ptr ss:[ebp-4],0
00401A60 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8]
00401A63 |. E8 48030000 call Cleaner.00401DB0
00401A68 |. 83F8 08 cmp eax,8 ; 注册码必须是8位
00401A6B |. 74 1B je short Cleaner.00401A88
00401A6D |. C645 F0 00 mov byte ptr ss:[ebp-10],0
00401A71 |. C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
00401A78 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8]
00401A7B |. E8 10970000 call <jmp.&MFC42.#800_CString::~CString>
00401A80 |. 8A45 F0 mov al,byte ptr ss:[ebp-10]
00401A83 |. E9 3C010000 jmp Cleaner.00401BC4
00401A88 |> 6A 00 push 0 ; /Arg1 = 00000000
00401A8A |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401A8D |. E8 6E030000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401A92 |. 0FBEF0 movsx esi,al ; ESI=取注册码的第1位
00401A95 |. 6A 02 push 2 ; /Arg1 = 00000002
00401A97 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401A9A |. E8 61030000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401A9F |. 0FBEC0 movsx eax,al ; EAX=取注册码的第3位
00401AA2 |. 03F0 add esi,eax ; ESI=EAX+ESI
00401AA4 |. 83FE 6D cmp esi,6D ; ESI==6D吗 不等就失败
00401AA7 |. 74 1B je short Cleaner.00401AC4
00401AA9 |. C645 EC 00 mov byte ptr ss:[ebp-14],0
00401AAD |. C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
00401AB4 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8]
00401AB7 |. E8 D4960000 call <jmp.&MFC42.#800_CString::~CString>
00401ABC |. 8A45 EC mov al,byte ptr ss:[ebp-14]
00401ABF |. E9 00010000 jmp Cleaner.00401BC4
00401AC4 |> 6A 01 push 1 ; /Arg1 = 00000001
00401AC6 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401AC9 |. E8 32030000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401ACE |. 0FBEF0 movsx esi,al ; ESI=取注册码的第2位
00401AD1 |. 6A 03 push 3 ; /Arg1 = 00000003
00401AD3 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401AD6 |. E8 25030000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401ADB |. 0FBEC8 movsx ecx,al ; ECX=取注册码的第4位
00401ADE |. 03F1 add esi,ecx ; ESI=ECX+ESI
00401AE0 |. 83FE 6A cmp esi,6A ; ESI==6A吗 不等就失败
00401AE3 |. 74 1B je short Cleaner.00401B00
00401AE5 |. C645 E8 00 mov byte ptr ss:[ebp-18],0
00401AE9 |. C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
00401AF0 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8]
00401AF3 |. E8 98960000 call <jmp.&MFC42.#800_CString::~CString>
00401AF8 |. 8A45 E8 mov al,byte ptr ss:[ebp-18]
00401AFB |. E9 C4000000 jmp Cleaner.00401BC4
00401B00 |> 6A 04 push 4 ; /Arg1 = 00000004
00401B02 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401B05 |. E8 F6020000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401B0A |. 0FBEF0 movsx esi,al ; ESI=取注册码的第5位
00401B0D |. 6A 05 push 5 ; /Arg1 = 00000005
00401B0F |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401B12 |. E8 E9020000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401B17 |. 0FBED0 movsx edx,al ; EDX=取注册码的第6位
00401B1A |. 03F2 add esi,edx ; ESI=EDX+ESI
00401B1C |. 83FE 6B cmp esi,6B ; ESI==6B吗 不等就失败
00401B1F |. 74 1B je short Cleaner.00401B3C
00401B21 |. C645 E4 00 mov byte ptr ss:[ebp-1C],0
00401B25 |. C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
00401B2C |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8]
00401B2F |. E8 5C960000 call <jmp.&MFC42.#800_CString::~CString>
00401B34 |. 8A45 E4 mov al,byte ptr ss:[ebp-1C]
00401B37 |. E9 88000000 jmp Cleaner.00401BC4
00401B3C |> 6A 06 push 6 ; /Arg1 = 00000006
00401B3E |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401B41 |. E8 BA020000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401B46 |. 0FBEF0 movsx esi,al ; ESI=取注册码的第7位
00401B49 |. 6A 07 push 7 ; /Arg1 = 00000007
00401B4B |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |ESI=取注册码的第7位
00401B4E |. E8 AD020000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401B53 |. 0FBEC0 movsx eax,al ; EAX=取注册码的第8位
00401B56 |. 03F0 add esi,eax ; ESI=EAX+ESI
00401B58 |. 83FE 6C cmp esi,6C ; ESI==6C吗 不等就失败
00401B5B |. 74 18 je short Cleaner.00401B75
00401B5D |. C645 E0 00 mov byte ptr ss:[ebp-20],0
00401B61 |. C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
00401B68 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8]
00401B6B |. E8 20960000 call <jmp.&MFC42.#800_CString::~CString>
00401B70 |. 8A45 E0 mov al,byte ptr ss:[ebp-20]
00401B73 |. EB 4F jmp short Cleaner.00401BC4
00401B75 |> 6A 00 push 0 ; /Arg1 = 00000000
00401B77 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401B7A |. E8 81020000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401B7F |. 0FBEF0 movsx esi,al ; ESI=取注册码的第1位
00401B82 |. 6A 07 push 7 ; /Arg1 = 00000007
00401B84 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8] ; |
00401B87 |. E8 74020000 call Cleaner.00401E00 ; \Cleaner.00401E00
00401B8C |. 0FBEC8 movsx ecx,al ; ECX=取注册码的第8位
00401B8F |. 03F1 add esi,ecx ; ESI=ECX+ESI
00401B91 |. 83FE 69 cmp esi,69 ; ESI==69吗 不等就失败
00401B94 |. 74 18 je short Cleaner.00401BAE
00401B96 |. C645 DC 00 mov byte ptr ss:[ebp-24],0
00401B9A |. C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
00401BA1 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8]
00401BA4 |. E8 E7950000 call <jmp.&MFC42.#800_CString::~CString>
00401BA9 |. 8A45 DC mov al,byte ptr ss:[ebp-24]
00401BAC |. EB 16 jmp short Cleaner.00401BC4
00401BAE |> C645 D8 01 mov byte ptr ss:[ebp-28],1
00401BB2 |. C745 FC FFFFF>mov dword ptr ss:[ebp-4],-1
00401BB9 |. 8D4D 08 lea ecx,dword ptr ss:[ebp+8]
00401BBC |. E8 CF950000 call <jmp.&MFC42.#800_CString::~CString>
00401BC1 |. 8A45 D8 mov al,byte ptr ss:[ebp-28]
00401BC4 |> 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
00401BC7 |. 64:890D 00000>mov dword ptr fs:[0],ecx
00401BCE |. 5E pop esi
00401BCF |. 8BE5 mov esp,ebp
00401BD1 |. 5D pop ebp
00401BD2 \. C3 retn
=========================================================================================
00405EED |. C605 505A4100>mov byte ptr ds:[415A50],1
00405EF4 |. 8D4D FC lea ecx,dword ptr ss:[ebp-4]
00405EF7 |. 51 push ecx ; /pHandle
00405EF8 |. 68 3F000F00 push 0F003F ; |Access = KEY_ALL_ACCESS
00405EFD |. 6A 00 push 0 ; |Reserved = 0
00405EFF |. 68 4C544100 push Cleaner.0041544C ; |Subkey = "Software\Legendsoft\Uninstaller"
00405F04 |. 68 02000080 push 80000002 ; |hKey = HKEY_LOCAL_MACHINE
00405F09 |. FF15 00D04000 call dword ptr ds:[<&ADVAPI32.RegOpenKeyExA>] ; \RegOpenKeyExA
00405F0F |. 85C0 test eax,eax
00405F11 |. 75 72 jnz short Cleaner.00405F85
00405F13 |. B9 4C5A4100 mov ecx,Cleaner.00415A4C
00405F18 |. E8 93BEFFFF call Cleaner.00401DB0
00405F1D |. 50 push eax
00405F1E |. B9 4C5A4100 mov ecx,Cleaner.00415A4C
00405F23 |. E8 88BEFFFF call Cleaner.00401DB0
00405F28 |. 50 push eax
00405F29 |. B9 4C5A4100 mov ecx,Cleaner.00415A4C
00405F2E |. E8 EF560000 call <jmp.&MFC42.#2915_CString::GetBuffer> ; 写入注册表
00405F33 |. 50 push eax ; |Buffer
00405F34 |. 6A 01 push 1 ; |ValueType = REG_SZ
00405F36 |. 6A 00 push 0 ; |Reserved = 0
00405F38 |. 68 6C544100 push Cleaner.0041546C ; |ValueName = "RegName"
00405F3D |. 8B55 FC mov edx,dword ptr ss:[ebp-4] ; |
00405F40 |. 52 push edx ; |hKey
00405F41 |. FF15 18D04000 call dword ptr ds:[<&ADVAPI32.RegSetValueExA>] ; \RegSetValueExA
00405F47 |. B9 485A4100 mov ecx,Cleaner.00415A48
00405F4C |. E8 5FBEFFFF call Cleaner.00401DB0
00405F51 |. 50 push eax
00405F52 |. B9 485A4100 mov ecx,Cleaner.00415A48
00405F57 |. E8 54BEFFFF call Cleaner.00401DB0
00405F5C |. 50 push eax
00405F5D |. B9 485A4100 mov ecx,Cleaner.00415A48
00405F62 |. E8 BB560000 call <jmp.&MFC42.#2915_CString::GetBuffer>
00405F67 |. 50 push eax ; |Buffer
00405F68 |. 6A 01 push 1 ; |ValueType = REG_SZ
00405F6A |. 6A 00 push 0 ; |Reserved = 0
00405F6C |. 68 74544100 push Cleaner.00415474 ; |ValueName = "RegCode"
00405F71 |. 8B45 FC mov eax,dword ptr ss:[ebp-4] ; |
00405F74 |. 50 push eax ; |hKey
00405F75 |. FF15 18D04000 call dword ptr ds:[<&ADVAPI32.RegSetValueExA>] ; \RegSetValueExA
00405F7B |. 8B4D FC mov ecx,dword ptr ss:[ebp-4]
00405F7E |. 51 push ecx ; /hKey
00405F7F |. FF15 1CD04000 call dword ptr ds:[<&ADVAPI32.RegCloseKey>] ; \RegCloseKey
===================================================================================================
总结:
注册码和拥护名无关,计算一个可用的注册码
35+38=6D 5,8 第1位5,第3位5
33+37=6A 3,7 第2位3,第4位7
35+36=6B 5,6 第5位5,第6位6
38+34=6C 8,4 第7位8,第8位4
35+34=69 5,4 第1位5,第8位4
所以得到:
53875684
注册后注册码在注册表的HKLM\SOFTWARE\Legendsoft\Uninstaller\RegCode
删除后提示未注册.
能力值:
( LV2,RANK:10 )
14 楼
NO13: 作者:落魄浪子
一个非常简单的注册
【破解作者】 落魄浪子
【作者邮箱】 zxy223_szb@21cn.net
【使用工具】 od1.1c
【破解平台】 Win9x/NT/2000/XP
【软件名称】 EmEditor V4.09
【软件简介】 一个很好的可以替换记事本的软件。
【破解声明】 我是一只菜菜,这几天被acp壳搞得头晕,所以就找一个不难的软件来开开刀,也好?足下自己。
--------------------------------------------------------------------------------
【破解内容】
软件无壳,呵呵,但愿所有的软件都这样。
静态反汇编程序找不到出错的提示字串,只好先用OD载入程序,查找MESSAGEBOXW下断点,运行,填入注册码0000-11
11-2222-3333,按确正,OK,OD断下了,向上找看看是从哪里跳过来的,一步步往上找,看到有好多地方都调用它,
不管,我全下断。最后找到004165EF处,这是个算法CALL,呵呵,总算给我找到了,进入后来到:
004272C4 /$ 56 push esi 注册码入栈
004272C5 |. 8BF0 mov esi,eax
004272C7 |. 0FB706 movzx eax,word ptr ds:[esi] 注册码第一组的DWORD值放入EAX
004272CA |. 6A 0A push 0A
004272CC |. 99 cdq
004272CD |. 59 pop ecx
004272CE |. F7F9 idiv ecx EAX整除A,商回送AX余数回送DX
004272D0 |. 3D B5000000 cmp eax,0B5 比较商是否等于0B5 ;0B5*0A这里得到第一组注册码为0721
004272D5 |. 74 05 je short emeditor.004272DC 不跳就玩完
004272D7 |. 83C8 FF or eax,FFFFFFFF
004272DA |. 5E pop esi
004272DB |. C3 retn
004272DC |> 57 push edi
004272DD |. 66:8B7E 06 mov di,word ptr ds:[esi+6] 注册码最后四位的DWORD值放入DI
004272E1 |. E8 FAFEFFFF call emeditor.004271E0 *进入
004272E6 |. 83F8 01 cmp eax,1
004272E9 |. 75 0D jnz short emeditor.004272F8
004272EB |. 33C0 xor eax,eax
004272ED |. 66:3B7E 06 cmp di,word ptr ds:[esi+6]
004272F1 |. 0F94C0 sete al
004272F4 |. 8D4400 FF lea eax,dword ptr ds:[eax+eax-1]
004272F8 |> 5F pop edi
004272F9 |. 5E pop esi
004272FA \. C3 retn 进入后来到这里:
004271E0 /$ 51 push ecx
004271E1 |. 51 push ecx
004271E2 |. 66:8B56 02 mov dx,word ptr ds:[esi+2] 注册码第二组放入DX
004271E6 |. 66:8366 06 00 and word ptr ds:[esi+6],0
004271EB |. 66:81FA 0F27 cmp dx,270F 比较第二组注册码是否等于最大数9999
004271F0 |. 0F87 C8000000 ja emeditor.004272BE
004271F6 |. 66:8B46 04 mov ax,word ptr ds:[esi+4] 第三组注册码放入AX
004271FA |. 66:3D 0F27 cmp ax,270F 比较第三组注册码是否等于最大数9999
004271FE |. 0F87 BA000000 ja emeditor.004272BE
00427204 |. 66:8B0E mov cx,word ptr ds:[esi] 第一组注册码放入CX
00427207 |. 66:81F9 1507 cmp cx,715 比较第一组注册码是否等于715
0042720C |. 894C24 04 mov dword ptr ss:[esp+4],ecx
00427210 |. 75 14 jnz short emeditor.00427226
00427212 |. 66:81FA 1E1C cmp dx,1C1E
00427217 |. 75 0D jnz short emeditor.00427226
00427219 |. 66:3D 9D15 cmp ax,159D
0042721D |. 75 07 jnz short emeditor.00427226
0042721F |> 6A FE push -2
00427221 |. E9 95000000 jmp emeditor.004272BB
00427226 |> 66:81F9 1A07 cmp cx,71A 比较第一组注册码是否等于71A
0042722B |. 75 0D jnz short emeditor.0042723A
0042722D |. 66:81FA 0910 cmp dx,1009
00427232 |. 75 06 jnz short emeditor.0042723A
00427234 |. 66:3D 1500 cmp ax,15
00427238 |.^ 74 E5 je short emeditor.0042721F
0042723A |> 53 push ebx
0042723B |. 55 push ebp
0042723C |. 57 push edi
0042723D |. 0FB7F8 movzx edi,ax 第三组注册码放入EDI
00427240 |. 0FB7C2 movzx eax,dx 第二组注册码产入EAX
00427243 |. 894424 0C mov dword ptr ss:[esp+C],eax
00427247 |. 6A 64 push 64
00427249 |. 5B pop ebx
0042724A |. 8BC7 mov eax,edi 第三组注册码放入EAX
0042724C |. 99 cdq
0042724D |. F7FB idiv ebx EAX/EBX=64 商=AX=16,余数=DX=16
0042724F |. 6A 0A push 0A
00427251 |. 5D pop ebp
00427252 |. 0FB7C9 movzx ecx,cx 第一组注册码放入ECX
00427255 |. 6A 64 push 64
00427257 |. 8BD8 mov ebx,eax 商=AX=16入EBX
00427259 |. 8BC1 mov eax,ecx 第一组注册码入EAX
0042725B |. 99 cdq
0042725C |. F7FD idiv ebp 第一组注册码0721/0A 商=AX=B5
0042725E |. 035C24 10 add ebx,dword ptr ss:[esp+10] 第二组注册码与余数=DX=16相加 记为N1
00427262 |. 03C3 add eax,ebx N1与 商=AX=B5相加 记为N2
00427264 |. 03C7 add eax,edi 第三组注册码与N2相加 记为N3
00427266 |. 99 cdq
00427267 |. 5F pop edi
00427268 |. F7FF idiv edi N3/64 商=AX=23,余数=DX=24
0042726A |. 8B4424 0C mov eax,dword ptr ss:[esp+C] 第二组注册码放入EAX
0042726E |. 6A 64 push 64
00427270 |. 5B pop ebx
00427271 |. 6A 64 push 64
00427273 |. 5D pop ebp
00427274 |. 55 push ebp
00427275 |. 66:8B3C95 38D7440>mov di,word ptr ds:[edx*4+44D738] 余数=DX=24 * 4 + 44D738 查表得 37
0042727D |. 99 cdq
0042727E |. 66:6BFF 64 imul di,di,64 37*64 记为 N4
00427282 |. F7FB idiv ebx 第二组注册码/64 商=AX=0B,余数=DX=0B
00427284 |. 8BD8 mov ebx,eax 商=AX=0B放入EBX 记为N5
00427286 |. 8BC1 mov eax,ecx 第一组注册码入EAX
00427288 |. 99 cdq
00427289 |. F7FD idiv ebp 第一组注册码/64 商=AX=12,余数=DX=0A
0042728B |. 03D9 add ebx,ecx N5 ADD 第一组注册码 记为N6
0042728D |. 59 pop ecx
0042728E |. 03C3 add eax,ebx N6 ADD 商=AX=12 记为N7
00427290 |. 99 cdq
00427291 |. F7F9 idiv ecx N7/64 商=AX=12,余数=DX=27
00427293 |. 66:033C95 38D7440>add di,word ptr ds:[edx*4+44D738] 余数=DX=27 * 4 + 44D738 查表得 4D ADD N4 记为N8
0042729B |. 66:817C24 10 1707 cmp word ptr ss:[esp+10],717 比较第一组注册码是否等于717
004272A2 |. 66:897E 06 mov word ptr ds:[esi+6],di
004272A6 |. 5F pop edi
004272A7 |. 5D pop ebp
004272A8 |. 5B pop ebx
004272A9 |. 74 0E je short emeditor.004272B9
004272AB |. 66:817C24 04 1607 cmp word ptr ss:[esp+4],716 比较第一组注册码是否等于716
004272B2 |. 74 05 je short emeditor.004272B9
004272B4 |. 33C0 xor eax,eax
004272B6 |. 40 inc eax
004272B7 |. EB 08 jmp short emeditor.004272C1
004272B9 |> 6A 02 push 2
004272BB |> 58 pop eax
004272BC |. EB 03 jmp short emeditor.004272C1
004272BE |> 83C8 FF or eax,FFFFFFFF
004272C1 |> 59 pop ecx
004272C2 |. 59 pop ecx
004272C3 \. C3 retn 返回
004272E6 |. 83F8 01 cmp eax,1 返回到这里 如果不等就玩完
004272E9 |. 75 0D jnz short emeditor.004272F8
004272EB |. 33C0 xor eax,eax
004272ED |. 66:3B7E 06 cmp di,word ptr ds:[esi+6] 比较最后一组注册码是否等于 N8
004272F1 |. 0F94C0 sete al 置注册标志
004272F4 |. 8D4400 FF lea eax,dword ptr ds:[eax+eax-1]
004272F8 |> 5F pop edi
004272F9 |. 5E pop esi
004272FA \. C3 retn
以下是码表:
0044D738 26 00 00 00 5B 00 00 00
0044D740 62 00 00 00 36 00 00 00
0044D748 34 00 00 00 60 00 00 00
0044D750 13 00 00 00 35 00 00 00
0044D758 19 00 00 00 54 00 00 00
0044D760 3F 00 00 00 44 00 00 00
0044D768 4C 00 00 00 38 00 00 00
0044D770 5D 00 00 00 33 00 00 00
0044D778 56 00 00 00 61 00 00 00
0044D780 42 00 00 00 21 00 00 00
0044D788 3E 00 00 00 2D 00 00 00
0044D790 23 00 00 00 0E 00 00 00
0044D798 1E 00 00 00 5F 00 00 00
0044D7A0 57 00 00 00 12 00 00 00
0044D7A8 1B 00 00 00 17 00 00 00
0044D7B0 22 00 00 00 58 00 00 00
0044D7B8 2C 00 00 00 63 00 00 00
0044D7C0 5C 00 00 00 18 00 00 00
0044D7C8 37 00 00 00 41 00 00 00
0044D7D0 59 00 00 00 4D 00 00 00
0044D7D8 15 00 00 00 5A 00 00 00
0044D7E0 53 00 00 00 0B 00 00 00
0044D7E8 05 00 00 00 1C 00 00 00
0044D7F0 10 00 00 00 2E 00 00 00
0044D7F8 49 00 00 00 40 00 00 00
0044D800 0D 00 00 00 07 00 00 00
0044D808 50 00 00 00 3D 00 00 00
0044D810 32 00 00 00 46 00 00 00
0044D818 0A 00 00 00 43 00 00 00
0044D820 2B 00 00 00 00 00 00 00
0044D828 3B 00 00 00 48 00 00 00
0044D830 5E 00 00 00 4E 00 00 00
0044D838 51 00 00 00 1F 00 00 00
0044D840 20 00 00 00 3A 00 00 00
0044D848 01 00 00 00 2A 00 00 00
0044D850 45 00 00 00 55 00 00 00
0044D858 4A 00 00 00 02 00 00 00
0044D860 52 00 00 00 27 00 00 00
0044D868 03 00 00 00 4B 00 00 00
0044D870 08 00 00 00 3C 00 00 00
0044D878 0F 00 00 00 14 00 00 00
0044D880 24 00 00 00 25 00 00 00
0044D888 28 00 00 00 29 00 00 00
0044D890 16 00 00 00 1D 00 00 00
0044D898 1A 00 00 00 11 00 00 00
0044D8A0 2F 00 00 00 39 00 00 00
0044D8A8 09 00 00 00 47 00 00 00
0044D8B0 06 00 00 00 4F 00 00 00
0044D8B8 04 00 00 00 31 00 00 00
0044D8C0 0C 00 00 00 30 00 00 00
0044D8C8 01 00 00 00 01 00 00 00 --------------------------------------------------------------------------------
【破解总结】 总的来说这个软件的算法非常简单
现在来总决算法:
注册码:R1-R2-R3-R4
预置数:A,64
R1/A=B5 R1符合条件的有712,715,71A ,717 ,716
第二组和第三组注册码不能大于9999
((((R2+(R3/64的余数))+(R1/A的商)+R3)/64的余数*4+44D738)查表*64)+((((R2/64的商+R1)+R1/64的商)/64的余数)*4+44D738)查表=R4
取上面R1的任何一个为第一组注册码,然后第二组和第三组取任何四位数但小于9999,按上面的算法可以得到第四组注册码
--------------------------------------------------------------------------------
【版权声明】 在本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
能力值:
( LV2,RANK:10 )
15 楼
NO14: 作者:kyc
自动精灵 2.00 破解教程
【破解作者】 kyc[dfcg][czg]
【作者邮箱】 muyang008@163.com
【使用工具】 old1.10c
【破解平台】 win2003
【软件名称】 自动精灵 2.00
【下载地址】 http://free.angeltowns.com/ascn/index.htm
【软件简介】自动精灵是一款功能强大、精致美观、操作简便的计算机定时自动执行软件。她绝对是众多自动执行软件中最好的,
出色的设计使您的操作更加简便,每一项功能都为您精心打造。她必将成为您的贴心助手。 【软件大小】 705 KB
【加壳方式】 无壳
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】 根据序列号错误 004ED4B9 |. 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004ED4BB |. 68 98D64E00 push AutoStar.004ED698 ; |Title = "自动精灵"
004ED4C0 |. 68 A4D64E00 push AutoStar.004ED6A4 ; |Text = "注册码不能为空!请重新输入!"
004ED4C5 |. E8 9A9AF1FF call <jmp.&user32.GetActiveWindow> ; |[GetActiveWindow
004ED4CA |. 50 push eax ; |hOwner
004ED4CB |. E8 0C9DF1FF call <jmp.&user32.MessageBoxA> ; \MessageBoxA
004ED4D0 |. 8B83 04030000 mov eax,dword ptr ds:[ebx+304]
004ED4D6 |. 8B10 mov edx,dword ptr ds:[eax]
004ED4D8 |. FF92 C4000000 call dword ptr ds:[edx+C4]
004ED4DE |. E9 71010000 jmp AutoStar.004ED654
004ED4E3 |> 8D55 F8 lea edx,dword ptr ss:[ebp-8]
004ED4E6 |. 8B83 04030000 mov eax,dword ptr ds:[ebx+304]
004ED4EC |. E8 D7A0F7FF call AutoStar.004675C8
004ED4F1 |. 8B55 F8 mov edx,dword ptr ss:[ebp-8]
004ED4F4 |. A1 5C1D4F00 mov eax,dword ptr ds:[4F1D5C]
004ED4F9 |. 8B00 mov eax,dword ptr ds:[eax]
004ED4FB |. E8 B4E1FFFF call AutoStar.004EB6B4 ; f7 关键算法
004ED500 |. 84C0 test al,al
004ED502 |. 0F84 1A010000 je AutoStar.004ED622
004ED508 |. 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004ED50A |. 68 98D64E00 push AutoStar.004ED698 ; |Title = "自动精灵"
004ED50F |. 68 C4D64E00 push AutoStar.004ED6C4 ; |Text = "注册成功!
谢谢您的支持!"
004ED514 |. E8 4B9AF1FF call <jmp.&user32.GetActiveWindow> ; |[GetActiveWindow
004ED519 |. 50 push eax ; |hOwner
=============================================================================call AutoStar.004EB6B4
004EB6BB |. 53 push ebx
004EB6BC |. 56 push esi
004EB6BD |. 8BF2 mov esi,edx
004EB6BF |. 8BD8 mov ebx,eax
004EB6C1 |. 33C0 xor eax,eax
004EB6C3 |. 55 push ebp
004EB6C4 |. 68 21B74E00 push AutoStar.004EB721
004EB6C9 |. 64:FF30 push dword ptr fs:[eax]
004EB6CC |. 64:8920 mov dword ptr fs:[eax],esp
004EB6CF |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
004EB6D2 |. 8BC3 mov eax,ebx
004EB6D4 |. E8 A3010000 call AutoStar.004EB87C
004EB6D9 |. 8D4D F8 lea ecx,dword ptr ss:[ebp-8]
004EB6DC |. 8B55 FC mov edx,dword ptr ss:[ebp-4] ; edx=code
004EB6DF |. 8BC3 mov eax,ebx
004EB6E1 |. E8 3E030000 call AutoStar.004EBA24 ; F7 关键算法
004EB6E6 |. 8B45 F8 mov eax,dword ptr ss:[ebp-8]
004EB6E9 |. E8 8E8FF1FF call AutoStar.0040467C
004EB6EE |. 50 push eax
004EB6EF |. 8BC6 mov eax,esi
004EB6F1 |. E8 868FF1FF call AutoStar.0040467C
004EB6F6 |. 5A pop edx
004EB6F7 |. E8 B4DCF1FF call AutoStar.004093B0
004EB6FC |. 85C0 test eax,eax
004EB6FE |. 75 04 jnz short AutoStar.004EB704
004EB700 |. B3 01 mov bl,1
004EB702 |. EB 02 jmp short AutoStar.004EB706
===========================================================================call AutoStar.004EBA24
004EBA4B |. 8BD8 mov ebx,eax
004EBA4D |. 8BC3 mov eax,ebx ; EAX=JQM
004EBA4F |. B9 85000000 mov ecx,85 ; ecx=85h
004EBA54 |. 99 cdq ; 双字转换为四字指令
004EBA55 |. F7F9 idiv ecx ; jqm/85h
004EBA57 |. 69C0 AB000000 imul eax,eax,0AB ; eax*abh
004EBA5D |. 35 FDC85C02 xor eax,25CC8FD ; eax^25cc8fdh
004EBA62 |. 99 cdq ; 双字转换为四字指令
004EBA63 |. 33C2 xor eax,edx ; eax^JQM%85H
004EBA65 |. 2BC2 sub eax,edx ; eax-edx
004EBA67 |. 05 68C4AC07 add eax,7ACC468 ; eax+7acc468h
004EBA6C |. 8BD8 mov ebx,eax ; ebx=eax ;这个值非常重要
004EBA6E |. 8D55 F8 lea edx,dword ptr ss:[ebp-8]
004EBA71 |. 8BC3 mov eax,ebx
004EBA73 |. E8 60D1F1FF call AutoStar.00408BD8 ; F7关键算法
004EBA78 |. 8D45 F4 lea eax,dword ptr ss:[ebp-C]
004EBA7B |. BA 10BB4E00 mov edx,AutoStar.004EBB10 ; ASCII "734618529841"
004EBA80 |. E8 CF87F1FF call AutoStar.00404254
004EBA85 |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
004EBA88 |. E8 2F87F1FF call AutoStar.004041BC
004EBA8D |. 8B45 F4 mov eax,dword ptr ss:[ebp-C] ; EAX=734618529841这个值是个常量
;;;;;;;;;;;;;;;;;;;;;;;搜索全部常数
004EBA90 |. E8 E789F1FF call AutoStar.0040447C
004EBA95 |. 8BD8 mov ebx,eax
004EBA97 |. 85DB test ebx,ebx
004EBA99 |. 7E 3A jle short AutoStar.004EBAD5
004EBA9B |. BE 01000000 mov esi,1 ; ESI=1
004EBAA0 |> /8D45 EC /lea eax,dword ptr ss:[ebp-14]
004EBAA3 |. |8B55 F4 |mov edx,dword ptr ss:[ebp-C] ; EDX=734618529841
004EBAA6 |. |8A5432 FF |mov dl,byte ptr ds:[edx+esi-1]
004EBAAA |. |E8 F588F1FF |call AutoStar.004043A4
004EBAAF |. |8B45 EC |mov eax,dword ptr ss:[ebp-14]
004EBAB2 |. |E8 5DD2F1FF |call AutoStar.00408D14
004EBAB7 |. |8B55 F8 |mov edx,dword ptr ss:[ebp-8] ; EDX=657532891
004EBABA |. |8A5402 FF |mov dl,byte ptr ds:[edx+eax-1] ; DL=RES[I]
004EBABE |. |8D45 F0 |lea eax,dword ptr ss:[ebp-10]
004EBAC1 |. |E8 DE88F1FF |call AutoStar.004043A4
004EBAC6 |. |8B55 F0 |mov edx,dword ptr ss:[ebp-10]
004EBAC9 |. |8D45 FC |lea eax,dword ptr ss:[ebp-4]
004EBACC |. |E8 B389F1FF |call AutoStar.00404484 ; F7 求注册码过程
004EBAD1 |. |46 |inc esi ; ESI++
004EBAD2 |. |4B |dec ebx ; EDX--
004EBAD3 |.^\75 CB \jnz short AutoStar.004EBAA0
004EBAD5 |> 8BC7 mov eax,edi
004EBAD7 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
004EBADA |. E8 3187F1FF call AutoStar.00404210
004EBADF |. 33C0 xor eax,eax
004EBAE1 |. 5A pop edx
004EBAE2 |. 59 pop ecx
004EBAE3 |. 59 pop ecx
004EBAE4 |. 64:8910 mov dword ptr fs:[eax],edx
004EBAE7 |. 68 01BB4E00 push AutoStar.004EBB01
004EBAEC |> 8D45 EC lea eax,dword ptr ss:[ebp-14]
004EBAEF |. BA 05000000 mov edx,5
004EBAF4 |. E8 E786F1FF call AutoStar.004041E0
004EBAF9 \. C3 retn
=======================================================================call AutoStar.00404484
00404484 $ 85D2 test edx,edx
00404486 . 74 3F je short AutoStar.004044C7
00404488 . 8B08 mov ecx,dword ptr ds:[eax]
0040448A . 85C9 test ecx,ecx
0040448C .^ 0F84 7EFDFFFF je AutoStar.00404210
00404492 . 53 push ebx
00404493 . 56 push esi
00404494 . 57 push edi
00404495 . 89C3 mov ebx,eax
00404497 . 89D6 mov esi,edx ; ESI=EDX
00404499 . 8B79 FC mov edi,dword ptr ds:[ecx-4]
0040449C . 8B56 FC mov edx,dword ptr ds:[esi-4]
0040449F . 01FA add edx,edi ; EDX+EDI
004044A1 . 39CE cmp esi,ecx
004044A3 . 74 17 je short AutoStar.004044BC
004044A5 . E8 5E030000 call AutoStar.00404808
004044AA . 89F0 mov eax,esi
004044AC . 8B4E FC mov ecx,dword ptr ds:[esi-4]
004044AF > 8B13 mov edx,dword ptr ds:[ebx]
004044B1 . 01FA add edx,edi
004044B3 . E8 90E4FFFF call AutoStar.00402948 ; F7求注册码过程
004044B8 . 5F pop edi
004044B9 . 5E pop esi
004044BA . 5B pop ebx
004044BB . C3 retn
=======================================================================call AutoStar.00402948
00402948 /$ 56 push esi
00402949 |. 57 push edi
0040294A |. 89C6 mov esi,eax
0040294C |. 89D7 mov edi,edx
0040294E |. 89C8 mov eax,ecx
00402950 |. 39F7 cmp edi,esi
00402952 |. 77 13 ja short AutoStar.00402967
00402954 |. 74 2F je short AutoStar.00402985
00402956 |. C1F9 02 sar ecx,2
00402959 |. 78 2A js short AutoStar.00402985
0040295B |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
0040295D |. 89C1 mov ecx,eax
0040295F |. 83E1 03 and ecx,3
00402962 |. F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00402964 |. 5F pop edi
00402965 |. 5E pop esi
00402966 |. C3 retn
00402967 |> 8D7431 FC lea esi,dword ptr ds:[ecx+esi-4]
0040296B |. 8D7C39 FC lea edi,dword ptr ds:[ecx+edi-4]
0040296F |. C1F9 02 sar ecx,2
00402972 |. 78 11 js short AutoStar.00402985
00402974 |. FD std
00402975 |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
00402977 |. 89C1 mov ecx,eax
00402979 |. 83E1 03 and ecx,3 ; ECX&3
0040297C |. 83C6 03 add esi,3 ; ESI+3
0040297F |. 83C7 03 add edi,3
00402982 |. F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00402984 |. FC cld
00402985 |> 5F pop edi
00402986 |. 5E pop esi
00402987 \. C3 retn
==================================================================================================
总结:先求出一串值然后利用常量数组的变量作为它的下标取得注册码
根据上述算法很容易得到注册机下面是注册机VC代码。
#include<iostream.h>
#include<string.h>
#include <Windows.h>
#include <stdlib.h>
int tmp[]={7,3,4,6,1,8,5,2,9,8,4,1};
char output[12],sn[12];
void main()
{
int jqm,m;
cout<<"请输入机器码:"<<endl;
cin>>jqm;
/* t=jqm=389463739;
jqm/=0x85;
m=jqm%0x85;
jqm*=0xab;jqm^=0x25CC8FD;
jqm^=m;
jqm-=m;
jqm+=0x7acc468;
t=jqm;
cout<<jqm<<endl;
//利用C代码数值有误差。
//因为数值太大直接利用了汇编代码。
*/
__asm
{
mov eax,jqm
mov ecx,85h
cdq
idiv ecx
imul eax,eax,0ABh
xor eax,25CC8FDh
cdq
xor eax,edx
sub eax,edx
add eax,7ACC468h
mov m,eax
}
cout<<m<<endl;
_itoa(m,output,10);//这里的参数 第一个为要转换的整数,第二个为输出的字符串,第三个为进制,
for(int i=0;i<12;i++)
{
sn[i]=output[tmp[i]-1];
}
cout<<"您的注册码是:";
for( i=0;i<12;i++)
cout<<sn[i];
cout<<endl;
}
我的机器码:389463739
注册码:875269351956
注册后藏在shg1008.sys文件的
[Register]
Key=875269351956
能力值:
( LV2,RANK:10 )
16 楼
NO15: 作者:kyc
黄金内存 V3.1 破解教程
【破解作者】 kyc[dfcg][czg]
【作者邮箱】 muyang008@163.com
【使用工具】 old1.10c
【破解平台】 win2003
【软件名称】 黄金内存 V3.1
【下载地址】http://www.skycn.com/soft/14815.html
【软件简介】黄金内存可以整理/回收/清理系统的物理内存,提高内存分配命中率,提高使用效率,
防止由于内存泄漏造成的内存不足。全图形化界面,让操作者对系统当前状态一目了然,令您爱不释手。
内存整理:可了解内存及CPU的使用情况,及时整理内存,调整物理内存的使用性能。
进程管理:可查看系统中正在运行的进程及内存情况,找出耗费内存的大户,并可以随时终止;
服务管理:可管理XP/2000中的服务项目,将不用的服务停止,加快启动速度,节省内存。
启动管理:可以将随机动项目延时启动或暂停启动,极大提高启动速度。
【软件大小】 768 KB
【加壳方式】 无壳
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】 根据序列号错误对 CTRL+N
名称位于 Memory_B,项目 146
地址=0042D37C
区段=.rdata
类型=导入
名称=MFC42.#4224_CWnd::MessageBoxA查找导入参考
参考位于Memory_B:.text 到 MFC42.#4224_CWnd::MessageBoxA
地址 反汇编 注释
00404F1A call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
00405863 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
00405B82 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
004061C2 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
00406304 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0040CA0C call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0040CD27 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
004130AF call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041321D call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041C1C1 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041C47D call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041C640 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041C8CD call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041CBAA call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041CE4D call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041D8CC call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0041DD8D call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
00421F38 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
00422029 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
004220C7 call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
0042422D call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
004275EC jmp dword ptr ds:[<&MFC42.#4224_CWnd::Messag MFC42.#4224_CWnd::MessageBoxA
全部下断
123456-123456-123456-123456
------------------------------------------------------------------------------
004131FD . E8 00430100 call <jmp.&MFC42.#858_CString::operator=>
00413202 . 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
00413206 . 885C24 34 mov byte ptr ss:[esp+34],bl
0041320A . E8 ED420100 call <jmp.&MFC42.#800_CString::~CString>
0041320F . 8B5424 0C mov edx,dword ptr ss:[esp+C]
00413213 . 6A 00 push 0
00413215 . 68 38634300 push Memory_B.00436338 ; ASCII "Memory Booster"
0041321A . 52 push edx
0041321B . 8BCE mov ecx,esi
0041321D . E8 CA430100 call <jmp.&MFC42.#4224_CWnd::MessageBoxA> 断在这里
向上看
---------------------------------------------------------------------------------
00412FD0 . 6A FF push -1 ; F2 下断
00412FD2 . 68 609C4200 push Memory_B.00429C60 ; SE handler installation
00412FD7 . 64:A1 0000000>mov eax,dword ptr fs:[0]
00412FDD . 50 push eax
00412FDE . 64:8925 00000>mov dword ptr fs:[0],esp
00412FE5 . 83EC 24 sub esp,24
00412FE8 . 53 push ebx
00412FE9 . 56 push esi
00412FEA . 8BF1 mov esi,ecx
00412FEC . 8D4C24 08 lea ecx,dword ptr ss:[esp+8]
00412FF0 . E8 19450100 call <jmp.&MFC42.#540_CString::CString>
00412FF5 . 8D4424 08 lea eax,dword ptr ss:[esp+8]
00412FF9 . 8BCE mov ecx,esi
00412FFB . 50 push eax
00412FFC . 68 5C040000 push 45C
00413001 . C74424 3C 000>mov dword ptr ss:[esp+3C],0
00413009 . E8 A2480100 call <jmp.&MFC42.#3097_CWnd::GetDlgItemTextA> ; ECX=假码
0041300E . 51 push ecx
0041300F . 8D5424 0C lea edx,dword ptr ss:[esp+C]
00413013 . 8BCC mov ecx,esp
00413015 . 896424 14 mov dword ptr ss:[esp+14],esp
00413019 . 52 push edx
0041301A . E8 CB440100 call <jmp.&MFC42.#535_CString::CString>
0041301F . E8 4C1A0000 call Memory_B.00414A70 ; F7 关键算法进入
00413024 . 83C4 04 add esp,4
00413027 . 85C0 test eax,eax
00413029 . 0F84 6E010000 je Memory_B.0041319D
=========================================================================call Memory_B.00414A70
00414A70 /$ 6A FF push -1
00414A72 |. 68 C89E4200 push Memory_B.00429EC8 ; SE handler installation
00414A77 |. 64:A1 0000000>mov eax,dword ptr fs:[0]
00414A7D |. 50 push eax
00414A7E |. 64:8925 00000>mov dword ptr fs:[0],esp
00414A85 |. 51 push ecx
00414A86 |. 56 push esi
00414A87 |. 51 push ecx
00414A88 |. 8D4424 1C lea eax,dword ptr ss:[esp+1C]
00414A8C |. 8BCC mov ecx,esp
00414A8E |. 896424 08 mov dword ptr ss:[esp+8],esp
00414A92 |. 50 push eax
00414A93 |. C74424 18 000>mov dword ptr ss:[esp+18],0
00414A9B |. E8 4A2A0100 call <jmp.&MFC42.#535_CString::CString>
00414AA0 |. E8 DBFCFFFF call Memory_B.00414780 ; F7 关键算法进入
00414AA5 |. 83C4 04 add esp,4
00414AA8 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
00414AAC |. 8BF0 mov esi,eax
00414AAE |. C74424 10 FFF>mov dword ptr ss:[esp+10],-1
00414AB6 |. E8 412A0100 call <jmp.&MFC42.#800_CString::~CString>
00414ABB |. 8B4C24 08 mov ecx,dword ptr ss:[esp+8]
00414ABF |. 8BC6 mov eax,esi
00414AC1 |. 64:890D 00000>mov dword ptr fs:[0],ecx
00414AC8 |. 5E pop esi
00414AC9 |. 83C4 10 add esp,10
00414ACC \. C3 retn
=========================================================================call Memory_B.00414780
00414780 /$ 6A FF push -1
00414782 |. 68 B09E4200 push Memory_B.00429EB0 ; SE handler installation
00414787 |. 64:A1 0000000>mov eax,dword ptr fs:[0]
0041478D |. 50 push eax
0041478E |. 64:8925 00000>mov dword ptr fs:[0],esp
00414795 |. 83EC 38 sub esp,38
00414798 |. 53 push ebx
00414799 |. 55 push ebp
0041479A |. 8D4424 50 lea eax,dword ptr ss:[esp+50] ; eax=假码
0041479E |. 8D4C24 08 lea ecx,dword ptr ss:[esp+8]
004147A2 |. 50 push eax
004147A3 |. C74424 4C 000>mov dword ptr ss:[esp+4C],0
004147AB |. E8 3A2D0100 call <jmp.&MFC42.#535_CString::CString>
004147B0 |. 8B4C24 08 mov ecx,dword ptr ss:[esp+8] ; eCx=假码
004147B4 |. C64424 48 01 mov byte ptr ss:[esp+48],1
004147B9 |. 8379 F8 11 cmp dword ptr ds:[ecx-8],11 ; 不能小于17位
004147BD |. 0F8C 64020000 jl Memory_B.00414A27
004147C3 |. 68 F8764300 push Memory_B.004376F8 ; 第7位看有没有-,没有就失败
004147C8 |. 8D4C24 0C lea ecx,dword ptr ss:[esp+C] ; eCx=假码
004147CC |. E8 672D0100 call <jmp.&MFC42.#2764_CString::Find>
004147D1 |. 83CD FF or ebp,FFFFFFFF
004147D4 |. 3BC5 cmp eax,ebp
004147D6 |. 0F84 63020000 je Memory_B.00414A3F
004147DC |. 6A 05 push 5
004147DE |. 6A 2D push 2D
004147E0 |. 8D4C24 10 lea ecx,dword ptr ss:[esp+10] ; 第14位看有没有-,没有就失败
004147E4 |. E8 6F310100 call <jmp.&MFC42.#6662_CString::Find>
004147E9 |. 3BC5 cmp eax,ebp
004147EB |. 0F84 4E020000 je Memory_B.00414A3F
004147F1 |. 6A 0B push 0B
004147F3 |. 6A 2D push 2D
004147F5 |. 8D4C24 10 lea ecx,dword ptr ss:[esp+10] ; 看有没有-,没有就失败
004147F9 |. E8 5A310100 call <jmp.&MFC42.#6662_CString::Find>
004147FE |. 3BC5 cmp eax,ebp
00414800 |. 0F84 39020000 je Memory_B.00414A3F
00414806 |. 33DB xor ebx,ebx ; EBX清零
00414808 |> 8AD3 /mov dl,bl ; DL=BL
0041480A |. 6A 01 |push 1
0041480C |. 80C2 61 |add dl,61 ; DL+0X61(a)
0041480F |. 8D4C24 0C |lea ecx,dword ptr ss:[esp+C]
00414813 |. 885424 1C |mov byte ptr ss:[esp+1C],dl ; [esp+1c]=dl
00414817 |. 8B4424 1C |mov eax,dword ptr ss:[esp+1C] ; eax=[esp+1c]
0041481B |. 50 |push eax ; 看有没有a,b,c,d..............z
0041481C |. E8 37310100 |call <jmp.&MFC42.#6662_CString::Find>
00414821 |. 3BC5 |cmp eax,ebp
00414823 |. 0F85 16020000 |jnz Memory_B.00414A3F ; 看有没有小写字母没有继续找有就失败
00414829 |. 43 |inc ebx ; EBX++
0041482A |. 83FB 1A |cmp ebx,1A ; EBX小于1A=26D吗
0041482D |.^ 7C D9 \jl short Memory_B.00414808
0041482F |. 33DB xor ebx,ebx ; EBX清零
00414831 |> 8ACB /mov cl,bl
00414833 |. 6A 01 |push 1
00414835 |. 80C1 41 |add cl,41
00414838 |. 884C24 1C |mov byte ptr ss:[esp+1C],cl
0041483C |. 8B5424 1C |mov edx,dword ptr ss:[esp+1C]
00414840 |. 52 |push edx
00414841 |. 8D4C24 10 |lea ecx,dword ptr ss:[esp+10]
00414845 |. E8 0E310100 |call <jmp.&MFC42.#6662_CString::Find> ; 看有没有A,B,C,D..............Z
0041484A |. 3BC5 |cmp eax,ebp
0041484C |. 0F85 ED010000 |jnz Memory_B.00414A3F ; 看有没有大写字母没有继续找有就失败
00414852 |. 43 |inc ebx
00414853 |. 83FB 1A |cmp ebx,1A
00414856 |.^ 7C D9 \jl short Memory_B.00414831
00414858 |. 56 push esi
00414859 |. 57 push edi
0041485A |. 8D4C24 1C lea ecx,dword ptr ss:[esp+1C]
0041485E |. E8 AB2C0100 call <jmp.&MFC42.#540_CString::CString>
00414863 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
00414867 |. C64424 50 02 mov byte ptr ss:[esp+50],2
0041486C |. E8 9D2C0100 call <jmp.&MFC42.#540_CString::CString>
00414871 |. 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
00414875 |. C64424 50 03 mov byte ptr ss:[esp+50],3
0041487A |. E8 8F2C0100 call <jmp.&MFC42.#540_CString::CString>
0041487F |. 8D4424 20 lea eax,dword ptr ss:[esp+20]
00414883 |. B3 04 mov bl,4 ; BL=4
00414885 |. 6A 05 push 5
00414887 |. 50 push eax
00414888 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18] ; eCx=假码
0041488C |. 885C24 58 mov byte ptr ss:[esp+58],bl
00414890 |. E8 9D2C0100 call <jmp.&MFC42.#4129_CString::Left>
00414895 |. 50 push eax ; EAX=前5位注册码
00414896 |. 8D4C24 20 lea ecx,dword ptr ss:[esp+20]
0041489A |. C64424 54 05 mov byte ptr ss:[esp+54],5
0041489F |. E8 5E2C0100 call <jmp.&MFC42.#858_CString::operator=>
004148A4 |. 8D4C24 20 lea ecx,dword ptr ss:[esp+20]
004148A8 |. 885C24 50 mov byte ptr ss:[esp+50],bl
004148AC |. E8 4B2C0100 call <jmp.&MFC42.#800_CString::~CString>
004148B1 |. 8D4C24 20 lea ecx,dword ptr ss:[esp+20]
004148B5 |. 6A 05 push 5
004148B7 |. 51 push ecx
004148B8 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
004148BC |. E8 BF2F0100 call <jmp.&MFC42.#5710_CString::Right>
004148C1 |. 50 push eax ; EAX=后5位注册码
004148C2 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
004148C6 |. C64424 54 06 mov byte ptr ss:[esp+54],6
004148CB |. E8 322C0100 call <jmp.&MFC42.#858_CString::operator=>
004148D0 |. 8D4C24 20 lea ecx,dword ptr ss:[esp+20]
004148D4 |. 885C24 50 mov byte ptr ss:[esp+50],bl
004148D8 |. E8 1F2C0100 call <jmp.&MFC42.#800_CString::~CString>
004148DD |. 6A 05 push 5
004148DF |. 8D5424 24 lea edx,dword ptr ss:[esp+24]
004148E3 |. 6A 06 push 6
004148E5 |. 52 push edx
004148E6 |. 8D4C24 1C lea ecx,dword ptr ss:[esp+1C]
004148EA |. E8 63300100 call <jmp.&MFC42.#4278_CString::Mid> ; 第2组首5位
004148EF |. 50 push eax
004148F0 |. 8D4C24 1C lea ecx,dword ptr ss:[esp+1C]
004148F4 |. C64424 54 07 mov byte ptr ss:[esp+54],7
004148F9 |. E8 042C0100 call <jmp.&MFC42.#858_CString::operator=>
004148FE |. 8D4C24 20 lea ecx,dword ptr ss:[esp+20]
00414902 |. 885C24 50 mov byte ptr ss:[esp+50],bl
00414906 |. E8 F12B0100 call <jmp.&MFC42.#800_CString::~CString>
0041490B |. 8B7C24 1C mov edi,dword ptr ss:[esp+1C] ; EDI=前5位
0041490F |. 8BCD mov ecx,ebp
00414911 |. 33C0 xor eax,eax ; EAX=0
00414913 |. 8D5424 24 lea edx,dword ptr ss:[esp+24]
00414917 |. F2:AE repne scas byte ptr es:[edi]
00414919 |. F7D1 not ecx
0041491B |. 2BF9 sub edi,ecx ; EDI=前5位
0041491D |. 8BC1 mov eax,ecx
0041491F |. 8BF7 mov esi,edi ; ESI=EDI=前5位
00414921 |. 8BFA mov edi,edx
00414923 |. 8D5424 30 lea edx,dword ptr ss:[esp+30]
00414927 |. C1E9 02 shr ecx,2 ; ECX SHR 2
0041492A |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
0041492C |. 8BC8 mov ecx,eax ; ECX=EAX=6
0041492E |. 33C0 xor eax,eax ; EAX=0
00414930 |. 83E1 03 and ecx,3 ; ECX AND 3=2
00414933 |. F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00414935 |. 8B7C24 18 mov edi,dword ptr ss:[esp+18] ; 第2组首5位
00414939 |. 8BCD mov ecx,ebp
0041493B |. F2:AE repne scas byte ptr es:[edi]
0041493D |. F7D1 not ecx
0041493F |. 2BF9 sub edi,ecx
00414941 |. 8BC1 mov eax,ecx
00414943 |. 8BF7 mov esi,edi
00414945 |. 8BFA mov edi,edx
00414947 |. C1E9 02 shr ecx,2 ; ECX SHR 2
0041494A |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
0041494C |. 8BC8 mov ecx,eax
0041494E |. 33C0 xor eax,eax ; EAX=0
00414950 |. 83E1 03 and ecx,3 ; ECX AND 3=2
00414953 |. 8D5424 3C lea edx,dword ptr ss:[esp+3C]
00414957 |. F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00414959 |. 8B7C24 14 mov edi,dword ptr ss:[esp+14] ; EDI=后5位注册码
0041495D |. 8BCD mov ecx,ebp
0041495F |. F2:AE repne scas byte ptr es:[edi]
00414961 |. F7D1 not ecx
00414963 |. 2BF9 sub edi,ecx
00414965 |. 8BC1 mov eax,ecx
00414967 |. 8BF7 mov esi,edi ; ESI=EDI=前5位
00414969 |. 8BFA mov edi,edx
0041496B |. C1E9 02 shr ecx,2 ; ECX SHR 2
0041496E |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
00414970 |. 8BC8 mov ecx,eax
00414972 |. 83E1 03 and ecx,3
00414975 |. F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00414977 |. 8B3D 94D64200 mov edi,dword ptr ds:[<&MSVCRT.atoi>] ; msvcrt.atoi挑选整数的函数
0041497D |. 8D4C24 24 lea ecx,dword ptr ss:[esp+24]
00414981 |. 51 push ecx ; /s
00414982 |. FFD7 call edi ; \atoi
00414984 |. 8D5424 34 lea edx,dword ptr ss:[esp+34]
00414988 |. 8BE8 mov ebp,eax ; EBP=第一组5位码变为整数
0041498A |. 52 push edx
0041498B |. FFD7 call edi
0041498D |. 8BF0 mov esi,eax ; ESI=第2组5位码变为整数(从第7位取)
0041498F |. 8D4424 44 lea eax,dword ptr ss:[esp+44]
00414993 |. 50 push eax
00414994 |. FFD7 call edi ; EAX=后5位注册码变为整数
00414996 |. 33F5 xor esi,ebp ; ESI^EBP
00414998 |. 83C4 0C add esp,0C
0041499B |. 81F6 ACD30000 xor esi,0D3AC ; ESI^0D3AC
004149A1 |. C64424 50 03 mov byte ptr ss:[esp+50],3
004149A6 |. 5F pop edi
004149A7 |. 3BF0 cmp esi,eax ; ESI==EAX 关键比较
004149A9 |. 5E pop esi
004149AA |. 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
004149AE |. 75 56 jnz short Memory_B.00414A06
=============================================================================================================
总结:
根据上述算法很容易得到注册机下面是注册机C代码。
#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>
#include <string.h>
void main( void )
{
char str1[6],str2[6];
int i1,i2,i3;
char *s1=str1;
char *s2=str2;
cout<<"请输入数字首位必须带-"<<endl;
cin>>s1;
if(strlen(s1)>5||strlen(s1)<5)
{
cout<<"必须是5位";
return;
}
cin>>s2;
if(strlen(s2)>5||strlen(s2)<5)
{
cout<<"必须是5位";
return;
} /* Test of atoi */
i1 = atoi( s1 );
i2 = atoi( s2 );
i3=i1^i2;
i3=i3^0x0D3AC;
cout<<""<<i1<<"*"<<i2<<"*"<<"-"<<i3<<endl;
cout<<"*代表任意非字母字符或数字"<<endl;
} 可用的注册码
-12312-456456-50865
注册信息保留在注册表的
HKLM_SOFTWARE_MemIdle_MemIdleSN
删除后提示未注册。
======================================================================================
能力值:
( LV2,RANK:10 )
17 楼
NO16: 作者:killl 一个非常简单的crackme算法注册机(适合入门)
附件:crackme4.rar 这个是极酷论坛的crackme4,算法简单,适合想做自己算法注册机的入门者学习
我们的重点放在算法上,peid查询得知,yoda's cryptor 1.2,使用脱壳板块的脱壳机即可脱壳。
错误提示为:
---------------------------
go on!
---------------------------
Try again!^_*
---------------------------
确定
---------------------------
所以下断 bpx messageboxa
004015F5 > \68 7C7140>push crackme4.0040717C ; |Title = "go on!"
004015FA . 68 6C7140>push crackme4.0040716C ; |Text = "Try again!^_*"
004015FF . 56 push esi ; |hOwner
00401600 . FF15 4871>call dword ptr ds:[<&USER32.MessageBoxA>] ; \MessageBoxA
00401606 > 5F pop edi ; Default case of switch 0040152D
输入假码,断在00401600
向上面看看:
004015B8 . 68 F09740>push crackme4.004097F0 ; ASCII "killl"用户名
004015BD . 68 F09640>push crackme4.004096F0 ; ASCII "123456"假码
004015C2 . 56 push esi
004015C3 . E8 E8FBFF>call crackme4.004011B0
004015C8 . 83C4 0C add esp,0C
004015CB . 85C0 test eax,eax
004015CD . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
004015CF . 74 24 je short crackme4.004015F5 ; |
004015D1 . 68 A07140>push crackme4.004071A0 ; |Title = "Congratulations!"
004015D6 . 68 847140>push crackme4.00407184 ; |Text = "Well Done, you've passed!"
004015DB . 56 push esi ; |hOwner
004015DC . FF15 4871>call dword ptr ds:[<&USER32.MessageBoxA>] ; \MessageBoxA
004015E2 . 5F pop edi
004015E3 . 33C0 xor eax,eax
004015E5 . 5E pop esi
004015E6 . 8B4C24 4C mov ecx,dword ptr ss:[esp+4C]
004015EA . E8 300100>call crackme4.0040171F
004015EF . 83C4 50 add esp,50
004015F2 . C2 1000 retn 10
004015F5 > 68 7C7140>push crackme4.0040717C ; |Title = "go on!"
就是从004015CF跳来的,所以004015C3 的call是关键,跟入:
00401217 |. 2BC6 sub eax,esi
00401219 |. 85C9 test ecx,ecx ; 注册码的位数
0040121B |. 74 67 je short crackme4.00401284
0040121D |. 83F8 08 cmp eax,8 ; 判断位数
00401220 |. 75 62 jnz short crackme4.00401284 ; 不是8位就完蛋了
00401222 |. 33C0 xor eax,eax
00401224 |. 85C9 test ecx,ecx ; 名字的位数
00401226 |. BE 78563412 mov esi,12345678 ; 先赋值一个常数
0040122B |. 76 17 jbe short crackme4.00401244
0040122D |. 8D49 00 lea ecx,dword ptr ds:[ecx]
00401230 |> 8BD6 /mov edx,esi
00401232 |. 03F6 |add esi,esi ; 乘以2
00401234 |. C1EA 07 |shr edx,7 ; 右移7位
00401237 |. 0BD6 |or edx,esi ; 跟edx异或
00401239 |. 0FB63438 |movzx esi,byte ptr ds:[eax+edi] ; 从名字第一位开始赋值
0040123D |. 33F2 |xor esi,edx
0040123F |. 40 |inc eax ; 下一位
00401240 |. 3BC1 |cmp eax,ecx ; 名字是不是已经比较完毕
00401242 |.^ 72 EC \jb short crackme4.00401230
00401244 |> 8D4424 0C lea eax,dword ptr ss:[esp+C]
00401248 |. 50 push eax
00401249 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
0040124D |. 51 push ecx
0040124E |. E8 4DFEFFFF call crackme4.004010A0
00401253 |. 8D5424 18 lea edx,dword ptr ss:[esp+18]
00401257 |. 52 push edx
00401258 |. 55 push ebp
00401259 |. E8 42FEFFFF call crackme4.004010A0
0040125E |. 8B7C24 1C mov edi,dword ptr ss:[esp+1C] ; 你的机器码
00401262 |. 8B4424 20 mov eax,dword ptr ss:[esp+20] ; 输入的假码
00401266 |. 83C4 10 add esp,10
00401269 |. 33C7 xor eax,edi ; 与机器码异或
0040126B |. 33C9 xor ecx,ecx
0040126D |. 3BC6 cmp eax,esi ; 跟上面的esi比较
0040126F |. 0F94C1 sete cl
00401272 |. 5F pop edi
00401273 |. 5E pop esi
00401274 |. 5D pop ebp
00401275 |. 8BC1 mov eax,ecx
00401277 |. 8B4C24 14 mov ecx,dword ptr ss:[esp+14]
0040127B |. E8 9F040000 call crackme4.0040171F
00401280 |. 83C4 18 add esp,18
00401283 |. C3 retn
算法很简单
00401226 esi=0x12345678
00401230 edi=esi
00401234 esi=esi+esi
00401237 esi=esi 异或 edi
00401239 esi=你输入名字的第一位
0040123D esi=esi 异或 edi
0040123D 计数器加一
00401240 名字是不是比较完毕
00401242 没有就跳到00401230
算法注册机如下:
tc2.0 + winxp sp2下编译通过
/* Name: keygen for 极酷论坛破解学院 crackme4 */
/* Author: KiLlL *//* Date: 2004-12-5 15:06 */ #include "stdio.h"
#include "conio.h"
main(){
unsigned long seed=0x12345678,sn,temp,machine=0x0;
char name[100];
int i;
printf("KeyGen for Crackme4 by: KiLlL 2004-12-5\n\n");
printf("Please enter your name: \n");
scanf("%s",name);
printf("Please enter your machine code: \n");
scanf("%lx",&machine);
for(i=0;i<name[i];i++)
{
temp=seed;
seed*=2;
temp>>=7;
temp|=seed;
seed=name[i]^temp;
}
sn=seed^machine;
printf("Your sn: %lX\n",sn);
getch();
return(0);}
能力值:
( LV2,RANK:10 )
18 楼
NO17: 作者:jackily
原创】控件注册 3dlink 1.6 sp2 的算法详解及注册机(手把手系列)
控件注册 3dlink 1.6 sp2 的算法详解及注册机 (手把手教你学注册)
【破解作者】 jackily
【作者邮箱】 jackily_zhang@msn.com;jackily_zhang@yahoo.com.cn
【作者主页】 http://estudy.ys168.com
【使用工具】 ollydbg 1.10
【破解平台】 Win9x/NT/2000/XP
【软件名称】 3dlink 1.6 sp2 控件
【下载地址】 http://www.3dlinx.com/downloads/3dlinx/3dlinx16sp2/3dlinx1_6sp2.zip
http://estudy.ys168.com 其它目录中的3dlintrail1.5.exe
【软件简介】 这个软件是个控件,被VC,C++,DELPHI来调用,可以非常简单地开发三维程序,这个是3dlinx最新版,安装完毕后全部是DLL文件。未注册时,加载控件时会有一个nag窗口,并有30天使用限制和10个设计窗口限制。3dlintrail1.5.exe是前一版本的测试版,带注册程序,名字是LinXRegister.exe。先安装1.6再安装1.5版本,不要安装在一起,就可以有一个独立的程序来注册了。
【破解声明】 本破解纯属以学习为目的,偶得一点心得,愿与大家分享!感谢Shooo提供了注册机的算法思路,本人进行了修改(在总结中有说明)。
--------------------------------------------------------------------------------
【破解内容】
经分析,其实真正的注册代码在1.6 sp2中的poppages.dll中。运行ollydbg,加载LinxRegister.exe。点右键―“搜索”―“字符参考”,找
到ASCII "Registration succeeded!"。地址是00401719,在00401717跳转处下断,而这段代码源于00401650。按F9调试,出现注册画面,分四
个输入栏,第一个是3dlink产品名称(可选);第二个是computer code entry(已自动生成,但可以修动);第三个是ID号(根据电脑配置和
操作系统自动生成,灰色不可修);第四个是注册码(要求用户输入)。第一栏是3DLINK,第二栏是“274925803”,第三栏是“481920”,在
第四栏中,我们输入“1234567”。点注册,在刚才下断的地方停下来。代码分析如下:
00401650 > 51 push ecx
00401651 . 56 push esi
00401652 . 57 push edi
00401653 . 8BF1 mov esi,ecx
00401655 . 6A 01 push 1
00401657 . BF 05400080 mov edi,80004005
0040165C . E8 7DC60000 call LinXRegi.0040DCDE
00401661 . 8B8E B0000000 mov ecx,dword ptr ds:[esi+B0]
00401667 . 85C9 test ecx,ecx
00401669 . 0F84 F9000000 je LinXRegi.00401768
0040166F . 8B86 B4000000 mov eax,dword ptr ds:[esi+B4]
00401675 . 8B11 mov edx,dword ptr ds:[ecx]
00401677 . 8D0440 lea eax,dword ptr ds:[eax+eax*2]
0040167A . C1E0 02 shl eax,2
0040167D . 8BB8 C0814100 mov edi,dword ptr ds:[eax+4181C0]
00401683 . 8B80 BC814100 mov eax,dword ptr ds:[eax+4181BC]
00401689 . 57 push edi
0040168A . 50 push eax
0040168B . 51 push ecx
0040168C . FF52 24 call dword ptr ds:[edx+24] ; poppages.01EBA5A5
0040168F . 8BF8 mov edi,eax
00401691 . 85FF test edi,edi
00401693 . /0F8C CF000000 jl LinXRegi.00401768
00401699 . |8B86 B0000000 mov eax,dword ptr ds:[esi+B0]
0040169F . |50 push eax
004016A0 . |8B08 mov ecx,dword ptr ds:[eax]
004016A2 . |FF51 0C call dword ptr ds:[ecx+C] ;分析是否已注册,是则到004016A9,退出。
004016A5 . |85C0 test eax,eax
004016A7 . |75 18 jnz short LinXRegi.004016C1 ;否则跳至004016c1继续注册程序
004016A9 . |50 push eax
004016AA . |68 90814100 push LinXRegi.00418190 ; ASCII "3DLinX Registration"
004016AF . |68 60854100 push LinXRegi.00418560 ; ASCII "This product is already registered."
004016B4 . |8BCE mov ecx,esi
004016B6 . |E8 C7BE0000 call LinXRegi.0040D582
004016BB . |5F pop edi
004016BC . |33C0 xor eax,eax
004016BE . |5E pop esi
004016BF . |59 pop ecx
004016C0 . |C3 retn
004016C1 > |8B86 A8000000 mov eax,dword ptr ds:[esi+A8] ;ASII "1234567"
004016C7 . |8B96 B0000000 mov edx,dword ptr ds:[esi+B0] ;ASII "274925803"
004016CD . |8BBE A0000000 mov edi,dword ptr ds:[esi+A0] ; ASII "481920" ,这三个数我们很熟悉吧。
004016D3 . |53 push ebx
004016D4 . |8B9E 98000000 mov ebx,dword ptr ds:[esi+98]
004016DA . |8D4C24 0C lea ecx,dword ptr ss:[esp+C]
004016DE . |55 push ebp
004016DF . |8B2A mov ebp,dword ptr ds:[edx]
004016E1 . |51 push ecx
004016E2 . |50 push eax
004016E3 . |E8 160E0000 call LinXRegi.004024FE ;将ASII码变成HEX十六进制数
004016E8 . |83C4 04 add esp,4
004016EB . |50 push eax
004016EC . |57 push edi
004016ED . |E8 0C0E0000 call LinXRegi.004024FE ;将ASII码变成HEX十六进制数
004016F2 . |83C4 04 add esp,4
004016F5 . |50 push eax
004016F6 . |53 push ebx
004016F7 . |E8 020E0000 call LinXRegi.004024FE ;将ASII码变成HEX十六进制数
004016FC . |8B96 B0000000 mov edx,dword ptr ds:[esi+B0]
00401702 . |83C4 04 add esp,4
00401705 . |50 push eax
00401706 . |52 push edx
00401707 . |FF55 20 call dword ptr ss:[ebp+20] ;关键调用,动态加载poppages.dll 地址:01EBA253,跟进。
;在实际调试时,尽管在同一机器上,该调用地址会随内存中进程而经
常变动。
0040170A . |5D pop ebp
0040170B . |8BF8 mov edi,eax
0040170D . |5B pop ebx
0040170E . |85FF test edi,edi ;比较标志,注册失败跳至00401750。成功则出现成功画面。这里不
;能完全爆破,因为在poppages.dll中的01EBA293 处有对控件文件
;的处理,否则只会出现成功画面,但下次还提示注册。
00401710 . |6A 00 push 0
00401712 . |68 90814100 push LinXRegi.00418190 ; ASCII "3DLinX Registration"
00401717 . |7C 37 jl short LinXRegi.00401750 ;刚才下断的地方
00401719 . |68 48854100 push LinXRegi.00418548 ; ASCII "Registration succeeded!"
0040171E . |8BCE mov ecx,esi
00401720 . |E8 5DBE0000 call LinXRegi.0040D582
00401725 . |68 34854100 push LinXRegi.00418534 ; ASCII "Product Registered"
0040172A . |8D8E A4000000 lea ecx,dword ptr ds:[esi+A4]
00401730 . |E8 72D30000 call LinXRegi.0040EAA7
00401735 . |6A 00 push 0
00401737 . |8BCE mov ecx,esi
00401739 . |E8 A0C50000 call LinXRegi.0040DCDE
0040173E . |8BB6 B0000000 mov esi,dword ptr ds:[esi+B0]
00401744 . |56 push esi
00401745 . |8B06 mov eax,dword ptr ds:[esi]
00401747 . |FF50 28 call dword ptr ds:[eax+28]
0040174A . |8BC7 mov eax,edi
0040174C . |5F pop edi
0040174D . |5E pop esi
0040174E . |59 pop ecx
0040174F . |C3 retn
00401750 > |68 04854100 push LinXRegi.00418504 ; ASCII "Registration failure. Check input for validity."
00401755 . |8BCE mov ecx,esi
00401757 . |E8 26BE0000 call LinXRegi.0040D582
0040175C . |8BB6 B0000000 mov esi,dword ptr ds:[esi+B0]
00401762 . |56 push esi
00401763 . |8B06 mov eax,dword ptr ds:[esi]
00401765 . |FF50 28 call dword ptr ds:[eax+28]
00401768 > \8BC7 mov eax,edi
0040176A . 5F pop edi
0040176B . 5E pop esi
0040176C . 59 pop ecx
0040176D . C3 retn
--------------------------------------------------------------------------------
由00401707跟进。
01EBA253 55 push ebp
01EBA254 8BEC mov ebp,esp
01EBA256 83EC 30 sub esp,30
01EBA259 56 push esi
01EBA25A 8B75 08 mov esi,dword ptr ss:[ebp+8]
01EBA25D 57 push edi
01EBA25E 807E 1C 00 cmp byte ptr ds:[esi+1C],0
01EBA262 0F84 B0000000 je poppages.01EBA318
01EBA268 8B7D 10 mov edi,dword ptr ss:[ebp+10]
01EBA26B 393D B02FEF01 cmp dword ptr ds:[1EF2FB0],edi
01EBA271 0F85 A1000000 jnz poppages.01EBA318 ;以下三行是刚才转换的三个HEX值
01EBA277 FFB6 68020000 push dword ptr ds:[esi+268] ;ESI+268是"123456"的HEX值“1E240”
01EBA27D 57 push edi ;EDI为ID的HEX值“75A80”。
01EBA27E FF75 0C push dword ptr ss:[ebp+C] ;这里是CODE ENTRY的HEX值“106308EB”
01EBA281 FF75 14 push dword ptr ss:[ebp+14] ;这里是0x69930,程序约定。
01EBA284 E8 B6680100 call poppages.01ED0B3F ;关键,调用算法程序,跟进。
01EBA289 8B4D 18 mov ecx,dword ptr ss:[ebp+18]
01EBA28C 83F8 01 cmp eax,1 ;EAX是否为1,注册码比较标志。
01EBA28F 8901 mov dword ptr ds:[ecx],eax
01EBA291 75 14 jnz short poppages.01EBA2A7 ;EAX不为1,注册码不正确。跳至poppages.01EBA2A7
01EBA293 6A 04 push 4 ;正确的话,程序对控件进处理,解除注册限制。
01EBA295 58 pop eax
01EBA296 3946 14 cmp dword ptr ds:[esi+14],eax
01EBA299 74 79 je short poppages.01EBA314
01EBA29B 68 90C6EE01 push poppages.01EEC690
01EBA2A0 8946 14 mov dword ptr ds:[esi+14],eax
01EBA2A3 6A 09 push 9
01EBA2A5 EB 59 jmp short poppages.01EBA300
01EBA2A7 83F8 31 cmp eax,31
01EBA2AA 75 28 jnz short poppages.01EBA2D4
01EBA2AC 8D45 08 lea eax,dword ptr ss:[ebp+8]
01EBA2AF 6A 00 push 0
01EBA2B1 50 push eax
01EBA2B2 8D45 10 lea eax,dword ptr ss:[ebp+10]
01EBA2B5 50 push eax
01EBA2B6 8D45 0C lea eax,dword ptr ss:[ebp+C]
01EBA2B9 50 push eax
01EBA2BA E8 42680100 call poppages.01ED0B01
01EBA2BF FF75 08 push dword ptr ss:[ebp+8]
01EBA2C2 FF75 10 push dword ptr ss:[ebp+10]
01EBA2C5 FF75 0C push dword ptr ss:[ebp+C]
01EBA2C8 6A 05 push 5
01EBA2CA FF76 18 push dword ptr ds:[esi+18]
01EBA2CD E8 48660100 call poppages.01ED091A
01EBA2D2 EB 40 jmp short poppages.01EBA314
01EBA2D4 83F8 32 cmp eax,32
01EBA2D7 75 31 jnz short poppages.01EBA30A
01EBA2D9 8B86 68020000 mov eax,dword ptr ds:[esi+268]
01EBA2DF 8B8E 6C020000 mov ecx,dword ptr ds:[esi+26C]
01EBA2E5 50 push eax
01EBA2E6 8D9401 40E20100 lea edx,dword ptr ds:[ecx+eax+1E240]
01EBA2ED 52 push edx
01EBA2EE 51 push ecx
01EBA2EF 50 push eax
01EBA2F0 8D45 D0 lea eax,dword ptr ss:[ebp-30]
01EBA2F3 57 push edi
01EBA2F4 50 push eax
01EBA2F5 E8 2E650100 call poppages.01ED0828
01EBA2FA 8D45 D0 lea eax,dword ptr ss:[ebp-30]
01EBA2FD 50 push eax
01EBA2FE 6A 0A push 0A
01EBA300 FF76 18 push dword ptr ds:[esi+18]
01EBA303 E8 255E0100 call poppages.01ED012D
01EBA308 EB 0A jmp short poppages.01EBA314
01EBA30A 83F8 01 cmp eax,1
01EBA30D 7E 09 jle short poppages.01EBA318
01EBA30F 83F8 31 cmp eax,31
01EBA312 7D 04 jge short poppages.01EBA318
01EBA314 33C0 xor eax,eax
01EBA316 EB 05 jmp short poppages.01EBA31D
01EBA318 B8 05400080 mov eax,80004005
01EBA31D 5F pop edi
01EBA31E 5E pop esi
01EBA31F C9 leave
01EBA320 C2 1400 retn 14
--------------------------------------------------------------------------------
由01EBA284 跟进,关键算法。
01ED0B3F 55 push ebp
01ED0B40 8B5424 10 mov edx,dword ptr ss:[esp+10] ;把ID的HEX值“75A80”给EDX
01ED0B44 8BEC mov ebp,esp
01ED0B46 56 push esi
01ED0B47 57 push edi
01ED0B48 8345 14 34 add dword ptr ss:[ebp+14],34 ;把0x69930加0x34
01ED0B4C 83FA 01 cmp edx,1
01ED0B4F 7D 05 jge short poppages.01ED0B56
01ED0B51 BA 01000000 mov edx,1
01ED0B56 8B7D 0C mov edi,dword ptr ss:[ebp+C] ;把CODE ENTRY的HEX值“106308EB”给EDI
01ED0B59 8BCF mov ecx,edi ;再分别赋于ECX和EAX
01ED0B5B 8BC7 mov eax,edi
01ED0B5D 81E1 00E00700 and ecx,7E000 ;ECX与0x7E000
01ED0B63 25 001F0000 and eax,1F00 ;EAX与0x1F00
01ED0B68 C1E9 0D shr ecx,0D ;ECX右移0x0D
01ED0B6B C1E8 08 shr eax,8 ;ECX右移0x8
01ED0B6E 81C1 BC070000 add ecx,7BC ;ECX加0x7BC
01ED0B74 6BC9 44 imul ecx,ecx,44 ;ECX乘0x44
01ED0B77 69C0 F3000000 imul eax,eax,0F3 ; EAX乘0x0F3
01ED0B7D 03C8 add ecx,eax ;ECX加EAX的值放入ECX中
01ED0B7F 8BC7 mov eax,edi ;再次把CODE ENTRY的HEX值“106308EB”给EAX
01ED0B81 25 00007800 and eax,780000 ;与0X780000
01ED0B86 C1E8 13 shr eax,13 ;右移0X13
01ED0B89 69C0 08010000 imul eax,eax,108 ;乘0X108
01ED0B8F 8D3401 lea esi,dword ptr ds:[ecx+eax] ;把ECX和EAX的值相加放入ESI中
01ED0B92 8BCF mov ecx,edi ; 再次把CODE ENTRY的HEX值“106308EB”给ECX
01ED0B94 81E1 0000807F and ecx,7F800000 ;与0X7F800000
01ED0B9A 81E7 FF000000 and edi,0FF ;EDI与0X0FF
01ED0BA0 C1E9 0F shr ecx,0F ;ECX右移0X0F
01ED0BA3 8B45 14 mov eax,dword ptr ss:[ebp+14] ;把01ED0B48语句中的0X69964赋予EAX
01ED0BA6 6BC0 07 imul eax,eax,7 ;乘0X7
01ED0BA9 03CF add ecx,edi ;ECX加EDI的值给ECX
01ED0BAB 6BC9 03 imul ecx,ecx,3 ;ECX乘0X3
01ED0BAE 03C8 add ecx,eax ;ECX加EAX的值给ECX
01ED0BB0 B8 01000000 mov eax,1 ;赋予EAX1,目的是给注册标志。表示成功
01ED0BB5 8D0C51 lea ecx,dword ptr ds:[ecx+edx*2] ;把ECX加上EDX乘2的值给ECX
01ED0BB8 8BD6 mov edx,esi
01ED0BBA 6BD2 1F imul edx,edx,1F ;EDX乘0X1F
01ED0BBD 03D1 add edx,ecx ;EDX加ECX
01ED0BBF 8D0C75 00000000 lea ecx,dword ptr ds:[esi*2]
01ED0BC6 8BF2 mov esi,edx ;EDX 给ESI
01ED0BC8 81E6 FFFFFF7F and esi,7FFFFFFF ;ESI与0X7FFFFFFF,换算完毕。
01ED0BCE 3B75 08 cmp esi,dword ptr ss:[ebp+8] ;关键比较,还记得EBP+8的内容吗?这里是“1E240”,也就是把
; 换算的值和我们输入的“123456”的HEX值比较。ESI内的值为“
; 802A35” ,换算为十进制为“8399413”。
01ED0BD1 74 0A je short poppages.01ED0BDD ;成功跳至01ED0BDD(这里是真正的爆破点)
01ED0BD3 03D1 add edx,ecx
01ED0BD5 40 inc eax
01ED0BD6 83F8 32 cmp eax,32
01ED0BD9 ^ 7E EB jle short poppages.01ED0BC6
01ED0BDB 33C0 xor eax,eax ;给EAX赋予0,表示注册不成功
01ED0BDD 5F pop edi
01ED0BDE 5E pop esi
01ED0BDF 5D pop ebp
01ED0BE0 C2 1000 retn 10
--------------------------------------------------------------------------------
【破解总结】
该控件的难点在于动态加载poppages.dll,有三个关键调用。不能用keymaker来作内存注册机,因为在代码分析中指出,poppages.dll的加载
是动态的,地址是随时可变的,也就是说做出的内存注册机不能通用,只能用一次。因此爆破点应选在poppages.dll文件中(w32dasm和hiew中的实际地址是10050BD1)。还需要指出的是在写注册机的时候,以上01ED0B5D 、01ED0B81、01ED0B94中0X7E000、0X780000和0X7F800000中的0必须写完整,还有必须用unsigned long(无符号,长整数)定义变量,否则不能得出正确结果。另外在01ED0BD3至01ED0BD9处的循环可以不用考虑。这就是在【声明】中我提到的修改了的注册机算法。
提供一组注册码
注 册 项 目:3DLINK
CODE ENTRY:274925803
COMPUTER ID:481920
SN :8399413
--------------------------------------------------------------------------------
【算法注册机】
/* 3Dlink 1.6 sp2算法注册机 */
/* 在Turboc 2.0 下调试通过 */
/* 感谢Shooo提供算法思路 */
#include "stdio.h"
main()
{ unsigned long code,id;
unsigned long i,j,k,l,m;
printf("3DLINK 1.6 SP2 Register by jackily 2004-12-11\n");
printf("Email:jackily_zhang@msn.com or jackily_zhang@yahoo.com.cn\n");
printf("please input code entry:");
scanf("%lu",&code);
printf("\nplease input computer id:");
scanf("%lu",&id);
m=id;
i=j=k=code;
i&=0x7e000;i>>=0x0d;i+=0x7bc;i*=0x44;
j&=0x1f00;j>>=0x08;j*=0xf3;
i+=j;
j=code;
j&=0x780000;j>>=0x13;j*=0x108;
l=i+j;
i=code;
i&=0x7f800000;i>>=0xf;
k&=0xff;
i+=k;
i*=0x3;
j=0x69964*0x7;
i+=j;
m*=2;
i+=m;
m=l;m*=0x1f;
m+=i;
l=m;
l&=0x7fffffff;
printf("\nserial number is %lu",l);
}
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!2004-12-11
能力值:
( LV2,RANK:10 )
19 楼
NO18: 作者:jackily
【原创】手把手系列之二―Axman 3.12r的注册算法详解及注册机
手把手系列之二―Axman 3.12rGB的注册算法详解及注册机
【破解作者】 jackily
【作者邮箱】 jackily_zhang@msn.com;jackily_zhang@yahoo.com.cn
【作者主页】 http://estudy.ys168.com
【使用工具】 ollydbg 1.10
【破解平台】 Win9x/NT/2000/XP
【软件名称】 axman 3.12rGB
【下载地址】 http://www.pc123.cn/SoftView/SoftView_5625.html
【软件简介】 一个非常不错的文件分割工具,该工具的主要作用是可以将大文件切成几个小文件便于拷贝到软盘或作为电子邮件附件发送。对于分割的文件,程序提供自动合并功能,同时该工具也提供非常简单的操作界面和操作方式以方便用户使用。未注册版本有30天的使用限制,并在开始程序时有nag窗口。
【破解声明】 本破解纯属以学习为目的,偶得一点心得,愿与大家分享:) xiA Qin 曾破解过3.10版(具体参见看雪精华II),但只是给了一个注册码而已,并没有给出算法和注册机,3.12版程序稍有变化,我们的目的是要找到算法并写出注册机。
--------------------------------------------------------------------------------
【破解内容】
安装完毕后主文件为axman.exe,用peid检查无壳。用ollydbg载入,运行,出现提示注册窗口,点击注册,要求输入name、company和注册码。这里我们分别输入jackily,http://estudy.ys168.com和123456。点确定,弹出“Invalid RegisterInformation”。好了,重新载入,点右键―“搜索”―“字符参考”,找到刚才的ASCII码,地址为00406933,向上看,00406923处有一call,为典型的注册关键调用。在此处下断,跟进。代码分析如下:
004068DA . 8D45 F0 lea eax,dword ptr ss:[ebp-10]
004068DD . 8D8E C8020000 lea ecx,dword ptr ds:[esi+2C8]
004068E3 . 50 push eax
004068E4 . C645 FC 02 mov byte ptr ss:[ebp-4],2
004068E8 . E8 B5B00000 call <jmp.&MFC42.#3874> ;将"jackily"放入地址00674660
004068ED . 8D45 E8 lea eax,dword ptr ss:[ebp-18]
004068F0 . 8D8E 08030000 lea ecx,dword ptr ds:[esi+308]
004068F6 . 50 push eax
004068F7 . E8 A6B00000 call <jmp.&MFC42.#3874> ; 将"http://estudy.ys168.com"放入地址006747a0
004068FC . 8D45 EC lea eax,dword ptr ss:[ebp-14]
004068FF . 8D8E 88020000 lea ecx,dword ptr ds:[esi+288]
00406905 . 50 push eax
00406906 . E8 97B00000 call <jmp.&MFC42.#3874> ; 将ASCII "123456")放入地址00674840
0040690B . 8D4D E4 lea ecx,dword ptr ss:[ebp-1C]
0040690E . E8 25FBFFFF call AXMAN.00406438
00406913 . FF75 EC push dword ptr ss:[ebp-14] ; /Arg3 = 00674840 ASCII "123456"
00406916 . 8D4D E4 lea ecx,dword ptr ss:[ebp-1C] ; |
00406919 . C645 FC 03 mov byte ptr ss:[ebp-4],3 ; |
0040691D . FF75 E8 push dword ptr ss:[ebp-18] ; |Arg2 = 006747A0 ASCII "http://estudy.ys168.com"
00406920 . FF75 F0 push dword ptr ss:[ebp-10] ; |Arg1 = 00674660 ASCII "jackily"
00406923 . E8 3CFBFFFF call AXMAN.00406464 ;典型的注册模式,有点意思,跟进
00406928 . 84C0 test al,al ; 检验注册标志,这里成功应是非0
0040692A . 75 18 jnz short AXMAN.00406944 ; 成功则到00406944
0040692C . 6A 30 push 30
0040692E . 68 10AC4100 push AXMAN.0041AC10 ; ASCII "AxMan - Error 400"
00406933 . 68 ECAB4100 push AXMAN.0041ABEC ; ASCII "Invalid Registration Information"
00406938 . 8BCE mov ecx,esi
0040693A . E8 21B00000 call <jmp.&MFC42.#4224>
0040693F . E9 8E000000 jmp AXMAN.004069D2
00406944 > 8D85 54FEFFFF lea eax,dword ptr ss:[ebp-1AC]
0040694A . 68 BCAB4100 push AXMAN.0041ABBC ; /src = "Thank you for registering your copy of AxMan
"
0040694F . 50 push eax ; |dest
00406950 . E8 CBB50000 call <jmp.&MSVCRT.strcpy> ; \strcpy
00406955 . 8D85 54FEFFFF lea eax,dword ptr ss:[ebp-1AC]
0040695B . 68 68AB4100 push AXMAN.0041AB68 ; /src = "You will need to stop and restart AxMan to remove the banner ads from displaying."
00406960 . 50 push eax ; |dest
00406961 . E8 C0B50000 call <jmp.&MSVCRT.strcat> ; \strcat
00406966 . 83C4 10 add esp,10
00406969 . 8D85 54FEFFFF lea eax,dword ptr ss:[ebp-1AC]
0040696F . 8BCE mov ecx,esi
00406971 . 6A 30 push 30
00406973 . 68 D8A64100 push AXMAN.0041A6D8 ; ASCII "AxMan"
00406978 . 50 push eax
00406979 . E8 E2AF0000 call <jmp.&MFC42.#4224> ; 解除程序限制,以下省略
.
.
.
------------------------------------------------------------
由00406923跟进,一级调用
00406464 /$ 55 push ebp
00406465 |. 8BEC mov ebp,esp
00406467 |. 83EC 18 sub esp,18
0040646A |. 8D45 E8 lea eax,dword ptr ss:[ebp-18]
0040646D |. 50 push eax
0040646E |. FF75 0C push dword ptr ss:[ebp+C] ; (ASCII "http://estudy.ys168.com")
00406471 |. FF75 08 push dword ptr ss:[ebp+8] ; (ASCII "jackily")
00406474 |. E8 18000000 call AXMAN.00406491 ;关键call,数据处理,为计算做准备,跟进
00406479 |. FF75 10 push dword ptr ss:[ebp+10] ; /s2 = "123456" 我们输入的假码
0040647C |. 8D45 E8 lea eax,dword ptr ss:[ebp-18] ; |
0040647F |. 50 push eax ; |s1 = "156-936-773" ,真实的注册码,但不要忘记我们的目 ;的是找算法,不应满足在找到注册码的水平上
00406480 |. E8 51BA0000 call <jmp.&MSVCRT.strcmp> ; \strcmp 比较
00406485 |. F7D8 neg eax
00406487 |. 59 pop ecx
00406488 |. 1AC0 sbb al,al
0040648A |. 59 pop ecx
0040648B |. FEC0 inc al
0040648D |. C9 leave
0040648E \. C2 0C00 retn 0C
-----------------------------------------------------------------------------
由00406474跟进,以下为数据处理,为计算做准备,把name和company字符串小写,再将"My Love"(注意大小写和空格)strcat在一起,也就是连接在一起。
00406491 /$ B8 C42B4100 mov eax,AXMAN.00412BC4
00406496 |. E8 15BA0000 call AXMAN.00411EB0
0040649B |. 81EC F8000000 sub esp,0F8
004064A1 |. 53 push ebx
004064A2 |. 56 push esi
004064A3 |. 57 push edi
004064A4 |. 8BF9 mov edi,ecx
004064A6 |. FF75 08 push dword ptr ss:[ebp+8] ; /s = "jackily"
004064A9 |. E8 22BA0000 call <jmp.&MSVCRT.strlen> ; \strlen 取字符串长度
004064AE |. 8B35 10464100 mov esi,dword ptr ds:[<&MSVCRT.mallo>; MSVCRT.malloc
004064B4 |. 40 inc eax
004064B5 |. 50 push eax ; /size
004064B6 |. FFD6 call esi ; \malloc
004064B8 |. 59 pop ecx
004064B9 |. 8BD8 mov ebx,eax
004064BB |. 59 pop ecx
004064BC |. 53 push ebx
004064BD |. 8BCF mov ecx,edi
004064BF |. FF75 08 push dword ptr ss:[ebp+8]
004064C2 |. E8 63020000 call AXMAN.0040672A
004064C7 |. FF75 0C push dword ptr ss:[ebp+C] ; /s = "http://estudy.ys168.com"
004064CA |. E8 01BA0000 call <jmp.&MSVCRT.strlen> ; \strlen 取字符串长度
.
. ;004064CF至0040651A非关键部分省略
.
0040651F |. FF75 EC push dword ptr ss:[ebp-14] ; /src = "jackily"
00406522 |. 8D85 FCFEFFFF lea eax,dword ptr ss:[ebp-104] ; |(ASCII "http://estudy.ys168.com")
00406528 |. 50 push eax ; |dest = 0065EB98
00406529 |. E8 F2B90000 call <jmp.&MSVCRT.strcpy> ; \strcpy
0040652E |. FF75 F0 push dword ptr ss:[ebp-10] ; /src = "http://estudy.ys168.com"
00406531 |. 8D85 FCFEFFFF lea eax,dword ptr ss:[ebp-104] ; | (ASCII "jackily")
00406537 |. 50 push eax ; |dest "jackily"
00406538 |. E8 E9B90000 call <jmp.&MSVCRT.strcat> ; \strcat
0040653D |. 8D85 FCFEFFFF lea eax,dword ptr ss:[ebp-104]
00406543 |. 68 60AB4100 push AXMAN.0041AB60 ; /src = "My Love"
00406548 |. 50 push eax ; |dest
00406549 |. E8 D8B90000 call <jmp.&MSVCRT.strcat> ; \strcat
0040654E |. 83C4 18 add esp,18
00406551 |. 8D45 E8 lea eax,dword ptr ss:[ebp-18] ; (ASCII "jackilyhttp://estudy.ys168.comMy Love")
00406554 |. 8BCF mov ecx,edi ;以上为 把name和company字符串所有字符小写并把“My Love”连接在一起
00406556 |. 50 push eax
00406557 |. 8D85 FCFEFFFF lea eax,dword ptr ss:[ebp-104]
0040655D |. 50 push eax
0040655E |. E8 8D010000 call AXMAN.004066F0 ;关键之关键,算法,跟进
00406563 |. FF75 E8 push dword ptr ss:[ebp-18] ; /<%u> = 95AAA45(注册码的HEX值,十进制为156936773)
00406566 |. 8D45 D0 lea eax,dword ptr ss:[ebp-30] ; |
00406569 |. 68 40A04100 push AXMAN.0041A040 ; |format = "%u" (c语言中代表无符号十进制值)
0040656E |. 50 push eax ; |s
0040656F |. FF15 30464100 call dword ptr ds:[<&MSVCRT.sprintf>>; \sprintf
00406575 |. 83C4 0C add esp,0C
00406578 |. 8D45 D0 lea eax,dword ptr ss:[ebp-30]
0040657B |. 8BCF mov ecx,edi
0040657D |. 6A 01 push 1
0040657F |. 6A 09 push 9
00406581 |. 6A 30 push 30
00406583 |. 50 push eax
00406584 |. E8 73000000 call AXMAN.004065FC
00406589 |. 8B75 10 mov esi,dword ptr ss:[ebp+10] ; 以下是将156936773每三个数字间加“-”
0040658C |. 8D45 D0 lea eax,dword ptr ss:[ebp-30] ; ASII "156936773"
0040658F |. 6A 03 push 3 ; /maxlen = 3 复制前3个字符
00406591 |. 50 push eax ; |src = "156936773"
00406592 |. 56 push esi ; |dest
00406593 |. FF15 D4454100 call dword ptr ds:[<&MSVCRT.strncpy>>; \strncpy
00406599 |. 8066 03 00 and byte ptr ds:[esi+3],0
0040659D |. BB 5CAB4100 mov ebx,AXMAN.0041AB5C
004065A2 |. 53 push ebx ; /src => "-"
004065A3 |. 56 push esi ; |dest = "156"
004065A4 |. E8 7DB90000 call <jmp.&MSVCRT.strcat> ; \strcat
004065A9 |. 8B3D D8454100 mov edi,dword ptr ds:[<&MSVCRT.strnc>; MSVCRT.strncat
004065AF |. 8D45 D3 lea eax,dword ptr ss:[ebp-2D]
004065B2 |. 6A 03 push 3 ; /maxlen = 3
004065B4 |. 50 push eax ; |src = "936773"
004065B5 |. 56 push esi ; |dest = "156-"
004065B6 |. FFD7 call edi ; \strncat
004065B8 |. 8066 07 00 and byte ptr ds:[esi+7],0
004065BD |. 56 push esi ; |dest = "156-936"
004065BD |. 56 push esi ; |dest
004065BE |. E8 63B90000 call <jmp.&MSVCRT.strcat> ; \strcat
004065C3 |. 8D45 D6 lea eax,dword ptr ss:[ebp-2A]
.
. ;004065C6至004065EB非关键部分省略
.
.
004065EE |. 5F pop edi
004065EF |. 5E pop esi
004065F0 |. 5B pop ebx
004065F1 |. 64:890D 00000000 mov dword ptr fs:[0],ecx
004065F8 |. C9 leave
004065F9 \. C2 0C00 retn 0C
-------------------------------------------------------------------
由 0040655E跟进,以下为此次重点,关键算法,到这里了,有一种自豪感吧。
004066F4 |. 33D2 xor edx,edx ; edx清0
004066F6 |. 8A01 mov al,byte ptr ds:[ecx] ;第一个字符“j”,HEX值为61,放入al
004066F8 |. 84C0 test al,al
004066FA |. 74 25 je short AXMAN.00406721 ;是0的话跳走
004066FC |. 56 push esi ;开始计算
004066FD |> 0FBEC0 /movsx eax,al ;eax=al
00406700 |. C1E2 04 |shl edx,4 ; edx 左移0x4
00406703 |. 03D0 |add edx,eax ;edx=edx+eax
00406705 |. 41 |inc ecx ; ecx加1,也就是上面指向字符串地址向后移一位,取下一个字符
00406706 |. 8BC2 |mov eax,edx ;把edx值给eax
00406708 |. 25 000000F0 |and eax,F0000000 ;与0xF0000000
0040670D |. 74 07 |je short AXMAN.00406716 ;为0的话,至00406716
0040670F |. 8BF0 |mov esi,eax
00406711 |. C1EE 18 |shr esi,18
00406714 |. 33D6 |xor edx,esi ;异或
00406716 |> F7D0 |not eax ;取反
00406718 |. 23D0 |and edx,eax ;
0040671A |. 8A01 |mov al,byte ptr ds:[ecx] ; 取下一个字符放入al里
0040671C |. 84C0 |test al,al ;检查是否为0,也就是是否取完字符串中的字符
0040671E |.^ 75 DD \jnz short AXMAN.004066FD ;满足条件的话,继续计算
00406720 |. 5E pop esi
00406721 |> 8B4424 08 mov eax,dword ptr ss:[esp+8]
00406725 |. 8910 mov dword ptr ds:[eax],edx ;最终结果放EAX指向的地址里
00406727 \. C2 0800 retn 8
--------------------------------------------------------------------------------
【破解总结】
由此向上追溯到00406480处,为比较真假注册码。此注册代码部分有三个关键call,分别是00406464、00406491和004066F0。个人认为关键算法倒不是很难,难点在于要理解“数据处理”,也就是把name和company字符串和"My Love"strcat在一起的部分,和将注册码每三个数字间加“-”这两个部分运算。好在ollydbg调试结构原理让我们能清晰、直观地分析这些调用。该注册机在本人文件空间 http://estudy.ys168.com 可以下载。
【用户名、密码】
提供一组注册码:
name:jackily
company:http://estudy.ys168.com
code:156-936-773
--------------------------------------------------------------------------------
【算法注册机】
【算法注册机】
/* axman 3.12rGB c语言注册机 */
/* 在Turboc 2.0 下调试通过 */
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
main()
{ char name[100]={0},company[50]={0},code[50]={0};
int i;
unsigned long l=0,k,m;
printf("Axman 3.12rGB KeyGen by jackily 2004-12-15\n");
printf("Email:jackily_zhang@msn.com or jackily_zhang@yahoo.com.cn\n");
printf("please input name:");
scanf("%s",name);
printf("\nplease input company:");
scanf("%s",company);
strcat(name,company);
strlwr(name);
strcat(name,"My Love");
for (i=0;i<strlen(name);i++)
{ k=name[i];l<<=0x4;l+=name[i];k=l;
if ((k&=0xf0000000)!=0) { m=k; m>>=0x18; l^=m;}
k=~k; /*0xffffffff-k;*/ /*not eax*/
l&=k;
}
ltoa(l,code,10); /* change "l" into string */
printf("\nserial number is:");
for (i=0;i<3;i++) printf("%c",code[i]);
printf("-");
for (i=3;i<6;i++) printf("%c",code[i]);
printf("-");
for (i=6;i<strlen(code);i++)
printf("%c",code[i]);
if (9-strlen(code)==1) printf("0"); /* 注册码长度小于9时,补0 */
if (9-strlen(code)==2) printf("00");
}
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
2004-11-15
能力值:
( LV2,RANK:10 )
20 楼
NO19: 作者:chenjiwl
有感于朋友们的鼓励,再送上艾克主页(*)2005 找破点,打SMC补丁(新手教程)
【软件名称】:艾克主页(*)2005 找破点,打SMC补丁(新手教程)
【大 小】:624 KB (638,976 字节)
【下载地址】:自己去找
【软件限制】:功能限制
【软件简介】:艾克主页(*)2005是一款功能强大的网页制作辅助工具,它可以轻松的给您的网页增加眩目的特效,并且可以直接通过网页模板制作基本的网页文件!同时还具有网页加密/压缩等功能。
【作 者】:chenjiwl chenjiwl@sina.com
【破解平台】:Windows xp
【目 标】:找到爆破点,再打SMC补丁
【难度系数】:★☆☆☆☆(容易)
【相关工具】:Ollydbg 1.10 Fly修改版,DeDe,aspackdie,Peid
【作者声明】: 主要是想给自己的主页做些特效,所以对它下了手,很容易的,可以做新手的教程。SMC部分系自己乱搞,请多指导!
【详细过程】
偶的作法一向是以稳健著称,一般不出手,出手必出精!
废话少说,开工!
安装程序先!
打开安装目录,这里偶给大家推荐一个软件(Total Commader),一个很强的文件管理软件。
一眼看去,不少文件!恩,还有几个DLL文件,先用Peid查一查吧!
眨眼的功夫已经出来了! 全部都是用ASPack 2.1 加的壳!
用aspackdie脱了再说!又眨了一下眼,已经搞定。
再用Peid查脱出来的程序,是Delphi编的程序,可以用上DeDe了。
---------------------------------------------------------------------------------
热身已经完成。
请看我的标准动作:
第一步:试一试
打开软件,界面很漂亮(一定用了SuiPack的控件),下面的状态条显示未注册!:=(,
随便试几个功能。在打开网页模板时弹出了提示框,上面说了:不给钱,不让用。
再转到注册窗口,随便输入电邮地址,用户名和注册码,再点确定。没反映?作者
有一定的反侦察能力!!!
大大的狡猾,死了死了的有!
---------------------------------------------------------------------------------
第二步:挖一挖
该用DeDe了,用DeDe将脱壳后的程序载入分析,一分钟就OK了,转到"Forms",
只有五个窗口,其中有两个是读数据库的窗口,是Delphi自带的,不用管。
还有三个:Ta_frm_load,Ta_frm_main,Tgetcol
一个是封面窗口,一个是主窗口,另一个是颜色拾取窗口。
重点在Ta_frm_main,请转到"Procedures"页面,在左边框中选择frm_main,右边框中
的过程定义十分清晰(作者的编程风格不错,偶编程序重来没写过一个正式的名称!)。
作者真是体贴我们啊!!! 秒秒钟,我就找到了注册框中“确定”按钮的过程:
btn_reg_okClick 00574948(这就是入口地址,在olldbg中有用)
双击这一项,转到相应的代码,请定位到下面的位置:
---------------------------------------------------------------------------------
* Reference to object Treginfo
|
005749E0 8B0D00DA4F00 mov ecx, [$004FDA00]
* Reference to: System.@CopyRecord;
|
005749E6 E8850CE9FF call 00405670
005749EB 803D3C03580000 cmp byte ptr [$0058033C], $00 //这里就是比较点
005749F2 746F jz 00574A63 //如果注册码不正确就跳走!!!!!!
005749F4 6A02 push $02
005749F6 66A1A84A5700 mov ax, word ptr [$00574AA8]
005749FC 50 push eax
005749FD 6A00 push $00
005749FF 8D45C4 lea eax, [ebp-$3C]
00574A02 8B0D20035800 mov ecx, [$00580320]
* Possible String Reference to: ' 软件已经成功注册给:'
|
00574A08 BAB44A5700 mov edx, $00574AB4 //正确就到这里读恭喜的信息了
---------------------------------------------------------------------------------
OK!很简单,看来只要将上面这个关键跳处理一下就可注册成功了!
在这里我要停一下,让大家分析一下了!下面这一段代码给我们什么启示?
005749EB 803D3C03580000 cmp byte ptr [$0058033C], $00 //这里就是比较点
005749F2 746F jz 00574A63 //如果注册码不正确就跳走!!!!!!
想出来了吗?
我来分析一下吧,很简单,即然在这里有一个比较[0058033C]中的值的指令,
就一定会有一个指令向[0058033C]中写一个值,不然它比较个屁啊!
明白了吗!明白了就继续!
---------------------------------------------------------------------------------
第三步:动一动
用Olldbg将脱壳后的程序载入! 记得上面的分析吗!
0058033C这个地址是我们的关键。
点击左下方的内存框,按Ctrl+G,填入0058033C, 转到这个地址,选择第一个数值,再
点右键,选择“断点”--“硬件访问”--“byte”。(任何指令访问这个地址都会中断下来)
按F9运行程序
很快会停在00402B4F:
-------------------------------------------------------------------------------
00402B3F |> \8D74>lea esi, dword ptr ds:[ecx+esi-4] >>源地址
00402B43 |. 8D7C>lea edi, dword ptr ds:[ecx+edi-4] >>目的地址
00402B47 |. C1F9>sar ecx, 2 >>拷贝的个数
00402B4A |. 78 1>js short unpacked.00402B5D
00402B4C |. FD std
00402B4D |. F3:A>rep movs dword ptr es:[edi], dword ptr ds:[esi] >>这里就是在给[0058033C]拷贝数据
00402B4F |. 89C1 mov ecx, eax >>>>>>>>>>>>>>>>>>硬件中断在这里
00402B51 |. 83E1>and ecx, 3
00402B54 |. 83C6>add esi, 3
00402B57 |. 83C7>add edi, 3
00402B5A |. F3:A>rep movs byte ptr es:[edi], byte ptr ds:[esi]
00402B5C |. FC cld
00402B5D |> 5F pop edi ; unpacked.004FDA4E
00402B5E |. 5E pop esi ; unpacked.004FDA4E
00402B5F \. C3 retn
-------------------------------------------------------------------------------
上面的rep指令就是给[0058033C]这个地方做标记的。但这条指令还只是一个杀手,要找到
下指令的人。请右下角的堆栈窗:
-------------------------------------------------------------------------------
0012FAF0 004FDA4E unpacked.004FDA4E
0012FAF4 0012FB4C
0012FAF8 00405785 返回到 unpacked.00405785 来自 <unpacked.@Move> >>>>>>>>>>>就是这个东西了!
-------------------------------------------------------------------------------
在堆栈窗中第三行上点右键,选择“反汇编中跟随”,CPU代码窗中就转到相应的地址!
-------------------------------------------------------------------------------
00405779 . /7E 0>jle short unpacked.00405785 >>>>>>>>>>>如果这里跳走了,就不会复制数据!很重要,SMC中会用
0040577B . |8D14>lea edx, dword ptr ds:[eax+ebx]
0040577E . |01F0 add eax, esi
00405780 . |E8 9>call <unpacked.@Move> >>>>>>>>>>>这个是调用杀手的代码
00405785 > \5D pop ebp ; unpacked.004FDA4E
00405786 . 5F pop edi ; unpacked.004FDA4E
00405787 . 5E pop esi ; unpacked.004FDA4E
00405788 . 5B pop ebx ; unpacked.004FDA4E
00405789 . C3 retn
-------------------------------------------------------------------------------
再按F9运行,又会被断下来,又是一个类似的代码:
-------------------------------------------------------------------------------
005692BE 803D>cmp byte ptr ds:[58033C], 0 >>>>比较标志点
005692C5 |. 74 2>je short unpacked.005692EE >>>>跳走
-------------------------------------------------------------------------------
到这里,我想不用再跟了!直接将所有cmp byte ptr ds:[58033C], 0改成
cmp byte ptr ds:[58033C], 1就可以了。
试一试再说。
在CPU代码窗中点选右键“搜索”---“全部命令”
填入: cmp byte ptr ds:[58033C], 0
找出了九处代码,全部改了,不要问我如何改!!!!!
再将代码另存,也不要问我如何存!!!!!!!!!!!!!!!
试一试!一切OK了,已经注册了!网页模板也可以用了!
到现在好像已经完成了吧!如果只是自己用,是已经可以了!可是好东东,一定要给大家分享!
还得做一个补丁!!
如果直接提供脱壳后的程序,好像太大了。只能用SMC补丁了。继续吧!!!
---------------------------------------------------------------------------------
第四步:改一改
SMC是做什么?说白了,我们要在未脱壳的程序上下手,在程序解压完成之后,没跳到OEP之前,
对程序打好所有的补丁。
整个流程是这样的:
1、找到一个适当的切入点
2、找一个空白的位置,以填入补丁代码
3、直接给[58033C]这个标志点填入1
4、同时要禁止向[58033C]填数据(就是要将jle short unpacked.00405785改成jmp short unpacked.00405785)
当这四项任务完成以后,程序的补丁就打好了!
让我们开始:
1、找到一个适当的切入点
Aspack的壳很好脱,切入点也很好找,一个简单的办法,按ctrl+f,输入popad,
转到这里:
-------------------------------------------------------------------------------------------
005E44F3 . 61 popad //转到这里
005E44F4 . 75 0>jnz short webshow5.005E44FE //这里就是一个很好的切入点*********************
005E44F6 . B8 0>mov eax, 1
005E44FB . C2 0>retn 0C
005E44FE > 68 0>push 0 //SMC处理后,回到这里
005E4503 . C3 retn //转到OEP处
-------------------------------------------------------------------------------------------
2、找一个空白的位置,填入补丁代码
不能随便找一个空白位置的,一个很容易的办法,在代码窗口点右键:
“复制到可执行文件”--“选择部分”,在弹出的窗口中,转到最后的部分,有一堆空白的位置,
选择一个位置吧,我选择了0009BFC1(文件偏移地址),先记下来!在这个位置点右键,选择“在反
汇编中查看镜像”就转到CPU窗口中对应的位置{{记好这个地址(逻辑地址)}}了,
3、直接给[58033C]这个标志点填入1
按空格键,进行汇编,改成:
005E65C1 C605 3>mov byte ptr ds:[58033C], 1 >>>这里给标志点置1
4、同时要禁止向[58033C]填数据(就是要将jle short unpacked.00405785改成jmp short unpacked.00405785)
再按空格键,继续汇编,改成:
005E65C8 C605 7>mov byte ptr ds:[405779], 0EB >>>>>将jle改成jmp (机器码7E改为EB)
处理完之后返回按空格键,继续汇编,改成:
005E65CF ^ E9 2AD>jmp webshow5.005E44FE >>>SMC完成返回
切入点的跳转还没有做,再回到005E44F4:
按空格键,进行汇编,改成:
005E44F4 /E9 C82>jmp webshow5.005E65C1 >>>>跳到SMC代码的入口
OK!OK!到这里,整个补丁流程就完了,很容易吧!保存吧。
注意了!建议每次修改一块代码后就保存到一个文件中,再打开这个文件,继续修改,不然会丢数据的。
原因自己看!!!!!!
OK了,请将全部修改过的程序改个名,再用KeyMaker做个补丁吧,送给大家做纪念! 这里我把我的补丁给大家,大家可以比较一下,修改后的程序与原程序的区别,就可以知道工作流程了。
---------------------------------------------------------------------------------
后记:
1、在找到关键点后,要分析它的来龙去脉,逆向思考。
2、SMC补丁是一项很麻烦的工程,要考虑很多方面,比如,节区是否可写等等
3、冷静,冷静,再冷静!!!1
注:有一个webshow.pin文件中保存了注册信息,你有功夫可以研究一下如何算注册码!
写完时已经 22:30 睡了! 886
chenjiwl
chenjiwl@sina.com 附件:webshow5_ccww.rar
能力值:
( LV2,RANK:10 )
21 楼
NO20: 作者:海风月影
魔术情书 6.55 破解过程+不脱壳打破解补丁【原创】
【破解作者】 海风月影
【作者邮箱】 zjhangtian@sohu.com
【使用工具】 od 1.10d,PEid,LoadPE,winHex,eXeScope
【破解平台】 WinXP
【软件名称】 魔术情书 6.55
【下载地址】 www.coolboo.com
【软件简介】 “魔术情书”是一款能由电脑自动书写情书的应用软件,有了她,可以让你从此不再为
写情书而烦恼,你只需轻轻点击几下鼠标就可以写出让你感到满意的情书。软件内含强
大情书库,可以用它书写出超过一万封不一样的情书,而且情书库可以随意地扩充。软
件内还带有一百多封古今中外经典的情书,只需点击鼠标,就可以自动套用:)你可以
选择“自动书写”、“模板式书写”及“组合式书写”这几种方式来快速写 情书,软
件支持在线发送情书,可以发送匿名邮件;可以将写的情书保存为“文本文件”、“Wo
rd文档”、“ 网页文件”等等,在网页文件选项中还可以选择把文件保存为“烂漫星
空”、“趣味求爱”、“音乐动力”等等网页,可以让你写的情书更具吸引力、更能博
得你心目中的女神、白马王子的欢心。
此次升级新增几十个个实用的功能,情书库扩大了三倍,增强了非常实用的背景音乐功
能,在线发送情书功能支持需要认证的邮件服务器,可以发送邮件附件,使用了全新的
皮肤界面技术,可以任意更换界面(共有九种精彩界面),马上下载亲自体验一下吧! 【软件大小】 2M
【加壳方式】 upx
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】 一、破解过程
1、peid查壳,UPX 0.80 - 0.84 -> Markus & Laszlo, 是简单的压缩壳,脱壳过程就不写了,不会脱也没关系,反正后面我们要不脱壳打补丁
2、用od载入,F9运行,出现对话框,显示用了几次,因此,首先把nag去掉。如何确定调用nag的代码呢?我介绍一种自己的方法,打开内存(ALT+M),选中当前执行区域,这里是
内存镜像,项目 28
地址=00401000
大小=00197000 (1667072.)
Owner=MSQingSh 00400000
区段=UPX0
类型=Imag 01001002
访问=R
初始访问=RWE
因为我们执行的位置在0056xxxx,属于上面那个区域。然后按F2,此时,程序被中断下来了
0044F25B E8 F8F9FFFF call MSQingSh.0044EC58
0044F260 E8 1F46FBFF call MSQingSh.00403884
0044F265 807D FB 00 cmp byte ptr ss:[ebp-5],0
0044F269 74 05 je short MSQingSh.0044F270
0044F26B E8 FC85FBFF call <jmp.&user32.WaitMessage>
0044F270 33C0 xor eax,eax ; 中断在这
0044F272 5A pop edx
0044F273 59 pop ecx
0044F274 59 pop ecx
0044F275 64:8910 mov dword ptr fs:[eax],edx
0044F278 68 92F24400 push MSQingSh.0044F292
0044F27D 8D45 F0 lea eax,dword ptr ss:[ebp-10]
0044F280 BA 02000000 mov edx,2
0044F285 E8 7E4BFBFF call MSQingSh.00403E08
0044F28A C3 retn
然后一路按F8,直到明显遇到一个循环,如下
0044BC11 E8 36BBFBFF call <jmp.&user32.SendMessageA>
0044BC16 8B45 FC mov eax,dword ptr ss:[ebp-4]
0044BC19 33D2 xor edx,edx
0044BC1B 8990 34020000 mov dword ptr ds:[eax+234],edx
0044BC21 8B03 mov eax,dword ptr ds:[ebx] ; 从这
0044BC23 E8 D42D0000 call MSQingSh.0044E9FC
0044BC28 8B03 mov eax,dword ptr ds:[ebx]
0044BC2A 80B8 8C000000 00 cmp byte ptr ds:[eax+8C],0
0044BC31 74 0F je short MSQingSh.0044BC42
0044BC33 8B45 FC mov eax,dword ptr ss:[ebp-4]
0044BC36 C780 34020000 02000000 mov dword ptr ds:[eax+234],2
0044BC40 EB 14 jmp short MSQingSh.0044BC56
0044BC42 8B45 FC mov eax,dword ptr ss:[ebp-4]
0044BC45 83B8 34020000 00 cmp dword ptr ds:[eax+234],0
0044BC4C 74 08 je short MSQingSh.0044BC56
0044BC4E 8B45 FC mov eax,dword ptr ss:[ebp-4]
0044BC51 E8 26FDFFFF call MSQingSh.0044B97C
0044BC56 8B45 FC mov eax,dword ptr ss:[ebp-4]
0044BC59 8B80 34020000 mov eax,dword ptr ds:[eax+234]
0044BC5F 85C0 test eax,eax
0044BC61 ^ 74 BE je short MSQingSh.0044BC21 ; 到这,是消息循环
0044BC63 8945 F8 mov dword ptr ss:[ebp-8],eax ; 在这下断点
0044BC66 6A 00 push 0
0044BC68 6A 00 push 0
0044BC6A 68 01B00000 push 0B001
0044BC6F 8B45 FC mov eax,dword ptr ss:[ebp-4]
0044BC72 E8 D9ABFEFF call MSQingSh.00436850
这个循环是windows的消息循环,因为程序是用delphi写的,不容易看出来,当窗体卸载时就退出循环,因此在0044BC63下断点,F9运行
断在44bc63处,小心按F8,一步一步走,不断地 ret ,遇到下面的这样的 ret 直接跳
0044BC97 5A pop edx
0044BC98 59 pop ecx
0044BC99 59 pop ecx
0044BC9A 64:8910 mov dword ptr fs:[eax],edx
0044BC9D 68 B2BC4400 push MSQingSh.0044BCB2 ; 这是跳转地址
0044BCA2 8B45 FC mov eax,dword ptr ss:[ebp-4]
0044BCA5 E8 7AFDFFFF call MSQingSh.0044BA24
0044BCAA C3 retn ; 这个实际上是个跳转
前面一个push,后面一个ret,实际上就是一个jmp,因此只管跳,碰到下面的ret 就要注意了,恢复ebp 就代表这个过程结束了
0044BD73 8B45 F8 mov eax,dword ptr ss:[ebp-8]
0044BD76 5E pop esi
0044BD77 5B pop ebx
0044BD78 8BE5 mov esp,ebp
0044BD7A 5D pop ebp ; 恢复ebp了,就要注意了
0044BD7B C3 retn ; 这个ret返回后的地址要注意
ret 后来到552379,上面一行的 call 就是调用 nag 的call
0055236A A1 2C835600 mov eax,dword ptr ds:[56832C]
0055236F 8B00 mov eax,dword ptr ds:[eax]
00552371 8B10 mov edx,dword ptr ds:[eax]
00552373 FF92 D8000000 call dword ptr ds:[edx+D8] ; 这个call就是调用nag的call
00552379 33C0 xor eax,eax ; 返回到这
0055237B 5A pop edx
0055237C 59 pop ecx
0055237D 59 pop ecx
0055237E 64:8910 mov dword ptr fs:[eax],edx
00552381 68 A6235500 push MSQingSh.005523A6
00552386 A1 2C835600 mov eax,dword ptr ds:[56832C]
0055238B 8B00 mov eax,dword ptr ds:[eax]
把00552373这行nop掉,nag就没有了 ^_^ 3、但还没有破解掉,因为虽然nag没了,但20次的限制还是有的,用了20次后碰到要注册的nag,这就说明这个nag是在上面去掉的nag前出现的,用od载入脱壳后的文件(不是把上面去掉nag的文件),F9运行,用刚才上面的方法确定nag的调用地址
005635D2 8990 EC020000 mov dword ptr ds:[eax+2EC],edx
005635D8 A1 CC825600 mov eax,dword ptr ds:[5682CC]
005635DD 8B00 mov eax,dword ptr ds:[eax]
005635DF E8 ACB5EEFF call MSQingSh.0044EB90 ; nag的call
005635E4 E8 9BCCFFFF call MSQingSh.00560284 ; 返回到这行
005635E9 E9 91070000 jmp MSQingSh.00563D7F ; 跳走就over了
然后向上看会发现很多这样的类似代码(call 44eb90 / call 560284 / jmp 563d7f),因此这段代码不能执行,一直向上看,代码类似就向上看直到看到代码不一样的时候,凭经验下断点(在跳转上下),然后重新运行,看看能否断下来。我找到一段可疑代码
0056218D 33DB xor ebx,ebx ;最可疑的是这里 ebx=0
0056218F A1 54D05600 mov eax,dword ptr ds:[56D054]
00562194 8B40 30 mov eax,dword ptr ds:[eax+30]
00562197 83C0 18 add eax,18
0056219A 8B15 B87E5600 mov edx,dword ptr ds:[567EB8] ; MSQingSh.0056B5E8
005621A0 8B52 24 mov edx,dword ptr ds:[edx+24]
005621A3 E8 901CEAFF call MSQingSh.00403E38
005621A8 8B15 B87E5600 mov edx,dword ptr ds:[567EB8] ; MSQingSh.0056B5E8
005621AE 8B52 20 mov edx,dword ptr ds:[edx+20]
005621B1 8BCB mov ecx,ebx
005621B3 A1 54D05600 mov eax,dword ptr ds:[56D054]
005621B8 E8 D358F0FF call MSQingSh.00467A90
.......
中间有很多这样结构的代码,太长了,不帖了
.......
00562823 8B15 B87E5600 mov edx,dword ptr ds:[567EB8] ; MSQingSh.0056B5E8
00562829 8B52 28 mov edx,dword ptr ds:[edx+28]
0056282C B9 674F0000 mov ecx,4F67
00562831 A1 60D05600 mov eax,dword ptr ds:[56D060]
00562836 E8 6DDDFFFF call MSQingSh.005605A8
0056283B E9 52100000 jmp MSQingSh.00563892 ;这里跳走
ebx = 0 ,猜测可能是清空计数器,从0开始计数(每次都清空,这样不就等于无限次数用了嘛^_^),记住行号0056218d,向上看有哪个跳转跳到这,很快就找到这里
00561FDB E8 B0CBEEFF call MSQingSh.0044EB90
00561FE0 E8 9FE2FFFF call MSQingSh.00560284
00561FE5 E9 951D0000 jmp MSQingSh.00563D7F
00561FEA E8 B1E2FFFF call MSQingSh.005602A0 ; 上面是无条件跳转,记住这个行号
00561FEF 803D 88D05600 00 cmp byte ptr ds:[56D088],0
00561FF6 74 43 je short MSQingSh.0056203B
00561FF8 803D 89D05600 00 cmp byte ptr ds:[56D089],0
00561FFF 74 3A je short MSQingSh.0056203B
00562001 803D 8AD05600 00 cmp byte ptr ds:[56D08A],0
00562008 74 31 je short MSQingSh.0056203B
0056200A 803D 8BD05600 00 cmp byte ptr ds:[56D08B],0
00562011 74 28 je short MSQingSh.0056203B
00562013 803D 8CD05600 00 cmp byte ptr ds:[56D08C],0
0056201A 74 1F je short MSQingSh.0056203B
0056201C 803D 8DD05600 00 cmp byte ptr ds:[56D08D],0
00562023 74 16 je short MSQingSh.0056203B
00562025 803D 8ED05600 00 cmp byte ptr ds:[56D08E],0
0056202C 74 0D je short MSQingSh.0056203B
0056202E 803D 8FD05600 00 cmp byte ptr ds:[56D08F],0
00562035 0F85 52010000 jnz MSQingSh.0056218D ; 找到这了,上面的都不能跳,这个要跳
0056203B A1 CC825600 mov eax,dword ptr ds:[5682CC]
00562040 8B00 mov eax,dword ptr ds:[eax]
在00561FEA下断点发现断不下来,所以继续向上找跳到00561FEA的跳转
00561B34 8B52 20 mov edx,dword ptr ds:[edx+20]
00561B37 B1 01 mov cl,1
00561B39 A1 54D05600 mov eax,dword ptr ds:[56D054]
00561B3E E8 C95DF0FF call MSQingSh.0046790C
00561B43 8BD8 mov ebx,eax
00561B45 84DB test bl,bl
00561B47 0F84 F30C0000 je MSQingSh.00562840 ; 这是关键的跳转,不能跳
00561B4D 8B0D B87E5600 mov ecx,dword ptr ds:[567EB8] ; MSQingSh.0056B5E8
00561B53 8B49 28 mov ecx,dword ptr ds:[ecx+28]
00561B56 8D85 ECFEFFFF lea eax,dword ptr ss:[ebp-114]
00561B5C 8B15 60D05600 mov edx,dword ptr ds:[56D060]
00561B62 E8 4925EAFF call MSQingSh.004040B0
00561B67 8B85 ECFEFFFF mov eax,dword ptr ss:[ebp-114]
00561B6D E8 D676EAFF call MSQingSh.00409248
00561B72 84C0 test al,al
00561B74 0F85 1E030000 jnz MSQingSh.00561E98 ;这些都不能跳,下面很多
......
中间很多这样的代码,省略
......
00561E69 75 2D jnz short MSQingSh.00561E98 ;不能跳
00561E6B 8B0D B87E5600 mov ecx,dword ptr ds:[567EB8] ; MSQingSh.0056B5E8
00561E71 8B49 70 mov ecx,dword ptr ds:[ecx+70]
00561E74 8D85 A4FEFFFF lea eax,dword ptr ss:[ebp-15C]
00561E7A 8B15 60D05600 mov edx,dword ptr ds:[56D060]
00561E80 E8 2B22EAFF call MSQingSh.004040B0
00561E85 8B85 A4FEFFFF mov eax,dword ptr ss:[ebp-15C]
00561E8B E8 B873EAFF call MSQingSh.00409248
00561E90 84C0 test al,al
00561E92 0F84 52010000 je MSQingSh.00561FEA ; 找到这,这个要跳
00561E98 A1 CC825600 mov eax,dword ptr ds:[5682CC]
00561E9D 8B00 mov eax,dword ptr ds:[eax]
00561E9F E8 54CCEEFF call MSQingSh.0044EAF8
找到
00561E92 0F84 52010000 je MSQingSh.00561FEA
但上面有很多
jnz short MSQingSh.00561E98
在第一个处下断点发现断不下来,因此找到关键的跳转
00561B47 0F84 F30C0000 je MSQingSh.00562840 ; 这是关键的跳转,不能跳
这是能断下来的跳转,直接改成 jmp 0056218D 跳到
0056218D 33DB xor ebx,ebx ;最可疑的是这里 ebx=0
因为中间的代码都是判断是否是第一次运行的,没必要执行,直接跳不影响结果,F9运行,果然出现了刚用了一次的nag(用没有去掉这个nag的文件),然后在nag掉下面这行
00552373 FF92 D8000000 call dword ptr ds:[edx+D8] ; 这个call就是调用nag的call
保存一下MSQingShu_cRacKEd.exe,运行一下,呵呵,成功了^_^!
此时次数已不受限制了,下面的第四步可有可无,但是考虑到这篇文章第二部分是逆向的,所以干脆就写详细点,把自己的名字也写进程序里^_^!
4、先确定自己名字的字符,新建文本文件,写入“cRacKEd bY 海风月影[NE365][DFCG]”,和“魔术情书 6.55 - cRacKEd bY 海风月影[NE365][DFCG]”,没有引号,前一个是放在about里的,后一个是标题栏。然后用winHex打开文件,看到16进制字符
用od运行破解后的程序,然后打开内存(ALT+M),点右键选搜索-整个区域,填入"(Richie)",没有引号,注意大小写,第一处
005C8540 69 6F 6E 06 13 D7 F7 D5 DF A3 BA D6 EC 20 BD AD ion作者:朱 江
005C8550 28 52 69 63 68 69 65 29 00 00 0F 54 62 73 53 6B (Richie)..TbsSk
这里是delphi的控件的属性,先记住偏移量005C8548,用loadPE查一下在文件里的偏移1c7148,用winHex修改此处的代码,保存,运行,发现没有用,这就说明在程序运行时修改了控件的属性,这条路走不通了。。。。。。
继续搜索下一个,搜到
00BB1B1C C4 A7 CA F5 C7 E9 CA E9 20 36 2E 35 35 20 20 20 魔术情书 6.55
00BB1B2C 20 20 D7 F7 D5 DF A3 BA D6 EC 20 BD AD 28 52 69 作者:朱 江(Ri
00BB1B3C 63 68 69 65 29 20 20 20 20 20 CD F8 D5 BE A3 BA chie) 网站:
00BB1B4C 77 77 77 2E 43 6F 6F 6C 42 6F 6F 2E 63 6F 6D 00 www.CoolBoo.com.
呵呵,这不是标题栏嘛,记住00BB1B1C这个地址,可惜,这个地址是动态生成的,原来程序文件里没有,因此要动态调试,用od重新载入,发现都没有00BB1B1C这个地址,看来要一步一步跟踪了,打开内存,把地址栏露出来能看到就行了,然后一步步跟踪,看看
内存镜像,项目 36
地址=00BB0000
大小=00088000 (557056.)
Owner= 00BB0000 (itself)
区段=
类型=Priv 00021004
访问=RW
初始访问=
这个页面什么时候出来
00403AE4 8B04DF mov eax,dword ptr ds:[edi+ebx*8] ; 这个是循环
00403AE7 43 inc ebx
00403AE8 891D B0945600 mov dword ptr ds:[5694B0],ebx
00403AEE 85C0 test eax,eax
00403AF0 74 02 je short MSQingSh.00403AF4
00403AF2 FFD0 call eax ; 运行到某一个时出现页面,下断点
00403AF4 3BF3 cmp esi,ebx
00403AF6 ^ 7F EC jg short MSQingSh.00403AE4
在00403AF0下断点,F9慢慢按,发现页面出来了就转到00BB1B1C去看看,发现还全是00(幸运^_^),对00BB1B1C下内存写入断点,取消 call eax 的断点,F9运行,断在
00402980 FD std
00402981 F3:A5 rep movsd ; 断在这,不能F8走
00402983 89C1 mov ecx,eax ; 在这下断点,F9运行,取消断点
00402985 83E1 03 and ecx,3
00402988 83C6 03 add esi,3
0040298B 83C7 03 add edi,3
0040298E F3:A4 rep movsb
00402990 FC cld
00402991 5F pop edi
00402992 5E pop esi
00402993 C3 retn
不能用F8走,一走就飞,所以在下一行下断点,F9运行,取消断点,然后一路F8,来到
0046A3C7 B8 30B25600 mov eax,MSQingSh.0056B230 ; 指针
0046A3CC BA 03000000 mov edx,3
0046A3D1 E8 4E9DF9FF call MSQingSh.00404124 ; 上面生成第一个字符串
0046A3D6 FF35 14B25600 push dword ptr ds:[56B214] ; 在这下断点,这里是第一个字符串
0046A3DC 68 F8E64600 push MSQingSh.0046E6F8
0046A3E1 FF35 24B25600 push dword ptr ds:[56B224] ; 这里是6.55
0046A3E7 68 622C0000 push 2C62
0046A3EC 8D45 DC lea eax,dword ptr ss:[ebp-24]
0046A3EF 50 push eax
0046A3F0 B9 C6570000 mov ecx,57C6
0046A3F5 BA 700A0000 mov edx,0A70
0046A3FA B8 04E74600 mov eax,MSQingSh.0046E704
0046A3FF E8 78E8FFFF call MSQingSh.00468C7C ; 生成第二个字符串
0046A404 FF75 DC push dword ptr ss:[ebp-24] ; 第二个字符串
0046A407 B8 18B25600 mov eax,MSQingSh.0056B218 ; 连接后放入的地址(即指针)
0046A40C BA 04000000 mov edx,4
0046A411 E8 0E9DF9FF call MSQingSh.00404124 ; 连接两个字符
0046A416 68 732C0000 push 2C73 ; 来到这,然后向上看
所以,找一个空白的地方,把 魔术情书 6.55 - cRacKEd bY 海风月影[NE365][DFCG] 复制过去,然后修改0056B218里的内容,指向我们的字符串,运行,出错,晕!! 重来一次,断在0046A3D6,仔细看每个字符串
00BB1A8C 01 00 00 00 ...
00BB1A9C 0D 00 00 00 C4 A7 CA F5 C7 E9 CA E9 20 36 2E 35 ....魔术情书 6.5
00BB1AAC 35 00 5. 00BB1ACC 01 00 00 00 32 00 00 00 ...2...
00BB1ADC 20 20 20 20 20 D7 F7 D5 DF A3 BA D6 EC 20 BD AD 作者:朱 江
00BB1AEC 28 52 69 63 68 69 65 29 20 20 20 20 20 CD F8 D5 (Richie) 网
在 字符串-8 偏移处有一个 01,在 字符串-4 偏移处的值正好是字符串的长度,应此我们把这两个信息也加上,再修改0056B218里的内容,指向我们的字符串,运行,发现标题已经变成 魔术情书 6.55 - cRacKEd bY 海风月影[NE365][DFCG] 了,下面就是保存了,在
0046A416 68 732C0000 push 2C73 ; 来到这,然后向上看
处打个smc补丁,随便找一片空地,写代码
push 2c73
mov dword ptr ds:[0056B218],(放标题的地址) ;smc补丁
jmp 46a41b ;跳到push 2c73的下一行
保存一下,标题栏就有我们的信息了。
about里的信息找法和上面一样,找到
0046A764 68 9B2C0000 push 2C9B
0046A769 8D45 88 lea eax,dword ptr ss:[ebp-78]
0046A76C 50 push eax
0046A76D B9 FF570000 mov ecx,57FF
0046A772 BA A90A0000 mov edx,0AA9
0046A777 B8 3CE94600 mov eax,MSQingSh.0046E93C
0046A77C E8 FBE4FFFF call MSQingSh.00468C7C
0046A781 8B55 88 mov edx,dword ptr ss:[ebp-78] ; 在这里 00BB207C
0046A784 B8 8CB25600 mov eax,MSQingSh.0056B28C ; 指针
0046A789 E8 AA96F9FF call MSQingSh.00403E38
修改方法可以用上面的方法,但这里没有连接两个字符串,所以我们可以这样改
0046A764 BA 20805900 mov edx,MSQingSh.00598020 ; 假设字符串存在00598020
0046A769 8955 88 mov dword ptr ss:[ebp-78],edx ; 保存一下,以防程序有校验
0046A76C EB 16 jmp short MSQingSh.0046A784 ; 跳到保存指针
0046A76E 90 nop
0046A76F 90 nop
。。。。中间的nop 省略
0046A782 90 nop
0046A783 90 nop
0046A784 B8 8CB25600 mov eax,MSQingSh.0056B28C ; 指针
0046A789 E8 AA96F9FF call MSQingSh.00403E38
上面要连接两个字符串,这里不用,所以让程序帮我们把指针填好,保存,这样就ok了。(注意要从 字符串-8 偏移处开始复制)
我还把about里图片给去掉了,大家自己去试试看,或者看我下面SMC代码。 二、不脱壳打破解补丁
1、原理:未脱壳的程序文件执行代码是动态生成的,所以不能用静态修改保存,自然想到SMC(Self Modify Code)来打补丁,关于SMC可以参考《加密与解密》第二版和《软件加密技术内幕》中关于SMC的介绍,在这我们直接用例子说明
2、在哪打补丁:补丁位置很显然放在壳把程序代码还原后,进入程序执行之前。对于压缩壳,最简单的地方就是在跳入oep时打补丁,对于这个程序,是用upx加壳的,跳入Oep的代码一般是
popad
jmp oep
那补丁打在哪呢? 打在popad 前面,因为popad 恢复寄存器前 寄存器是随便我们用的,而壳代码又结束了,不影响程序正常执行。
3、下面要注意的问题就是空间问题,用od载入,跳入oep附近的代码
0064880A ^\EB E2 jmp short MSQingSh.006487EE
0064880C 61 popad
0064880D - E9 BE84F1FF jmp MSQingSh.00560CD0
00648812 0000 add byte ptr ds:[eax],al
00648814 0000 add byte ptr ds:[eax],al
00648816 0000 add byte ptr ds:[eax],al
00648818 0000 add byte ptr ds:[eax],al
0064881A 0000 add byte ptr ds:[eax],al
用loadPE 查一下64880d在文件中的偏移是b0c0d,属于第二区段,看一下区段表中第三区段的文件中偏移b0e00,剩余空间1f3
(这里可以用 nbw的剩余空间查看器自动算,我找不到了,所以手动算一下),如果空间不够,可以在后面加一个区段
然后我们把我们的代码插在
jmp short MSQingSh.006487EE
和
popad
之间。 打补丁后的代码如下,我尽量把我写的代码的注释写详细点:
0064880A ^\EB E2 jmp short MSQingSh.006487EE
0064880C A2 F37F5C00 mov byte ptr ds:[5C7FF3],al ; 修改属性5个
00648811 A2 FD7F5C00 mov byte ptr ds:[5C7FFD],al ; about里图片height=0,width=0
00648816 C605 07805C00 08 mov byte ptr ds:[5C8007],8 ; about里图片autosize=false
0064881D C605 61845C00 67 mov byte ptr ds:[5C8461],67 ; about里label.left
00648824 C605 68845C00 5A mov byte ptr ds:[5C8468],5A ; about里label.top
0064882B C705 471B5600 E9410600 mov dword ptr ds:[561B47],641E9 ; 爆破点,两个
00648835 C705 73235500 EB049090 mov dword ptr ds:[552373],909004EB
0064883F C705 64A74600 BA898864 mov dword ptr ds:[46A764],648889BA ; 修改代码
00648849 C705 68A74600 00895588 mov dword ptr ds:[46A768],88558900 ; 让about里有我们的信息
00648853 C705 6CA74600 EB169090 mov dword ptr ds:[46A76C],909016EB
0064885D C705 16A44600 E9CBE41D mov dword ptr ds:[46A416],1DE4CBE9 ; 修改代码,让程序跳到我们的代码,跳转要用5个字节,但考虑到最后一个字节是00,和原来的程序一样,所以我们只要改前面4个就行了
00648867 61 popad
00648868 - E9 6384F1FF jmp MSQingSh.00560CD0
0064886D 0000 add byte ptr ds:[eax],al
0064886F 0000 add byte ptr ds:[eax],al
00648871 0000 add byte ptr ds:[eax],al
00648873 0000 add byte ptr ds:[eax],al
00648875 0000 add byte ptr ds:[eax],al
00648877 0000 add byte ptr ds:[eax],al
00648879 0000 add byte ptr ds:[eax],al
0064887B 0000 add byte ptr ds:[eax],al
0064887D 0000 add byte ptr ds:[eax],al
0064887F 0000 add byte ptr ds:[eax],al
00648881 0100 add dword ptr ds:[eax],eax ; 这里是我们保存的数据
00648883 0000 add byte ptr ds:[eax],al
00648885 2000 and byte ptr ds:[eax],al
00648887 0000 add byte ptr ds:[eax],al
00648889 6352 61 arpl word ptr ds:[edx+61],dx ; 第一个字符串(about里的)
0064888C 634B 45 arpl word ptr ds:[ebx+45],cx
0064888F 64:2062 59 and byte ptr fs:[edx+59],ah
00648893 20BA A3B7E7D4 and byte ptr ds:[edx+D4E7B7A3],bh
00648899 C2 D3B0 retn 0B0D3
0064889C 5B pop ebx
0064889D 4E dec esi
0064889E 45 inc ebp
0064889F 3336 xor esi,dword ptr ds:[esi]
006488A1 35 5D5B4446 xor eax,46445B5D
006488A6 43 inc ebx
006488A7 47 inc edi
006488A8 5D pop ebp
006488A9 0001 add byte ptr ds:[ecx],al
006488AB 0000 add byte ptr ds:[eax],al
006488AD 0032 add byte ptr ds:[edx],dh
006488AF 0000 add byte ptr ds:[eax],al
006488B1 00C4 add ah,al ; 第二个字符串(标题栏的)
006488B3 A7 cmpsd
006488B4 CA F5C7 retf 0C7F5
006488B7 - E9 CAE92036 jmp 36857286
006488BC 2E:34 39 xor al,39
006488BF 2020 and byte ptr ds:[eax],ah
006488C1 2D 20206352 sub eax,52632020
006488C6 61 popad
006488C7 634B 45 arpl word ptr ds:[ebx+45],cx
006488CA 64:2062 59 and byte ptr fs:[edx+59],ah
006488CE 20BA A3B7E7D4 and byte ptr ds:[edx+D4E7B7A3],bh
006488D4 C2 D3B0 retn 0B0D3
006488D7 5B pop ebx
006488D8 4E dec esi
006488D9 45 inc ebp
006488DA 3336 xor esi,dword ptr ds:[esi]
006488DC 35 5D5B4446 xor eax,46445B5D
006488E1 43 inc ebx
006488E2 47 inc edi
006488E3 5D pop ebp
006488E4 0000 add byte ptr ds:[eax],al
006488E6 68 732C0000 push 2C73 ; 保存原来代码
006488EB C705 18B25600 B2886400 mov dword ptr ds:[56B218],MSQingSh.006488B2 ; 打补丁
006488F5 - E9 211BE2FF jmp MSQingSh.0046A41B ; 跳回去
4、改完后保存一下,因为这是在壳上打补丁,所以不用考虑可读可写可执行的问题,下面就用keymaker做一下文件补丁就行了,这里我用的是dREAMtHEATER的XCell(R) Version 1.0做的补丁 --------------------------------------------------------------------------------
【破解总结】 后记:本文难度不大,主要是做一个抛砖引玉的作用,最近很忙,而且上不了网,我是破解的魔术情书 6.49版,刚破完发现出来了6.55版,好在同一作者编程思路相同,所以6.55版破解的点和6.49一样,还有作者的其他些软件都差不多。这篇文章写好时 6.56版又出来了。。。。。。 作者动作真快,大家用6.56版对照这看吧,代码基本都是一样的。
本文只是暴力破解,对于判断是否注册的地方一直没找到,希望有高手能指点一二。
--------------------------------------------------------------------------------
【爆破地址】 00552373 FF92 D8000000 call dword ptr ds:[edx+D8];nop掉
00561B47 0F84 F30C0000 je MSQingSh.00562840;改成 jmp 0056218D
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
2004-12-4
本代码的着色效果由xTiNt自动完成
下载xTiNt http://211.90.75.84/web/kanaun/download/xTiNt.rar
能力值:
( LV4,RANK:50 )
22 楼
没必要吧,浪费版面啊.
需要的可以自己搜索嘛,而且看雪精华里面也肯定会收藏.
能力值:
( LV2,RANK:10 )
23 楼
这样放在一起菜鸟容易找
能力值:
( LV2,RANK:10 )
24 楼
感谢各位老大,可是教程上面的软件,一个都下不了,谁有
qq加我28794402,谢谢
能力值:
( LV2,RANK:10 )
25 楼
今天星期六,我这个外行想从入门初级起学做一遍,可惜指定的地址进不去,没有作业题,只能等以后了.