爱语魔咒的资源提取

豆瓣不给力 放这里吧~~

 

 最近要搞搞 ,爱语魔咒的资源提取,学习了简单的封包提取

爱语魔咒的封包就是对每个资源文件进行简单的zlib加密,然后将资源首尾连接一起,在后面加入文件的索引

资源文件:
Love Chronicles - The Spell.vst

工具:
UltraEdit, Notepad++

过程:
UltraEdit主要用来分析资源文件(幸好文件索引没有加密),分析出该资源文件所包含的文件数目,各文件文件名信息,文件的起始偏移地址。Notepad写代码的~~~
资源文件概述:
00000000h~10d6affch 是 存放所有资源文件的二进制代码

10d6afe0h: AE A1 68 67 4C 63 1A D3 98 C6 34 A6 31 8D 69 4C ; hgLc.訕??峣L 
10d6aff0h: 63 1A D3 98 5A A3 FF 07 11 17 9A B2 19 1C 00 00 ; c.訕Z?...毑.... 
10d6b000h: 1D 00 00 00 43 45 5C 43 4F 4D 49 43 53 5C 30 31 ; ....CE\COMICS\01 
10d6b010h: 5C 50 4C 49 56 45 54 5C 31 2D 30 2D 30 2E 42 4D ; \PLIVET\1-0-0.BM 
10d6b020h: 50 00 00 00 00 87 A1 00 00 1E 00 00 00 43 45 5C ; P....嚒......CE\ 
10d6b030h: 43 4F 4D 49 43 53 5C 30 31 5C 50 4C 49 56 45 54 ; COMICS\01\PLIVET 
10d6b040h: 5C 31 2D 30 2D 30 5F 2E 4A 50 47 87 A1 00 00 75 ; \1-0-0_.JPG嚒..u 
10d6b050h: 88 01 00 1F 00 00 00 43 45 5C 43 4F 4D 49 43 53 ; ?.....CE\COMICS 


 


10d6affch开始就是索引文件,从10d6affch开始,前4个字节 19 1c 00 00,是文件的个数,就是1c19,7193个资源文件。然后四个字节1d 00 00 00是首个文件的文件名长度,表示后面29(00 00 00 1d )个字节是第一个文件的文件名,略过29的字节的文件名后,开始的4个字节就是文件的起始地址,首个文件的起始地址就是00 00 00 00。然后四个字节表示文件的大小,单位是字节,87 A1 00 00 就表示这个文件长度为6791个字节,之后的4个字节就是下个文件的文件名长度了,以后就一次类推。


索引文件的起始信息10d6affch 起始存在这个文件的后4个字节里

10dadb60h: 00 00 00 54 55 54 4F 52 5C 31 2D 30 2D 30 2E 42 ; ...TUTOR\1-0-0.B 
10dadb70h: 4D 50 E4 27 D6 10 77 24 00 00 0C 00 00 00 54 55 ; MP??w$......TU 
10dadb80h: 54 4F 52 5C 49 50 2E 42 4D 50 5B 4C D6 10 A1 63 ; TOR\IP.BMP[L? 
10dadb90h: 00 00 FC AF D6 10 ; ..? 



ok 现在就可以写代码解包了,不要忘记数据还要zlib解压

 

 

再贴解包代码

#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
#   
#
# Usage:
#   python <fileName> <资源文件> <目标文件夹>   
#
# example:
#	python extractor.py The_Spell.vst temp
import sys, os
import os.path
import binascii
import zlib

#转换小端模式 int
def lETransformInt(hexString):
	sbr=""
	j=0
	for i in range(len(hexString)-1,-1,-1):
		sbr = sbr + hexString[i]
	return int(binascii.b2a_hex(sbr), 16)
	
#转换小端模式 String
def lETransformStr(hexString):
	sbr=""
	j=0
	for i in range(len(hexString)-1,-1,-1):
		sbr = sbr + hexString[i]
	return binascii.b2a_hex(sbr)
	
#创建目录 并构造文件路径
def getRootDir(path):
	fullPath = os.getcwd() + "\\"+ sys.argv[2] +"\\"
	print fullPath
	fileName = os.path.basename(path)
	reFilePath = path.split(fileName)[0]
	
	fullPath = fullPath + reFilePath
	if not os.path.isdir(fullPath):
		os.makedirs(fullPath)

	return fullPath + fileName
	
#按路径写入文件
def wtiteFileWithPathAndHex(path, HexStr):
	fileName = getRootDir(path)
	
	hexF = open(fileName, "wb")
	hexF.write(zlib.decompress(HexStr))
	hexF.close()

if len(sys.argv) != 3 :
	print "Usage:\n\tpython <fileName> <资源文件> <目标文件夹> \nexample:\n\tpython extractor.py The_Spell.vst temp "

else:
	f = open(sys.argv[1], "rb")
	#282505212 索引的偏移地址
	f.seek(282505212, 0)

	#读取文件数目
	fileCount = lETransformStr(f.read(4))
	#读取第一个文件长度
	filePathLength = lETransformInt(f.read(4))

	globalOffset = 282505212 + 8

	fileNum = 0
	while filePathLength != 282505212:
		fileNum = fileNum + 1
		#定位到偏移地址
		f.seek(globalOffset, 0)
		print "--------------" + str(globalOffset)
	
		#读取文件路径
		filePath = f.read(filePathLength)
		print "path:" + binascii.b2a_hex(filePath) + "\n" +filePath
	
		#读取偏移地址
		originAdd = lETransformInt(f.read(4))
		print "originAdd:" + str(originAdd)
	
		#读取偏移长度
		offsetAdd = lETransformInt(f.read(4))
		print "offsetAdd:" + str(offsetAdd)
	
		#获取下一个文件的路径长度
		newFilePathLength = lETransformInt(f.read(4))
		print "filePathLength:" + str(filePathLength)
	
		#按偏移地址读取
		f.seek(originAdd, 0)
		#获取偏移的长度的数据
		fileStr = f.read(offsetAdd)
	
		wtiteFileWithPathAndHex(filePath, fileStr)

		#计算文件索引位置
		globalOffset = globalOffset + 12 + filePathLength
	
		filePathLength = newFilePathLength
	
	


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值