菜鸟逆袭 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 


分析很透彻,就随带写了注册机,出了点小问题,用python无法定义出unsigned int,只能转为c语言写了。

// 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;}



原创粉丝点击