飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 7731|回复: 11

学习逍遥风对HappyTown兄弟的crackme_13(CRC32)的算法分析,超菜级笔记

[复制链接]
  • TA的每日心情
    开心
    2016-6-17 14:50
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2006-8-11 21:18:48 | 显示全部楼层 |阅读模式
    选自逍遥风算法精华集第2篇,自己没能力分析出来,照搬学习也是一种途径呀,就怕眼高手低。
    自我安慰,呵呵!

    前几天天下了逍遥兄的算法分析,把这篇跟了几次,还是有点看不明白。好不容易等到周五,终于有空了,于是有了下面的学习笔记。
    OD载入后,断点非常容易找到,超级字符串查找到'GOOD JOB,MAN!'在以下处F2下断。

    0040116E  |.  68 FF000000   PUSH 0FF                                 ; /Count = FF (255.)
    00401173  |.  68 8C344000   PUSH CrackMe_.0040348C                   ; |Buffer = CrackMe_.0040348C
    00401178  |.  68 EC030000   PUSH 3EC                                 ; |ControlID = 3EC (1004.)
    0040117D  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
    00401180  |.  E8 6D020000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
    00401185  |.  83F8 04       CMP EAX,4
    00401188  |.  73 05         JNB SHORT CrackMe_.0040118F
    0040118A  |.  E9 11020000   JMP CrackMe_.004013A0
    0040118F  |>  A3 8F354000   MOV DWORD PTR DS:[40358F],EAX
    00401194  |.  68 FF000000   PUSH 0FF                                 ; /Count = FF (255.)
    00401199  |.  68 93354000   PUSH CrackMe_.00403593                   ; |Buffer = CrackMe_.00403593
    0040119E  |.  68 ED030000   PUSH 3ED                                 ; |ControlID = 3ED (1005.)
    004011A3  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
    004011A6  |.  E8 47020000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
    004011AB  |.  BA 1B344000   MOV EDX,CrackMe_.0040341B                ;  上面这两个CALL是取字符串长度的,结果放在EAX里
    004011B0  |.  8902          MOV DWORD PTR DS:[EDX],EAX
    004011B2  |.  E8 49FEFFFF   CALL CrackMe_.00401000                   ;  初始化CRC32数据表
    004011B7  |.  8D1D 1B344000 LEA EBX,DWORD PTR DS:[40341B]            ;  储存注册码的位数准备进行CRC32计算
    004011BD  |.  E8 78FEFFFF   CALL CrackMe_.0040103A                   ;  开始对注册码的位数进行CRC32计算
    004011C2  |.  3D F716602F   CMP EAX,2F6016F7
    004011C7  |.  0F85 D3010000 JNZ CrackMe_.004013A0
    004011CD  |.  6A 08         PUSH 8                                   ; /Length = 8
    004011CF  |.  68 7F344000   PUSH CrackMe_.0040347F                   ; |Destination = CrackMe_.0040347F
    004011D4  |.  E8 FB010000   CALL <JMP.&kernel32.RtlZeroMemory>       ; \RtlZeroMemory
    004011D9  |.  8D05 93354000 LEA EAX,DWORD PTR DS:[403593]            ;  试练码存放地址403593放在[EAX]
    004011DF  |.  83C0 08       ADD EAX,8                                ;  指向试练码第9位
    004011E2  |.  8A18          MOV BL,BYTE PTR DS:[EAX]                 ;  使BL等于试练码的第9位
    004011E4  |.  8D15 7F344000 LEA EDX,DWORD PTR DS:[40347F]
    004011EA  |.  881A          MOV BYTE PTR DS:[EDX],BL
    004011EC  |.  42            INC EDX
    004011ED  |.  83C0 09       ADD EAX,9                                ;  指向试练码的第18位,EAX原值为9
    004011F0  |.  8A18          MOV BL,BYTE PTR DS:[EAX]
    004011F2  |.  881A          MOV BYTE PTR DS:[EDX],BL
    004011F4  |.  E8 07FEFFFF   CALL CrackMe_.00401000
    004011F9  |.  8D1D 7F344000 LEA EBX,DWORD PTR DS:[40347F]            ;  注册码第9位与第18位合并在一起储存在EDX中
    004011FF  |.  E8 36FEFFFF   CALL CrackMe_.0040103A                   ;  注册码的第9位与第18位连接为一个整体,对整体做CRC32计算。
    00401204  |.  3D 65142C24   CMP EAX,242C1465                         ;  这里就知道第9和18位为什么是'-'了,呵呵
    00401209  |.  0F85 91010000 JNZ CrackMe_.004013A0                    ;  计算的结果等于0x242C1465?不等跳完
    0040120F  |.  6A 0A         PUSH 0A                                  ; /Length = A (10.)
    00401211  |.  8D45 EA       LEA EAX,DWORD PTR SS:[EBP-16]            ; |
    00401214  |.  50            PUSH EAX                                 ; |Destination
    00401215  |.  E8 BA010000   CALL <JMP.&kernel32.RtlZeroMemory>       ; \RtlZeroMemory
    0040121A  |.  6A 0A         PUSH 0A                                  ; /Length = A (10.)
    0040121C  |.  8D45 E0       LEA EAX,DWORD PTR SS:[EBP-20]            ; |
    0040121F  |.  50            PUSH EAX                                 ; |Destination
    00401220  |.  E8 AF010000   CALL <JMP.&kernel32.RtlZeroMemory>       ; \RtlZeroMemory
    00401225  |.  33C9          XOR ECX,ECX
    00401227  |.  8D05 93354000 LEA EAX,DWORD PTR DS:[403593]            ;  试练码
    0040122D  |>  8A1401        /MOV DL,BYTE PTR DS:[ECX+EAX]            ;  逐位取试练码ASCII码放在EAX低位
    00401230  |.  80FA 39       |CMP DL,39                               ;  与0x39(对应字符9的ASCII)比较
    00401233  |.  76 05         |JBE SHORT CrackMe_.0040123A             ;  小于等于就跳下来,我的是第一次是0x31('1'),所以跳
    00401235  |.  80FA 41       |CMP DL,41
    00401238  |.  72 0A         |JB SHORT CrackMe_.00401244
    0040123A  |>  80FA 30       |CMP DL,30                               ;  与0x30(对应字符0的ASCII)比较,
    0040123D  |.  72 05         |JB SHORT CrackMe_.00401244              ;  小于就跳,我的第一次是'1',就不跳了
    0040123F  |.  80FA 46       |CMP DL,46                               ;  与0x46(对应字符F的ASCII)比较
    00401242  |.  76 05         |JBE SHORT CrackMe_.00401249             ;  小于等于就跳下来,我的是第一次是0x31('1'),所以跳
    00401244  |>  E9 57010000   |JMP CrackMe_.004013A0
    00401249  |>  41            |INC ECX                                 ;  ECX计数器+1
    0040124A  |.  83F9 08       |CMP ECX,8                               ;  取注册码的前8位(注册码第一部分)
    0040124D  |.^ 75 DE         \JNZ SHORT CrackMe_.0040122D             ;  上面两句实现了只对试练码的前8位比较
    0040124F  |.  33C9          XOR ECX,ECX
    00401251  |.  33DB          XOR EBX,EBX
    00401253  |.  8D75 EA       LEA ESI,DWORD PTR SS:[EBP-16]
    00401256  |>  C1E3 04       /SHL EBX,4                               ;  左移4位,相当于乘10
    00401259  |.  8A1401        |MOV DL,BYTE PTR DS:[ECX+EAX]            ;  逐位取注册码第一部分(即前8位)
    0040125C  |.  8816          |MOV BYTE PTR DS:[ESI],DL
    0040125E  |.  80FA 41       |CMP DL,41                               ;  与0x41(对应字符A的ASCII)比较,
    00401261  |.  72 0A         |JB SHORT CrackMe_.0040126D              ;  小于就跳,我的第一位是0x31,就跳了
    00401263  |.  80FA 46       |CMP DL,46
    00401266  |.  77 05         |JA SHORT CrackMe_.0040126D
    00401268  |.  80EA 37       |SUB DL,37
    0040126B  |.  EB 03         |JMP SHORT CrackMe_.00401270
    0040126D  |>  80EA 30       |SUB DL,30
    00401270  |>  80E2 0F       |AND DL,0F
    00401273  |.  0ADA          |OR BL,DL
    00401275  |.  46            |INC ESI
    00401276  |.  41            |INC ECX
    00401277  |.  83F9 08       |CMP ECX,8                               ;  这两句好眼熟,与前一循环作用相同,呵呵
    0040127A  |.  895D FC       |MOV DWORD PTR SS:[EBP-4],EBX
    0040127D  |.^ 75 D7         \JNZ SHORT CrackMe_.00401256             ;  将注册码的第一部分转换成对应的16进制
    0040127F  |.  E8 7CFDFFFF   CALL CrackMe_.00401000                   ;  运行到这里时可以看到EBX是转为16进制的前8位试练码
    00401284  |.  8D1D 8C344000 LEA EBX,DWORD PTR DS:[40348C]            ;  用户名的存放地址[40348C]放在EBX
    0040128A  |.  E8 ABFDFFFF   CALL CrackMe_.0040103A                   ;  开始对用户名作CRC32计算
    0040128F  |.  3945 FC       CMP DWORD PTR SS:[EBP-4],EAX             ;  对用户名CRC32计算的结果与试练码的前8位比较,不等就跳完
    00401292      0F85 08010000 JNZ CrackMe_.004013A0                    ;  真码第一部分就是CRC32(用户名)。我的用户名是agang,CRC32后是A53C759F
    00401298  |.  33C9          XOR ECX,ECX
    0040129A  |.  8D05 93354000 LEA EAX,DWORD PTR DS:[403593]            ;  试练码又呼出来,准备第二部分的计算了
    004012A0  |.  83C0 09       ADD EAX,9
    004012A3  |>  8A1401        /MOV DL,BYTE PTR DS:[ECX+EAX]            ;  从这里开始。。。
    004012A6  |.  80FA 39       |CMP DL,39
    004012A9  |.  76 05         |JBE SHORT CrackMe_.004012B0
    004012AB  |.  80FA 41       |CMP DL,41
    004012AE  |.  72 0A         |JB SHORT CrackMe_.004012BA
    004012B0  |>  80FA 30       |CMP DL,30
    004012B3  |.  72 05         |JB SHORT CrackMe_.004012BA
    004012B5  |.  80FA 46       |CMP DL,46
    004012B8  |.  76 05         |JBE SHORT CrackMe_.004012BF
    004012BA  |>  E9 E1000000   |JMP CrackMe_.004013A0
    004012BF  |>  41            |INC ECX
    004012C0  |.  83F9 08       |CMP ECX,8
    004012C3  |.^ 75 DE         \JNZ SHORT CrackMe_.004012A3
    004012C5  |.  33C9          XOR ECX,ECX                              ;       逍遥兄称上述循环为'格式检验',说得够精练的,我等菜菜要慢慢分析才能看出来
    004012C7  |.  33DB          XOR EBX,EBX
    004012C9  |.  8D75 E0       LEA ESI,DWORD PTR SS:[EBP-20]
    004012CC  |>  C1E3 04       /SHL EBX,4
    004012CF  |.  8A1401        |MOV DL,BYTE PTR DS:[ECX+EAX]
    004012D2  |.  8816          |MOV BYTE PTR DS:[ESI],DL
    004012D4  |.  8810          |MOV BYTE PTR DS:[EAX],DL
    004012D6  |.  80FA 41       |CMP DL,41
    004012D9  |.  72 0A         |JB SHORT CrackMe_.004012E5
    004012DB  |.  80FA 46       |CMP DL,46
    004012DE  |.  77 05         |JA SHORT CrackMe_.004012E5
    004012E0  |.  80EA 37       |SUB DL,37
    004012E3  |.  EB 03         |JMP SHORT CrackMe_.004012E8
    004012E5  |>  80EA 30       |SUB DL,30
    004012E8  |>  80E2 0F       |AND DL,0F
    004012EB  |.  0ADA          |OR BL,DL
    004012ED  |.  46            |INC ESI
    004012EE  |.  41            |INC ECX
    004012EF  |.  83F9 08       |CMP ECX,8
    004012F2  |.  895D F8       |MOV DWORD PTR SS:[EBP-8],EBX
    004012F5  |.^ 75 D5         \JNZ SHORT CrackMe_.004012CC             ;       以上循环将试练第二部分转为16进制,记为S1吧
    004012F7  |.  E8 04FDFFFF   CALL CrackMe_.00401000                   ;  初始化CRC32数据表
    004012FC  |.  8D5D EA       LEA EBX,DWORD PTR SS:[EBP-16]            ;  取出试练码前8位
    004012FF  |.  E8 36FDFFFF   CALL CrackMe_.0040103A                   ;  对注册码的前8位进行CRC32计算
    00401304  |.  3945 F8       CMP DWORD PTR SS:[EBP-8],EAX             ;  S1与CRC32(CRC32(agang))[也就是真码第一部分的CRC32结果]比较,
    00401307  |.  0F85 93000000 JNZ CrackMe_.004013A0                    ;  注册码的第一部分CRC32计算后的值即为注册码的第2部分
    0040130D  |.  E8 EEFCFFFF   CALL CrackMe_.00401000                   ;  又是初始化CRC32数据表
    00401312  |.  8D5D E0       LEA EBX,DWORD PTR SS:[EBP-20]            ;  取真码的第二部分,就是刚刚算出来那个。我的是39944E09
    00401315  |.  E8 20FDFFFF   CALL CrackMe_.0040103A                   ;  对其再进行CRC32计算,我这里的结果是AD14BD73
    0040131A  |.  8945 F8       MOV DWORD PTR SS:[EBP-8],EAX
    0040131D  |.  33C9          XOR ECX,ECX
    0040131F  |.  8D05 93354000 LEA EAX,DWORD PTR DS:[403593]
    00401325  |.  83C0 12       ADD EAX,12                               ;  从试练码的第19位开始取值(取注册码的第3部分)
    00401328  |>  8A1401        /MOV DL,BYTE PTR DS:[ECX+EAX]
    0040132B  |.  80FA 39       |CMP DL,39
    0040132E  |.  76 05         |JBE SHORT CrackMe_.00401335
    00401330  |.  80FA 41       |CMP DL,41
    00401333  |.  72 0A         |JB SHORT CrackMe_.0040133F
    00401335  |>  80FA 30       |CMP DL,30
    00401338  |.  72 05         |JB SHORT CrackMe_.0040133F
    0040133A  |.  80FA 46       |CMP DL,46
    0040133D  |.  76 02         |JBE SHORT CrackMe_.00401341
    0040133F  |>  EB 5F         |JMP SHORT CrackMe_.004013A0
    00401341  |>  41            |INC ECX
    00401342  |.  83F9 08       |CMP ECX,8
    00401345  |.^ 75 E1         \JNZ SHORT CrackMe_.00401328             ;  格式验证,再多说也没意义了,呵呵
    00401347  |.  33C9          XOR ECX,ECX
    00401349  |.  33DB          XOR EBX,EBX
    0040134B  |>  C1E3 04       /SHL EBX,4
    0040134E  |.  8A1401        |MOV DL,BYTE PTR DS:[ECX+EAX]
    00401351  |.  8810          |MOV BYTE PTR DS:[EAX],DL
    00401353  |.  80FA 41       |CMP DL,41
    00401356  |.  72 0A         |JB SHORT CrackMe_.00401362
    00401358  |.  80FA 46       |CMP DL,46
    0040135B  |.  77 05         |JA SHORT CrackMe_.00401362
    0040135D  |.  80EA 37       |SUB DL,37
    00401360  |.  EB 03         |JMP SHORT CrackMe_.00401365
    00401362  |>  80EA 30       |SUB DL,30
    00401365  |>  80E2 0F       |AND DL,0F
    00401368  |.  0ADA          |OR BL,DL
    0040136A  |.  41            |INC ECX
    0040136B  |.  83F9 08       |CMP ECX,8
    0040136E  |.  895D F4       |MOV DWORD PTR SS:[EBP-C],EBX
    00401371  |.^ 75 D8         \JNZ SHORT CrackMe_.0040134B             ;  转为16进制
    00401373  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]             ;  [EBP-4]里是A53C759F
    00401376  |.  3345 F8       XOR EAX,DWORD PTR SS:[EBP-8]             ;  [EBP-8]是真码第二部分再作CRC32计算的结果,与A53C759F异或
    00401379  |.  3B45 F4       CMP EAX,DWORD PTR SS:[EBP-C]             ;  我这里的结果是0828C8EC,[EBP-C]存的是试练码第三部分,两者比较
    0040137C      75 22         JNZ SHORT CrackMe_.004013A0
    0040137E  |.  68 D2204000   PUSH CrackMe_.004020D2                   ; /good job, man!
    00401383  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
    00401386  |.  E8 8B000000   CALL <JMP.&user32.SetWindowTextA>        ; \SetWindowTextA
    0040138B  |.  68 EE030000   PUSH 3EE                                 ; /ControlID = 3EE (1006.)
    00401390  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
    00401393  |.  E8 54000000   CALL <JMP.&user32.GetDlgItem>            ; \GetDlgItem
    00401398  |.  6A 00         PUSH 0                                   ; /Enable = FALSE
    0040139A  |.  50            PUSH EAX                                 ; |hWnd
    0040139B  |.  E8 40000000   CALL <JMP.&user32.EnableWindow>          ; \EnableWindow
    004013A0  |>  33C0          XOR EAX,EAX

    --------------------逍遥兄的算法总结-------------------
      1)注册码必须为26位,第9位与第18位必须是:- 
      注册码的形式为12345678-01234567-90123456
      2)将注册名进行CRC32计算,将注册码的第1部分转换成对应的16进制。两个值必须相等
      3)将注册码的第1部分进行CRC32计算(设为A),将注册码的第2部分转换成对应的16进制。两个值必须相等
      4)将注册码的第2部分进行CRC32计算(设为B)。
      5)将A,B做XOR运算,将注册码的第3部分转换成对应的16进制。两个值必须相等
      即。注册码
      第一部分:CRC(注册名)
      第二部分:CRC(注册码第一部分)
      第三部分:XOR [  第一部分,CRC(第二部分)]
    ------------------------------------------------------------
    我的试练信息说明
    用户名:agang
    试练码:12345678-abcdefgh-98765432
    真  码:A53C759F-39944E09-0828C8EC


    此CRACKME分三部分对注册码检验,建议采用逐步替换的方式进行调试。
    即:用户名:agang,
       注册码这样逐步替换:
        第一次:12345678-abcdefgh-98765432;
        第二次:A53C759F-abcdefgh-98765432
        第三次:A53C759F-39944E09-98765432
        第四次:A53C759F-39944E09-0828C8EC

    这样可以清晰的看到逍遥兄算法分析的结果,
        第一部分:CRC(注册名)------------------------我的是CRC32(agang),结果是A53C759F(真码的第一部分)
      第二部分:CRC(注册码第一部分)-----------------我的是CRC32(A53C759F),结果是39944E09(真码的第二部分)
      第三部分:XOR [  第一部分,CRC(第二部分)]----我的是XOR(A53C759F,CRC32(39944E09)),结果是0828C8EC(真码的第三部分)


    最后有两个地方想说一下:
    1、连接符'-'的穷举法问题。
    此crackme的第9位和第18位均要求是'-',其中在
    004011F9 |. 8D1D 7F344000 LEA EBX,DWORD PTR DS:[40347F];处,
    把注册码第9位与第18位作为一个整体,也就是'--',再对它进行CRC32计算。
    这里我在想,当我们只有CRC32结果,要对其逆推并穷举出原字符串是多大的工程啊?
    逍遥兄是不是应用了社会工程学原理呀?
    要不就是爆CRC32原码的专用工具(像MD5爆破一样)?如果是,请兄弟们不要金屋藏娇了,拿出来大家共享下吧,在下先谢过了。。。
    2、提示成功窗口的问题。
    我按照逍遥兄的分析,得出自己的正确注册码并载入OD。当第三部分验证结束后,我以为会弹出提示成功的窗口信息,所以一直F8,就等着听响[XP的系统声音],过了好久,仍不见动静,反而又跳到不知道是什么地方。我以为是我的注册码不对,遂关掉OD,直接运行软件注册。
    这才明白了,原来我们在OD中超级字符串找到的'GOOD JOB, MAN!'并不是提示窗口,而是标题栏的信息。也就是说注册成功后,软件会把标题栏原来的信息'Coded by [HappyTown]'改成为'GOOD JOB ,MAN!',并且设置Check按钮不可用。
    这里我想说的是,Crackme作者HappyTown兄弟的思路,非常适合应用到实际。防止我等菜鸟上来就是窗口拦截断点打到入手处。如果字符再加密,恐怕我等菜辈下断都成问题了。必竟我等菜菜还是占多数嘛!呵呵

    agang好啰嗦,谢谢兄弟能坚持看这里。

    CrackMe_0013.rar

    14.13 KB, 下载次数: 13, 下载积分: 飘云币 -2 枚

    这里有crackme和我的.udd

    PYG19周年生日快乐!

    该用户从未签到

    发表于 2006-8-11 21:32:10 | 显示全部楼层
    好文,学习了/:D!!!
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-6-17 14:50
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2006-8-11 23:47:50 | 显示全部楼层
    兄弟所讲的凭经验,道上也叫社会工程学,呵呵

    作者都说了是CRC32,其结果是8位,共分三组比较,再加两个连接符,这也是经验吧,
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-1-3 23:56:30 | 显示全部楼层
    /:D 学习,社会工程学,呵呵~~穷举可是个工程了
    PYG19周年生日快乐!
  • TA的每日心情
    无聊
    2020-4-10 17:02
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2007-1-4 14:23:10 | 显示全部楼层
    agang  好像是黑道高手!:lol: :lol:

    无意中见过!
    PYG19周年生日快乐!
  • TA的每日心情
    无聊
    2017-8-31 14:43
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2007-1-4 15:49:46 | 显示全部楼层
    看的不是很懂,,,,我不会算法的哦,,,呵呵。。。。努力中
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2017-6-11 12:16
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2007-1-4 19:40:12 | 显示全部楼层
    加密算法
    ........
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2023-10-11 00:31
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2007-1-4 20:34:13 | 显示全部楼层
    好呀,很详细!
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-1-11 15:52:03 | 显示全部楼层
    学习一下,共同进步:handshake
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-6-17 14:50
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2007-1-11 23:16:54 | 显示全部楼层
    属于自己的时间越来越少了,每天睁眼忙到现在才有空触网,急得要死.

    TO书生兄弟:你在PYG讲话很有影响力的,在PYG我是密界菜菜,其余的暂且不谈.哈哈
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表