Welcome to Yumao′s Blog.
續上一個拆包記錄
獲得文件塊地址之後
我們就可以從對應的dat0文檔中
找到對應的文件塊了
這章就著重講下文件塊頭的解析
我們還是以前面例子的0a0000.win32.dat0文檔做例子
從前文寫的代碼中有幫我們找出三個地址
那麽我們就從第一個地址 53 B1 80 開始
附近的塊内容如下:
53b170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 53b180: 80 00 00 00 02 00 00 00 8c 1a 00 00 16 00 00 00 53b190: 13 00 00 00 01 00 00 00 00 00 00 00 80 09 8c 1a 53b1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
接著還是給出個人對此段代碼的理解吧
0x53b180-0x53b183 文件頭的長度 0x53b184-0x53b187 未知 0x53b188-0x53b18b 解壓后的文件長度 0x53b80c-0x53b80f 未知 0x53b190-0x53b193 未知 0x53b194-0x53b197 文件塊中文件個數 之後的每八字節為一組 内容為塊内各個文件的説明 例如:本代碼塊只包含一個文件 所以有數據的部分只有0x53b198-0x53b19f 0x53b198-0x53b19b 文件起始相對第一個文件的偏移值 因爲是單文件所以這裡值為0 0x53b19c-0x53b19d 未知 0x53b19e-0x53b19f 單文件解壓后的大小
然後我們按照文件頭的長度偏移到文件開始部分
每個文件開始都會有長度為0x10也就是十六字節的文件頭
下面是此文件頭的例子:
53b200: 10 00 00 00 00 00 00 00 2d 09 00 00 8c 1a 00 00
依然是羽毛的解析時間
從多條案例來看是這樣的理解:
0x53b200-0x53b203 此條文件頭的長度 固定為0x10 0x53b204-0x53b207 全空 0x53b208-0x53b20b 文件壓縮前的長度 0x53b20e-0x53b20f 文件解壓后的長度
老樣子給出代碼
代碼實現的的功能暫時為
尋址到文件内容
獲取文件内容以及壓縮前後的大小
解密的話..下節講喔
private static void getFileContent(long addr, String filePatch2) throws Exception { //解析同文件夾內的dat0文件地址 String dat0Path = filePath.substring(0,filePath.indexOf(".index"))+".dat0"; //開始讀取 RandomAccessFile randomAccessFile = new RandomAccessFile(dat0Path, "r"); randomAccessFile.seek(addr); //進行標准數據頭格式判斷 if(addr<randomAccessFile.length()&&randomAccessFile.readByte()==(byte)0x80){ //數據頭長度獲取 long headerLength = getHeaderLength(randomAccessFile,addr); //數據段內文件個數獲取 int fileCount = getFileCount(randomAccessFile,addr); System.out.print("\r該數據塊內文件個數爲:" + fileCount + " "); //多文件讀取 先將指針偏移到說明頭 獲取文件長度 randomAccessFile.seek(addr+headerLength); //循環幹的事情 for(int i=0;i<fileCount;i++){ int count = i+1; System.out.print("正在處理第 " + count + "個文件 "); while(randomAccessFile.readByte()!=(byte)0x10){ //什麽都不做 就是偏移指針 直到跳到下壹段數據的開始 } //獲取指針 然後處理文件輸出 long nowAddr = randomAccessFile.getFilePointer()-1; //搞定文件即可 System.out.print("地址爲:"+Long.toHexString(nowAddr)+" "); outputFile(randomAccessFile,nowAddr); } }else{ System.out.println(); } randomAccessFile.close(); } private static int getHeaderLength(RandomAccessFile randomAccessFile,long addr) throws Exception{ //按照分析前面四位應該是文件頭的長度 2^7對齊 randomAccessFile.seek(addr); byte[] tmp = new byte[4]; for(int i=3;i>0;i--){ tmp[i] = randomAccessFile.readByte(); } return Integer.parseInt(HexUtils.Bytes2HexString(tmp).replace(" ", ""),16); }
輸出結果參考:
文件塊地址爲: 53 B1 80 該數據塊內文件個數爲:1 正在處理第 1個文件 地址爲:53b200 文件大小爲:[2349, 6796] 文件塊地址爲: 18 文件塊地址爲: 64 00