Jan 11

文件逆向工程思路小记

Lrdcq , 2017/01/11 22:09 , 程序 , 閱讀(7738) , Via 本站原創
这两天拆了一个微信小程序的自定义文件格式wxapkg(详见另一篇关于微信小程序的博客文章),虽然这个文件格式确实很简单,不过也是基于我以前拆文件的经验才分分钟看透的。既然有做了这么一件事儿,那就来顺便总结总结,对文件逆向工程时我的思路和方法。

-1. 开始前的工作

我们需要一个hex编辑器,不需要编辑的话hex浏览器就可以了
我们需要样本文件,至少要两个。如果有能够生成这个文件的软体本体更好。
我们先尝试过常见文件格式进行操作,比如zip什么的,太常见了。

0. 基础:指针和长度

和文本文件不同,一般的二进制文件里储存了大量的作用是offset和size的数据作为数据段的索引。最关键的所谓offset,就是目标数据在文件中的实际位置了,一般是ulong的数据,实际就是一个指针。一般读取文件时会先找到一个offset,然后file.seek(offset)到对应的位置然后接着读区。对于较为复杂的文件格式,offset飞来飞去非常频繁。同样,大部分储存了offset的地方也储存了size的,嘛用于校验数据避免指针越界嘛。因此,一旦我们可以确认一个文件中某一段数据段,就可以通过它的位置(offset)和大小(size)的实际数据进行搜索,逆向找到指向它的数据位置,并且继续逆向直到解析完整的文件。

1. 关键目标:字符串

直观的打开Hex浏览器/编辑器打开文件,我们习惯性的在字符串化窗口中寻找可直接阅读的字符串。在二进制文件里出现字符串,往往意味着:a.这是一个真的字符串。b.这是这个文件的标志位置。

如果是a的话,一般一个真的字符串在二进制文件里有两种储存方式:一种是不记录字符串的长度,读取字符串到0x00位置也就是常说的/0,这样的字符串非常明显每个字符串后面都有空白的字节;还有一种方式是没有0x00结尾,但是一定有某一个地方储存了这个字符串的长度,一般就在前面紧跟着;如果没有紧跟着,我们已知当前看到这个字符串的长度,那么直接搜索这个长度就可以了,找到后还应该在前后记录了字符串的offset,如果能确认的话就能解开更多信息了。

如果是b的话,一般是header中的标志位(比如著名的坑爹货utf8头),或者类似的东西,不一定是在文件最开始的,但是一定是这样的作用。

2. 关键手段:对比

有多个sample文件的主要作用,就是对面,打开两个相同格式的文件,很容易就能够看出文件中那些字段是固定的,哪些结构,哪些长度是固定的,

另外,如果有生成软件本体就更好了,我们可以通过微量修改来观察文件的变化来找到文件结构和意义——这招其实是当年修改单机游戏存档或者内存修改作弊的常见招式,当然对于所有文件都适用咯。当然,我们实际上往往面对的就是一个找不到生成软件本体的文件,所以还是靠双眼观察更靠谱。

3. 其他:猜

当然,作为一个逆向工程的手段,猜,或者叫推理肯定是必不可少的。首先根据文件的作用,猜想文件中可能出现些什么东西,比如目录,截图,纯文本文件,脚本。比如常见的,大量格式相近的数据罗列,必然是一个索引目录的数据段;看见数据中莫名出现的常见文件头,可以知道这里硬打包入了一个对应的文件,甚至可以直接把这个文件抽出来。这些其实只要亲自看几个文件的hex,很容易就能了解这些经典的经验。

解wxapkg时的思路

接下来应用上面所说的东西,重现一下我接wxapkg时的思路:

1. 首先我们随便打开一个wxapkg,如下图:
點擊在新視窗中瀏覽此圖片

第一眼,我们就可以看到很多信息了,包括:

a. 我们知道这个文件肯定是个打包文件,所以肯定有目录。看见这么多目录字符串的罗列了么,这一段肯定是目录索引段落。
b. 偶然看见下面有一个PNG文件头,所以下面肯定已经是文件的数据段落了。另外从这个png的数据可以看到,数据完全没有经过压缩或者加密,这让我们大大松了一口气。

2. 那我们来看看索引段数据,直接看到两个字符串之间的数据,比如这里:
點擊在新視窗中瀏覽此圖片

看起来并不像是有结尾符0的字符串,就算有,中间我们也能看到3个数字:0x7B1 0xA7 0x26。显然一对比,0x26就是下一个字符串的长度了,那么这个字符串的前一ulong是不是这个“/images/countDown/icon_add.png”的长度呢?嗯,数一数,0x1E,那就对了。

然后,我们知道这个数据肯定是文件索引,那么这个0x7B1(=1969)是不是就是这个文件的位置呢,实际往下面看看,还就是了。同样0xA7也正是这个文件的长度。

那么到这里,索引部分就简单的清晰了,每条索引的结构是:文件名长度,文件名,文件offset,文件size。

3. 但是还差一些东西,比如索引的条数是哪儿确定的呢?手动数数,这个文件一共有40条文件,诶,正好索引区域前面的那一个ulong正好就是这个数0x28诶:
點擊在新視窗中瀏覽此圖片

4. 这样,剩下的未解之谜就是前面header部分的结构了。这时候,我们就上对比大法了。另外开一个wxapkg文件,我们发现了很多相同之处:
點擊在新視窗中瀏覽此圖片

最明显的,开始的0xBE和索引数前的0xED是完全固定的,而且中间正好可以分为3个ulong,分别是:0x00,0x6AE(1710),0x447CF(280527),这三个数是干嘛的呢?再宏观的拉一下文件,很快就可以猜到,第二个数是索引段的数据长度,第三个数是文件段的数据长度。因此至少很清晰了,后两个数是header之外的两段的数据长度,用于校验防止溢出的。

到此为止,我们可以说基本清晰的分析出了wxapkg的文件结构,最后如下图:
點擊在新視窗中瀏覽此圖片
关键词:反编译 , 逆向工程
logo
MewX
2018/01/05 21:03
Thank you!