• 哈萨克斯坦今年计划启动1吉瓦可再生能源项目 2019-06-16
  • 有理讲理,不要诬蔑。 2019-06-16
  • 新鲜出炉 三款高颜值个性SUV你准备好了么? 2019-06-15
  • 张育林代表推进泰兴经济社会发展高质量上台阶 2019-06-08
  • 光明日报副总编辑李春林 2019-06-07
  • 紫光阁中共中央国家机关工作委员会 2019-06-06
  • 国务院部署实施蓝天保卫战三年计划 2019-06-06
  • 最高法发布互联网公开审判流程信息规定 9月1日起施行 2019-06-02
  • 一周新疆新闻图片扫描(6.2——6.8) 2019-06-02
  • 海底捞回应侵犯音乐人林海著作权:已停止播放 2019-05-25
  • 十三届全国人大一次会议在北京闭幕 2019-05-19
  • 清明美食之青团:从祭祖供品到时令小吃 2019-05-19
  • 新华时评:美逆潮流而动,必将付出代价 2019-05-15
  • 非洲大叔都中暑了,高温津贴更应阶梯化 2019-05-15
  • 海南省委常委张韵声任宁夏回族自治区党委政法委书记 2019-05-08
  • 吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|新疆喜乐彩开奖介绍 www.sl-36.com

     找回密码
     注册[Register]

    QQ登录

    只需一步,快速开始

    搜索
    查看: 857|回复: 4
    上一主题 下一主题

    福利彩票快乐十分: [原创] 160个Crackme之023学习笔记

    [复制链接]
    跳转到指定楼层
    楼主
    海天一色001 发表于 2019-5-30 10:11 回帖奖励
    打开023,输入Name/Serial=“52pojie/1234567890”,程序界面如下:

    Status栏中仍然是错误提示,点击About按钮,弹出提示框:

    初步猜测这个程序可能是当Name文本框中每输入一个字符就进行运算后得到注册码,然后再与输入的Serial进行比较,结果输入到Status框中去。这个程序的关闭按钮和Alt+F4组合键都不管用,只能用右键点击弹出的菜单中选择“Alt+F4”这一项才能关闭,不知道怎么回事。
    先查壳,无壳,显示是ASM程序:

    第一步、爆破
    将Chafe.1.exe加载入OD中,习惯性地用智能搜索去查字符串,很轻松地得到了各类文本内容:

    双击004012CE这一行正确提示处来到CPU窗口:

    马上看到正确提示来源于上面一句je命令,跳过了错误提示,所以直接将je命令修改为jmp命令,
      
    存为可执行文件Chafe.1_jmp.exe,试运行一下,输入name后,在Serial框中刚输入“1”这个字符,下方的Status框中就出现了正确提示,说明爆破成功。

    第二步、追码
    撤消刚才爆破时的修改,然后上下观察代码,感觉ASM的代码确实是很短小,一会儿就翻完了。

    因为作者在About中说了不让爆破,要找到注册算法,所以仔细查看004012B6上面,004012B3处是比较命令,只有[eax]=0x10时,才能成功,所以继续向上分析,找到给eax赋值的语句:
    从00401239至00401322处应该是判断注册码的代码段,很自然地在段首00401239处下断,然后F9运行程序,不行,程序仍然是暂停状态,再多按几次,仍然是在这里暂停!
    不管它,先F8向下,可以走:
    从0040123F处看到注释的内容是Switch (cases 1..113),然后看指令,先是[eax]与0x10比较,再与0xF比较,再与0x1比较,均不能相等,再与0x113比较,必须相等,而下面又是要求[eax]=0x10这样才能正确,所以只有00401294处,这里的call可能就是赋值的关键call了。
    所以在寄存器窗口将Z标志位的0改为1,使00401292处的jnz short Chafe_1.004012E4指令不成立,可以到下一步去:
    到00401294处的call Chafe_1.00401453指令,F7跟入,F8单步,运行一遍后出来了,还是错误,找不到算法!不死心地F9了几次,还是不行。
      
    静下心来,回头去看,断点位置在自己认为的判断注册码算法的段首处,可能不是很合适,因为这个断点作用不大,在没有输入任何内容,没来得及给ds:[0x403166]/ ds:[0x403167] /ds:[0x403188]之类的地址进行赋值之前程序就被它中断了,造成[eax]=ds:[0x403166]=0,向下单步运行肯定不正确。所以要找到一个合适的断点来看看:
    从开始向下看,到00401076处,自动注释了“GetWindowTextA”,应该是得到输入的文本吧,在这里下断试一试:
    Ctrl+F2重载程序,F9运行,不知道怎么回事023程序窗口直接最大化显示,但还好能恢复到原窗口大小。
    输入name=“52pojie”,刚在Serial框中输入1个字符“1”时,程序中断到00401076处,此时GetWindowTextA的参数是Count=0x14(20),Buffer= Chafe_1.0040318C,hWnd = 00450750 (class='Edit',parent=01200766),[eax]=0x4;
    这个0040318C地址里是什么东西?在这里点右键,选择“数据窗口中跟随—立即数”,内存地址栏中马上显示出一串0来。
    F8单步,[eax]马上变成了0x7!此时地址栏里,0040318C地址变成了“52pojie”,刚输入的name,而[eax]=7,可能是[eax]=len(name)了。
    [Asm] 纯文本查看 复制代码
    00401063   .  8B25 A0314000 mov esp,dword ptr ds:[0x4031A0]
    00401069   .  6A 14         push 0x14                                ; /Count = 14 (20.)
    0040106B   .  68 8C314000   push Chafe_1.0040318C                    ; |Buffer = Chafe_1.0040318C=str(name)
    00401070   .  FF35 74314000 push dword ptr ds:[0x403174]             ; |hWnd = 00470750 (class='Edit',parent=01CD076E)
    00401076   .  E8 7D040000   call <jmp.&USER32.GetWindowTextA>        ; \GetWindowTextA
    0040107B   .  B9 14000000   mov ecx,0x14                             ;  [ecx]=0x14(20)
    00401080   .  2BC8          sub ecx,eax                              ;  [ecx]=0x14-[eax]=0xD(13)
    00401082   .  8DB8 8C314000 lea edi,dword ptr ds:[eax+0x40318C]
    00401088   >  C607 00       mov byte ptr ds:[edi],0x0
    0040108B   .  47            inc edi                                  ;  [edi]=[edi]+1
    0040108C   .  49            dec ecx                                  ;  [ecx]=[ecx]-1
    0040108D   .^ 75 F9         jnz short Chafe_1.00401088               ;  循环0x14-len(name)次,将后面全变成0
    0040108F   .  85C0          test eax,eax
    00401091   .  74 10         je short Chafe_1.004010A3                ;  name不能为0
    00401093   .  8005 66314000>add byte ptr ds:[0x403166],0x4           ;  给ds:[0x403166]赋值
    0040109A   .  C605 68314000>mov byte ptr ds:[0x403168],0x0           ;  ds:[0x403168]=0x0
    004010A1   .  EB 06         jmp short Chafe_1.004010A9
    004010A3   >  8825 66314000 mov byte ptr ds:[0x403166],ah
    004010A9   >  C9            leave
    004010AA   .  C3            retn                                     ;  返回到 00401299 (Chafe_1.00401299)

    多试了几个name,确定从00401069 到0040108D间代码的作用是取得name字符串并将其格式化,如果len(name)<20,则将name字符串后面用“0”填充成有20位的字符串;如果len(name)>=20则len(name)=19,然后后面用“0”填充,总之,最后一位字符是“0”。
    再向下到004010AA处,retn至401299地址,此时ds:[0x403166]=0x8,运行这一句后[eax]=0x8。继续向下又失败了。
    (后来的分析中慢慢发现这一段的用处,先格式化得到的字符串,再使ds:[0x403166]= ds:[0x403166]+0x4。)
    这样下断可能也不合适,没有找到程序的执行顺序。
    再到004012B3处看,由于在最后判断前要让[eax]= 0x10这样才能正确,而之前[eax]可以看到的值必须是0x113,那么只有00401294处call里会给[eax]赋值0x10这样才能正确。由于刚才在00401294处的call Chafe_1.00401453指令,F7跟入,F8单步运行一遍后没有找到算法,但在这个call出来后看到 [eax]= ds:[0x403166],那么找到ds:[0x403166]的赋值语句去试着看看:

    在00401299处右键选择“查找参考—地址常量”命令,立即看到有8处与ds:[0x403166]有关的指令,

    第一个是地址00401093处,一般来说会是首先运行这一句,所以先在这一行下断,并清除原来的断点,重新加载程序,F9运行,输入name=“52pojie”,刚在Serial框中输入1个字符“1”时,程序中断,猜测是每个输入的字符都要经过一定的运算,结果存入ds:[0x403166]中吧。(错误的猜测,在后来的分析过程中发现是Serial框输入时开始先对name框中的内容进行格式化,然后再判断name框的字符串是否全为0,不为0则ds:[0x403166]累加0x4。)继续F8向下,一直到004012B3处,此时[eax]=0x8,还是失败;
    干脆将所有为ds:[0x403166]赋值的6个地址都下断试一试:
    重载程序,F9运行,输入name=“52pojie”,没变化,刚在Serial框中输入1个字符“1”时,程序中断于00401093处,F9再向下中断于00401093,F9再向下中断于00401398,F9再向下中断于004012B3, F9再向下中断于004014B3仍是失败,说明应该在输入Serial前就已经算好了值,只在这里找ds:[0x403166]是远远不够的:



    Ctrl+F2重新开始,在内存0x403166处选择“断点—内存写入”,清除其他所有断点,F9运行,粘贴入name=“52pojie”,粘贴入serial=“1234567890”,
    此时程序中断于00401493处,
    F9运行,又中断于00401093处,
    F9运行,又中断于00401398处,
    F9运行,又中断于004014B3处,
    继续运行,又是00401493—00401093—00401398--004014B3的循环。这和给6个赋值语句都下断的结果差不多,只少了004012B3一处。
    结合以前的经验,程序运行顺序应该是:
    从00401000开始,到00401018处转到00401023处,再一直执行到004011F7处显示程序界面;
    输入name/serial后,在00401239段内利用时间控件进行循环:
    到00401294处运行call 00401453,再运行0040146F--0040149B处的代码段,返回到00401299处;
    运行计算判断后再call 00401453,再运行00401063—004010AA处的段,返回到00401299处;
    继续call 00401453,再运行00401361—004013A0处的段,返回到00401299处;
    再call 00401453,再运行0040149C-- 004014C1处的段,返回到00401299处;
    代码段的作用继续具体分析:
    (1)0040146F--0040149B处,作用是得到输入的注册码,为纯数字时ds:[0x403166]= ds:[0x403166]+0x4;
    [Asm] 纯文本查看 复制代码
    0040146F   .  8B25 A0314000 mov esp,dword ptr ds:[0x4031A0]
    00401475   .  6A 00         push 0x0                                 ; /IsSigned = FALSE
    00401477   .  8D45 FC       lea eax,dword ptr ss:[ebp-0x4]           ; |
    0040147A   .  50            push eax                                 ; |pSuccess = NULL
    0040147B   .  6A 64         push 0x64                                ; |ControlID = 64 (100.)
    0040147D   .  FF35 70314000 push dword ptr ds:[0x403170]             ; |hWnd = 008707B6 ('TEXme v1.0',class='TEXcls')
    00401483   .  E8 64000000   call <jmp.&USER32.GetDlgItemInt>         ; \[eax]=hex(Serial)
    00401488   .  A3 88314000   mov dword ptr ds:[0x403188],eax          ;  ds:[0x403188]=[eax]=0-0x9112478
    0040148D   .  837D FC 00    cmp dword ptr ss:[ebp-0x4],0x0
    00401491   .  74 07         je short Chafe_1.0040149A
    00401493   .  8005 66314000>add byte ptr ds:[0x403166],0x4           ;  此句未运行前ds:[0x403166]=0x8才能正确
    0040149A   >  C9            leave
    0040149B   .  C3            retn                                     ;  retn 00401299

    (2)00401063—004010AA处作用是格式化name字符串并给ds:[0x403166]赋值为ds:[0x403166]+0x4(前面已经分析过了);
    (3)00401361—004013A0处作用是循环16次对name字符串进行各种运算,使之最后的值为0-0x9112478=0xF6EEDB88,存入ds:[0x403188]中,并给ds:[0x403166]赋值为ds:[0x403166]+0x4;
    [Asm] 纯文本查看 复制代码
    00401361   .  8D3D 8C314000 lea edi,dword ptr ds:[0x40318C]          ;  [edi]=ds:[0x40318C](name),导入输入的name字符串
    00401367   .  0FBE05 683140>movsx eax,byte ptr ds:[0x403168]         ;  [eax]=ds:[0x403168]
    0040136E   .  03F8          add edi,eax                              ;  [edi]=[edi]+[eax]
    00401370   .  FE05 68314000 inc byte ptr ds:[0x403168]               ;  ds:[0x403168]=ds:[0x403168]+1
    00401376   .  A1 88314000   mov eax,dword ptr ds:[0x403188]          ;  [eax]=ds:[0x403188]
    0040137B   .  8B25 A0314000 mov esp,dword ptr ds:[0x4031A0]          ;  [esp]=ds:[0x4031A0]
    00401381   .  40            inc eax                                  ;  [eax]=[eax]+1
    00401382      FF05 88314000 inc dword ptr ds:[0x403188]              ;  ds:[0x403188]=ds:[0x403188]+1
    00401388   .  3307          xor eax,dword ptr ds:[edi]               ;  [eax]=[eax] xor ds:[edi]
    0040138A   .  A3 88314000   mov dword ptr ds:[0x403188],eax          ;  循环16次后ds:[0x403188]=[eax]=0-0x9112478=0xF6EEDB88才能正确
    0040138F   .  803D 68314000>cmp byte ptr ds:[0x403168],0x10          ;  ds:[0x403168]必等于0x10才行,上面代码需循环16次
    00401396   .  75 07         jnz short Chafe_1.0040139F
    00401398   .  8005 66314000>add byte ptr ds:[0x403166],0x4           ;  给ds:[0x403166]赋值处
    0040139F   >  C9            leave
    004013A0   .  C3            retn

    (4)0040149C-- 004014C1处判断计算后的注册码,如正确则给ds:[0x403166]赋值为ds:[0x403166]+0x4;
    [Asm] 纯文本查看 复制代码
    0040149C   .  A1 88314000   mov eax,dword ptr ds:[0x403188]          ;  ds:[0x403188]=0-0x9112478
    004014A1   .  05 78241109   add eax,0x9112478                        ;  [eax]=[eax]+0x9112478
    004014A6   .  85C0          test eax,eax                             ;  [eax]此时必等于0
    004014A8   .  75 09         jnz short Chafe_1.004014B3
    004014AA   .  8005 66314000>add byte ptr ds:[0x403166],0x4           ;  此句未运行前ds:[0x403166]必为0xC才能正确
    004014B1   .  EB 07         jmp short Chafe_1.004014BA
    004014B3   >  C605 66314000>mov byte ptr ds:[0x403166],0x0           ;  给ds:[0x403166]赋值为0,与上方互斥关系,肯定失败,所以必跳过
    004014BA   >  8B25 A0314000 mov esp,dword ptr ds:[0x4031A0]
    004014C0   .  C9            leave
    004014C1   .  C3            retn

    从最后正确的结果开始逆向分析,先确定正确的情况该怎么执行代码,一步步向上倒推,在注释栏加上自己的注释;从这四段代码的作用可以看出,程序中只要输入了name与纯数字的serial就可以让给ds:[0x403166]的值达到0xC(12),只要再将注册码填对就可以再给ds:[0x403166]赋值为ds:[0x403166]+0x4,使ds:[0x403166]=0x10(16),让程序界面的satus栏显示正确提示。所以注册码算法在第三段代码的位置:
    Ctrl+F2重新开始,在内存00401361处下断,清除其他所有断点,F9运行,粘贴入name=“52pojie”,粘贴入serial=“1234567890”,此时程序中断于00401361处,下方可以看到给edi导入输入的name(“52pojie”):

    为了找到如何对name字符串进行运算得到注册码的,F8单步进行下去,进行分析的结果,是ds:[0x403168]作为循环变量的寄存器,进行循环加1运算(00401370处),然后判断ds:[0x403168]是否为0x10,是则给ds:[0x403166]赋值为ds:[0x403166]+0x4;ds:[0x403188]首先存入的是输入的serial字符串“1234567890”的16进制数值0x499602D2,

    然后加1,变成0x499602D3;到00401388处,[eax]=[eax] xor ds:[edi],
      
    此时在信息窗口右键点击第一行的ds:[0040318C],选择“数据窗口中跟随地址”,可以看到内存地址中ASCII码为“52pojie”,而ds:[0040318C]的值是逆向取name字符串前4个字符的16进制ASCII数值:

    F8向下,到0040138A处,将结果0x26E630E6存入ds:[0x403188]中;
    继续向下,返回到00401299处,再到004012AB处,命令是retn 0x10,信息窗口中是“返回到 77D18734 (user32.77D18734)”,耐心地F8走,终于返回到程序领空00401207处,继续F8走:
    结果在00401230这里陷入了死循环,不断地跳回00401207处。在上面四段代码中没有循环语句,但是能做到循环,说明应该是利用时间控件做到的,我这样单步,时间控件估计不起作用,所以F9一下试试,程序马上又中断到00401361处了;
    第二次循环后,ds:[0x403168]=0x2,ds:[0x403188]= 0x4C8940D5;
    第三次循环后,ds:[0x403168]=0x3,ds:[0x403188]= 0x25E32FA6;
    。。。。。。
    第十五次循环后,ds:[0x403168]=0xF,ds:[0x403188]= 0x40EF49B3;
    第十六次循环后,ds:[0x403168]=0x10,ds:[0x403188]= 0x40EF49B4;
    而0x40EF49B4与0xF6EEDB88相差太大,肯定不是正确的结果,“1234567890”不是“52pojie”对应的注册码;继续向下,ds:[0x403166]=0xC,不是0x10,所以会失败。
    那么程序应该从第十六次循环倒推回去,将0xF6EEDB88减去1,再与name字符串从后向前每四位的hex值组成的数值xor,最后的结果就是注册码了。
    还是用VB编写注册机吧,下面是最简单的原理代码,到处是错误,主要是数值溢出错误,还有Name字符串长度过长过短等问题没在下面显示。
    Serial=0xF6EEDB88
    Namestr=text1.text
    For i=1 to 16
    Namehex=hex(mid(Namestr,i+3,1) & hex(mid(Namestr,i+2,1) & hex(mid(Namestr,i+1,1) & hex(mid(Namestr,i,1)
    Serial=Serial xor Namehex
    Serial=Serial-1
    Next
    Text2.text=Serial
    注册机已写好,程序源码均在内。一开始就是一个数值溢出问题,上网找了一大堆资料,借用了别人的大数运算代码,总是有问题所以又试着用VC编程,本想VB、VC都是微软同一公司的,界面什么的都相似,只是数值范围不一样,应该好学一些,结果是悲剧,死活不会用,找不到可视化编程的窗体等,还需要以后再重新学习;再就是用易语言了,也是费了九牛二虎之力,终于编写出了易语言的注册机,不知怎么回事,杀毒软件老杀。这两个注册机的源码和程序均放入压缩包里了,如不放心,易语言生成的注册机请勿使用。
    附件 023.zip (1018.49 KB, 下载次数: 8) ,含CM原程序、爆破后的程序、注册机、OD的调试文件等。
    百度链接是://pan.baidu.com/s/1skMkJY9密码: 86pm,160个CM、我已练习过的前23个crackme程序(不含012)都在里面。

    免费评分

    参与人数 1威望 +1 吾爱币 +7 热心值 +1 收起 理由
    Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

    查看全部评分

    发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

    沙发
    q130545 发表于 2019-5-30 10:26
    牛人!看的我一愣一愣的
    3#
    SnowRen 发表于 2019-5-30 10:27
    易语言写的程序老报毒算是基本操作,就是这个原因我都没在用易写程序
    4#
    Ars 发表于 2019-5-30 16:52
    标记一下,先看看好不好,谢谢楼主咯!
    5#
    吾爱、小江 发表于 2019-5-30 20:32
    写的太棒了,叔,特别详细,
    您需要登录后才可以回帖 登录 | 注册[Register]

    本版积分规则 警告:禁止回复与主题无关内容,违者重罚!

    快速回复 收藏帖子 返回列表 搜索

    RSS订阅|小黑屋|联系我们|新疆喜乐彩开奖介绍 ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

    GMT+8, 2019-6-17 03:16

    Powered by Discuz!

    © 2001-2017 Comsenz Inc.

    快速回复 新疆喜乐彩开奖介绍 返回列表
  • 哈萨克斯坦今年计划启动1吉瓦可再生能源项目 2019-06-16
  • 有理讲理,不要诬蔑。 2019-06-16
  • 新鲜出炉 三款高颜值个性SUV你准备好了么? 2019-06-15
  • 张育林代表推进泰兴经济社会发展高质量上台阶 2019-06-08
  • 光明日报副总编辑李春林 2019-06-07
  • 紫光阁中共中央国家机关工作委员会 2019-06-06
  • 国务院部署实施蓝天保卫战三年计划 2019-06-06
  • 最高法发布互联网公开审判流程信息规定 9月1日起施行 2019-06-02
  • 一周新疆新闻图片扫描(6.2——6.8) 2019-06-02
  • 海底捞回应侵犯音乐人林海著作权:已停止播放 2019-05-25
  • 十三届全国人大一次会议在北京闭幕 2019-05-19
  • 清明美食之青团:从祭祖供品到时令小吃 2019-05-19
  • 新华时评:美逆潮流而动,必将付出代价 2019-05-15
  • 非洲大叔都中暑了,高温津贴更应阶梯化 2019-05-15
  • 海南省委常委张韵声任宁夏回族自治区党委政法委书记 2019-05-08