菜鸟逆袭 Crackme第二弹 附带注册机
来源:互联网 发布:连云港网络推广 编辑:程序博客网 时间:2024/05/17 04:19
本来想每天一破的,发现我天真了。
目标:crackme.rar
先检查有没有壳: crackme6.exe:ASPack 2.x (without poly) -> Alexey Solodovnikov [Overlay] 用AspackDie1.41脱壳后: unpacked.ExE:LCC Win32 1.x -> Jacob Navia [Overlay] 用w32dasm打开,发现了:GetDlgItemTextA 很好,接下来用OD打开。 用Ctrl+N 下API断点:GetDlgItemTextA F9运行下00401539 |. E8 FA010000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA0040153E |. 89C3 MOV EBX,EAX ; EAX是返回的长度,EBX = EAX 00401540 |. 09DB OR EBX,EBX ; if (len(name) != 0 )00401542 |. 75 04 JNZ SHORT unpacked.0040154800401544 |. 31C0 XOR EAX,EAX 00401546 |. EB 50 JMP SHORT unpacked.0040159800401548 |> BF BC020000 MOV EDI,2BC ; 2BC 是十进制 7000040154D |. BE 30000000 MOV ESI,30 ; 30 是十进制 48 也就是 '9'00401552 |. B8 48000000 MOV EAX,48 ; 48 是十进制 72 00401557 |. 99 CDQ ; Convert Double to Quad,EDX拓展为EAX的高位 00401558 |. F7FB IDIV EBX ; 0040155A |. 29C6 SUB ESI,EAX 0040155C |. 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4]0040155F |. 29F7 SUB EDI,ESI00401561 |. 6BFF 6B IMUL EDI,EDI,6B00401564 |. 81EF 6CCF0000 SUB EDI,0CF6C0040156A |. 81FF 00230000 CMP EDI,230000401570 |. 7F 08 JG SHORT unpacked.0040157A00401572 |. 81FF 90010000 CMP EDI,19000401578 |. 7D 04 JGE SHORT unpacked.0040157E0040157A |> 31C0 XOR EAX,EAX0040157C |. EB 1A JMP SHORT unpacked.004015980040157E |> 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100]分析过程: a = 30 - (48/len(name)) b = 2BC - ptr[a+4a] c = b * b * 6B d = c - 0CF6C 可能是个负数。。 if d > 2300 跳到 0040157A 然后就完蛋了 if d >= 190 跳到 0040157E 有戏 EDI与0CF6C想减后为e, 400 <= e <=8960 往上看,发现EDI - ESI,然后一开始的EDI赋值为2BC,关键在ESI ESI 赋值为30,30 - (48/len(name)),余数放在EAX中,然后ESI - EAX 减去这个余数 然后取地址。。这个地址怎么办?DWORD PTR DS:[ESI+ESI*4]? 在这里做不下去了,看了下答案,发现2点很可怕的地方: (1)DWORD PTR DS:[ESI+ESI*4] 是取ESI * 5 ,据大神说,lea是专业计算这类公式的 ,这里有中括号,就当成特殊处理吧 (2)IMUL EDI,EDI,6B 是将 第二个操作数 * 第三个操作数 然后结果放在第一个操作数 纠错后,总结下: EDI = [ 2bc - (30 - 48/namelen)*5 ]*6b- CF6C 然后结果要: 190 <= EDI <= 2300 那么经过一番运算后:namelen 要在 [3,9] 之间。。 F9重新运行下,输入长度为6的 xihuan 序列号输入:woaini 接下来进行序列号的猜解:004013B4 |. 09C0 OR EAX,EAX ;if namelen == 0 跳走00401504 挂了004013B6 |. 0F84 48010000 JE unpacked.00401504004013BC |. B8 CF110000 MOV EAX,11CF 004013C1 |. 0FB68D E1FCFF>MOVZX ECX,BYTE PTR SS:[EBP-31F] ;这里是序列号的第一位'w' 004013C8 |. 99 CDQ004013C9 |. F7F9 IDIV ECX004013CB |. 83FA 17 CMP EDX,17 ;if (EDX == 17) 004013CE |. 74 07 JE SHORT unpacked.004013D7 ; 跳到004013D7 不挂 004013D0 |. 31C0 XOR EAX,EAX004013D2 |. E9 2D010000 JMP unpacked.00401504 ; 不跳走就挂掉了,004013D7 |> 31DB XOR EBX,EBX004013D9 |. EB 0B JMP SHORT unpacked.004013E6004013DB |> 8B45 10 /MOV EAX,DWORD PTR SS:[EBP+10] ; name = "xihuan"004013DE |. 0FBE0418 |MOVSX EAX,BYTE PTR DS:[EAX+EBX] ; name的第一个字符'x' 004013E2 |. 0145 FC |ADD DWORD PTR SS:[EBP-4],EAX ; ?!004013E5 |. 43 |INC EBX ; 自增 004013E6 |> 3B5D 0C CMP EBX,DWORD PTR SS:[EBP+C] ; name 的 长度 6 004013E9 |.^ 7C F0 \JL SHORT unpacked.004013DB ; 递增至长度6则结束004013EB |. 31DB XOR EBX,EBX004013ED |. E9 83000000 JMP unpacked.00401475分析过程:EAX = 11CFECX = 'w' EAX/ECX 商放在EAX,余数放在EDXif (EDX == 17) 就不会挂 ,那么这个ECX应该是 23(10) = 17(h): 36 * 126 + 23 42 * 108 + 23 54 * 84 + 23 56 * 81 + 23 63 * 72 + 23 72 * 63 + 23 81 * 56 + 23 84 * 54 + 23 这里我去108,也就是'l',重新开始,F9 序列号输入为lwoaini,判定成功,避免挂了 004013DB |> 8B45 10 /MOV EAX,DWORD PTR SS:[EBP+10] ; name = "xihuan"004013DE |. 0FBE0418 |MOVSX EAX,BYTE PTR DS:[EAX+EBX] ; name的第一个字符'x' 004013E2 |. 0145 FC |ADD DWORD PTR SS:[EBP-4],EAX ; 不懂!004013E5 |. 43 |INC EBX ; 自增 004013E6 |> 3B5D 0C CMP EBX,DWORD PTR SS:[EBP+C] ; 004013E9 |.^ 7C F0 \JL SHORT unpacked.004013DB这段就是把用户名 "xihuan"的每一个字符都加到 SS:[EBP-4]中。那么SS:[EBP-4]到底是什么?找到0D中的:0012F8F0 0000021F <- 这个地方就是EBP-4。0012F8F4 /0012FA140012F8F8 |0040158E RETURN to unpacked.0040158E from unpacked.004013050012F8FC |004903320012F900 |00000006 <- 这里就是 EBP+C 也就是存在着长度0012F904 |0012F914 ASCII "xihuan"0012F908 |0012FA3B ASCII "SHiT ... you entered the correct serial!"0012F90C |00402593 ASCII "You have to make an own working keygen!这里我懂了,把name的每一个字符都加到[EBP-4]中,最后加完 “xihuan”总和为28D.加完之后又会跳入一个循环,这个循环是计算用:004013F2 |> 8B55 10 /MOV EDX,DWORD PTR SS:[EBP+10] ;这是“xihuan”的地址004013F5 |. 0FBE3C1A |MOVSX EDI,BYTE PTR DS:[EDX+EBX] ;这里循环不断去xihuan的单字符,第一个为x 004013F9 |. 8B75 FC |MOV ESI,DWORD PTR SS:[EBP-4] ; 刚刚的 xihuan 字符和 :28D004013FC |. 89D9 |MOV ECX,EBX ; 004013FE |. C1E1 02 |SHL ECX,2 ; ECX 左移2为,第一次中为000即为 0 00401401 |. 89DA |MOV EDX,EBX ; 00401403 |. 42 |INC EDX ; 第一次中,EDX 增1 为 100401404 |. 29D1 |SUB ECX,EDX ; 0 - 1 = FFFFFFFF 00401406 |. 0FB68C0D E1FE>|MOVZX ECX,BYTE PTR SS:[EBP+ECX-11F] ; 查看了地址发现是 ECX = 0 0040140E |. 89FA |MOV EDX,EDI ; EDX = 'x' 00401410 |. 31CA |XOR EDX,ECX ; EDX = name[i] ^SS:[EBP+(3*i-1)-11F]00401412 |. 89F1 |MOV ECX,ESI ; ECX = 28D ..字符和 00401414 |. 0FAFCB |IMUL ECX,EBX ; 00401417 |. 29F1 |SUB ECX,ESI00401419 |. 89CE |MOV ESI,ECX0040141B |. 83F6 FF |XOR ESI,FFFFFFFF ; ESI = (sum*i-sum)^FFFFFFFF 0040141E |. 8DB432 4D0100>|LEA ESI,DWORD PTR DS:[EDX+ESI+14D] ; ESI = DS:[EDX + ESI + 14D] 00401425 |. 8B4D 0C |MOV ECX,DWORD PTR SS:[EBP+C] ; 00401428 |. 89DA |MOV EDX,EBX0040142A |. 83C2 03 |ADD EDX,30040142D |. 0FAFCA |IMUL ECX,EDX00401430 |. 0FAFCF |IMUL ECX,EDI00401433 |. 89F0 |MOV EAX,ESI00401435 |. 01C8 |ADD EAX,ECX00401437 |. B9 0A000000 |MOV ECX,0A0040143C |. 31D2 |XOR EDX,EDX0040143E |. F7F1 |DIV ECX00401440 |. 83C2 30 |ADD EDX,3000401443 |. 88941D FCFEFF>|MOV BYTE PTR SS:[EBP+EBX-104],DL0040144A |. 0FB6BC1D FCFE>|MOVZX EDI,BYTE PTR SS:[EBP+EBX-104]00401452 |. 81F7 ACAD0000 |XOR EDI,0ADAC00401458 |. 89DE |MOV ESI,EBX0040145A |. 83C6 02 |ADD ESI,20040145D |. 89F8 |MOV EAX,EDI0040145F |. 0FAFC6 |IMUL EAX,ESI00401462 |. B9 0A000000 |MOV ECX,0A00401467 |. 99 |CDQ00401468 |. F7F9 |IDIV ECX0040146A |. 83C2 30 |ADD EDX,300040146D |. 88941D FCFEFF>|MOV BYTE PTR SS:[EBP+EBX-104],DL00401474 |. 43 |INC EBX00401475 |> 3B5D 0C CMP EBX,DWORD PTR SS:[EBP+C]00401478 |.^ 0F8C 74FFFFFF \JL unpacked.004013F2分析过程:这一段好长。其中涉及到 是一段字母表 CBA0 GFED ...:0012F7D4 434241000012F7D8 474645440012F7DC 4B4A49480012F7E0 4F4E4D4C0012F7E4 535251500012F7E8 575655540012F7EC 005A5958(((((name[i]^helpStr[i*3-1])+((sum*i-sum)^0xffffffff)+0x14d+(i+3)*name_len*name[i])%10+0x30)^0xadac)*(i+2))%10+0x30;其中helpStr就是26字母表把这计算结果存放到 SS:[EBP+EBX-104]Ps:贫道做完这个计算过程分析后,深感蛋疼。0040147E |. 8D85 FCFEFFFF LEA EAX,DWORD PTR SS:[EBP-104] ;这里存在着计算完的序列号 204069 00401484 |. 50 PUSH EAX00401485 |. 6A 54 PUSH 5400401487 |. 8D85 DCFBFFFF LEA EAX,DWORD PTR SS:[EBP-424]0040148D |. 50 PUSH EAX ; |Format0040148E |. 8D85 E1FBFFFF LEA EAX,DWORD PTR SS:[EBP-41F] ; |00401494 |. 50 PUSH EAX ; |s00401495 |. E8 CE020000 CALL <JMP.&USER32.wsprintfA> ; \wsprintfA <- 这里把结算结果改为T2040690040149A |. 8B7D 0C MOV EDI,DWORD PTR SS:[EBP+C] ; namelen = 60040149D |. 89F8 MOV EAX,EDI ; 60040149F |. 0FAF45 FC IMUL EAX,DWORD PTR SS:[EBP-4] ; 6 * 2BD (sum(name)) 004014A3 |. B9 64000000 MOV ECX,64 ; 64 004014A8 |. 99 CDQ 004014A9 |. F7F9 IDIV ECX ; 6 * 2BD (sum(name)) /64004014AB |. 89D7 MOV EDI,EDX ; 6 * 2BD (sum(name)) mod 64004014AD |. 83C7 30 ADD EDI,30 ; 6 * 2BD (sum(name)) mod 64 + 30004014B0 |. 57 PUSH EDI 004014B1 |. 8DBD E1FBFFFF LEA EDI,DWORD PTR SS:[EBP-41F] 004014B7 |. 57 PUSH EDI004014B8 |. 8DBD D6FBFFFF LEA EDI,DWORD PTR SS:[EBP-42A]004014BE |. 57 PUSH EDI ; |Format004014BF |. 8DBD E1FDFFFF LEA EDI,DWORD PTR SS:[EBP-21F] ; | format("%s-%d","T204069",42)004014C5 |. 57 PUSH EDI ; |s 42的十进制是66 004014C6 |. E8 9D020000 CALL <JMP.&USER32.wsprintfA> ; \wsprintfA <- 到这里计算结果为T204069-66004014CB |. 83C4 20 ADD ESP,20004014CE |. 8D8D E1FDFFFF LEA ECX,DWORD PTR SS:[EBP-21F] 004014D4 |. 83C8 FF OR EAX,FFFFFFFF 004014CB |. 83C4 20 ADD ESP,20004014CE |. 8D8D E1FDFFFF LEA ECX,DWORD PTR SS:[EBP-21F] ; 这里要注意。。应该遍历字符串004014D4 |. 83C8 FF OR EAX,FFFFFFFF004014D7 |> 40 /INC EAX004014D8 |. 803C01 00 |CMP BYTE PTR DS:[ECX+EAX],0 ; 直到取到了字符‘\0’也就是结尾004014DC |.^ 75 F9 \JNZ SHORT unpacked.004014D7004014DE |. 50 PUSH EAX ; /Arg3004014DF |. 8D85 E1FCFFFF LEA EAX,DWORD PTR SS:[EBP-31F] ; | T204069-TT004014E5 |. 50 PUSH EAX ; |Arg2004014E6 |. 8D85 E1FDFFFF LEA EAX,DWORD PTR SS:[EBP-21F] ; | lwoaini 004014EC |. 50 PUSH EAX ; |Arg1004014ED |. E8 D0FDFFFF CALL unpacked.004012C2 ; \unpacked.004012C2 这里进去看看004014F2 |. 83C4 0C ADD ESP,0C 004014F5 |. 83F8 00 CMP EAX,0004014F8 |. 75 07 JNZ SHORT unpacked.00401501004014FA |. B8 00000000 MOV EAX,0004014FF |. EB 03 JMP SHORT unpacked.0040150400401501 |> 31C0 XOR EAX,EAX00401503 |. 40 INC EAX00401504 |> 5F POP EDI00401505 |. 5E POP ESI00401506 |. 5B POP EBX00401507 |. C9 LEAVE00401508 \. C3 RETN参数是T204069-66 和 lwoaini ,进来call 看看:004012C2 /$ 55 PUSH EBP ; 004012C3 |. 89E5 MOV EBP,ESP004012C5 |. 53 PUSH EBX004012C6 |. 56 PUSH ESI004012C7 |. 57 PUSH EDI004012C8 |. 8B5D 10 MOV EBX,DWORD PTR SS:[EBP+10] ; len=10004012CB |. 31F6 XOR ESI,ESI 004012CD |. 46 INC ESI ; <- 这一步导致'T'被忽略从'2'开始 004012CE |. EB 29 JMP SHORT unpacked.004012F9 ; 循环开始 004012D0 |> 8B55 08 /MOV EDX,DWORD PTR SS:[EBP+8] ; 204069-66 004012D3 |. 0FBE3C32 |MOVSX EDI,BYTE PTR DS:[EDX+ESI] ; 2 004012D7 |. 89F8 |MOV EAX,EDI 004012D9 |. 83F0 20 |XOR EAX,20 ; 2 XOR 20 004012DC |. B9 0A000000 |MOV ECX,0A 004012E1 |. 99 |CDQ 004012E2 |. F7F9 |IDIV ECX ; (2 XOR 20)/0A004012E4 |. 89D7 |MOV EDI,EDX ; (2 XOR 20) mod 0A004012E6 |. 83C7 30 |ADD EDI,30 ; EDI = (2 XOR 20) mod 0A + 30004012E9 |. 8B55 0C |MOV EDX,DWORD PTR SS:[EBP+C] ; lwoaini 004012EC |. 0FBE1432 |MOVSX EDX,BYTE PTR DS:[EDX+ESI] ; EDX = l 004012F0 |. 39D7 |CMP EDI,EDX ; 比较 EDI 和 EDX <- 注意这里是关键!!004012F2 |. 74 04 |JE SHORT unpacked.004012F8004012F4 |. 31C0 |XOR EAX,EAX004012F6 |. EB 08 |JMP SHORT unpacked.00401300004012F8 |> 46 |INC ESI004012F9 |> 39DE CMP ESI,EBX 004012FB |.^ 7C D3 \JL SHORT unpacked.004012D0总结: 1. 用户名“xihuan”经过(((((name[i]^helpStr[i*3-1])+((sum*i-sum)^0xffffffff)+0x14d+(i+3)*name_len*name[i])%10+0x30)^0xadac)*(i+2))%10+0x30; 变成了“204069”,然后+'T'变成'T204069',加'-',然后加尾巴'66','66'是这么来的 (sum * length) % 0x64 +0x30;(Ps:'66'的分析较简单,于是没写出来) 2. 每个字符 EDI = (T XOR 20) mod 0A + 30 合起来就是“xihuan”的序列号了 if __name__ == "__main__": str = "204069-66"; res = "" for i in str : lrc = (ord(i) ^ 32) %10 +48 print "%c %d",i,ord(i),lrc res = res + chr(lrc) print 'l'+res结果:l860625322至此:用户名是xihuan 序列号是:l860625322
// getSerial.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "string.h"#include "stdlib.h"#include <stdio.h>int main(int argc, char* argv[]){unsigned int i,sum,length,length2,esi,ecx,edx,edi;char name[] = "xihuan"; char helpstr[]={'\0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; while (true){printf("Please enter username(finished with '#' , name's length in [3,9]) :");scanf("%s",name) ;if(strcmp(name,"#") == 0) break;length = strlen(name);char *tmpStr = (char*)malloc( sizeof(char)*length);char *tmpStr2 = (char*)malloc(sizeof(char)*length+4);char *resStr = (char*)malloc(sizeof(char)*length+4);sum = 0;for(i = 0 ; i < length ; i++) sum += (unsigned int)name[i];for(i = 0 ; i < length ; i++) {if (i == 0) edx = 0 ^ (unsigned int)name[i];elseedx = (unsigned int)helpstr[3*i] ^ (unsigned int)name[i];esi = (0xFFFFFFFF ^ sum*(i-1)) +edx +0x14d;ecx =(length*(i+3)*(unsigned int)name[i]+esi)%0xA+0x30;ecx =( (ecx ^ 0xADAC) *(2+i))%0xA+0x30;tmpStr[i]=ecx;}tmpStr[i] = '\0';edi = (sum * length) % 0x64 +0x30;sprintf(tmpStr2,"%s-%d",tmpStr,edi);length2 = strlen(tmpStr2);for(i = 0 ; i < length2 ; i++){tmpStr2[i] = (tmpStr2[i] ^ 0x20) % 0xA +0x30;}sprintf(resStr,"%c%s",'l',tmpStr2); printf("Result is: %s\n",resStr);}return 0;}
- 菜鸟逆袭 Crackme第二弹 附带注册机
- 菜鸟逆袭 Crackme第三弹 附带注册机
- 菜鸟逆袭 CrackMe第一弹
- 破解的一个crackme,附注册机
- 逆向CrackMe-01写注册机
- 逆向CrackMe-02写注册机
- 逆向CrackMe-03写注册机
- 《加密与解密》第三版 CrackMe的注册机代码
- 一个简单crackme破解及注册机编写
- CrackMe破解【1】菜鸟级别
- CrackMe破解【2】-菜鸟级别
- 教菜鸟写注册机
- 西电第四届网络攻防竞赛Crackme破解第四关分析及注册机
- 教菜鸟学习注册机文章学习
- Acronis Disk Director Suite v10.0.2160 英文正式版 附带 Acronis Disk Director Suite v10 注册机
- 算法注册机编写扫盲---第二课
- 教菜鸟写注册机——初级篇
- 教菜鸟写注册机——中级篇
- 妙趣横生的算法实例1-4
- Linux使用文件创建swap
- 了解SVG
- 利用hash表思想,实现查找到第一个在字符串中出现的字符
- 操作系统--1写这一系列的目的
- 菜鸟逆袭 Crackme第二弹 附带注册机
- Squid的main函数源码分析
- Yii: 如何在CGridView组件中根据不同的记录行数据显示不同的操作
- objc 的新特性
- iPhone、iPhone4、iPad 程序启动画面的总结
- informatica客户端连接报错pcsf_46008
- 为Android加入busybox工具
- Shell十三问之一:什么是shell?
- 在weblogic下部署找不到授权文件的解决方法