设为首页收藏本站官方微博

【汉化资料】浅谈网络游戏《天XXX》的文件加密格式

[复制链接]
查看: 1933|回复: 0
打印 上一主题 下一主题

【汉化资料】浅谈网络游戏《天XXX》的文件加密格式

跳转到指定楼层
楼主
发表于 2008-10-30 20:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

【汉化资料】浅谈网络游戏《天XXX》的文件加密格式

学习一下人家的破解过程,这个游戏是开源游戏引擎OGRE进行开发的喔。 ( w* x) B3 P. |) D* t
: R8 M6 y, e0 _0 D/ z' t( I: ^
; r  q+ w" y0 L! w' g+ A$ }7 Y

+ @7 {& V/ t: N2 A  {发信站: 饮水思源 (2007年06月22日02:36:37 星期五)
# b1 [' q. u. s0 R( l: C1 n
8 O( k) ]: b, k+ ]# q: T1 ]' w- N作者:[email protected]
, l, _0 @! i0 n2 ^: ^. L
$ h0 W" n7 K1 l1 v; S- u三月份时玩了某狐公司的网络游戏《天XXX》,感觉还是蛮有意思的,遂研究了一下。
9 Y. h* E9 ^  D3 V这个游戏是利用开源游戏引擎OGRE进行开发的,看了一下目录里面的文件结构,主要的数
  g0 L1 X! S* ~8 `据都放在Data目录下面。不过文件基本都是.AXP后缀的,每一个动辄几十兆,料想肯定是 4 o! H) P! h) J$ V. o  |9 t
把游戏文件打包到一起并加密过的,GOOGLE未遂。开始用UE打开看了一下这个AXP文件,发 % {* D2 v- u( Q. L/ ]2 g3 k
现里面居然大部分都是明文的,开始以为只是把文件罗列在一起,不过仔细看了一下,发
2 }9 Q9 S8 n5 y& m6 m现每个文件都有一段间隔,前面还有一个数据头,而且文件与名字也无法对应。于是打开 9 }8 z5 ~( V7 m- }! g/ j
OD手动分析一下,主要过程其实比较简单,CreateFile函数下断,找到文件Buffer位置,
: [& S1 e( Y" @* G2 p再下内存访问断点即可来到关键代码区域。略过具体跟踪细节及文件校验部分不讲,文件
/ n6 E/ H6 z) k/ T! h, {( q; W格式主要分析如下:
5 @6 P: C- H" J) \# o. \
; Q7 I# G$ q2 W整个AXP文件可以分成四个部分:1.文件头 2.文件名索引 3.文件索引 4.文件数据
4 Y( H% d$ w2 {9 s! i" p2 f
+ |( d0 e( M7 y/ C% k- u* w+ X- v& A% t4 @! D* f
1.文件头: + K" L  l- b9 Z6 L& N1 j3 p
  整个文件头固定为0x28字节,其中第20个字节开始的一个整数乘以12代表了第三部分 ' e8 ?0 D3 Q) |2 x
即文件索引部分的长度(因为每个索引有三个整数构成) ) k! l9 F* s3 D6 |3 G% M
2.文件名索引: - v$ |( h' E3 _3 W! F
  整个文件名索引固定为0x60000字节,其中包含了每个压缩文件对应的文件索引位置 8 i; t' L1 y6 R( J( [# k* [2 B
8 O7 a: G+ y! V( e+ B; P5 b) c: ~
3.文件索引:
0 K, {' z6 g: M9 c/ O3 {5 Q$ [2 a. X  本部分长度由文件头相关数据决定,其中包含了每个压缩文件在.axp中的实际偏移位
+ v2 J: _* @" o& F7 h: |# `% J3 Y# n置及文件大小 ' o9 t- r% v7 ?9 v. g$ d% N
4.文件数据: ' ~5 M9 P. L5 o. Q
  本部分包含所有压缩文件的具体数据,每个文件之间用若干零填充。 9 [* L; s0 l5 J

4 c( h% w6 P/ j0 i' z- [* C+ ^首先说说解压总体过程:比如我们要从A.axp中解压出一个叫file.txt的文件,那么先根据 ) }5 }% I+ J6 g7 [( S7 P% w
文件名file.txt到文件名索引中去找到对应的文件索引,然后再根据文件索引找到这个文
; h1 R# _# V7 Q6 q* y$ ~0 E* y( J件在axp文件中的位置和大小,最后把其解压出来。 ! H8 k  ^' V( K' B$ w
1 I- }3 `1 i( N. ?; u5 U
解压具体过程如下: 6 c" I. z# V4 t5 A' _7 F6 [! X
  将待解压的文件名转为小写(如果为英文字母),利用GetDisp(char* s,int v)函数
4 C9 Z( k) U" r) Z' W8 g; {计算相关数据,其中s代表文件名,v代表计算参数,分别计算GetDisp(fname,1),GetDisp 9 }( B6 I& @6 B1 F# d) o  E2 W# h
(fname,2), * y* M. n6 H+ k7 z; ^, C
GetDisp(fname,3),得到三个值a1,a2,a3。其中a3低位与在文件名索引中的位置有关,a3最 % g2 m, a- y7 ]- K6 v; S' @% D
高位及a1,a2用来进行校验,如果三个值不能同时满足要求,则将偏移位置顺移继续验证, 8 y) x9 ^7 q* a% z6 C: y7 }  \
具体细节懒得写了。 + k$ u7 r8 i5 b) U
以下为GetDisp函数具体内容,我直接将跟踪代码里面的汇编改造了一下拿出来用,其中s 2 p9 J2 X6 a& i" \- ~+ y* u* V
ucks为一个随机数数组,这里不列出来了。 5 ?' [" r4 s* i7 y4 j
unsigned int TLBBUnpacker::GetDisp(char* s,int v)
: x7 ^* m$ o' |# j6 A0 y{
; s$ V- W, c! ___asm * a/ e5 t* r* n9 T
{
* ~9 i+ I7 Z- w" Jpush esi / f# k, w2 H: y. G! m- _, K
mov esi,s $ {0 S! f- t6 S6 E. ?* p9 ]
mov cl,byte ptr ds:[esi] 9 `3 }  M; n4 h" C# v
test cl,cl
. j/ P! x  z* m2 @. ?; h6 Zmov eax,0x7FED7FED ) m* o, {9 C8 a3 f  H: P& e
mov edx,0xEEEEEEEE
  a$ G4 d" s4 kje end
2 `: H5 X/ U0 j% w$ jpush ebx
( Z( i% [! N; N  a8 r* b* d& ~push ebp ) V' o$ i1 P  ~+ g: s: U- P
push edi ) L' V, \8 p- S5 |+ |
mov edi,v
. g/ }& G" w, E" s9 kshl edi,0x8
+ `6 Y, b: [% S2 Titer: ' S8 ]' x2 a; K8 U  T* U
add eax,edx ) e+ ?& S, y  D8 U
imul edx,edx,0x21
8 g- ^5 S$ p# Y! Ymovsx ecx,cl ' C) [/ W: R1 \% \9 f7 m. M
lea ebx,dword ptr ds:[edi+ecx] 0 P( E9 W! ^4 `/ T* D
mov ebp,dword ptr ds:[ebx*4+sucks] ' ~; m) Q" `- G1 H7 `- E6 G
inc esi , X& `2 m+ a  L
add edx,ecx
$ E& ~" F; Z% ]mov cl,byte ptr ds:[esi]
: Z7 j- y! ?$ j$ axor eax,ebp
" o5 T& j2 q1 R% v$ P! G, T5 ltest cl,cl 6 v7 r# N+ X: `2 @) l) D
lea edx,dword ptr ds:[edx+eax+3] - Q9 ]& Z+ N7 |$ a" o
jnz iter
/ x1 k4 \# e# [" `  l9 V% E, wpop edi ) @3 c  Y1 e) S/ h: A
pop ebp
2 a% ~) `; H) A# }pop ebx 6 Z* @1 @' Q1 l
end: " g+ E6 S$ b# R7 g" I5 g
pop esi
" J+ y+ }+ p; F7 @} 9 y% @: o6 k0 B& c+ T
} 4 y2 G# \. G3 D4 L- F. ^
这个为解压单个文件的函数GenerateFile,用到了QT作GUI,大家就当伪代码看吧。
* m* J8 K6 E- b! g! xbool TLBBUnpacker::GenerateFile(QString name) 0 o! ?# l9 T9 I. J
{
! K( d: h5 E" Q! r9 lname=name.toLower(); . y) n0 R0 i8 v0 c) I8 P7 }
unsigned int a=GetDisp(name.toLocal8Bit().data(),3),a2=GetDisp(name.toLocal8B
6 m9 Q5 j) Y, o, B' f7 v' `( dit().data(),2),a1=GetDisp(name.toLocal8Bit().data(),1),b,disp,length; 3 y' X- B" \- R4 [! H% D, y
a&=0x7FFF; ( N5 V1 W2 H) k
while(!((b=((int*)buffer2)[a*3+2])&0x80000000)||a1!=((int*)buffer2)[a*3]||a2!
7 W9 U5 q& r: j) a7 w9 Y, I=((int*)buffer2)[a*3+1]) 4 V% s; R- L; \
{
. R( Z. l/ l# c) M  M/ Sa++; 3 W2 a9 s2 m6 ~4 {4 `( v
a&=0x7FFF;
- I- n# p; [! ?, m1 ?' [9 S} ' c7 J3 N) W, [/ i+ i, _% p$ r) K& G
b&=0x3FFFFFFF;
, c) n4 u$ |, _" edisp=((int*)buffer3)[b*3]; ! ?5 T9 p7 a2 Q8 v
length=((int*)buffer3)[b*3+1]; $ I; o$ V0 l( x2 k1 v: J2 n9 y- o
3 g" M; x' ]8 d% N0 r1 M
QFile pdata(this->package_name);
/ k0 W$ g+ ~0 f$ T$ dif (pdata.open(QFile::ReadOnly)&&pdata.seek(disp)) { 2 k" x& F: V9 N% x' a  n  `
- s; I/ [/ u4 |/ T& b0 p" e
QString wdir=QDir::currentPath()+QDir::separator()+QFileInfo(pdata).fileName : T; U1 D1 O* T, e
()+QDir::separator(); . m, h) M2 G! A: S, W! n7 H$ s- W+ S
QDir dir;
, m4 L5 o# O. ^- |! W0 T* eQDataStream pfin(&pdata);
) g9 @. s; q: j0 E: @2 m1 vQFile file(wdir+name); + Y) X& L, N$ |+ l
QFileInfo info(file);
5 y" x5 X! E; w- w# n, Fdir.mkpath(info.absolutePath());
4 ~1 @/ M& B$ S3 L- d6 kif(file.open(QFile::WriteOnly))
# A+ h/ a  }6 _- E' Q7 ^! l{
* P, t6 i/ u' o* e. s; I" dchar* pBuffer=new char[length];; % @8 B2 [3 }$ A8 A* k+ t$ C
QDataStream fout(&file);
$ ?  K* S# b" f' [+ lpfin.readRawData(pBuffer,length);
6 ~; P, z/ E9 V7 j# h) Z. w! Kfout.writeRawData(pBuffer,length); 8 s: O" P: d$ B5 A! k& o
delete []pBuffer; 9 i; z) _* ]- e1 y: z+ P" P
return true;
/ m  k9 {& Q4 O6 V9 }0 b} 2 y2 V9 w  H& B# A' W
} 8 h$ G' w/ R7 X% w6 }8 Y& [
return false;
/ a  M4 D% w; B; X+ G( p1 C} ; [, L) d7 Z% W; z' f( R0 s0 P
得到待解压文件在文件索引中的位置後就可以找出该文件在axp文件中的具体偏移量和文件
& Y2 f" A2 N9 i- g2 N大小了,然后直接fseek一下然后在弄出来就OK了。
9 V  B8 @; Q9 u( a0 U最后说一下,这个AXP压缩包本身就含有一个文件列表文件叫做(list),所以每次只要先解
& Y* o* i; u9 @+ Z% y压缩这个文件,然后按照里面的文件列表来一一解压缩就OK了。
* W, E9 J, S+ q0 K8 Z) a! C& }
7 B# f0 Z; D, T1 G5 M1 B
6 G$ t; i+ W! H3 n  i以上就是文件大致格式,感觉还是比较简单的,也可以考虑在自己的项目中使用类似方法
4 m  e4 K0 J8 u, r. N进行文件压缩。
8 b- V$ m4 w7 j& u. \$ E- J, t0 l0 K$ j9 T# R* A) S
PS:本文仅供学习,本人不负任何责任。。。。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 很美好很美好 很差劲很差劲
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

冒险解谜游戏中文网 ChinaAVG

官方微博官方微信号小黑屋 微信玩家群  

(C) ChinaAVG 2004 - 2019 All Right Reserved. Powered by Discuz! X3.2
辽ICP备11008827号 | 桂公网安备 45010702000051号

冒险,与你同在。 冒险解谜游戏中文网ChinaAVG诞生于2004年9月9日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

快速回复 返回顶部 返回列表