【摸鱼】新游戏神尾的引擎的一点解析

实际上可以Hook这几个函数,自己实现一套封包,做个缓存机制,能大幅提高这个引擎的读取效率。
顺便自己的还能加密。


楼主 展鸿丶  发布于 2020-02-08 14:28:00 +0800 CST  
顺便也分析一下图片压缩算法。
这个引擎的图像格式是KG。文件头部4字节GCGK标识。

IDA走起。
老办法,搜一波扩展名直接定位。


文件头12字节。
结构如下:


图像数据分成两部分。
1、一个int数组。大小是 图像高度 * sizeof( int )
1、图像数据。


上面这个函数只负责把文件读入内存,还没解析。
IDA里可以按X查找哪里调用了这个函数。


看到只有一个地方,直接过去看。


上面一坨好像只是把文件头的信息复制到别的地方去。先不管。
继续往下看。




几个看起来很长的嵌套循环。
这里就是解压图像数据的代码。
IDA的代码还是挺好看懂,但是还需要整理一下。
VS走起。


解压算法简述:
offset_table记录了在压缩的图像数据中,每一行的字节的起始位置。
所以使用一个循环来遍历offset_table的每个值,解压每一行像素。
每一行的第一个字节是透明度,第二个字节是像素数量。
也就是说,该算法把透明度相同的像素的透明度值压缩成了一个。
例如:有20个像素,完整的数据需要20*4=80个字节来储存。把透明度值压缩之后,
只需要1(透明度)+1(数量)+20(像素)*3=62字节。
并且如果遇到完全透明的像素,只输出2个字节即可。
循环判断:透明度+数量,然后读取像素(如果有) 即可完成一行像素的解压。
重复上述过程解压每一行像素,即可完成整个图像的解压。


压缩过程如下:
它检查每一行的每个像素,以第一个遇到的像素为基准,往右查找,直到遇到透明度不同的像素或者到达行尾。
完成一次查找后,输出一个字节表达本次查找遇到的透明度,再输出一个字节表达本次查找到了多少个透明度相同的像素。
接着输出本次查找到的像素的RGB值,每个像素3字节。如果本次查找到的像素为完全透明,则不输出任何像素字节。
重复上述查找、输出字节过程,直到查找完一行像素。
完成一行查找后,记录本行输出的字节数,作为下一行输出字节的起始位置,也就是offset。
重复上述过程直到查找完整个图像的每一行。
最后把每一行输出的字节的offset写入offset_table即可完成压缩。

楼主 展鸿丶  发布于 2020-02-08 17:24:00 +0800 CST  
最后把解压好的像素写出到PNG文件。

啊,是龙王,WSL


楼主 展鸿丶  发布于 2020-02-08 17:27:00 +0800 CST  

楼主:展鸿丶

字数:6471

发表时间:2020-02-07 02:55:00 +0800 CST

更新时间:2020-08-29 13:15:34 +0800 CST

评论数:101条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看