Coming Heart 资源分析(二)

上次我们准备好了调试的环境,这次我们来看看怎么上手。

目标

我们先给这个系列定个小目标:解析出开场 CG。

准备知识

可能有朋友还记得之前我们寻找程序读取文件的部分是用 BPINT 21 3f 来下断点, 这个现在已经不能用了,这也是为什么我们不再用 dosbox 的原因。Windows 下, 打开调用的是 kernel32.dll 的 CreateFileA。 如果有人不太了解 windows API,那么容我分享一下我的一知半解, 我们来看下这个函数:

HANDLE CreateFileA(
  [in]           LPCSTR                lpFileName,
  [in]           DWORD                 dwDesiredAccess,
  [in]           DWORD                 dwShareMode,
  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  [in]           DWORD                 dwCreationDisposition,
  [in]           DWORD                 dwFlagsAndAttributes,
  [in, optional] HANDLE                hTemplateFile
);

这个是摘自 Win32 的 API, 和 Win16 的 API 应该会有所不同,但是万变不离其宗,在 CreateFileA 中, 我们需要告诉内核我们要读取哪个文件(lpFileName), 内核会给我们一个代表文件的 handle。

一个题外话,CreateFileA 还有一个兄弟 CreateFileW,用来打开多字节的路径, 使用 CreateFileW 就可以识别英文字符外的路径文件, 不过我们这次没有涉及到 CreateFileW,所以先按下不表。

Cutter

经过对 Turbo Debugger for Win32(tdw) 一段简单的研究, 我没有发现如何把程序中断在打开文件的方法, 所以我们需要用 Cutter 来定位一下文件是哪里打开的。

1. 打开 exe

我们打开 maplwin.exe:

cutter open exe

加载选项默认就好:

Untitled

2. 寻找 CreateFile

在「导入表」的页签下,我们就可以找到 CreateFileA 的位置了:

Untitled

我们也可以看到,程序并没有调用 CreateFileW,所以如果安装路径中有中文, 那么这个程序可能会有问题,我们右击 CreateFileA ,选择「显示 X-Refs」, 来查看函数的引用(调用)位置:

Untitled

只有一个地方,很好,这样我们找起来会更简单,双击左侧蓝色行:

Untitled

这里应该就是调用 CreateFileA 的位置了,我们记下地址 0x0040ef64

Untitled

根据我的一点点汇编的知识,call ebp 是呼叫 CreateFileA , 之前的 push 则是把函数的参数压入栈中。所以,读取的文件名一定在这几个 push 中。

TDW

确认了打开文件的位置后,我们可以用 TDW 下断点,确认一下,哪个参数代表了文件名

1. TDW 基础操作

我们现根据上一期的流程,加载 maplwin.exe,中断在程序入口:

Untitled

TDW 的主界面分为四块,左上是程序,右上是寄存器,左下是内存,右下我们用不到。 蓝色的滚动条代表它是当前活动窗口,我们可以用 tab 键在四个窗口切换。

我们可以在程序窗口按 ctrl-g,来定位到打开文件的位置 0x0040ef64 ,注意, 在 TDW 中,这个地址要写做 0040ef64h ,不可以写成 0x 开头的格式:

Untitled

0040ef6bh 处按 F2 下断点,断点行会变成红色,可以稍微移动下蓝色当前行, 确认我们断点已经下了:

Untitled

这时按 F9,让程序执行,程序很快就会进到断点:

Untitled

我们把活动窗口调整到内存窗口,同样用 Ctrl-g, 检查 414524h (ecx 的值)处的内存存了什么:

Untitled

mpx\maplsys.cfg,这就是程序读取的第一个文件。

Untitled

F9 继续程序,很快又会进入断点,如法炮制,我们就知道程序启动时打开了如下几个文件:

  1. mpx\maplsys.cfg
  2. hhp\cframe.hhp
  3. hhp\black.hhp
  4. hhp\black.hhp
  5. hhp\black.hhp
  6. 未知(c7fe1ch
  7. hhp\chtitle.hhp

有重复的内容,另外有一个位置的位置,不过这些不重要,我们注意到最后一个文件, chtitle.hhp,这个很有可能就是我们要找的资源了。

上文 Windows API 小课堂我们说到,内核打开文件成功后会返回一个 handle, 这个 handle 就保存在 eax 中,我们按 F7 执行到下一步,记录下 eax 的值:

Untitled

18h,后面我们会用它来判断是哪个文件。

总结

我们用 cutter 和 tdw,结合一些 windows API 的知识, 确定了程序启动过程中打开了哪些文件,接下来, 我们会具体看一看程序是怎么读取这些文件的。