以新手的视角做Crackme006-aLoNg3x.1

前言:

        刚入逆向,想着做一些Crackme练练手,也记录一下做的时候自己是怎么想的。

1. 观察程序

首先运行程序,观察程序的布局。三个按钮,其中Ok是不可点击的。Nome和Codice应该就是用户名和注册码。

点About Help看看,大概意思就是这个Crackme破解的方法是让OK和Cancella按钮消失以看到一个logo。后续的弹窗意思就是有问题邮件他。

OK不管这个弹窗,弹窗应该只是起到提示的功能。对于破解没什么用。

 点击Cancella按钮,发现这个按钮是让注册码的值改为0的。

2. 查壳

使用die分析程序。32位系统,Delphi写的,无壳。

 3. 分析

将程序拖入IDR中,IDR是一款用于分析Delphi程序中,控件以及对应事件的软件。

 可以看到两个按钮都有一个点击事件。因为OK处于不可点击状态。所以先分析Cancella看看。

找到Cancella的点击事件的地址并记下来。push ebp:把栈底指针入栈,一般代表了函数开始。

在把程序拖入x86dbg进行分析。在push ebp处下断点。单步运行看值。不知道为啥我使用SwissArmyKnife不能导入Map文件。只好对着call的地址进入IDA中查找。然后在dbg中添加标签,便于后续分析。

00442AFC | 8955 F8                  | mov dword ptr ss:[ebp-8],edx            | edx = 前面经过strtoint得到的数
00442AFF | 8945 FC                  | mov dword ptr ss:[ebp-4],eax            | [ebp-4] = ID
00442B02 | 8B45 FC                  | mov eax,dword ptr ss:[ebp-4]            | [ebp-4]:"abcde"
00442B05 | E8 DE10FCFF              | call <along3x.1.字符串引用计数(不管)>            |
00442B0A | 33C0                     | xor eax,eax                             |
00442B0C | 55                       | push ebp                                |
00442B0D | 68 902B4400              | push along3x.1.442B90                   |
00442B12 | 64:FF30                  | push dword ptr fs:[eax]                 |
00442B15 | 64:8920                  | mov dword ptr fs:[eax],esp              |
00442B18 | 8B45 FC                  | mov eax,dword ptr ss:[ebp-4]            | [ebp-4]:&"斢@"
00442B1B | E8 140FFCFF              | call <along3x.1.strLength>              | 返回eax = 5
00442B20 | 83F8 05                  | cmp eax,5                               | 小于5就jmp走了
00442B23 | 7E 53                    | jle along3x.1.442B78                    |
00442B25 | 8B45 FC                  | mov eax,dword ptr ss:[ebp-4]            | [ebp-4] = ID
00442B28 | 0FB640 04                | movzx eax,byte ptr ds:[eax+4]           | eax+4 = "ef" | eax = ‘e’倒数第二位
00442B2C | B9 07000000              | mov ecx,7                               |
00442B31 | 33D2                     | xor edx,edx                             |
00442B33 | F7F1                     | div ecx                                 | 除以7
00442B35 | 8BC2                     | mov eax,edx                             | 取余数
00442B37 | 83C0 02                  | add eax,2                               | 余数+2
00442B3A | E8 E1FEFFFF              | call <along3x.1.sub_442A20>             | 还没进去看
00442B3F | 8BF0                     | mov esi,eax                             | eax = 'x' = 78
00442B41 | 33DB                     | xor ebx,ebx                             |
00442B43 | 8B45 FC                  | mov eax,dword ptr ss:[ebp-4]            | [ebp-4] = "abcdef"
00442B46 | E8 E90EFCFF              | call <along3x.1.strLength>              |
00442B4B | 85C0                     | test eax,eax                            |
00442B4D | 7E 16                    | jle along3x.1.442B65                    |
00442B4F | BA 01000000              | mov edx,1                               |
00442B54 | 8B4D FC                  | mov ecx,dword ptr ss:[ebp-4]            | [ebp-4]:&"斢@"
00442B57 | 0FB64C11 FF              | movzx ecx,byte ptr ds:[ecx+edx-1]       | 取ID第一位 | 第二位
00442B5C | 0FAFCE                   | imul ecx,esi                            | 第一位乘以'x'(0x78) = 0x2D78
00442B5F | 03D9                     | add ebx,ecx                             | ebx = 0 |乘的值累加起来
00442B61 | 42                       | inc edx                                 |
00442B62 | 48                       | dec eax                                 |
00442B63 | 75 EF                    | jne along3x.1.442B54                    |
00442B65 | 2B5D F8                  | sub ebx,dword ptr ss:[ebp-8]            | ebp-8是前面strtoint出来的数
00442B68 | 81FB 697A0000            | cmp ebx,7A69                            | 这里关键,不能跳转到eax清零的地方 这里让ebx = 7A69才能跳出去

ID大于5,取倒数第二位的asicc,除以7的余数加2,取出来为m(不是一个常数,是操作出来的数),计算前面m的阶乘为n,把每个数乘以n再累加。最后减去函数前算出来的strtoint(密码直接变成数字)得到的是7A69。才解开右边的按钮。

注册机如下:例如:abcdef:40303

    str = str(x)
    ascii = ord(str[-2])
    tmp = ascii % 7 + 2
    res = 0
    sum = 1
    for i in range(2, tmp + 1):
        sum = sum * i
    for i in range(len(str)):
        res += ord(str[i]) * sum
    num = res - int("7A69", base=16)
    print(num)

之后会发现,OK按钮可以点了。然后同样的步骤,找到OK的地址,下断点,接着分析。

00442C01 | 8D4430 FF                | lea eax,dword ptr ds:[eax+esi-1]        |
00442C05 | 50                       | push eax                                |
00442C06 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-8]            | eax = 密码
00442C09 | 0FB64430 FF              | movzx eax,byte ptr ds:[eax+esi-1]       | 取密码从最后一位开始往前取
00442C0E | F7E8                     | imul eax                                | 自乘
00442C10 | 0FBFC0                   | movsx eax,ax                            |
00442C13 | F7EE                     | imul esi                                | 乘以第几位
00442C15 | B9 19000000              | mov ecx,19                              |
00442C1A | 99                       | cdq                                     |
00442C1B | F7F9                     | idiv ecx                                | 除以0x19
00442C1D | 83C2 41                  | add edx,41                              | edx = 15+41|edx放的是余数
00442C20 | 58                       | pop eax                                 |
00442C21 | 8810                     | mov byte ptr ds:[eax],dl                | 把edx后两位移动到了eax上去
00442C23 | 4E                       | dec esi                                 |
00442C24 | 85F6                     | test esi,esi                            |
00442C26 | 75 D1                    | jne along3x.1.442BF9                    |
00442C28 | 8B45 F4                  | mov eax,dword ptr ss:[ebp-C]            | [ebp-C] = 密码
00442C2B | 8B55 FC                  | mov edx,dword ptr ss:[ebp-4]            | [ebp-4] = 用户名

逻辑是,判断密码大于5,然后从最后一位往前取。ASCII码值自乘,再乘以位数,除以0x19,余数加41获得其中一位

注册机如下:例如:123456:BADQUV

str = str(x)
sum = 0
res = []
for i in range(len(str) - 1, -1, -1):
   tmp = ord(str[i])
   sum = (tmp * tmp * (i + 1)) % int("19", base=16) + int("41", base=16)
   letter = chr(sum)
   res.append(letter)
result = "".join(res[::-1])
print(result)

4.验证        

                  

                 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_48067850

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值