By:刺刀 发表于 2016-9-11 14:31

分析一个CrackMe, 爆破及算法分析

本帖最后由 By:刺刀 于 2016-9-11 16:14 编辑

起因是和朋友聊天时 发我一个CrackMe程序让我试试! 也是一个很简单的CrackMe.软件截图:


寻找关键call的话:
输入假码, 发现弹出一个信息框
下断
bp MessageBoxA/W
也可以直接字符串查找, 不过当时破解的时候忘记了.....使用回溯大法, 在call入口处下断

以下就是程序的关键调用处,

文笔不好,请见谅!
大神莫笑

0040137E/$8B7424 04   mov   esi,dword ptr ss:       ;算法call
00401382|.56            push    esi                              ;CRACKME.0040218E
00401383|>8A06          /mov   al,byte ptr ds:
00401385|.84C0          |test    al,al
00401387|.74 13         |je      short CRACKME.0040139C          ;过滤非法字符
00401389|.3C 41         |cmp   al,0x41
0040138B|.72 1F         |jb      short CRACKME.004013AC          ;用户名为非法字符,跳转到MessageBox
0040138D|.3C 5A         |cmp   al,0x5A
0040138F|.73 03         |jnb   short CRACKME.00401394          ;跳转到小写转换大写call
00401391|.46            |inc   esi                           ;CRACKME.0040218E
00401392|.^ EB EF         |jmp   short CRACKME.00401383
00401394|>E8 39000000   |call    CRACKME.004013D2
00401399|.46            |inc   esi                           ;CRACKME.0040218E
0040139A|.^ EB E7         \jmp   short CRACKME.00401383
0040139C|>5E            pop   esi                              ;user32.756F6899
0040139D|.E8 20000000   call    CRACKME.004013C2               ;用户名累加call
004013A2|.81F7 78560000 xor   edi,0x5678                     ;用户名累加call 执行完毕,将计算结果异或,其结果为Key最终结果
004013A8|.8BC7          mov   eax,edi
004013AA|.EB 15         jmp   short CRACKME.004013C1
004013AC|>5E            pop   esi                              ;user32.756F6899
004013AD|.6A 30         push    0x30                           ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004013AF|.68 60214000   push    CRACKME.00402160               ; |No luck!
004013B4|.68 69214000   push    CRACKME.00402169               ; |No luck there, mate!
004013B9|.FF75 08       push                            ; |hOwner = 0018FED0
004013BC|.E8 79000000   call    <jmp.&USER32.MessageBoxA>      ; \MessageBoxA
004013C1\>C3            retn



004013D2/$2C 20         sub   al,0x20                        ;小写转换为大写
004013D4|.8806          mov   byte ptr ds:,al
004013D6\.C3            retn



004013C2/$33FF          xor   edi,edi                        ;用户名累加call
004013C4|.33DB          xor   ebx,ebx
004013C6|>8A1E          /mov   bl,byte ptr ds:
004013C8|.84DB          |test    bl,bl
004013CA|.74 05         |je      short CRACKME.004013D1
004013CC|.03FB          |add   edi,ebx                         ;累加用户名并将计算结果存放在edi中.
004013CE|.46            |inc   esi                           ;CRACKME.0040218E
004013CF|.^ EB F5         \jmp   short CRACKME.004013C6
004013D1\>C3            retn

以下为 验证call

004013D8/$33C0          xor   eax,eax                        ;CharToInt
004013DA|.33FF          xor   edi,edi
004013DC|.33DB          xor   ebx,ebx
004013DE|.8B7424 04   mov   esi,dword ptr ss:       ;CRACKME.0040217E
004013E2|>B0 0A         /mov   al,0xA
004013E4|.8A1E          |mov   bl,byte ptr ds:
004013E6|.84DB          |test    bl,bl
004013E8|.74 0B         |je      short CRACKME.004013F5
004013EA|.80EB 30       |sub   bl,0x30
004013ED|.0FAFF8      |imul    edi,eax
004013F0|.03FB          |add   edi,ebx
004013F2|.46            |inc   esi                           ;CRACKME.00402192
004013F3|.^ EB ED         \jmp   short CRACKME.004013E2
004013F5|>81F7 34120000 xor   edi,0x1234                     ;将CharToInt后的结果,异或
004013FB|.8BDF          mov   ebx,edi
004013FD\.C3            retn



请各位爷看在幸苦的份上, 有什么不好的地方请点评一下下, 这样才能知道不足之处
算法分析成品:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

int main (int argc, char *argv[]) {
      if (argc < 2) {
                printf("Help: \n%s: Name\n", argv);
                exit(0);
      }
      char *str = argv;
      int key = 0;
      for (int i = 0; strlen(argv) > i; i++) {
                key += (*(str++) - 32);
      }
      printf("Key: %d\n", key ^ 0x5678 ^ 0x1234);
      _getch();
      return 0;
}

这个是验证算法

#include <stdio.h>
#include <string.h>
#include <conio.h>

int main() {
      int a = 10, b = 0, c = 0;
      char *str = "17736";
      for (char *i = str; ; i++) {
                if (!*i) {
                        break;
                }
                char temp = *(str++);
                b = *i - 0x30;
                c = b + a * c;
      }
      c = c ^ 0x1234;
      printf("%d\n", c);
      _getch();
}

CrackMe 下载:








KaQqi 发表于 2016-9-11 14:48

算法不是很难,基本可以一次推出来。如果楼主能把软件截图以及关键call寻找的过程放上来就更好了

By:刺刀 发表于 2016-9-11 14:50

cqr2287 发表于 2016-9-11 14:48
算法不是很难,基本可以一次推出来。如果楼主能把软件截图以及关键call寻找的过程放上来就更好了

我试试 主要是文笔不太好

x518255 发表于 2016-9-11 15:03

160个CRACKME 之33

miaoyu220 发表于 2016-9-13 15:07

感谢分享,学习了。

footbal1 发表于 2016-9-21 19:36

感谢 分享!

耶稣 发表于 2016-10-5 20:06

楼主这CM 是学破解论坛学徒的算码教程联系软件醉了你这朋友   不想说了

jmuxiaolu 发表于 2016-10-7 01:56

耶稣 发表于 2016-10-5 20:06
楼主这CM 是学破解论坛学徒的算码教程联系软件醉了你这朋友   不想说了

确实不是很难,找到存放Name,Serial的位置,然后下个内存短点,直接运行。。。然后就到了算法的位置了{:1_912:}
页: [1]
查看完整版本: 分析一个CrackMe, 爆破及算法分析