Left 4 dead 破解攻略

【文章标题】: Left 4 dead 破解攻略
【文章作者】: sunwayking
【作者邮箱】: sunwayking@163.com
【作者主页】: http://hi.baidu.com/suwnay
【作者QQ号】: 410109674
【软件名称】: Left 4 dead(求生之路)
【软件大小】: null
【下载地址】: 自己搜索下载
【加壳方式】: Steam App
【保护方式】: Steam检测+压缩壳
【编写语言】: VC++
【使用工具】: OD,PE Tools
【操作平台】: Windows
【软件介绍】: Left 4 dead 是一款非常成功的FPS游戏.
【作者声明】: 只为研究加密解密技术,不为破解而破解!失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  大家好,早就承诺要放出 Left 4 dead (以下简称 L4D) 的详尽的破解过程,因为最近很忙所以一直拖到现在.好了下面切入正题...

QUOTE:
对于一下过程中的术语等内容大家可以参考 ghgzhilian大 发表的破解入门


  首先我们大体感知一下这个游戏的加密手段,运行 Left4dead.exe 文件,游戏并未启动,而是出现了steam的登陆窗口(前提是您安装了steam,不要关闭steam的登陆窗口,再次运行L4D,这次可以进入游戏.所以可以判定游戏在启动的时候会有一段代码检测steam是否运行了(注意,游戏对是否登陆并不要求.


  所以我们继续保留哪个steam 的登陆窗口,并且用 OD 载入 Left4dead.exe 文件,来到:



QUOTE:

  0041C2ED >  53              push    ebx
  0041C2EE    51              push    ecx
  0041C2EF    52              push    edx
  0041C2F0    56              push    esi
  0041C2F1    57              push    edi
  0041C2F2    55              push    ebp
  0041C2F3    8BEC            mov     ebp, esp
  0041C2F5    81EC 00100000   sub     esp, 1000
  0041C2FB    C785 78FFFFFF F>mov     dword ptr [ebp-88], 0041E1F4
  0041C305    8BB5 78FFFFFF   mov     esi, dword ptr [ebp-88]
  0041C30B    B9 D9000000     mov     ecx, 0D9
  0041C310    8DBD 10FCFFFF   lea     edi, dword ptr [ebp-3F0]
  0041C316    F3:A5           rep     movs dword ptr es:[edi], dword p>
  0041C318    8D85 10FCFFFF   lea     eax, dword ptr [ebp-3F0]
  0041C31E    8985 04FCFFFF   mov     dword ptr [ebp-3FC], eax
  0041C324    C785 D4FBFFFF 7>mov     dword ptr [ebp-42C], 54B777D
 


  这里大家注意以下,有些OD在调试 L4D 的时候使用 F8 过 Call 或者使用 F4 时会出现跑飞的现象,最简单的解决办法就是使用 F2 + F9 的组合跳过即可.

  我在第一次调试 L4D 的时候并没有单步跟踪,而是往下翻,因为前往 OEP 的代码一般是一个跨区段的大跳转,而且根据当前入口点有寄存器顺序入栈的特点,我想,飞向光明顶的大跳转之前一定是那些寄存器按照 "FILO 原理" 弹出堆栈,即:


QUOTE:
  

  pop     ebp
  pop     edi
  pop     esi
  pop     edx
  pop     ecx
  pop     ebx

  jmp     [OEP]
  


  果然,在如下地方找到了符合要求的代码:


QUOTE:

  0041D96B    8B85 D0FBFFFF   mov     eax, dword ptr [ebp-430]
  0041D971    81C4 00100000   add     esp, 1000
  0041D977    5D              pop     ebp
  0041D978    5F              pop     edi
  0041D979    5E              pop     esi
  0041D97A    5A              pop     edx
  0041D97B    59              pop     ecx
  0041D97C    5B              pop     ebx
  0041D97D    FFE0            jmp     eax                              ; //此处就将跳到OEP
  0041D97F    0FBE85 44FCFFFF movsx   eax, byte ptr [ebp-3BC]
  0041D986    83F8 35         cmp     eax, 35
  



  在 "jmp eax"上下断点(F2 ,然后 F9 运行程序,程序停在 "jmp eax" 处.如果您的 OD 使用 F4(运行到所选不会跑飞也可以使用 F4.
  这样,继续 F8 ,峰回路转,我们经过一个大跳转后来到了光明顶:


QUOTE:

  004018B0    E8 55330000     call    00404C0A
  004018B5  ^ E9 16FEFFFF     jmp     004016D0
  004018BA    56              push    esi
  004018BB    8B35 9CF04000   mov     esi, dword ptr [40F09C]
  004018C1    EB 26           jmp     short 004018E9
  004018C3    57              push    edi
  004018C4    50              push    eax
  004018C5    FF7424 10       push    dword ptr [esp+10]
  004018C9    E8 11350000     call    00404DDF
  004018CE    83C4 0C         add     esp, 0C
  004018D1    85C0            test    eax, eax
  004018D3    75 11           jnz     short 004018E6
  


  在此处(004018B0 用OD自带的插件转存,却发现会出现读取错误,而此时内存镜像事实上是读写权限.拿出 PE Tools 将此进程转存(dump 出来,删除最后两个区段,并且将入口点(OP 修正为刚才得到的 004018B0,最后重建一下 PE 文件即可.至此steam已经完全被脱去.最后的文件大小应该在 80kb~90KB.

  现在让我们回头在看看保护程序的大体流程,这里我没有做详尽的分析,事实上破解程序并不需要对所有代码进行分析,甚至有些代码因为是编译器编译出来的,所以非常怪异甚至非常愚蠢.

  程序有这么几处会导致游戏不运行(要么退出要么运行steam:

  1.


QUOTE:

  0041C7E4    0FB685 ACF2FFFF movzx   eax, byte ptr [ebp-D54]
  0041C7EB    85C0            test    eax, eax
  0041C7ED    75 11           jnz     short 0041C800                   ; //关键位置
  0041C7EF    C685 44FCFFFF 4>mov     byte ptr [ebp-3BC], 45
  0041C7F6    E9 84110000     jmp     0041D97F
  0041C7FB    E9 7F110000     jmp     0041D97F

  0041C800    FF55 F0         call    dword ptr [ebp-10]
  


  2.


QUOTE:

  0041C866    8885 44FCFFFF   mov     byte ptr [ebp-3BC], al
  0041C86C    0FBE85 44FCFFFF movsx   eax, byte ptr [ebp-3BC]
  0041C873    83F8 30         cmp     eax, 30
  0041C876    74 0A           je      short 0041C882                   ; //关键位置
  0041C878    E9 02110000     jmp     0041D97F
  0041C87D    E9 FD100000     jmp     0041D97F

  0041C882    64:A1 18000000  mov     eax, dword ptr fs:[18]
  0041C888    8985 78FBFFFF   mov     dword ptr [ebp-488], eax
  


  3.


QUOTE:

  0041C8D5    0FB685 77FBFFFF movzx   eax, byte ptr [ebp-489]
  0041C8DC    85C0            test    eax, eax
  0041C8DE    74 11           je      short 0041C8F1                   ; //关键位置
  0041C8E0    C685 44FCFFFF 5>mov     byte ptr [ebp-3BC], 54
  0041C8E7    E9 93100000     jmp     0041D97F
  0041C8EC    E9 8E100000     jmp     0041D97F

  0041C8F1    8B85 34FCFFFF   mov     eax, dword ptr [ebp-3CC]
  0041C8F7    8B00            mov     eax, dword ptr [eax]
  


  4.


QUOTE:

  0041CAC7    8885 44FCFFFF   mov     byte ptr [ebp-3BC], al
  0041CACD    0FBE85 44FCFFFF movsx   eax, byte ptr [ebp-3BC]
  0041CAD4    83F8 30         cmp     eax, 30
  0041CAD7    74 0A           je      short 0041CAE3                   ; //关键位置
  0041CAD9    E9 A10E0000     jmp     0041D97F
  0041CADE    E9 9C0E0000     jmp     0041D97F

  0041CAE3    8B85 34FCFFFF   mov     eax, dword ptr [ebp-3CC]
  0041CAE9    8B00            mov     eax, dword ptr [eax]
  0041CAEB    3B85 30FCFFFF   cmp     eax, dword ptr [ebp-3D0]
  0041CAF1    74 11           je      short 0041CB04                   ; //关键位置
  0041CAF3    C685 44FCFFFF 4>mov     byte ptr [ebp-3BC], 4D
  0041CAFA    E9 800E0000     jmp     0041D97F
  0041CAFF    E9 7B0E0000     jmp     0041D97F

  0041CB04    FFB5 38FCFFFF   push    dword ptr [ebp-3C8]
  0041CB0A    6A 00           push    0
  


  5.


QUOTE:

  0041D83F    50              push    eax
  0041D840    FF55 C8         call    dword ptr [ebp-38]
  0041D843    83BD 0CFCFFFF 0>cmp     dword ptr [ebp-3F4], 0
  0041D84A    75 11           jnz     short 0041D85D                   ; //关键位置
  0041D84C    C685 44FCFFFF 4>mov     byte ptr [ebp-3BC], 42
  0041D853    E9 27010000     jmp     0041D97F
  0041D858    E9 22010000     jmp     0041D97F

  0041D85D    FFB5 38FCFFFF   push    dword ptr [ebp-3C8]
  0041D863    FFB5 34FCFFFF   push    dword ptr [ebp-3CC]
  0041D869    FF95 0CFCFFFF   call    dword ptr [ebp-3F4]              ; //校验steam是否运行,如果运行则释放L4D真正的代码,并将OEP定位信息存放在eax里
  0041D86F    8985 D0FBFFFF   mov     dword ptr [ebp-430], eax         ; OEP存入[ebp-430]
  0041D875    8B85 38FCFFFF   mov     eax, dword ptr [ebp-3C8]
  0041D87B    8985 48F9FFFF   mov     dword ptr [ebp-6B8], eax
  


  6.


QUOTE:

  0041D8CD    50              push    eax
  0041D8CE    FF55 C8         call    dword ptr [ebp-38]
  0041D8D1    81BD D0FBFFFF F>cmp     dword ptr [ebp-430], 0FF
  0041D8DB    73 16           jnb     short 0041D8F3                   ; //又是关键位置,修改标志位C即可更改跳转状态
  0041D8DD    8A85 D0FBFFFF   mov     al, byte ptr [ebp-430]
  0041D8E3    8885 44FCFFFF   mov     byte ptr [ebp-3BC], al
  0041D8E9    E9 91000000     jmp     0041D97F
  0041D8EE    E9 8C000000     jmp     0041D97F                         ; 跳飞,程序转而运行steam.

  0041D8F3    8D85 10FCFFFF   lea     eax, dword ptr [ebp-3F0]
  



  总结一下以上几段代码的特点,那就是只要 jmp 到 0041D97F,那么游戏就不会运行了.为什么呢,因为 "jmp eax" 那句的地址是 0041D97D.
  第 5 段里的带注释的 call 的功能正是解压 OEP 入口处代码,如果 steam 没有在运行,那么这个 call 就不会解压入口点的代码.另外整个流程也说明了为什么只要 steam 开着,无论是否登陆都可以进入单机游戏,正如本文开头所述.

posted @ 2010-08-31 20:05  Max Woods  阅读(698)  评论(0编辑  收藏  举报