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

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

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

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

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

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

学习一下人家的破解过程,这个游戏是开源游戏引擎OGRE进行开发的喔。 / r& W1 A! I- D" k6 {" c, I  j. V
! L! v  P3 f3 C" t+ Q4 j( H) E

) n% c6 M2 m! g9 l6 v6 B; Y1 `1 ~& g. s/ e/ |+ S! @4 c
发信站: 饮水思源 (2007年06月22日02:36:37 星期五) 5 u4 g! w/ S: V' @
8 J  I  p$ r& ]) D' g/ d2 O
作者:[email protected]
  d8 Z8 `" _. g- p
8 v5 R8 |* f  z& j8 s. h8 s三月份时玩了某狐公司的网络游戏《天XXX》,感觉还是蛮有意思的,遂研究了一下。
& ~( J  r  n; K- h; P这个游戏是利用开源游戏引擎OGRE进行开发的,看了一下目录里面的文件结构,主要的数
: j) P& o) s! U' {5 T/ o据都放在Data目录下面。不过文件基本都是.AXP后缀的,每一个动辄几十兆,料想肯定是 " l  g( i" d$ |$ ]- s9 a& f- v
把游戏文件打包到一起并加密过的,GOOGLE未遂。开始用UE打开看了一下这个AXP文件,发 7 Q7 ?8 b9 ^: ^4 m8 N
现里面居然大部分都是明文的,开始以为只是把文件罗列在一起,不过仔细看了一下,发 & O% E5 A; ~9 U$ ?) i7 f0 D2 S! L
现每个文件都有一段间隔,前面还有一个数据头,而且文件与名字也无法对应。于是打开
3 q/ r: t# e# r: K, |OD手动分析一下,主要过程其实比较简单,CreateFile函数下断,找到文件Buffer位置, + _( E+ n$ x# V. H" c/ C7 ]
再下内存访问断点即可来到关键代码区域。略过具体跟踪细节及文件校验部分不讲,文件 5 g1 q9 D+ d& }
格式主要分析如下:
. g: j! h0 d# z
) d, P+ O, \- L整个AXP文件可以分成四个部分:1.文件头 2.文件名索引 3.文件索引 4.文件数据
0 a9 t. [) m$ A$ `7 }$ Y
% [' J7 X$ M' k' S5 V' ~& Q8 K; c" k( f
1.文件头:
5 }; a% u7 _. ]* {9 ]7 @5 O  整个文件头固定为0x28字节,其中第20个字节开始的一个整数乘以12代表了第三部分 ( }7 ~6 F1 v! |8 x" m
即文件索引部分的长度(因为每个索引有三个整数构成) 5 n  i; R5 j- }1 h1 e
2.文件名索引: 7 |' r7 k: w- i# g6 _% k
  整个文件名索引固定为0x60000字节,其中包含了每个压缩文件对应的文件索引位置 7 l7 m( q! C% w
7 J& h9 ?8 O" ]
3.文件索引: & T4 Z8 p) [0 x
  本部分长度由文件头相关数据决定,其中包含了每个压缩文件在.axp中的实际偏移位 9 L8 r. L, r8 v2 G' w
置及文件大小
; C1 D2 k6 ~0 C* c8 o7 I' F4.文件数据:
; @% S  C; L* ]  本部分包含所有压缩文件的具体数据,每个文件之间用若干零填充。 5 z1 Z2 R( `/ K8 ]" U+ K+ ~
% `/ H; q7 g" E& ?& i
首先说说解压总体过程:比如我们要从A.axp中解压出一个叫file.txt的文件,那么先根据 % b* H! p: @" F5 I4 Z1 s; q4 D
文件名file.txt到文件名索引中去找到对应的文件索引,然后再根据文件索引找到这个文
" p+ Y; ]: z8 g$ ?" P( F( ]1 z件在axp文件中的位置和大小,最后把其解压出来。 : x7 A( c% U+ D5 w# |% _+ Y
$ m7 i# q& n0 {. C
解压具体过程如下:
' H7 @9 g# ^9 w  将待解压的文件名转为小写(如果为英文字母),利用GetDisp(char* s,int v)函数
7 i  ~- {- c/ L8 x. }* f- ]$ d计算相关数据,其中s代表文件名,v代表计算参数,分别计算GetDisp(fname,1),GetDisp 3 w$ H5 S9 @1 Q
(fname,2),
/ g+ V  T" {8 D0 P4 _0 F- ^GetDisp(fname,3),得到三个值a1,a2,a3。其中a3低位与在文件名索引中的位置有关,a3最 4 |% c) N5 b' B0 z% V
高位及a1,a2用来进行校验,如果三个值不能同时满足要求,则将偏移位置顺移继续验证, . ]% k; z/ i  s! }
具体细节懒得写了。 4 C% D. p0 S0 F% a% B8 g
以下为GetDisp函数具体内容,我直接将跟踪代码里面的汇编改造了一下拿出来用,其中s
. Z$ N6 B; M- G; k2 aucks为一个随机数数组,这里不列出来了。 : J8 F4 N/ J0 A
unsigned int TLBBUnpacker::GetDisp(char* s,int v) 4 Q4 s7 N0 F' Z. {
{ ; R  T! j! V  V: Y( z- X
__asm $ l5 {- ^! \0 c
{ % V9 J1 }* w) H! r5 P
push esi
" u9 a, ^& F  Z0 X0 i/ `mov esi,s
9 h. z/ W, d, E3 ^' r' h& O! ]7 i: Kmov cl,byte ptr ds:[esi] : O/ v1 {5 V5 l/ u9 q% o" S# B
test cl,cl
7 D, `1 D, M7 T1 ~7 K) R9 S- I3 kmov eax,0x7FED7FED 3 {3 S6 M# |! t# b; e8 U7 u* W: ?
mov edx,0xEEEEEEEE : r% I1 l2 |; D2 f
je end   z1 ~) `5 x- J9 S- Q! @( I
push ebx
% o0 g' H7 q- A% ~% Gpush ebp
3 u- a5 R- m& Vpush edi + j7 g! D0 Q& D5 f
mov edi,v
$ Q2 G# @- Q+ ?/ y/ n' W6 v, @4 T$ Lshl edi,0x8
* P( j* v- q% F/ ^$ Z# ~iter:   Q) p- e8 l/ K8 m, v
add eax,edx ! @" N0 B! R: g  [7 \% b1 x
imul edx,edx,0x21
1 Q; k. l$ d  Xmovsx ecx,cl
8 S2 h7 R( ]" N& ?( K$ elea ebx,dword ptr ds:[edi+ecx] " i, V8 J* i- _- ~
mov ebp,dword ptr ds:[ebx*4+sucks] 9 y; t! ], y7 z5 s
inc esi 0 w( |9 k( n3 d: ^: _
add edx,ecx
( f8 h% W$ l9 bmov cl,byte ptr ds:[esi]
# C7 q/ J. f/ w3 _' s& pxor eax,ebp
# M8 Y4 N3 `$ a  r5 U- ?3 G/ H8 ctest cl,cl
; Q% r/ k; N' t. T$ E  N0 olea edx,dword ptr ds:[edx+eax+3] ; @: s9 h: Y" \- r: i: B  t% }% C
jnz iter ( _- l* H7 R' B7 K# y% S0 O
pop edi & q7 [0 \1 i/ n4 X% X& u- @
pop ebp
0 G* T# d  z% I+ A5 W  ?- _pop ebx
6 J  |% G( f0 d. T; T" B0 @end: & K# f3 k7 S# h( h  t
pop esi
- X, o7 h; x- f9 s} , d) q/ [% u5 T( V% K
} . E* M; D' h1 D% {  R
这个为解压单个文件的函数GenerateFile,用到了QT作GUI,大家就当伪代码看吧。
# b2 I. C! E/ a" i8 w/ ebool TLBBUnpacker::GenerateFile(QString name) 5 k# W0 [7 Y" m, i2 q/ U6 T
{
$ h) S6 {% u; a2 j. I: @* A: x9 q' _) Tname=name.toLower();
' b+ j* t! W# @2 gunsigned int a=GetDisp(name.toLocal8Bit().data(),3),a2=GetDisp(name.toLocal8B 2 Z0 y4 f9 K: i  q
it().data(),2),a1=GetDisp(name.toLocal8Bit().data(),1),b,disp,length; ( t) F  b. F+ f2 Q! d) B" L
a&=0x7FFF;
# J2 U5 E* j# M  q- R' `& [6 f7 s8 H3 vwhile(!((b=((int*)buffer2)[a*3+2])&0x80000000)||a1!=((int*)buffer2)[a*3]||a2!
, |  X1 y& W7 L0 G9 `, o=((int*)buffer2)[a*3+1])
; d- |. d1 B. |: X6 W% ?6 D3 `% \{
+ g1 D; i" V$ ]3 l; }/ q% s& b- C6 La++; " L* @" e9 I0 E' Y( C- [; X( T3 q
a&=0x7FFF; ' \% @5 s! @1 o' h. ~, j
}
8 _/ ?1 H# b! a: ]% lb&=0x3FFFFFFF;
, e; L: l* G+ D( ]' n/ {; |2 zdisp=((int*)buffer3)[b*3]; 5 X: C) s+ f+ s
length=((int*)buffer3)[b*3+1]; / [& e# j' F7 C& O3 H
; t# \# g9 J. y! q
QFile pdata(this->package_name); 0 z& K, }* j4 T* b9 n+ B/ @/ t* o
if (pdata.open(QFile::ReadOnly)&&pdata.seek(disp)) { ( R0 `7 c  K& _4 Q; p

- ?1 b/ w$ B! Q" j) iQString wdir=QDir::currentPath()+QDir::separator()+QFileInfo(pdata).fileName % r2 \7 Q* p4 R9 i
()+QDir::separator(); / B% C! J' j2 L
QDir dir;
' w# p" `, r# x/ g( JQDataStream pfin(&pdata);
. `5 z" S' s' O! zQFile file(wdir+name);
' |0 y# |) b: Q9 CQFileInfo info(file);
. C. e8 h( I' W. \( U5 _  J1 Mdir.mkpath(info.absolutePath());
& T& R: {2 V- {$ n& A9 dif(file.open(QFile::WriteOnly)) $ z9 L& N7 G. t) d% g, Y
{ 5 c& J7 F4 S9 S2 A: Y
char* pBuffer=new char[length];;
, }7 q( p5 P& ], n( v% mQDataStream fout(&file); % Y. i/ t8 f) L. w) L0 i
pfin.readRawData(pBuffer,length); $ L' ]! e& i/ V
fout.writeRawData(pBuffer,length);   r, P$ @8 p. C2 q
delete []pBuffer;
$ A0 V% u. \8 @+ ~return true;
' c- C0 x  x, r4 u2 X2 C, J3 G3 E}
0 V* I8 e9 j4 s}
  D* w  _# G  L8 b( G9 ureturn false; ; k; b3 Z- Y% W
}
( @( i0 v% U: F; R1 w& J9 }得到待解压文件在文件索引中的位置後就可以找出该文件在axp文件中的具体偏移量和文件 ; L* \! ?% t0 Q
大小了,然后直接fseek一下然后在弄出来就OK了。 + h1 \: T- `/ x9 [# y3 T) q
最后说一下,这个AXP压缩包本身就含有一个文件列表文件叫做(list),所以每次只要先解
3 q8 `: i4 \  u0 o压缩这个文件,然后按照里面的文件列表来一一解压缩就OK了。
! f" K9 O6 @0 A1 }( ~5 s) h" g( y! @5 @3 O

, X7 a" H& L9 j. B7 k+ x$ h9 t' i以上就是文件大致格式,感觉还是比较简单的,也可以考虑在自己的项目中使用类似方法 & \- u/ c* \" x1 D& g
进行文件压缩。 4 W6 L7 ]1 Y9 G; k2 Y6 C; w0 e7 w" Q' c
3 C7 L5 D+ c+ S  J3 Z& B
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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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