狠色狠色狠狠色综合久久,伊人久久大香线焦综合四虎,久久久91精品国产一区二区三区http://www.shnenglu.com/feixuwu/category/14247.htmlzh-cnSat, 17 Jul 2010 07:46:39 GMTSat, 17 Jul 2010 07:46:39 GMT60劍3資源格式分析(僅用于學(xué)習(xí)和技術(shù)研究)(二)http://www.shnenglu.com/feixuwu/archive/2010/07/16/120581.htmlfeixuwufeixuwuFri, 16 Jul 2010 12:47:00 GMThttp://www.shnenglu.com/feixuwu/archive/2010/07/16/120581.htmlhttp://www.shnenglu.com/feixuwu/comments/120581.htmlhttp://www.shnenglu.com/feixuwu/archive/2010/07/16/120581.html#Feedback7http://www.shnenglu.com/feixuwu/comments/commentRss/120581.htmlhttp://www.shnenglu.com/feixuwu/services/trackbacks/120581.html本文僅用于學(xué)習(xí)研究,不提供解壓工具和實(shí)際代碼。
由于時(shí)間倉(cāng)促,劍3資源格式分析(僅用于學(xué)習(xí)和技術(shù)研究)(一) 大部分只是貼出了分析的結(jié)果,并沒有詳細(xì)的分析過程,比如:如何知道那是一個(gè)pak文件處理對(duì)象,
如何根據(jù)虛表偏移獲取實(shí)際函數(shù)地址等等,這就需要讀者對(duì)c++對(duì)象在內(nèi)存中的layout有一定基礎(chǔ)。
開始正文了~~,先整理下前面的分析結(jié)果:
1、劍3是通過package.ini 來管理pak文件的,最多可配置key從 0-32(0x20)的32個(gè)文件。
2、每個(gè)pak文件都用一個(gè)獨(dú)立對(duì)象來管理,所有的pak對(duì)象指針存儲(chǔ)在一個(gè)數(shù)組里(這個(gè)后面會(huì)用到)。
3、pak文件格式:[pak標(biāo)記(Uint32)] + [文件數(shù)目(Uint32)]+[索引數(shù)據(jù)偏移(Uint32)]+未知內(nèi)容。另外,每個(gè)文件的索引數(shù)據(jù)是16個(gè)字節(jié)。

一、路徑名哈希

  劍3的pak的內(nèi)部文件是通過hash值來查找的,這樣有利于加快查詢速度。這就需要有一個(gè)函數(shù)通過傳入 路徑名返回hash值。
這個(gè)函數(shù)居然是導(dǎo)出的。。。g_FileNameHash  這個(gè)函數(shù)代碼比較少,可以逆向出來用C重寫,也可以直接使用引擎函數(shù)(LoadLibrary,GetProceAddress來使用)。
熟悉劍俠系列的朋友會(huì)發(fā)現(xiàn),這個(gè)函數(shù)從新劍俠情緣(可能歷史更久)開始就沒有變過(確實(shí)沒必要變),具體細(xì)節(jié)就不逐個(gè)分析了,我是寫了一個(gè)單獨(dú)的命令行工具
來測(cè)試的。

二、查詢過程

查詢函數(shù)在sub_10010E00 里,也就是(0x10010E00)的位置,我是通過簡(jiǎn)單分析g_IsFileExist 得知這個(gè)函數(shù)功能的。下面
來分析這個(gè)函數(shù)過程:

從前文可知,pak文件對(duì)象是存儲(chǔ)在一個(gè)數(shù)組的這個(gè)數(shù)組是類似 KPakFile* m_szPakFile[0x21];
前面0x20個(gè)存儲(chǔ)的都是KPakFile對(duì)象指針,最后一個(gè)存儲(chǔ)的是數(shù)組長(zhǎng)度。
這個(gè)搜索結(jié)構(gòu)比較簡(jiǎn)單,就是遍歷所有的KPakFile對(duì)象,逐個(gè)查詢,找到了就返回。想知道具體怎么查詢的嗎,
接下來要看sub_100108B0了。

這個(gè)函數(shù)稍微有點(diǎn)長(zhǎng),分幾個(gè)部分來分析吧:

首先,驗(yàn)證下Hash值是否是0,如果是0,肯定是錯(cuò)了:)
然后接著開始根據(jù)這個(gè)hash值進(jìn)行查找了,經(jīng)過分析,我發(fā)現(xiàn)這個(gè)函數(shù)其實(shí)是一個(gè)二分查找,代碼貼出來如下 sub_10010320 :



從上面的代碼還是比較容易可以知道,每個(gè)文件的16個(gè)索引數(shù)據(jù)中,前4個(gè)字節(jié)是hash值,這個(gè)函數(shù)返回的是這個(gè)文件是pak包的第幾個(gè)。

接著前面的sub_100108B0 來看吧

這一段是保存查詢到的數(shù)據(jù)到對(duì)象里。分析到這里,我只知道16個(gè)索引數(shù)據(jù)前4個(gè)字節(jié)是hash值,那么剩下的12個(gè)字節(jié)呢,
剩下的數(shù)據(jù)基本可以確定是:文件偏移、文件長(zhǎng)度。我是個(gè)懶人,接下來的分析我是通過在fseek、fread下斷點(diǎn)來得到的,為什么不是在SetFilePointer和ReadFile呢,
這是根據(jù)前面的分析得到的,因?yàn)閜ak文件管理對(duì)象使用的是C標(biāo)準(zhǔn)庫函數(shù)。
根據(jù)fread和fseek的結(jié)果,可以得到如下結(jié)果:
索引數(shù)據(jù)構(gòu)成是:
[哈希數(shù)值(Uint32)] + [文件偏移(Uint32)]+[未知數(shù)據(jù)(Uint32)] + 2(文件長(zhǎng)度)+2(未知數(shù)據(jù))。
剩下的,就是看看單獨(dú)內(nèi)部文件的解壓方式了,
在fread的緩沖區(qū)上設(shè)置內(nèi)存斷點(diǎn),就可以找到解壓函數(shù)了:
sub_10018020
這個(gè)函數(shù)不算太長(zhǎng),一開始我也想逆向成C語言,后來看到如此多的分支就放棄了,轉(zhuǎn)而用了一個(gè)偷懶的辦法解決了:
從匯編代碼可知這個(gè)函數(shù)的原型:
typedef int (*PUNPACK_FUN)(void* psrcData, int nSrcLen, void* pDstData, int* pDstLen);
直接加載劍3的dll,設(shè)置函數(shù)地址:
PUNPACK_FUN pEngineUnpack = (PUNPACK_FUN)((unsigned int)hEngineModule + 0x18020);
hEngineModule 是引擎dll的基址,大家看到了吧,dll的函數(shù)即使不導(dǎo)出,我們也是可以調(diào)用的:)

三、尾聲

到這里,已經(jīng)可以寫出一個(gè)pak文件的解壓包了,但是,我們還是沒有還原真實(shí)的文件名,
下面是我解壓的script.pak的文件的部分內(nèi)容:

 終于看到大俠們的簽名了。當(dāng)然,對(duì)著一堆hash值為名字的文件,閱讀起來確實(shí)很困難,
那么有辦法還原真實(shí)的文件名嗎,辦法還是有一些的,可以通過各種辦法改寫g_OpenFileInPak記錄參數(shù)名,來獲取游戲中用到的pak內(nèi)部文件名,相信這難不倒各位了。



]]>
劍3資源格式分析(僅用于學(xué)習(xí)和技術(shù)研究)(一)http://www.shnenglu.com/feixuwu/archive/2010/07/15/120478.htmlfeixuwufeixuwuThu, 15 Jul 2010 13:07:00 GMThttp://www.shnenglu.com/feixuwu/archive/2010/07/15/120478.htmlhttp://www.shnenglu.com/feixuwu/comments/120478.htmlhttp://www.shnenglu.com/feixuwu/archive/2010/07/15/120478.html#Feedback6http://www.shnenglu.com/feixuwu/comments/commentRss/120478.htmlhttp://www.shnenglu.com/feixuwu/services/trackbacks/120478.html不過總體來說還是處于菜鳥階段,這篇文章希望和其他有興趣的兄弟分享下這幾天的經(jīng)歷,僅僅作為技術(shù)研究。


一、安全保護(hù)

  一般來說,很少有游戲的資源格式可以直接通過分析資源文件本身得到答案,大部分難免要靜態(tài)逆向、動(dòng)態(tài)調(diào)試。
無論是靜態(tài)逆向還是動(dòng)態(tài)調(diào)試,首先需要知道當(dāng)前exe和dll的保護(hù)情況,用peid查看,發(fā)現(xiàn)只有g(shù)ameupdater.exe 用upx加殼了。不太明白金山為什么對(duì)客戶端沒有加殼。
其實(shí)我并不關(guān)心gameupdater.exe 是否加殼,畢竟要?jiǎng)討B(tài)分析的目標(biāo)是JX3Client.exe ,要?jiǎng)討B(tài)調(diào)試JX3Client.exe,首先要解決啟動(dòng)參數(shù)問題。

二、啟動(dòng)參數(shù)

  如果直接啟動(dòng)JX3Client.exe,JX3Client.exe會(huì)直接退出,并啟動(dòng)gameuodater.exe,然后通過gameupdater.exe啟動(dòng)JX3Client.exe。
這種啟動(dòng)方式會(huì)影響動(dòng)態(tài)調(diào)試,所以首先我需要找出JX3Client.exe的啟動(dòng)參數(shù)。打開IDA逆向,轉(zhuǎn)到啟動(dòng)處,匯編代碼如下:
start proc near
call    ___security_init_cookie
jmp     ___tmainCRTStartup
start endp
這是一個(gè)典型的VC程序入口,在___tmainCRTStartup 里,crt會(huì)初始化全局變量、靜態(tài)變量,然后進(jìn)入main,我們需要做的是直接找到main,
跟進(jìn)去,會(huì)發(fā)現(xiàn)IDA已經(jīng)幫我們找到WinMain了,直接跟進(jìn)去,
關(guān)鍵代碼在WinMain的入口處:

從這個(gè)代碼片段可以知道,WinMain開始就比較了命令行參數(shù)是否是"DOTNOTSTARTGAMEBYJX3CLIENT.EXE ",如果不是,
則轉(zhuǎn)到啟動(dòng)更新程序了。這個(gè)好辦,我們寫一個(gè)run.bat,內(nèi)容只有一行:
JX3Client.exe DOTNOTSTARTGAMEBYJX3CLIENT.EXE
運(yùn)行,果然,直接看到加載界面了。

三、PAK文件管理

  在劍3里,PAK目錄下有很多PAK文件,劍3是通過package.ini 來加載和管理pak內(nèi)部文件的。
這個(gè)文件內(nèi)容如下:
[SO3Client]
10=data_5.pak
1=ui.pak
0=update_1.pak
3=maps.pak
2=settings.pak
5=scripts.pak
4=represent.pak
7=data_2.pak
6=data_1.pak
9=data_4.pak
Path=.\pak
8=data_3.pak
基本上PAK目錄下所有的PAK文件都列出來了,其實(shí)劍3的資源文件打包方式基本上和新劍俠情緣類似(細(xì)節(jié)還是有比較大的差別)。
打開ollyDbg,帶參數(shù)啟動(dòng)JX3Client.exe,在CreateFile設(shè)置斷點(diǎn),可以發(fā)現(xiàn),package.ini 的讀取和處理是在
Engine_Lua5.dll 的g_LoadPackageFiles 函數(shù),熟悉新劍俠情緣資源管理方式的同學(xué)大概會(huì)猜到這個(gè)函數(shù)是做什么的,先看看函數(shù)內(nèi)容吧,這個(gè)函數(shù)比較長(zhǎng)
只能逐步的分析了,首先是打開ini文件

使用g_OpenIniFile打開前面提到的ini文件,如果打開失敗,自然直接返回了。
打開成功后,循環(huán)讀取ini配置的文件,讀取的section是SO3Client 讀取的key是0到0x20。

loc_1001119A:           ; int
push    0Ah
lea     ecx, [esp+1A0h+var_178]
push    ecx             ; char *
push    ebx             ; int
call    ds:_itoa        ; 這是根據(jù)數(shù)字生成key的代碼
mov     edx, [ebp+0]
mov     edx, [edx+24h]
add     esp, 0Ch
push    40h
lea     eax, [esp+1A0h+var_168]
push    eax
mov     eax, [esp+1A4h+var_184]
push    offset unk_10035B8C
lea     ecx, [esp+1A8h+var_178]
push    ecx
push    eax
mov     ecx, ebp
call    edx             ; 讀取INI內(nèi)容 readString(section, key)
test    eax, eax
jz      loc_1001127A

這段是通過readString("SO3Client", key)來獲取pak文件名, key就是"0"~"32"的字符串,也就是最多能配置32個(gè)Pak文件。
獲得了pak文件名后,下面就是打開和保存pak文件的索引數(shù)據(jù)了。

后面的注釋是我分析的時(shí)候加上的,IDA這個(gè)功能不錯(cuò)!
首先new一個(gè)0x20字節(jié)的空間用來存儲(chǔ)pak對(duì)象(我自己命名的類),接著調(diào)用構(gòu)造函數(shù),創(chuàng)建pak對(duì)象。
創(chuàng)建對(duì)象后,要用這個(gè)Pak對(duì)象打開對(duì)應(yīng)的pak文件了,這是我們下面的代碼:

首先通過
mov     [edi+edx*4], eax
將對(duì)象保存,然后,調(diào)用這個(gè)類的成員函數(shù)打開pak文件,具體代碼在sub_10010ca0。

這段代碼的意思很明白了,打開文件,讀取0x20的文件頭,


這里做的是驗(yàn)證文件格式,和一些必要的驗(yàn)證。

這段是讀取pak內(nèi)部文件數(shù)目,讀取索引數(shù)據(jù),以備后面查詢使用。
到此為止,所有pak文件的管理對(duì)象都已經(jīng)加載和設(shè)置完畢了。
以上內(nèi)容看起來很順理成章,但是實(shí)際上凝聚了無數(shù)的失敗和重試。
后面是pak內(nèi)部文件的查找和讀取了。
剩下的內(nèi)容明天貼了~~~




]]>
色8激情欧美成人久久综合电| 99久久99久久精品免费看蜜桃| 久久成人国产精品一区二区| 老司机午夜网站国内精品久久久久久久久 | 久久久久无码精品国产| 精品永久久福利一区二区| 97精品伊人久久久大香线蕉| 久久精品国产99久久久香蕉| 亚洲中文字幕久久精品无码喷水 | 久久AV高潮AV无码AV| 成人免费网站久久久| 精品久久久久久久久免费影院| .精品久久久麻豆国产精品| 亚洲国产综合久久天堂 | 国产毛片久久久久久国产毛片 | 久久九色综合九色99伊人| 色8久久人人97超碰香蕉987| 久久精品国产欧美日韩| 国产精品一区二区久久| 性欧美大战久久久久久久久| 久久无码人妻精品一区二区三区| 久久影院综合精品| 2021国产精品午夜久久| 日本亚洲色大成网站WWW久久| 久久综合久久综合九色| 精品无码久久久久久尤物| 无码人妻少妇久久中文字幕蜜桃| 精品久久久久中文字| 激情久久久久久久久久| 久久久久夜夜夜精品国产| 99久久人妻无码精品系列| 国产亚洲精品自在久久| 亚洲中文字幕无码久久2020| 久久国产AVJUST麻豆| 久久久久久久精品妇女99| 日韩精品久久久久久久电影| 久久天天躁狠狠躁夜夜av浪潮| 久久99精品国产99久久6| 久久久无码精品午夜| 97视频久久久| 亚洲精品高清国产一线久久|