首页
社区
课程
招聘
[原创]超~详细的CrackMe算法分析
发表于: 2020-3-21 21:45 5376

[原创]超~详细的CrackMe算法分析

2020-3-21 21:45
5376

前言:这是来自看雪的一道题,年代久远。4nil前辈留下的一个crakeme。在此给出个人写得详细的,可以使新手从汇编到高级语言一一对应上的解析。希望不管是大佬还是新手,都可以来“刁难”我,提出问题,让我看看自己还有哪些不足,我会尽力回答的。

这是无壳版本(壳本身不难)。这道题的亮点在于:1.有多个导致挂的判断。2.无错误提示。3.有中间注册码,循环渐进的一个crackme。


爆破过程如下:

载入后输入name,Serial -> 鼠标右键 -> 中文搜索引擎 -> 搜索ASCII -> 发现” SHiT ... you entered the correct serial!”,下断点->往前翻找到004015A1的push下断 -> 从004015A1的push 一路F8下来,会发现0040162D的je short unpacked.00401682是关键跳转,

双击改变Z的值


继续F8,会弹窗


->在  0040162D 鼠标右键 -> 二进制用nop填充 -> 鼠标右键 -> 复制到可执行文件 -> 所有修改 -> 是 -> 鼠标右键 -> 保存文件,就可以了。




[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 3
支持
分享
最新回复 (5)
雪    币: 603
活跃值: (381)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
2
我第一行一行的代码,删不掉,另外希望有人对我的格式,写法提出更多意见。谢谢!
2020-3-21 21:56
0
雪    币: 260
活跃值: (345)
能力值: ( LV4,RANK:49 )
在线值:
发帖
回帖
粉丝
3
感谢楼主,写的真的很详细
2020-3-22 00:03
0
雪    币:
活跃值: (56)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
4

有两点说一下

1.这段指令实际是对name长度做了限制,只能在3-8之间

0040156A  |.  81FF 00230000 cmp     edi, 2300
00401570  |.  7F 08         jg      short 0040157A
00401572  |.  81FF 90010000 cmp     edi, 190
00401578  |.  7D 04         jge     short 0040157E

2.这段指令应该是编译器优化过的,实际为 esi = edx - esi - 1 + 0x14D

0040141B  |.  83F6 FF       |xor     esi, FFFFFFFF                   ;  esi = (SUM*(i-1))^0xFFFFFFFF
0040141E  |.  8DB432 4D0100>|lea     esi, dword ptr [edx+esi+14D]    ;  esi = edx + esi + 0x14D

另外,附上我写的注册机

#include<stdio.h>
#include<math.h>
#define OFFSET(i) (3*(i)-1<0? 0:3*(i)-1+0x41)
int main(int argc,char**argv)
{
  char name[20],key[20];
  int len,SUM=0;
  printf("name:");
  if(argc!=2)
    scanf("%[^\n]",name);
  else
    sprintf(name,"%s",argv[1]);
  printf("%s\n",name);
  len=strlen(name);
  if(len<3 || len >9)
    return 0;
  for(int i=0;i<len;i++)
    SUM+=name[i];
  for(int i=0;i<len;i++)
    {
      name[i]=((((name[i]^OFFSET(i))-SUM*(i-1)-1+0x14D+name[i]*(i+3)*strlen(name))%10+0x30^0xADAC)*(i+2))%10+0x30;
    }
  sprintf(key,"%d%s-%d",6,name,len*SUM%0x64+0x30);
  len=strlen(key);
  for(int i=1;i<len;i++)
    {
      key[i]=(key[i]^0x20)%0xA+0x30;
    }
  printf("key:%s",key);
}
最后于 2020-3-23 12:27 被zzhwaxy编辑 ,原因:
2020-3-23 12:26
0
雪    币: 19
活跃值: (341)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
楼主跟楼上的都挺厉害的。
2020-3-23 13:44
0
雪    币: 603
活跃值: (381)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
6
zzhwaxy # 有两点说一下 1.这段指令实际是对name长度做了限制,只能在3-8之间 ``` 0040156A |. 81FF 00230000 cmp edi, 2300 0040157 ...
所言极是,谢谢提醒。
2020-3-23 16:30
0
游客
登录 | 注册 方可回帖
返回