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

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

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

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

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

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

学习一下人家的破解过程,这个游戏是开源游戏引擎OGRE进行开发的喔。
! a. w* i% o2 g3 e& f* r* O
4 J. J! X4 c" n( J+ q  Z" S5 {& l# {1 N5 D6 {4 ?/ V9 g. B
  I% |8 ?9 M+ Y4 B
发信站: 饮水思源 (2007年06月22日02:36:37 星期五) % c, F* {+ V9 M) B

9 W0 M: W, p" N. {7 l作者:[email protected]
& M* v5 j0 ^" X0 F- O, _. j
9 a. m- a5 C. ~三月份时玩了某狐公司的网络游戏《天XXX》,感觉还是蛮有意思的,遂研究了一下。 ) [7 [- k* J0 \& s, g6 c8 R
这个游戏是利用开源游戏引擎OGRE进行开发的,看了一下目录里面的文件结构,主要的数
% R) z$ D" `1 E" @% ~据都放在Data目录下面。不过文件基本都是.AXP后缀的,每一个动辄几十兆,料想肯定是
: r( F+ c9 I2 [( W把游戏文件打包到一起并加密过的,GOOGLE未遂。开始用UE打开看了一下这个AXP文件,发
1 X' P( Z& i8 }现里面居然大部分都是明文的,开始以为只是把文件罗列在一起,不过仔细看了一下,发 6 ~# T# E6 n- a
现每个文件都有一段间隔,前面还有一个数据头,而且文件与名字也无法对应。于是打开 $ n' J6 w, S% i; W
OD手动分析一下,主要过程其实比较简单,CreateFile函数下断,找到文件Buffer位置,
6 P  h; _. _2 j; e+ B. `/ r2 A再下内存访问断点即可来到关键代码区域。略过具体跟踪细节及文件校验部分不讲,文件
! Q) \5 G$ B( q+ f" U9 r格式主要分析如下: . p& ^6 S; w2 [# Y6 Z. w6 [
9 I0 X5 S1 T8 Z3 W9 j
整个AXP文件可以分成四个部分:1.文件头 2.文件名索引 3.文件索引 4.文件数据
5 r. o/ G1 r) W+ |, `) A9 e* |( h- t% N3 t) v/ U
& l, U- C" `$ S+ d; |
1.文件头:
' B- g0 s1 j! r, t( d  整个文件头固定为0x28字节,其中第20个字节开始的一个整数乘以12代表了第三部分
2 E8 [' F" w$ u" ?* ?; J' _. d' ?即文件索引部分的长度(因为每个索引有三个整数构成) 7 n( x0 l+ [- e0 S9 q* E5 d8 K
2.文件名索引: . ~7 I% I# x$ B; G& P- P
  整个文件名索引固定为0x60000字节,其中包含了每个压缩文件对应的文件索引位置
( u9 H3 i2 C+ I, q* f! J
' b; B3 `; P5 `. t6 w# K) a3.文件索引: " ~$ G$ M0 q0 n4 v1 w  X
  本部分长度由文件头相关数据决定,其中包含了每个压缩文件在.axp中的实际偏移位 9 s2 u% U; Z8 ~) ^; z
置及文件大小
6 H- A& f/ B0 i: k; O; L4.文件数据: & k# W: H  C& }# m
  本部分包含所有压缩文件的具体数据,每个文件之间用若干零填充。 & l  r' q" ]. E* _1 p6 q8 u9 f
3 f/ @  F/ T$ P8 v5 A* b% U
首先说说解压总体过程:比如我们要从A.axp中解压出一个叫file.txt的文件,那么先根据
) @, S! n9 f8 k) ^. R文件名file.txt到文件名索引中去找到对应的文件索引,然后再根据文件索引找到这个文
9 t0 R' \+ Q, K: l1 f/ _, M2 A件在axp文件中的位置和大小,最后把其解压出来。 2 G: h0 L7 y# {6 F
9 }7 X+ N* Z& B6 y. S! q. C
解压具体过程如下:
/ G& p7 m: M, L  将待解压的文件名转为小写(如果为英文字母),利用GetDisp(char* s,int v)函数
5 e1 F" P# G: ]. @; f计算相关数据,其中s代表文件名,v代表计算参数,分别计算GetDisp(fname,1),GetDisp
4 M, F* t4 X5 c% y6 x" J& ]% |(fname,2),
8 F8 x3 Z0 X( g' s( F( CGetDisp(fname,3),得到三个值a1,a2,a3。其中a3低位与在文件名索引中的位置有关,a3最
$ Z+ E9 T4 e' P( ]: `高位及a1,a2用来进行校验,如果三个值不能同时满足要求,则将偏移位置顺移继续验证,
+ e, Y- ]+ C9 P9 E. G" d具体细节懒得写了。 - `5 o9 I" ^; M, {1 x: L+ D0 W6 L
以下为GetDisp函数具体内容,我直接将跟踪代码里面的汇编改造了一下拿出来用,其中s
  u0 L; B4 v/ y% ~* `: J" x+ O4 X! Sucks为一个随机数数组,这里不列出来了。 7 o2 K) l$ C- e5 [
unsigned int TLBBUnpacker::GetDisp(char* s,int v) 7 L2 V2 j% ^& n: O+ l: r! J
{
" b! K6 D2 _3 S0 D__asm $ }8 v* Y% E* I' B8 c
{
% i. r9 v. `: A5 ~5 f: Y8 opush esi
. r$ ]2 z) V7 {, }$ i% Kmov esi,s 3 o$ P# \  i9 s1 ^
mov cl,byte ptr ds:[esi] 8 @  y0 h1 ]8 v6 F5 d% N6 r
test cl,cl 2 h8 c# i  _/ T
mov eax,0x7FED7FED
& \' ^. ]% ], Ymov edx,0xEEEEEEEE
( g" `5 T( o6 _, B  u* Mje end # g5 b$ S1 i' k0 R" b
push ebx   O! m% G- I' X
push ebp 8 t  ?; c, [+ d5 P- f4 L% p0 U
push edi * A8 i# p$ x1 L' `7 }2 A/ {, H
mov edi,v + m) _- s8 ^7 U3 c
shl edi,0x8 ( c, b: G2 F8 W! f' L2 h+ X
iter:
' u" _0 ?. U3 N; a. t1 `  ladd eax,edx 0 F/ P0 y# z6 p. L
imul edx,edx,0x21
+ b2 v% k) x) B. C  E( t# pmovsx ecx,cl   M5 e9 [* x8 y8 v/ Y
lea ebx,dword ptr ds:[edi+ecx] * I  D- P) W; v' f4 H1 {
mov ebp,dword ptr ds:[ebx*4+sucks] ( F* h. r' Q0 q- `
inc esi
, f) ~, H3 n1 n4 E8 [) q4 Fadd edx,ecx
2 \4 i/ X1 X/ V1 R* M+ \  R9 C0 V5 n( tmov cl,byte ptr ds:[esi] ! t1 c! `8 D+ e8 C3 n0 s. e
xor eax,ebp * _. c; ?2 l- Y2 Q
test cl,cl + F+ }9 x3 ]. p( f, ~
lea edx,dword ptr ds:[edx+eax+3] # R4 d+ X" i# u! Z- J6 ~# L1 I) `
jnz iter $ E! t6 n; O, K1 h
pop edi 7 h8 D( ?# k) @+ E" n
pop ebp
5 m( K9 U- G6 \+ l/ ]/ epop ebx ) z' Q8 L6 z% b# G. {7 K0 x
end: ; X3 y) S( |3 I% T
pop esi
: Y5 g# z$ k+ @7 n% L7 R* i1 \% m}
  X" }# n: p1 @3 _, u4 ]# K} 1 L2 t' d7 g$ ?) A6 Q$ H
这个为解压单个文件的函数GenerateFile,用到了QT作GUI,大家就当伪代码看吧。 4 D5 {* |5 r) L! I0 _
bool TLBBUnpacker::GenerateFile(QString name)
6 m  M8 H3 @( Q- N4 e7 h: ]{ / S2 V5 S) O( z& q9 Y* k
name=name.toLower();
$ K; d& B9 E6 gunsigned int a=GetDisp(name.toLocal8Bit().data(),3),a2=GetDisp(name.toLocal8B
4 K4 j  Q5 A$ R, v; ]it().data(),2),a1=GetDisp(name.toLocal8Bit().data(),1),b,disp,length;
" ^; Y' @; F) W* x7 oa&=0x7FFF; , _% E8 U! x& l) q, u/ C7 U
while(!((b=((int*)buffer2)[a*3+2])&0x80000000)||a1!=((int*)buffer2)[a*3]||a2!
' ?! V9 D/ n( ]* d: B$ S8 A=((int*)buffer2)[a*3+1]) $ G0 b3 o+ W- p2 E* ^5 W* X% q
{
4 l- o- u, g1 J) W2 ]: F. X' na++; 9 U* c4 O6 G6 I6 Q" [5 D# R
a&=0x7FFF; ! b4 H* e- }; l, y, P# W
}
: q6 K: V: `: B5 m7 `1 Rb&=0x3FFFFFFF; / G9 w9 x/ t0 I# ^# T5 @  p
disp=((int*)buffer3)[b*3];
- h- t& ^9 `3 a  w8 R$ l6 [/ Elength=((int*)buffer3)[b*3+1];
, p0 j& K: M6 r. a/ Z3 i) h2 M0 l& @8 q7 u6 G5 U& d( p
QFile pdata(this->package_name);
5 B0 y1 E2 D3 ^$ d1 f9 Yif (pdata.open(QFile::ReadOnly)&&pdata.seek(disp)) { : i* ^# e; h+ D3 S& X$ L7 i

0 D+ u9 `. d5 f8 J2 X) JQString wdir=QDir::currentPath()+QDir::separator()+QFileInfo(pdata).fileName & o1 u- u1 C! t+ {
()+QDir::separator(); ! x6 K% C& }4 p6 _
QDir dir;
% S- L. M7 K0 k& `QDataStream pfin(&pdata);
! T# e8 G, P* |/ hQFile file(wdir+name);
5 `) N6 j% W" x8 lQFileInfo info(file);
% I4 X% w6 P2 e& Ldir.mkpath(info.absolutePath()); ( T8 j7 _( \! L% A
if(file.open(QFile::WriteOnly))
! t% T9 K5 \& ]" R0 V& K{
/ W2 ]1 _! k8 w. lchar* pBuffer=new char[length];;
' S; F, ]. K5 A  K, `, qQDataStream fout(&file);
4 b5 v/ o4 D% F  a4 H/ i; e2 Upfin.readRawData(pBuffer,length);
# F8 k0 }) A7 L  q' P* Mfout.writeRawData(pBuffer,length);
4 V! }' k8 ^# d) J* ~6 Z9 Jdelete []pBuffer; 9 a% S1 j: P/ I* z: i6 o
return true;
" n$ Z5 Y( [( B0 B) q} / m+ Q5 Q  G; M' ~  m8 }
} 6 c) K; U8 f; e! Y" i% K
return false; # x/ W" ?1 R: y. d$ g' n
}
" L& w) q/ b2 F4 f9 o  R* L$ T: N. @) d得到待解压文件在文件索引中的位置後就可以找出该文件在axp文件中的具体偏移量和文件 1 q$ q8 w. w( r& e8 W2 x
大小了,然后直接fseek一下然后在弄出来就OK了。 8 \4 [8 [3 D& c) b0 g( H! ?# z
最后说一下,这个AXP压缩包本身就含有一个文件列表文件叫做(list),所以每次只要先解
. w; x! |6 b, z  X2 P: Q! z压缩这个文件,然后按照里面的文件列表来一一解压缩就OK了。
- o( Z3 q5 \9 j5 V* ~4 E; j7 A( q7 Y1 U' v1 t- C* q6 T8 f3 Z

3 v- T/ Z* g& X( Y3 B, w8 L以上就是文件大致格式,感觉还是比较简单的,也可以考虑在自己的项目中使用类似方法
! {8 M0 K; a. D进行文件压缩。 ' T4 e/ j9 j$ g
' x* N3 B( c2 X4 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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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