1、第13课 注册算法进阶第13课 注册算法进阶例1目标程序:easy1.exe。0167:004014FC 8D45FC LEA EAX,EBP-040167:004014FF E814040000 CALL 004019180167:00401504 8B5594 MOV EDX,EBP-6C0167:00401507 0FBE0C10 MOVSX ECX,BYTE EAX+EDX /依次取name中的字符0167:0040150B 014DA0 ADD EBP-60,ECX /累加到ebp-60中0167:0040150E FF4594 INC DWORD EBP-6C /计数0167:00
2、401511 8D45FC LEA EAX,EBP-040167:00401514 E8DDE10000 CALL 0040F6F60167:00401519 3B4594 CMP EAX,EBP-6C0167:0040151C 7FDE JG 004014FC /如果没取完,就跳转,形成循环上面程序的功能是将所有输入的name字符累加起来,以我输入的”TAE”为例,程序每次取一个字符然后将他们相加,就像这样:”T”的ascii码为0x54,”A”的ascii码为0x41,”E”的ascii码为0x45,”!”的ascii码为0x21,所以0x54+0x41+0x45+0x21=0xFB,结果
3、就是0xFB,现在还没有结束,请看下面程序对这个0xFB的操作:0167:0040151E 6955A032130000 IMUL EDX,EBP-60,13320167:00401525 8955A0 MOV EBP-60,EDX0167:00401528 694DA032130000 IMUL ECX,EBP-60,13320167:0040152F 894DA0 MOV EBP-60,ECX0167:00401532 6945A032130000 IMUL EAX,EBP-60,13320167:00401539 8945A0 MOV EBP-60,EAX0167:0040153C 81
4、45A04A0F0000 ADD DWORD EBP-60,0F4A 大家能看懂上面的程序吗?其实就是用0xFB连续乘三次0x1332,然后用这个结果加上0x0F4A,经过这样的计算就得到了你的注册码了0167:00401543 8B5598 MOV EDX,EBP-680167:00401546 3B55A0 CMP EDX,EBP-60 /” ebp-60”中保存正确注册码0167:00401549 0F8571010000 JNZ NEAR 004016C0 /判断注册码是否正确,不同的话就跳到出错提示了0167:0040154F 66C745C05000 MOV WORD EBP-40
5、,500167:00401555 8D45E8 LEA EAX,EBP-180167:00401558 8B55A0 MOV EDX,EBP-60我得到的注册码: Name:TAE! Sn: -1861903902下面给出easy1的keymake的算法注册机(keygen.rek):.const.dataszHomePage db ,0szEmail db mailto:fpx425,0szErrMess db 请输入姓名!,0szBuffer db 50 dup (0)szHex db %ld,0.codemov esi,eaxinvoke lstrlen,esimov ecx,eaxxo
6、r edx,edxxor ebx,ebxxor eax,eaxn1:mov bl, byte ptr esi+eaxadd edx,ebxinc eaxcmp ecx,eaxjg n1mov eax,edximul eax,eax,1332himul eax,eax,1332himul eax,eax,1332hadd eax,0F4Ahinvoke wsprintf,addr szBuffer,addr szHex,eaxlea eax,szBuffer注意其中红字标出的部分。例2目标程序nullz的第1、2关。大家看到了吧,是分三六九等的,一起来试试,先来个最简单的吧!方法一:工具:Win
7、Hex过程:用前面教过的方法,一试就出来,不信请看看到了吗?qJT62aWfviq0P57JGs2FelQkX这个就是注册码,什么?不信?我有证据,请看!还有一种方法就是直接用W32DASM反汇编即可!如图:是不是更简单?呵呵,好的,我们进入下一层!开始,如图:出现错误提示?肯定的了,让我们来一步步分析它,这次光用WINHEX和W32DASM可就不管用了,要动用“动态分析软件”了,例如使用ollydbg。过程::00401AE4 8D4C247C lea ecx, dword ptr esp+7C:00401AE8 6A33 push 00000033:00401AEA 51 push ecx
8、:00401AEB 68ED030000 push 000003ED:00401AF0 8BCB mov ecx, ebx* Reference To: MFC42.Ordinal:0C1A, Ord:0C1Ah |:00401AF2 E8E7100000 Call 00402BDE:00401AF7 8D542414 lea edx, dword ptr esp+14:00401AFB 52 push edx* Reference To: KERNEL32.lstrlenA, Ord:02A1h |:00401AFC FF1500404000 Call dword ptr 00404000:
9、00401B02 8BF0 mov esi, eax:00401B04 83FE05 cmp esi, 00000005-比较用户名是否大于5位:00401B07 7311 jnb 00401B1A-小于就出现错误信息:00401B09 6A40 push 00000040* Possible StringData Ref from Data Obj -CrackMe |:00401B0B 6804514000 push 00405104* Possible StringData Ref from Data Obj -User Name must have at least 5 -charac
10、ters. |:00401B10 68D8504000 push 004050D8:00401B15 E9BA000000 jmp 00401BD4* Referenced by a (U)nconditional or (C)onditional Jump at Address:|:00401B07(C)|:00401B1A B801000000 mov eax, 00000001-给EAX赋值为1,做为计数器:00401B1F 33FF xor edi, edi-EDI清零,做储数器:00401B21 3BF0 cmp esi, eax:00401B23 7211 jb 00401B36*
11、 Referenced by a (U)nconditional or (C)onditional Jump at Address:|:00401B34(C)|:00401B25 0FBE4C0414 movsx ecx, byte ptr esp+eax+14- 提取你输入用户名的第二位的十六进制:00401B2A 03CF add ecx, edi ECXECX+EDI:00401B2C 0FAFC8 imul ecx, eax ECXECX*EAX:00401B2F 40 inc eax EAX+1:00401B30 8BF9 mov edi, ecxEDIECX:00401B32 3B
12、C6 cmp eax, esi :00401B34 76EF jbe 00401B25形成循环以我输入的名字lllufh为例l的十六进制6C、u的十六进制75、f的十六进制66、h的十六进制68计算过程如下:初始化:EDX=0 EAX=1第一次循环:1.ecx=6c2.ecx=ecx+edi=6c3.ecx=ecx*eax=6c4.eax=eax+1=25.edi=ecx=6c第二次循环:1.ecx=6c2.ecx=ecx+edi=d83.ecx=ecx*eax=1b04.eax=eax+1=35.edi=ecx=1b0第三次循环:1.ecx=752.ecx=ecx+edi=2253.ecx=
13、ecx*eax=66f4.eax=eax+1=45.edi=ecx=66f第四次循环:1.ecx=662.ecx=ecx+edi=6d53.ecx=ecx*eax=1b544.eax=eax+1=55.edi=ecx=1b54第五次循环:1.ecx=682.ecx=ecx+edi=1bbc3.ecx=ecx*eax=8aac4.eax=eax+1=65.edi=ecx=8aac第六次循环:1.ecx=02.ecx=ecx+edi=8aac3.ecx=ecx*eax=340084.eax=eax+1=75.edi=ecx=34008循环结束.* Referenced by a (U)ncondi
14、tional or (C)onditional Jump at Address:|:00401B23(C)|:00401B36 33C9 xor ecx, ecx-ecx清零 做计数器:00401B38 85F6 test esi, esi:00401B3A 7620 jbe 00401B5C* Referenced by a (U)nconditional or (C)onditional Jump at Address:|:00401B5A(C)|第二次计算开始。:00401B3C 0FBE6C0C14 movsx ebp, byte ptr esp+ecx+14 提取用户名的第一位:00
15、401B41 8BC7 mov eax, edi/ eax=edi:00401B43 33D2 xor edx, edx / edx清零:00401B45 F7F5 div ebp/ eax=eax/ebp 商进EAX,余数进EDX:00401B47 33D2 xor edx, edx /edx清零:00401B49 BD0A000000 mov ebp, 0000000A / ebp=0xA:00401B4E F7F5 div ebp / eax=ex/ebp 商进EAX,余数进EDX:00401B50 80C230 add dl, 30 / edx=edx+0x30:00401B53 88
16、540C48 mov byte ptr esp+ecx+48, dl / 把EDX的值赋到字符串中:00401B57 41 inc ecx ecx=ecx+1:00401B58 3BCE cmp ecx, esi:00401B5A 72E0 jb 00401B3C 形成循环接着以我输入的名字lllufh为例继续计算:第一次循环:1. ebp=6c2. eax=edi=340083. edx=04. eax=eax/ebp=7b4 edx=185. edx=06. ebp=a7. eax=eax/ebp=c5 edx=028. edx=02+30=329. esp+ecx+48=3210. ec
17、x=ecx+1=1因为我输入的用户名的都三位都一样,所以第二次、第三次循环的值也都是一样的第四次循环:1. ebp=752. eax=edi=340083. edx=04. eax=eax/ebp=71c edx=3c5. edx=06. ebp=a7. eax=eax/ebp=b6 edx=08. edx=0+30=309. esp+ecx+48=3010. ecx=ecx+1=4第五次循环:1. ebp=662. eax=edi=340083. edx=04. eax=eax/ebp=828 edx=185. edx=06. ebp=a7. eax=eax/ebp=0 edx=088. e
18、dx=8+30=389. esp+ecx+48=3811. ecx=ecx+1=5第六次循环: 1. ebp=682.eax=edi=340083.edx=04.eax=eax/ebp=800 edx=085.edx=06.ebp=a7.eax=eax/ebp=cc edx=088.edx=8+30=389.esp+ecx+48=3811. ecx=ecx+1=6跳出循环。依次把六次循环的余数提出,为222088,这就是注册码喽!晕,又不信,自己看图吧!* Referenced by a (U)nconditional or (C)onditional Jump at Address:|:00
19、401B3A(C)|:00401B5C 8D542448 lea edx, dword ptr esp+48-这里是真码:00401B60 8D44247C lea eax, dword ptr esp+7C-这里是假码:00401B64 52 push edx:00401B65 50 push eax* Reference To: KERNEL32.lstrcmpA, Ord:0295h |:00401B66 FF1508404000 Call dword ptr 00404008:00401B6C 85C0 test eax, eax:00401B6E 7550 jne 00401BC0:
20、00401B70 6870434000 push 00404370:00401B75 8D4C2414 lea ecx, dword ptr esp+14* Reference To: MFC42.Ordinal:0219, Ord:0219h |:00401B79 E85A100000 Call 00402BD8* Possible StringData Ref from Data Obj -Difficulty LEVEL-2 Completed!下面给出nullz的第2关的keymake的算法注册机(keygen.rek):.const.dataszHomePage db ,0szEma
21、il db mailto:fpx425,0szErrMess db 请输入姓名!,0szBuffer db 50 dup (0)szHex db %d,0len dd 0.codemov esi,eaxinvoke lstrlen,esimov len,eaxmov eax,1xor edi,edin1:movsx ecx,byte ptr esi+eaxadd ecx,ediimul ecx,eaxinc eaxmov edi,ecxcmp eax,lenjbe n1xor ecx,ecxn2:movsx ebp,byte ptr esi+ecxmov eax,edixor edx,edxd
22、iv ebpxor edx,edxmov ebp,0Ahdiv ebpadd dl,30hmov byte ptr szBuffer+ecx,dlinc ecxcmp ecx,lenjb n2lea eax,szBuffer 以上基本上来自程序的反汇编代码:注意其中的红字部分,我第一次编译没通过,就是因为数字后面没加h。例3目标程序nullz的第3关。该第三阶段了,可是一个比上一个要难哟,睁大眼睛仔细看呀!什么?和第二个一样?别急呀,外表一样,芯可不一样喽,跟我一步步来吧!:00401C72 8D4C2414 lea ecx, dword ptr esp+14:00401C76 51 push
23、 ecx:00401C77 68ED030000 push 000003ED:00401C7C 8BCF mov ecx, edi* Reference To: MFC42.Ordinal:0C19, Ord:0C19h |:00401C7E E8670F0000 Call 00402BEA:00401C83 8B6C2418 mov ebp, dword ptr esp+18ebp=0x650088以后计算用:00401C87 8B55F8 mov edx, dword ptr ebp-08为用户名个数:00401C8A 83FA05 cmp edx, 00000005进行比较:00401C
24、8D 7D11 jge 00401CA0不能小于5位:00401C8F 6A40 push 00000040* Possible StringData Ref from Data Obj -CrackMe |:00401C91 6804514000 push 00405104* Possible StringData Ref from Data Obj -User Name must have at least 5 -characters. |:00401C96 68D8504000 push 004050D8:00401C9B E9E2000000 jmp 00401D82* Referen
25、ced by a (U)nconditional or (C)onditional Jump at Address:|:00401C8D(C)|:00401CA0 33C0 xor eax, eax / eax清零:00401CA2 3BD3 cmp edx, ebx / 比较是否输入注册码:00401CA4 7E3C jle 00401CE2 / 没有则出错:00401CA6 B901000000 mov ecx, 00000001 / ecx=1:00401CAB 33FF xor edi, edi / edi清零:00401CAD 2BCD sub ecx, ebp / ecx=ecx-
26、ebp:00401CAF 894C241C mov dword ptr esp+1C, ecx / 把ecx的值放入esp+1c中* Referenced by a (U)nconditional or (C)onditional Jump at Address:|:00401CDA(C)|计算注册码过程开始:00401CB3 0FBE5C0500 movsx ebx, byte ptr ebp+eax / 依次提取用户名第一位的十六进制:00401CB8 8D4C0500 lea ecx, dword ptr ebp+eax / ecx=ebp+eax:00401CBC 03F3 add e
27、si, ebx / esi=esi+ebx:00401CBE 8BD8 mov ebx, eax / ebx=ebx+eax:00401CC0 C1E308 shl ebx, 08 / ebx左移三位:00401CC3 33F3 xor esi, ebx / esi=esi xor ebx:00401CC5 8B5C241C mov ebx, dword ptr esp+1C / ebx=esp+1c:00401CC9 03D9 add ebx, ecx / ebx=ebx+ecx:00401CCB 8BCF mov ecx, edi / ecx=edi:00401CCD 0FAFF3 imu
28、l esi, ebx / esi=esi*ebx:00401CD0 F7D1 not ecx / ecx取反:00401CD2 0FAFF1 imul esi, ecx / esi=esi*ecx:00401CD5 40 inc eax / eax=eax+1:00401CD6 03FA add edi, edx / edi=edi+edx:00401CD8 3BC2 cmp eax, edx:00401CDA 7CD7 jl 00401CB3 形成循环:00401CDC 8B7C2420 mov edi, dword ptr esp+20:00401CE0 33DB xor ebx, ebx
29、* Referenced by a (U)nconditional or (C)onditional Jump at Address:|:00401CA4(C)|:00401CE2 56 push esi:00401CE3 8D542414 lea edx, dword ptr esp+14* Possible StringData Ref from Data Obj -%lu |:00401CE7 682C514000 push 0040512C:00401CEC 52 push edx* Reference To: MFC42.Ordinal:0B02, Ord:0B02h |:00401CED E8F20E0000 Call 00402BE4:00401CF2 8B74241C mov esi, dword ptr esp+1C-这里就是真码了
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1