首页
社区
课程
招聘
[原创]从破解到SMC补丁制作详解
发表于: 2012-4-4 22:14 8439

[原创]从破解到SMC补丁制作详解

2012-4-4 22:14
8439
【文章标题】: 从破解到SMC补丁制作详解
【文章作者】: BeyondMe
【作者邮箱】: futuring@126.com
【作者主页】: http://hi.baidu.com/beyond0769
【软件名称】: 向明单词连连看 2012 Build 3180
【下载地址】: http://www.skycn.com/soft/23152.html
【加壳方式】: ASPack
【保护方式】: 序列号
【编写语言】: BC++
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  本文纯粹从SMC补丁制作角度来分析这个软件,没有任何商业目的。
  
  SMC补丁要达到的效果:
  1、使“关于”对话框的中已注册用户名为 BeyondMe@UPK.cn,并去掉所有“未注册”或Unregister字样
  2、真正实现已经注册效果,无功能限制。
  
  要制作SMC补丁,首先得清楚要对源代码哪些部分进行补丁。所以首先还是进行脱壳,方便分析。这一步略过。
  
  脱壳后OD载入,简单分析一下算法流程:
  
  第一步:搞定“关于”对话框的注册标志:
  在未注册时,显示“这个产品注册给了:Unregister”
  ASCII查找字符串,关注 未注册 字样,来到处理 注册与未注册过程  
  
00404E30 /$ 55 push ebp ; 检测注册过程
00404E31 |. 8BEC mov ebp,esp
00404E33 |. 83C4 B8 add esp,-0x48
00404E36 |. B8 10B64200 mov eax,Un_llk.0042B610
00404E3B |. 53 push ebx
00404E3C |. 56 push esi ; Un_llk.0042A4F9
00404E3D |. 57 push edi
00404E3E |. E8 11FA0000 call Un_llk.00414854
00404E43 |. BE E8A44200 mov esi,Un_llk.0042A4E8
00404E48 |. 8D7D B8 lea edi,[local.18] ; 注册Local.18变量将保存解密后的用户名
00404E4B |. B9 04000000 mov ecx,0x4
00404E50 |. F3:A5 rep movs dword ptr es:[edi],dword pt>; 初始化Local.18变量为空
00404E52 |. A4 movs byte ptr es:[edi],byte ptr ds:[>
00404E53 |. EB 10 jmp short Un_llk.00404E65
00404E55 | 57 db 57 ; CHAR 'W'
00404E56 | 4C db 4C ; CHAR 'L'
00404E57 | 20 db 20 ; CHAR ' '
00404E58 | 20 db 20 ; CHAR ' '
00404E59 | 04 db 04
00404E5A | 00 db 00
00404E5B | 00 db 00
00404E5C | 00 db 00
00404E5D | 00 db 00
00404E5E | 00 db 00
00404E5F | 00 db 00
00404E60 | 00 db 00
00404E61 | 57 db 57 ; CHAR 'W'
00404E62 | 4C db 4C ; CHAR 'L'
00404E63 | 20 db 20 ; CHAR ' '
00404E64 | 20 db 20 ; CHAR ' '
00404E65 |> 8D45 B8 lea eax,[local.18] ; 关注这个变量
00404E68 |. 50 push eax
00404E69 |. E8 0E460200 call <jmp.&DCK.le_user_read> ; 核心算法CALL
00404E6E |. 8BD8 mov ebx,eax
00404E70 |. 891D B03A4300 mov dword ptr ds:[0x433AB0],ebx
00404E76 |. 83FB 02 cmp ebx,0x2
00404E79 |. 75 35 jnz short Un_llk.00404EB0 ; 跳到“未注册”,直接NOP掉
00404E7B |. 66:C745 DC 0800 mov word ptr ss:[ebp-0x24],0x8
00404E81 |. 8D55 B8 lea edx,[local.18] ; 读取Local.18指针的字符串为已注册的用户名
00404E84 |. 8D45 FC lea eax,[local.1]
00404E87 |. E8 50FB0000 call Un_llk.004149DC
00404E8C |. 8BD0 mov edx,eax
00404E8E |. FF45 E8 inc [local.6]
00404E91 |. B8 B8394300 mov eax,Un_llk.004339B8
00404E96 |. E8 85FC0000 call Un_llk.00414B20
00404E9B |. FF4D E8 dec [local.6]
00404E9E |. 8D45 FC lea eax,[local.1]
00404EA1 |. BA 02000000 mov edx,0x2
00404EA6 |. E8 45FC0000 call Un_llk.00414AF0
00404EAB |. E9 8E000000 jmp Un_llk.00404F3E
00404EB0 |> 66:C745 DC 1400 mov word ptr ss:[ebp-0x24],0x14
00404EB6 |. BA 28A94200 mov edx,Un_llk.0042A928 ; 未注册
00404EBB |. 8D45 F8 lea eax,[local.2]
  
  有兴趣可以跟进 核心算法CALL
  00404E69  |.  E8 0E460200       call <jmp.&DCK.le_user_read>         ;  核心算法CALL
  去看看里面的加密和解密过程,但本人对此不感兴趣,大概知道通过读取 "C:\WINDOWS\system32\license.llk"
  里面的值,因为里面保存了注册码。
  
  
  回头看上述代码,其实只要把
  
00404E79 |. 75 35 jnz short Un_llk.00404EB0

  一句直接nop掉就可以让“关于”对话框出现Local.18处的字符串了。
  
  但我的目标是用自己的名字 BeyondMe@UPK.cn 显示在关于里。这就得想下办法了。
  我的做法是在适当处跳转到一个空白代码段,写入 BeyondMe@UPK.cn 字符串,然后把这个字符串赋值给 Local.18即可。
  
  在反汇编里我这样修改。
  
  从这一句开始JMP到一个空白段00429520
00404E52 . /E9 C9460200 jmp Un_llk_O.00429520

  
  然后开始写入字符串:
  
  00429520   > \C745 B8 42657>mov dword ptr ss:[ebp-0x48],0x6F796542
  00429527   .  C745 BC 6E644>mov dword ptr ss:[ebp-0x44],0x654D646E
  0042952E   .  C745 C0 40557>mov dword ptr ss:[ebp-0x40],0x6B705540
  00429535   .  C745 C4 2E636>mov dword ptr ss:[ebp-0x3C],0x6E632E
  0042953C   .  A4            movs byte ptr es:[edi],byte ptr ds:[esi]
  0042953D   .^ E9 39B9FDFF   jmp Un_llk_O.00404E7B
  
  注意跳回来的位置是00404E7B,直接跳过了加密解密过程,省去不少啰嗦。呵呵
  
  至此,第一步完成。
  
  
  
  但是这一修改只是表面工夫,事实上没有真正注册成功的。这一步如何实现?
  或许刚才在看ASCII字符串时应该有提示,下断所有 未注册 字符串,可以很快定位到一个全局标志的东东。
  就是这个地址:0x433C48
  
  然后用OD查找一个所有常量0x433C48,得到以下结果,
  
0040D4AA mov byte ptr ds:[0x433C48],0x0 ds:[00433C48]=00
0040D55A mov byte ptr ds:[0x433C48],0x1 ds:[00433C48]=00
0040D57D mov byte ptr ds:[0x433C48],0x0 ds:[00433C48]=00
0040D596 cmp byte ptr ds:[0x433C48],0x0 ds:[00433C48]=00

  
  只要把赋值为0的都改为1就OK了。
  
  至此,整个软件的破解过程完成。================================================
  
  接下来的SMC补丁过程才是重头戏。
  
  由于是第一次弄这东东,还是先翻了翻《加密解密第三版》,以及看看天草大大的视频,有了点头绪。
  
  原理即:在壳自解完成后,马上跳到SMC补丁代码处,通过SMC代码来修改内存中的代码实现破解。
  
  第一步:来整理一下,刚才修改过的代码:
  
  第一处: 
     把 00404E79   . /75 35         jnz short Un_llk_O.00404EB0 直接nop掉,即 9090 填充。
  第二步:
     把 00404E52  |.  A4                movs byte ptr es:[edi],byte ptr ds:[>
       00404E53  |.  EB 10             jmp short Un_llk.00404E65
     修改为
            00404E52   . /E9 C9460200   jmp Un_llk_O.00429520
  第三步:
     添加自己的代码
00429520 > \C745 B8 42657>mov dword ptr ss:[ebp-0x48],0x6F796542
00429527 . C745 BC 6E644>mov dword ptr ss:[ebp-0x44],0x654D646E
0042952E . C745 C0 40557>mov dword ptr ss:[ebp-0x40],0x6B705540
00429535 . C745 C4 2E636>mov dword ptr ss:[ebp-0x3C],0x6E632E
0042953C . A4 movs byte ptr es:[edi],byte ptr ds:[esi]
0042953D .^ E9 39B9FDFF jmp Un_llk_O.00404E7B

  第四步:
     修改标志位代码:
      把 0040D4AA  |.  C605 483C4300 00  mov byte ptr ds:[0x433C48],0x0
     和 0040D57D  |> \C605 483C4300 00  mov byte ptr ds:[0x433C48],0x0
     两处的结束修改为1,即可。
  
  第二步:写SMC代码:
    知道了需要修改的结果,SMC补丁代码如下(不作过多解释),当然是对加壳的程序进行修改的。
  
     004AAFF9    66:C705 794E400>mov word ptr ds:[0x404E79],0x9090
  
     004AB002    C705 524E4000 E>mov dword ptr ds:[0x404E52],0x246C9E9
     004AB00C    C705 564E4000 0>mov dword ptr ds:[0x404E56],0x4209000
  
     004AB016    C705 20954200 C>mov dword ptr ds:[0x429520],0x42B845C7
     004AB020    C705 24954200 6>mov dword ptr ds:[0x429524],0xC76F7965
     004AB02A    C705 28954200 4>mov dword ptr ds:[0x429528],0x646EBC45
     004AB034    C705 2C954200 4>mov dword ptr ds:[0x42952C],0x45C7654D
     004AB03E    C705 30954200 C>mov dword ptr ds:[0x429530],0x705540C0
     004AB048    C705 34954200 6>mov dword ptr ds:[0x429534],0xC445C76B
     004AB052    C705 38954200 2>mov dword ptr ds:[0x429538],0x6E632E
     004AB05C    C705 3C954200 A>mov dword ptr ds:[0x42953C],0xB939E9A4
     004AB066    C705 40954200 F>mov dword ptr ds:[0x429540],0xFFFD
  
     004AB070    C605 B0D44000 0>mov byte ptr ds:[0x40D4B0],0x1
     004AB077    C605 83D54000 0>mov byte ptr ds:[0x40D583],0x1
  
     004AB07E    68 C4144000     push llk_SMC+.004014C4     ;压OEP入栈,也可以直接JMP OEP
     004AB083    C3              retn
  
  
  第三步:修改壳自解结束位置,跳到SMC以及SMC后返回OEP。
    ASPack壳直接ESP定律搞定:
  
004A63B0 /0F85 434C0000 jnz llk_SMC+.004AAFF9 [这句修改为JMP到SMC代码段]
004A63B6 |90 nop
004A63B7 |C2 0C00 retn 0xC

  
  最后,填上代码如上第二步结果:
   004AB07E 68 C4144000 push llk_SMC+.004014C4     ;压OEP入栈,也可以直接JMP OEP
   004AB083 C3 retn

  
  保存。运行,所有功能也没有限制了。

--------------------------------------------------------------------------------
【版权声明】: 本文原创于BeyondMe, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2012年04月04日 17:28:59

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
2
谢谢楼主的分享,学习!
2012-4-4 22:46
0
雪    币: 2882
活跃值: (1267)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yjd
3
BeyondMe这个id记得在upk以前经常看到?
2012-4-4 23:02
0
雪    币: 241
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
正是本人也
2012-4-4 23:19
0
雪    币: 408
活跃值: (156)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
5
BeyondMe兄写了好多经典的算法文章啊~
2012-4-5 01:17
0
雪    币: 241
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
对于大牛们来说都是浮云
2012-4-5 08:58
0
雪    币: 0
活跃值: (954)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
这个壳没有校验?
2012-4-6 08:45
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
8
多来点浮云吧。
2012-4-6 09:58
0
雪    币: 96
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
一如既往的支持!
2012-4-6 19:34
0
游客
登录 | 注册 方可回帖
返回
//