
Anybody who could make a step by step tutor here for a complete noob in file extraction? I got Wraith Acron
aluigi wrote:Black Ops 3 used the KAPI/IPAK format, maybe this new game uses the same, try this script:
http://aluigi.org/bms/cod_kapi.bms
Code: Select all
idstring "KAPI"
get ZERO short
get VER short
if VER > 10
get DUMMY longlong
get KAPI_SIZE longlong
#for SECTION = 0
get FILES longlong
get OFFSET longlong
get SIZE longlong
if OFFSET == 0 || OFFSET u> KAPI_SIZE
break
endif
savepos SECTION_OFF
goto OFFSET
for i = 0 < FILES
savepos OFFSET
get CHUNKS long
get DUMMY long
if CHUNKS u< 0xffff
if CHUNKS == 0xa7a7a7a7
break
endif
set FILESIZE long 0
for c = 0 < CHUNKS
get CHUNK_META long
xmath FILESIZE "FILESIZE + (CHUNK_META & 0x00FFFFFF)"
next c
padding 128
savepos CHUNKS_OFFSET
print "Offset %CHUNKS_OFFSET|X%"
log "" CHUNKS_OFFSET FILESIZE
goto FILESIZE 0 SEEK_CUR
padding 128
endif
next i
goto SECTION_OFF
#next SECTION
endif
Code: Select all
//------------------------------------------------
//--- 010 Editor v9.0 Binary Template
//
// File:
// Authors:
// Version:
// Purpose:
// Category:
// File Mask:
// ID Bytes:
// History:
//------------------------------------------------
local char KAPI_HEADER[4] = "KAPI";
uint Normalize(uint value) {
return Ceil(value / 128.0) * 128;
}
struct KapiFile {
struct KapiFileData (uint chunks) {
local int c;
local uint chunk_size;
local uint filesize = 0;
local int chunk_flags;
for (c = 0; c < chunks; c++) {
uint chunk_meta <bgcolor=0x00FF00, name="Chunk Meta">;
chunk_size = chunk_meta & 0x00FFFFFF;
chunk_flags = (chunk_meta & 0xFF000000) >> 24;
Assert(chunk_flags == 0 || chunk_flags == 8 || chunk_flags == 0xCF, "Chunk flag is not 0, 8 or 0xCF!");
filesize += chunk_size;
}
FSeek(foffset + 0x80);
byte contents[Normalize(filesize)] <bgcolor=0x00FF00, name="Contents">;
};
local uint foffset = FTell();
uint64 chunks <bgcolor=0x00FF00, name="Chunks Count">;
if (chunks < 0xFFFF) {
if (chunks == 0xA7A7A7A7A7A7A7A7) {
break;
}
KapiFileData filedata(chunks) <name="File Data">;
}
};
struct KapiFiles(uint64 files_count) {
local uint i;
for (i = 0; i < files_count; i++) {
KapiFile file <name="File">;
}
};
struct KapiMeta(uint64 files_count) {
struct KapiFileMeta {
uint64 id <bgcolor=0x00FF00, name="ID">;
uint64 no_idea1 <bgcolor=0x0000FF>;
uint64 no_idea2 <bgcolor=0x0000FF>;
};
local uint i;
for (i = 0; i < files_count; i++) {
KapiFileMeta meta <name="Meta">;
}
};
struct KapiIndices(uint64 files_count) {
// files_count can be many times bigger than in KapiFiles
local uint i;
for (i = 0; i < files_count; i++) {
uint64 id <bgcolor=0x00FF00, name="ID">;
}
};
struct KapiText(uint64 files_count) {
struct KapiFileDesc {
uint64 id <bgcolor=0x00FF00, name="ID">;
uint64 text_length <bgcolor=0x00FF00, name="Text Length">;
char text[text_length] <bgcolor=0x00FF00>;
};
local uint i;
for (i = 0; i < files_count; i++) {
KapiFileDesc file_desc <bgcolor=0x00FF00, name="File Desc">;
}
};
struct KapiBlock(int type) {
uint64 files_count <bgcolor=0x00FF00, name="Files Count">;
uint64 offset <bgcolor=0x00FF00, name="Offset">;
uint64 size <bgcolor=0x00FF00, name="Data Size">;
if (offset == 0 || size == 0 || offset > kapisize) {
break;
}
local uint fpos = FTell();
FSeek(offset);
switch (type) {
case 1: KapiFiles files(files_count); break;
case 2: KapiMeta meta(files_count); break;
case 3: KapiIndices indices(files_count); break;
case 4: KapiText text_index(files_count); break;
}
FSeek(fpos);
};
struct KapiData {
uint64 files <bgcolor=0x00FF00, name="Files Count">;
uint64 offset <bgcolor=0x00FF00, name="Offset">;
uint64 size <bgcolor=0x00FF00, name="Data Size">;
};
struct KAPI11 {
uint64 dummy <bgcolor=0x0000FF>;
uint64 kapisize <bgcolor=0x00FF00>;
KapiBlock block(1);
KapiBlock block(2);
KapiBlock block(3);
KapiBlock block(4);
};
struct {
uchar signature[4] <bgcolor=0x00FF00, name="Signature">;
Assert(signature == KAPI_HEADER, "Wrong file format!");
ushort zero <bgcolor=0x00FF00>;
ushort version <bgcolor=0x00FF00, name="Version">;
if (version > 10) {
KAPI11 kapi;
}
} file <name="KAPI">;
aluigi wrote:few hours ago
Code: Select all
idstring "KAPI"
get ZERO short
get VER short
###############################
# Arrays:
# 0 - UIDs of files in KAPI
# 1 - Per file: chunk size
# 2 - Per file: chunk flags
###############################
if VER > 10
get DUMMY longlong
get KAPI_SIZE longlong
get DATA_FILES_COUNT longlong
get DATA_OFFSET longlong
get DATA_SIZE longlong
get META_FILES_COUNT longlong
get META_OFFSET longlong
get META_SIZE longlong
get INDEX_FILES_COUNT longlong
get INDEX_OFFSET longlong
get INDEX_SIZE longlong
get TEXT_FILES_COUNT longlong
get TEXT_OFFSET longlong
get TEXT_SIZE longlong
if DATA_FILES_COUNT <> META_FILES_COUNT
|| DATA_OFFSET u> KAPI_SIZE
|| META_OFFSET u> KAPI_SIZE
|| INDEX_OFFSET u> KAPI_SIZE
|| TEXT_OFFSET u> KAPI_SIZE
print "Error: data files count is not equal to meta files count - can't match files with their UIDs"
cleanexit
endif
########################################################
# First we need to get list of file UIDs for later use #
########################################################
if META_OFFSET != 0
goto META_OFFSET
for i = 0 < META_FILES_COUNT
get UID1 long
get UID2 long
get UNK1 longlong
get UNK2 longlong
string SUID1 p= "%08X" UID1
string UID p= "%08X" UID2
string UID + SUID1
putarray 0 i UID
next i
endif
###########################################################################
# Now that we have them, we can use UIDs to save files under these names. #
###########################################################################
if DATA_OFFSET != 0
goto DATA_OFFSET
for i = 0 < DATA_FILES_COUNT
get CHUNKS long
get DUMMY long
if CHUNKS u< 0xffff
if CHUNKS == 0xa7a7a7a7
break
endif
set FILESIZE long 0
for c = 0 < CHUNKS
get CHUNK_META long
math CHUNK_SIZE = CHUNK_META
math CHUNK_SIZE & 0x00FFFFFF
math CHUNK_FLAGS = CHUNK_META
math CHUNK_FLAGS & 0xFF000000
math CHUNK_FLAGS u>> 24
math FILESIZE + CHUNK_SIZE
putarray 1 c CHUNK_SIZE
putarray 2 c CHUNK_FLAGS
next c
padding 128
savepos CHUNKS_OFFSET
putvarchr MEMORY_FILE FILESIZE 0
log MEMORY_FILE 0 0
#for c = 0 < CHUNKS
#getarray CHUNK_SIZE 1 0
getarray CHUNK_FLAGS 2 0
if CHUNK_FLAGS == 0
log MEMORY_FILE CHUNKS_OFFSET FILESIZE
elif CHUNK_FLAGS == 1
comtype lzolx
clog MEMORY_FILE CHUNKS_OFFSET FILESIZE 0x8000
elif CHUNK_FLAGS == 3
comtype lz4
clog MEMORY_FILE CHUNKS_OFFSET FILESIZE 0x8000
elif CHUNK_FLAGS == 8
comtype oodle
goto CHUNKS_OFFSET
get CHUNK_XSIZE long
math CHUNKS_OFFSET + 4
math FILESIZE - 4
clog MEMORY_FILE CHUNKS_OFFSET FILESIZE CHUNK_XSIZE
elif FLAGS == 0xcf
log MEMORY_FILE CHUNKS_OFFSET FILESIZE
else
print "Error: unknown CHUNK_FLAGS %CHUNK_FLAGS|X%, contact me"
cleanexit
endif
#math CHUNKS_OFFSET + CHUNK_SIZE
#next c
getarray FILENAME 0 i
get MEM_SIZE asize MEMORY_FILE
log FILENAME 0 MEM_SIZE MEMORY_FILE
goto FILESIZE 0 SEEK_CUR
padding 128
endif
next i
endif
#####################################################
# And finally we can dump meta description per file #
#####################################################
/*
if TEXT_OFFSET != 0
goto TEXT_OFFSET
for i = 0 < TEXT_FILES_COUNT
get UID1 long
get UID2 long
string SUID1 p= "%08X" UID1
string UID p= "%08X" UID2
string UID + SUID1
string UID + ".meta"
get TEXT_LENGTH longlong
savepos OFFSET
//print "%UID% %OFFSET|X% %TEXT_LENGTH%"
log UID OFFSET TEXT_LENGTH
math OFFSET + TEXT_LENGTH
goto OFFSET
next i
endif
*/
endif
Code: Select all
set WHITELIST string ",meta1,meta2,meta3,"
string MYMETA p ",%s," MYMETA # MYMETA was "meta2"
if WHITELIST & MYMETA
do stuff
endif
aluigi wrote:There is a simple trick for using "whitelists" like that