浅谈网络游戏《天龙X部》的文件加密格式

简介:
三月份时玩了某狐公司的网络游戏《天龙X部》,感觉还是蛮有意思的,遂研究了一下。
这个游戏是利用开源游戏引擎OGRE进行开发的,看了一下目录里面的文件结构,主要的数
据都放在Data目录下面。不过文件基本都是.AXP后缀的,每一个动辄几十兆,料想肯定是
把游戏文件打包到一起并加密过的,GOOGLE未遂。开始用UE打开看了一下这个AXP文件,发
现里面居然大部分都是明文的,开始以为只是把文件罗列在一起,不过仔细看了一下,发
现每个文件都有一段间隔,前面还有一个数据头,而且文件与名字也无法对应。于是打开
OD手动分析一下,主要过程其实比较简单,CreateFile函数下断,找到文件Buffer位置,
再下内存访问断点即可来到关键代码区域。略过具体跟踪细节及文件校验部分不讲,文件
格式主要分析如下:

整个AXP文件可以分成四个部分:1.文件头 2.文件名索引 3.文件索引 4.文件数据


1.文件头:
  整个文件头固定为0x28字节,其中第20个字节开始的一个整数乘以12代表了第三部分
即文件索引部分的长度(因为每个索引有三个整数构成)
2.文件名索引:
  整个文件名索引固定为0x60000字节,其中包含了每个压缩文件对应的文件索引位置

3.文件索引:
  本部分长度由文件头相关数据决定,其中包含了每个压缩文件在.axp中的实际偏移位
置及文件大小
4.文件数据:
  本部分包含所有压缩文件的具体数据,每个文件之间用若干零填充。

首先说说解压总体过程:比如我们要从A.axp中解压出一个叫file.txt的文件,那么先根据
文件名file.txt到文件名索引中去找到对应的文件索引,然后再根据文件索引找到这个文
件在axp文件中的位置和大小,最后把其解压出来。

解压具体过程如下:
  将待解压的文件名转为小写(如果为英文字母),利用GetDisp(char* s,int v)函数
计算相关数据,其中s代表文件名,v代表计算参数,分别计算GetDisp(fname,1),GetDisp
(fname,2),
GetDisp(fname,3),得到三个值a1,a2,a3。其中a3低位与在文件名索引中的位置有关,a3最
高位及a1,a2用来进行校验,如果三个值不能同时满足要求,则将偏移位置顺移继续验证,
具体细节懒得写了。
以下为GetDisp函数具体内容,我直接将跟踪代码里面的汇编改造了一下拿出来用,其中s
ucks为一个随机数数组,这里不列出来了。
None.gifunsigned  int TLBBUnpacker::GetDisp( char* s, int v)
ExpandedBlockStart.gif {
InBlock.gif    __asm
ExpandedSubBlockStart.gif    {
InBlock.gif        push esi
InBlock.gif            mov esi,s
InBlock.gif            mov cl,byte ptr ds:[esi]
InBlock.gif        test cl,cl
InBlock.gif            mov eax,0x7FED7FED
InBlock.gif            mov edx,0xEEEEEEEE
InBlock.gif            je end
InBlock.gif            push ebx
InBlock.gif            push ebp
InBlock.gif            push edi
InBlock.gif            mov edi,v
InBlock.gif            shl edi,0x8
InBlock.gifiter:
InBlock.gif        add eax,edx
InBlock.gif            imul edx,edx,0x21
InBlock.gif            movsx ecx,cl
InBlock.gif            lea ebx,dword ptr ds:[edi+ecx]
InBlock.gif        mov ebp,dword ptr ds:[ebx*4+sucks]
InBlock.gif        inc esi
InBlock.gif            add edx,ecx
InBlock.gif            mov cl,byte ptr ds:[esi]
InBlock.gif        xor eax,ebp
InBlock.gif            test cl,cl
InBlock.gif            lea edx,dword ptr ds:[edx+eax+3]
InBlock.gif        jnz iter
InBlock.gif            pop edi
InBlock.gif            pop ebp
InBlock.gif            pop ebx
InBlock.gifend:
InBlock.gif        pop esi
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

这个为解压单个文件的函数GenerateFile,用到了QT作GUI,大家就当伪代码看吧。
None.gif bool TLBBUnpacker::GenerateFile(QString name)
ExpandedBlockStart.gif {
InBlock.gif    name=name.toLower();
InBlock.gif    unsigned int a=GetDisp(name.toLocal8Bit().data(),3),a2=GetDisp(name.toLocal8B
InBlock.gifit().data(),2),a1=GetDisp(name.toLocal8Bit().data(),1),b,disp,length;
InBlock.gif    a&=0x7FFF;
InBlock.gif    while(!((b=((int*)buffer2)[a*3+2])&0x80000000)||a1!=((int*)buffer2)[a*3]||a2!
InBlock.gif=((int*)buffer2)[a*3+1])
ExpandedSubBlockStart.gif    {
InBlock.gif        a++;
InBlock.gif        a&=0x7FFF;
ExpandedSubBlockEnd.gif    }

InBlock.gif    b&=0x3FFFFFFF;
InBlock.gif    disp=((int*)buffer3)[b*3];
InBlock.gif    length=((int*)buffer3)[b*3+1];
InBlock.gif
InBlock.gif    QFile pdata(this->package_name);
ExpandedSubBlockStart.gif    if (pdata.open(QFile::ReadOnly)&&pdata.seek(disp)) {
InBlock.gif
InBlock.gif        QString wdir=QDir::currentPath()+QDir::separator()+QFileInfo(pdata).fileName
InBlock.gif()+QDir::separator();
InBlock.gif        QDir dir;
InBlock.gif        QDataStream pfin(&pdata);
InBlock.gif        QFile file(wdir+name);
InBlock.gif        QFileInfo info(file);
InBlock.gif        dir.mkpath(info.absolutePath());
InBlock.gif        if(file.open(QFile::WriteOnly))
ExpandedSubBlockStart.gif        {
InBlock.gif            char* pBuffer=new char[length];;
InBlock.gif            QDataStream fout(&file);
InBlock.gif            pfin.readRawData(pBuffer,length);
InBlock.gif            fout.writeRawData(pBuffer,length);
InBlock.gif            delete []pBuffer;
InBlock.gif            return true;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    return false;
ExpandedBlockEnd.gif}

None.gif


得到待解压文件在文件索引中的位置後就可以找出该文件在axp文件中的具体偏移量和文件
大小了,然后直接fseek一下然后在弄出来就OK了。
最后说一下,这个AXP压缩包本身就含有一个文件列表文件叫做(list),所以每次只要先解
压缩这个文件,然后按照里面的文件列表来一一解压缩就OK了。


以上就是文件大致格式,感觉还是比较简单的,也可以考虑在自己的项目中使用类似方法
进行文件压缩。
目录
相关文章
|
11天前
|
SQL 安全 算法
网络防御前线:洞悉漏洞、加固加密与提升安全意识
【4月更文挑战第8天】在数字化时代,网络安全与信息安全已成为维系信息社会正常运转的关键。本文从网络安全的漏洞发现、加密技术的应用以及提高个人和组织的安全意识三个维度出发,深入探讨了如何构建更为坚固的网络防御体系。通过对现有网络安全威胁的分析,我们揭示了漏洞挖掘的重要性,并介绍了当前流行的加密技术及其在保护数据完整性和隐私中的作用。同时,文章还强调了培养良好的安全习惯对预防潜在攻击的重要性。本文旨在为读者提供全面的网络安全知识框架,以便更好地应对日益复杂的网络威胁环境。
|
12天前
|
安全 算法 网络安全
网络防御的三重奏:漏洞管理、加密技术与安全意识
【4月更文挑战第7天】在数字化时代,网络安全和信息安全已成为企业和个人不可忽视的战场。本文将深入探讨网络安全的核心问题——漏洞管理,介绍现代加密技术的进展,并强调提升安全意识的重要性。通过分析网络攻击的常见手段,我们揭示了有效管理漏洞的策略;同时,评估了从对称加密到非对称加密,再到量子加密的技术演进。最后,文章指出,在技术和工具不断进步的同时,用户的安全意识仍是防御体系中不可或缺的一环。
|
7天前
|
安全 网络协议 网络安全
网络原理(5)--HTTPS是如何进行加密的
网络原理(5)--HTTPS是如何进行加密的
5 0
|
7天前
|
安全 算法 网络协议
保障数据安全:网络安全漏洞与加密技术探析
网络安全漏洞的存在已成为当今互联网世界中的一大隐患,而加密技术的应用则被视为保障信息安全的有效手段。本文将就网络安全漏洞的成因、加密技术的原理以及提升安全意识的重要性进行探讨,旨在加深读者对网络安全与信息安全的认识,为构建更安全的网络环境贡献一份力量。
13 2
|
11天前
|
监控 安全 算法
网络安全与信息安全:防范漏洞、强化加密、提升意识
【4月更文挑战第8天】在数字化时代,网络安全与信息安全已成为全球关注的焦点。本文将深入探讨网络安全中的漏洞问题、加密技术的发展以及安全意识的重要性。通过对这些关键领域的分析,旨在为读者提供全面的安全防护策略和实践建议,以应对日益复杂的网络威胁。
|
21天前
|
安全 网络安全 数据安全/隐私保护
探究网络安全漏洞与加密技术:保护信息安全的关键
在当今数字化时代,网络安全漏洞已成为信息安全的重要挑战之一。本文将深入探讨网络安全漏洞、加密技术以及安全意识对于信息安全的重要性,旨在引起人们对网络安全问题的关注,提升信息安全意识。
11 3
|
21天前
|
存储 安全 网络安全
探究网络安全与信息安全:漏洞、加密与安全意识
在当今数字化时代,网络安全和信息安全日益受到重视。本文将深入探讨网络安全漏洞、加密技术以及安全意识等方面的知识,帮助读者更好地了解和应对网络安全挑战。通过分析现有漏洞、介绍加密技术原理以及强调安全意识的重要性,旨在提升读者对网络安全的认识和应对能力。
12 0
|
23天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:防范漏洞、强化加密、提升意识
随着互联网的普及和技术的飞速发展,网络安全和信息安全问题日益凸显。本文将探讨网络安全漏洞的形成原因、加密技术的应用以及提升安全意识的重要性,以期为读者提供关于网络安全与信息安全的知识分享。
11 2
|
24天前
|
存储 安全 网络安全
探索网络安全之道:漏洞修复、加密技术与安全意识
在当今数字化时代,网络安全问题日益突出,漏洞、加密技术和安全意识成为保障信息安全的关键。本文将深入探讨网络安全领域的重要议题,带您一起了解漏洞修复的必要性、加密技术的应用以及提升安全意识的重要性。
10 1
|
24天前
|
安全 网络安全 区块链
网络安全与信息安全:漏洞、加密技术与安全意识
在当今数字化时代,网络安全和信息安全已经成为人们关注的焦点。本文将深入探讨网络安全漏洞、加密技术以及安全意识等方面的知识,并提出相应的解决方案,以增强读者对网络安全和信息安全的认识。
8 0