Skip to content

Instantly share code, notes, and snippets.

Created December 2, 2012 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4188391 to your computer and use it in GitHub Desktop.
Save anonymous/4188391 to your computer and use it in GitHub Desktop.
Unpacker for .pack files in World at Arms on iPhone
% ruby unpack.rb
{"unknown_1"=>1, "files"=>10, "unknown_2"=>1}
[{"len"=>7, "name"=>"text_en", "addr_offset"=>168, "file_length"=>221984},
{"len"=>7, "name"=>"text_fr", "addr_offset"=>222152, "file_length"=>241480},
{"len"=>7, "name"=>"text_de", "addr_offset"=>463632, "file_length"=>238680},
{"len"=>7, "name"=>"text_sp", "addr_offset"=>702312, "file_length"=>236167},
{"len"=>7, "name"=>"text_it", "addr_offset"=>938479, "file_length"=>230940},
{"len"=>7, "name"=>"text_br", "addr_offset"=>1169419, "file_length"=>236455},
{"len"=>7, "name"=>"text_jp", "addr_offset"=>1405874, "file_length"=>261112},
{"len"=>7, "name"=>"text_kr", "addr_offset"=>1666986, "file_length"=>246884},
{"len"=>7, "name"=>"text_cn", "addr_offset"=>1913870, "file_length"=>222938},
{"len"=>7, "name"=>"text_ru", "addr_offset"=>2136808, "file_length"=>319494}]
Start extraction....
Done! file = Data_Texts.pack/text_en, length = 221984
Done! file = Data_Texts.pack/text_fr, length = 241480
Done! file = Data_Texts.pack/text_de, length = 238680
Done! file = Data_Texts.pack/text_sp, length = 236167
Done! file = Data_Texts.pack/text_it, length = 230940
Done! file = Data_Texts.pack/text_br, length = 236455
Done! file = Data_Texts.pack/text_jp, length = 261112
Done! file = Data_Texts.pack/text_kr, length = 246884
Done! file = Data_Texts.pack/text_cn, length = 222938
Done! file = Data_Texts.pack/text_ru, length = 319494
..................................
# requires ruby 1.9.3p0
# USAGE: ruby unpack.rb
# BEFORE RUN THIS COMMAND, YOU MUST PUT 'packs/*.pack'
# THEREFORE LS OUTPUT IS LIKE THIS:
# % ls
# unpack.rb packs/
require 'pp'
require 'fileutils'
require 'bindata'
class PackInfo < BinData::Record
endian :little
uint16 :unknown_1
uint16 :files
uint32 :unknown_2
end
class Record < BinData::Record
endian :little
uint8 :len
string :name, :read_length => :len
uint32 :addr_offset
uint32 :file_length
end
Dir.glob("packs/*.pack").each do |pack_name|
io = File.open(pack_name)
# read .pack info
pack_info = PackInfo.read(io)
pp pack_info
# read each records
records = []
pack_info[:files].times do
records << Record.read(io)
end
# extract
pp records
puts "\nStart extraction...."
records.each_with_index{|r, i|
io.seek(r[:addr_offset], IO::SEEK_SET)
dir_name = File.basename(pack_name)
begin
FileUtils.mkdir(dir_name, {:noop => false, :verbose=>false})
rescue
end
path = "#{dir_name}/#{r[:name]}"
contents = io.read(r[:file_length])
File.open(path, "w"){|f| f.write(contents) }
puts "Done! file = #{path}, length = #{r[:file_length]}"
}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment