• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 14,  comments - 57,  trackbacks - 0
               繼續未完成的內容,聲明本文僅用于學習研究,不提供解壓工具和實際代碼
            由于時間倉促,劍3資源格式分析(僅用于學習和技術研究)(一) 大部分只是貼出了分析的結果,并沒有詳細的分析過程,比如:如何知道那是一個pak文件處理對象,
            如何根據虛表偏移獲取實際函數地址等等,這就需要讀者對c++對象在內存中的layout有一定基礎。
            開始正文了~~,先整理下前面的分析結果:
            1、劍3是通過package.ini 來管理pak文件的,最多可配置key從 0-32(0x20)的32個文件。
            2、每個pak文件都用一個獨立對象來管理,所有的pak對象指針存儲在一個數組里(這個后面會用到)。
            3、pak文件格式:[pak標記(Uint32)] + [文件數目(Uint32)]+[索引數據偏移(Uint32)]+未知內容。另外,每個文件的索引數據是16個字節。

            一、路徑名哈希

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

            二、查詢過程

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

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

            這個函數稍微有點長,分幾個部分來分析吧:

            首先,驗證下Hash值是否是0,如果是0,肯定是錯了:)
            然后接著開始根據這個hash值進行查找了,經過分析,我發現這個函數其實是一個二分查找,代碼貼出來如下 sub_10010320 :



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

            接著前面的sub_100108B0 來看吧

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

            三、尾聲

            到這里,已經可以寫出一個pak文件的解壓包了,但是,我們還是沒有還原真實的文件名,
            下面是我解壓的script.pak的文件的部分內容:

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

            posted on 2010-07-16 20:47 feixuwu 閱讀(4740) 評論(11)  編輯 收藏 引用 所屬分類: 逆向工程

            FeedBack:
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-16 22:20 | yafare
            hook他的lua.dll加載腳本的函數,文件名以及腳本緩沖區都可以在堆棧找到。這樣更簡單一些  回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-16 22:47 | feixuwu
            @yafare
            恩,不過這個只對lua有效,打包lua文件一般用luaL_loadBuffer加載。
            而且hook了luaL_loadbuffer是得不到文件名的,對除script以外的資源也無效。  回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-16 23:39 | yafare
            @feixuwu

            之前弄過劍俠世界的腳本,在luaL_loadBuffer斷下之后,文件名是在堆棧里面可以找到的,當時dump了他的一套腳本,可以用來搞外掛了
              回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-17 00:14 | feixuwu
            @yafare
            int luaL_loadbuffer (lua_State *L,
            const char *buff,
            size_t sz,
            const char *name);
            打包文件加載是從內存中加載的,理論上來說是可以沒有文件名的。不過也可能是為了方便調試,主動將最后一個name設置為文件名了。
            外掛其實有更簡單的辦法,結合協程可以做一個單獨的AI腳本,可以做得比較靈活。逆向資源最初是想做游戲卻沒有資源。。。  回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-17 10:32 | yafare
            @feixuwu
            沒試過協程,hook了他lua腳本里面的一個timer,在那里面搞的外掛邏輯
              回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-17 11:36 | feixuwu
            @yafare
            yafare是常在cloud的blog發言的那位?  回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-17 14:46 | yafare
            @feixuwu
            Cloud是啥?
              回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-21 19:44 | suiniannian
            很強很厲害。  回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2010-07-21 20:46 | suiniannian
            你的文章很有用。
            關于索引數據,結合你的理解我有兩種猜測:
            1. 索引數據構成是:
            [哈希數值(Uint32)] + [文件偏移(Uint32)]+[解壓后文件長度] + 2byte(文件在pak中的數據長度)+2byte(0000代表此文件在pak中沒壓縮,0020代表有壓縮)。

            2.用最后1byte就可以分別文件有沒有壓縮,所以也有可能是這樣:
            [哈希數值(Uint32)] + [文件偏移(Uint32)]+[解壓后文件長度] + 3byte(文件在pak中的數據長度)+1byte(00代表此文件在pak中沒壓縮,0x20代表有壓縮)。  回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)[未登錄]
            2013-04-26 16:38 | albert
            感覺就像做夢~瀏覽完了,就是天書~看懂了,就快升天了,自己搞定,就又回到地面了~等完全透析,就進入地獄~  回復  更多評論
              
            # re: 劍3資源格式分析(僅用于學習和技術研究)(二)
            2013-08-19 18:23 | 得一帥
            PAK文件介紹
              PAK文件是使用在劍網1,2,3,劍俠世界中的用來存放資源和相關游戲客戶端文件的壓縮文件格式。

            PAK文件格式結構
              PAK文件格式被組織為一個線性的數據流,它是由一個XPackFileHeader頭部開始,接著就是文件數據區里面每個子文件的數據內容,緊接其后的就是XPackIndexInfo信息,每個文件對應一個XPackIndexInfo,具體分布請看圖1:
            XPackFileHeader
            File_Data_1
            File_Data_2
            File_Data_3
            .......
            File_Data_N
            N * XPackIndexInfo
              



















                            圖1

            數據結構以及說明
              XPackIndexInfo
                struct XPackFileHeader
                {
                 unsigned char cSignature[4]; //四個字節的文件的頭標志,固定為字符串'PACK'
                 unsigned int uCount; //數據的條目數
                 unsigned int uIndexTableOffset; //索引的偏移量
                 unsigned int uDataOffset; //數據的偏移量
                 unsigned int uCrc32; //校驗和(根據索引表內容數據求得)
                 unsigned int uPakTime; //打包文件制作時的時間,秒為單位time()
                 unsigned char cReserved[8]; //保留的字節
                };
              
              uCount:這個PAK內一共包含文件的個數。
              uIndexTableOffset:文件信息XPackIndexInfo在文件中的偏移位置。
              uDataOffset:文件數據區在文件的偏移。
              
              
              XPackIndexInfo
                
                struct XPackIndexInfo
                {
                 unsigned int uId; //子文件id
                 unsigned int uOffset; //子文件在包中的偏移位置
                 unsigned int uSize; //子文件的原始大小
                 unsigned int uCompressSizeFlag; //子文件壓縮后的大小和壓縮方法
                };
                
                uId:是通過HASH代碼得到的HASH值,是由該文件的目錄決定的,并不是對文件內容進行HASH。
                uOffset:這個偏移地址是從文件開始算起的。
                uSize:并未壓縮的文件大小。
                uCompressSizeFlag:包含2個內容,1是壓縮的標記,2是壓縮后的實際大小。最高字節表示壓縮標記,低的三個字節表示子文件壓縮后的大小,對于分塊壓縮的文件,包含該文件全部分塊數據,頭信息數據,分塊信息表等加起來的全部大小,壓縮標記可以使用 uCompressSizeFlag & 0xF0000000 得到,大小可以 uCompressSizeFlag & 0x07FFFFFF得到。
                
                數據區是沒有數據結構的,它只是每個文件內容經過壓縮后組成的一個線性的區域,其中壓縮方式有3中:
                不壓縮,壓縮標記為0x00000000 表示這個文件的內容沒有被壓縮,如果某文件在使用UCL壓縮后比原來還大,那么就不壓縮了
                UCL壓縮,壓縮標記為0x20000000 表示經過了UCL算法壓縮,uCompressSizeFlag里的大小和uSize不相同,UCL壓縮后的大小最大支持128MB。
            子文件分塊壓縮,壓縮標記為0x10000000 表示該文件數據是經過分塊壓縮,就是文件內容被分成了幾塊,內容為該文件全部分塊數據,頭信息數據,分塊信息表組成  回復  更多評論
              
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            文章轉載請注明出處

            常用鏈接

            留言簿(11)

            隨筆分類

            隨筆檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            亚洲国产精品久久久天堂 | 狠狠色丁香久久婷婷综| 亚洲精品成人久久久| 国产精品免费久久久久影院| 久久丫精品国产亚洲av| 久久久久高潮综合影院| 久久受www免费人成_看片中文| 亚洲精品无码久久久久AV麻豆| 国产农村妇女毛片精品久久| 国产成人精品久久亚洲高清不卡| 久久久精品免费国产四虎| 久久777国产线看观看精品| 精品午夜久久福利大片| 国产精品亚洲综合专区片高清久久久 | 久久综合亚洲色HEZYO国产| 国产精品无码久久久久| 久久久久免费视频| 国产精品久久久久蜜芽| 久久精品久久久久观看99水蜜桃| 亚洲AV日韩AV天堂久久| 久久99国产精一区二区三区| 四虎国产精品免费久久5151 | 久久无码人妻精品一区二区三区| 深夜久久AAAAA级毛片免费看| 久久久久久久波多野结衣高潮| 久久成人国产精品| 久久天堂电影网| 午夜视频久久久久一区 | 欧美亚洲国产精品久久蜜芽 | 99久久99这里只有免费费精品| 久久精品国产精品青草app| 精品久久久久久无码中文字幕 | 精品久久久久久国产牛牛app| 亚洲欧美国产精品专区久久| 久久人人爽人人爽人人片av高请| 一级做a爰片久久毛片16| 久久精品成人欧美大片| 四虎国产永久免费久久| 久久亚洲AV成人无码| 国产成人久久久精品二区三区| 国内精品伊人久久久久777|