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

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

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

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

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

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

学习一下人家的破解过程,这个游戏是开源游戏引擎OGRE进行开发的喔。 & F" Q. H* n, o. i! Z
  y1 w/ O: K8 |( ~1 K
/ M! f" ?4 r4 p* ~
6 L* j- O! Z% c
发信站: 饮水思源 (2007年06月22日02:36:37 星期五)
0 s; D. J' O4 a* g6 o6 w/ ~. e- S; s; J' p8 ?+ U2 i5 p2 `6 r( B; v7 {
作者:[email protected]
! O! M- w" y2 U6 ?/ J+ {' \6 A/ V4 e  E
三月份时玩了某狐公司的网络游戏《天XXX》,感觉还是蛮有意思的,遂研究了一下。
6 W; M! p; R- j. ?. d这个游戏是利用开源游戏引擎OGRE进行开发的,看了一下目录里面的文件结构,主要的数 3 Z8 t$ M2 Y  n( g( p2 Q6 f) I+ d' Z
据都放在Data目录下面。不过文件基本都是.AXP后缀的,每一个动辄几十兆,料想肯定是
" |; u; @( X' y  y把游戏文件打包到一起并加密过的,GOOGLE未遂。开始用UE打开看了一下这个AXP文件,发
' ^! w8 E. x* C" Q; i; w现里面居然大部分都是明文的,开始以为只是把文件罗列在一起,不过仔细看了一下,发 " h' q$ V) E( |" @; @. p
现每个文件都有一段间隔,前面还有一个数据头,而且文件与名字也无法对应。于是打开
6 W  _/ K& z8 z8 V2 p" i; i2 ~OD手动分析一下,主要过程其实比较简单,CreateFile函数下断,找到文件Buffer位置, 9 t* s! b0 T  J& H( J) l
再下内存访问断点即可来到关键代码区域。略过具体跟踪细节及文件校验部分不讲,文件
2 h- H0 z6 G" t  a格式主要分析如下: . I% R8 }* e5 K3 Z8 s  `, ^
4 S* L  }* t% C8 U- ?% @! B. }. Q
整个AXP文件可以分成四个部分:1.文件头 2.文件名索引 3.文件索引 4.文件数据
& m) t, U- ~9 |# M
. {) F. x( k1 o
3 ~+ l, I  q9 D, s1.文件头:   a6 o' k2 u6 J7 B/ u
  整个文件头固定为0x28字节,其中第20个字节开始的一个整数乘以12代表了第三部分
3 k4 x0 \5 ]$ _8 y( `, q即文件索引部分的长度(因为每个索引有三个整数构成) - h  d+ F" v  c9 Q: F+ R
2.文件名索引:
  t4 F. P4 M; K  整个文件名索引固定为0x60000字节,其中包含了每个压缩文件对应的文件索引位置
8 t7 L! {% p, }7 }" A1 j: A5 L6 V( B9 `/ w" ?+ f* y" X2 m* J9 X
3.文件索引:
# ~: v5 v* K/ `) k  本部分长度由文件头相关数据决定,其中包含了每个压缩文件在.axp中的实际偏移位
# H% H9 U3 F% F/ ^8 i/ D& i1 Y, q置及文件大小 9 C2 {& T' E: [* V8 a1 C
4.文件数据:
4 y( Q2 j2 v& d- [4 G- m  本部分包含所有压缩文件的具体数据,每个文件之间用若干零填充。 . \6 ^2 m! M. o6 i+ b2 P' I3 E
6 r" ]! ]( a/ U7 `$ J' |1 x) q! A
首先说说解压总体过程:比如我们要从A.axp中解压出一个叫file.txt的文件,那么先根据
! Z" t5 Z1 y3 q9 A* g5 y/ R文件名file.txt到文件名索引中去找到对应的文件索引,然后再根据文件索引找到这个文 0 A+ D  u2 l! ^3 j" R% ]* _
件在axp文件中的位置和大小,最后把其解压出来。 : g3 i6 _% x2 |, t
7 A! a% D( w) l3 \+ I% l6 Q% X
解压具体过程如下: % {0 k+ h1 }1 P4 v" h
  将待解压的文件名转为小写(如果为英文字母),利用GetDisp(char* s,int v)函数
4 m. S. D5 L5 f2 w计算相关数据,其中s代表文件名,v代表计算参数,分别计算GetDisp(fname,1),GetDisp * S; N6 P6 q' }! C3 ~$ w: f
(fname,2), : a' i4 y- f% p
GetDisp(fname,3),得到三个值a1,a2,a3。其中a3低位与在文件名索引中的位置有关,a3最 9 d1 y5 @) Z0 J( R( J& G
高位及a1,a2用来进行校验,如果三个值不能同时满足要求,则将偏移位置顺移继续验证,
9 d, [% _- D8 C; z具体细节懒得写了。 : ]* L+ e% S; h, U% n
以下为GetDisp函数具体内容,我直接将跟踪代码里面的汇编改造了一下拿出来用,其中s
7 a# C$ A1 u+ o6 C# Mucks为一个随机数数组,这里不列出来了。
+ o: q3 N1 x! K# c  o5 |+ Munsigned int TLBBUnpacker::GetDisp(char* s,int v) / Y6 E$ M) |" C% R5 O' ]- K1 f
{
, F  w- r4 k/ \- ]0 h5 L__asm . h6 w: I5 C. Q1 j# Q4 l
{ - @  V) }7 C, `3 v) ]6 `8 M% D- c
push esi
/ n% N1 N9 u0 P4 }7 R/ S  i5 Y' X: k) W. smov esi,s 7 ?4 ]& d+ o: i# q5 Y# V- e
mov cl,byte ptr ds:[esi]
8 J5 h6 f+ ?1 N8 P3 Z8 S5 stest cl,cl : P0 R$ ?/ A, t2 `$ {" {- \
mov eax,0x7FED7FED
/ }6 I, Q1 b+ ^7 umov edx,0xEEEEEEEE
6 a/ p6 X$ c2 O0 e- V, r, |je end ' S% n; @* X! \- h
push ebx
1 V3 T9 d, u5 P& g# E$ apush ebp 5 W" D4 w3 y% r. v5 U2 ^
push edi
3 w  J2 y7 q) E, C" v* I' ?mov edi,v
5 Q, @* S- m6 R# ushl edi,0x8 ( J0 e3 V2 ^7 i2 R3 V; O
iter:
, m9 G2 l' w1 @: \% E: Zadd eax,edx
3 M2 i4 y9 _, ?0 [$ Q; d7 j" Pimul edx,edx,0x21
$ A5 {0 x1 w! U% o9 H6 Lmovsx ecx,cl
# C: I8 g9 O# alea ebx,dword ptr ds:[edi+ecx] % a! l" y0 x) ?" B$ L
mov ebp,dword ptr ds:[ebx*4+sucks]
+ [6 ^1 V9 W7 a, u/ z/ K0 finc esi
* U7 Q# [  A' n; s2 {; xadd edx,ecx
6 r3 f! G5 ^. M% @! J4 m, Kmov cl,byte ptr ds:[esi] 7 J; ]2 x# A9 z2 v
xor eax,ebp : `9 |; e# V$ F' T6 ?' ^2 t* B2 F
test cl,cl # I4 _- ?5 ?$ r1 T' l& W4 I3 O
lea edx,dword ptr ds:[edx+eax+3] ( K% G) x0 _* h! q# H7 j( l# U% Q& X
jnz iter
% V1 @* j' X% |' L; kpop edi
9 n7 R& L9 q4 ^$ `# ?% ]& ?& z4 |pop ebp * ~) @- i, z  i& Q0 M0 X
pop ebx 8 ?0 n2 j& t4 V
end:
% F2 s) J. o! u; L6 t! Npop esi   [5 {2 A! y; D' X" }. J
}
. C) @$ {, v4 j' N+ p  t4 {7 z}
" [" E8 k" V$ D" M+ g这个为解压单个文件的函数GenerateFile,用到了QT作GUI,大家就当伪代码看吧。
5 k+ X5 i! V0 e- h+ X1 O/ sbool TLBBUnpacker::GenerateFile(QString name)
7 F' |7 x! T( y. H6 B. [& V2 m{ 3 _" H* c- G1 X3 z% b$ u
name=name.toLower(); ) z6 U7 i( ?! Y' h4 C7 E/ Q
unsigned int a=GetDisp(name.toLocal8Bit().data(),3),a2=GetDisp(name.toLocal8B : @2 M# \7 L! U
it().data(),2),a1=GetDisp(name.toLocal8Bit().data(),1),b,disp,length; 2 L# y- J/ e% [1 Z1 j3 i5 p, D
a&=0x7FFF; / ?' f9 g& f. l& {4 A- ~) t9 f
while(!((b=((int*)buffer2)[a*3+2])&0x80000000)||a1!=((int*)buffer2)[a*3]||a2! / M) ^7 p. }4 {* F
=((int*)buffer2)[a*3+1]) ! ^8 w! M# d+ p8 U6 T) e( n3 e
{
" @! |: t$ N0 U! R7 q/ ~6 Pa++; , `1 q( m# o) _" h0 z
a&=0x7FFF; 2 ?  B) {/ c3 G* B$ w% k5 M* x: l# u
}
2 X; \; o! e  A1 ^* P, vb&=0x3FFFFFFF; # S% f  n% ?% r7 y& h( X
disp=((int*)buffer3)[b*3]; - E2 k  }6 Q1 c, y5 H
length=((int*)buffer3)[b*3+1]; 1 k! I6 @2 t8 p6 y

; ^2 M/ \  p( f$ ?/ SQFile pdata(this->package_name); $ o- V( u% d6 ]; v7 E" U
if (pdata.open(QFile::ReadOnly)&&pdata.seek(disp)) {
& \4 X: }' O; i+ e- c7 d
5 O8 C) O+ d2 }+ R: o- X  M5 _+ m  `# KQString wdir=QDir::currentPath()+QDir::separator()+QFileInfo(pdata).fileName
& Z* M# {% R, o* t0 A+ V4 L. D()+QDir::separator();
$ @5 u( I3 ?. |& o3 H* K8 B5 x  SQDir dir; ( G2 [( A8 C4 A
QDataStream pfin(&pdata);
8 A1 ?. ]3 P2 IQFile file(wdir+name);
3 q( B% z; g2 {& K! b" ^7 R2 [QFileInfo info(file);
* M+ a5 w0 ~4 a) A9 X$ Jdir.mkpath(info.absolutePath()); $ M0 y6 c5 o6 H; J- u2 H
if(file.open(QFile::WriteOnly))
; O6 G- F# h+ Y2 H9 i{
: I  J# E/ I$ F  r/ @7 Gchar* pBuffer=new char[length];; 1 d" ~) ^4 d) Q2 W( `0 S0 ]6 M- W$ {) s
QDataStream fout(&file); + w5 O8 C/ K: B) Y. i
pfin.readRawData(pBuffer,length); 4 ]% N" q! s5 {  Z
fout.writeRawData(pBuffer,length); 7 J4 E3 o2 L5 B1 \8 s! l
delete []pBuffer; & X( s6 g9 b* }! g5 A# i) `/ ?
return true;
# a$ A! i2 D- ?) g4 A. }( d} 4 u2 g" F7 v. S1 l3 R/ N2 F' w
}
* n% b9 {; f# i9 `& creturn false; * Z& v$ M) X7 d) y
}
+ {8 K) \: ]* q1 e. ?4 w% r. C得到待解压文件在文件索引中的位置後就可以找出该文件在axp文件中的具体偏移量和文件
8 b! A. }6 S( F) n2 Q大小了,然后直接fseek一下然后在弄出来就OK了。
/ J/ ~0 V; I% I' q# G; E5 z最后说一下,这个AXP压缩包本身就含有一个文件列表文件叫做(list),所以每次只要先解 8 h: c; o  U* k9 @
压缩这个文件,然后按照里面的文件列表来一一解压缩就OK了。 $ H) n2 v3 Z3 I4 q4 U7 _1 C: x$ i

' Y/ r/ H  _& l. O  D/ r$ v& b
4 G3 B$ G& K; Y. \以上就是文件大致格式,感觉还是比较简单的,也可以考虑在自己的项目中使用类似方法
& G1 |8 c# U& U) w2 q进行文件压缩。 1 I* t8 m' w% ^% b5 F0 y" [

: U6 q" l7 K( w4 C7 m3 E% wPS:本文仅供学习,本人不负任何责任。。。。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 很美好很美好 很差劲很差劲
回复

使用道具 举报

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

本版积分规则

冒险解谜游戏中文网 ChinaAVG

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

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

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

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