BMS script to split archive at byte pattern?

Doubts, help and support about QuickBMS and other game research tools
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

BMS script to split archive at byte pattern?

Post by Acewell »

Hi, i know you can combine binary files with a QuickBMS script but can you split them at specific byte patterns?

Lets say i have an uncompressed archive with ten files inside and the header of each file is a1b2 and i want to split these back into ten individual files.
How could i search for a1b2 and loop through the archive while splitting them up?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: BMS script to split archive at byte pattern?

Post by aluigi »

This is a simple example I have in my bms folder that can be easily modified:

Code: Select all

findloc OFFSET string "a1b2"
do
    goto OFFSET
    get DUMMY long
    findloc NEXT_OFFSET string "a1b2" 0 ""
    if NEXT_OFFSET == ""
        get SIZE asize
    else
        math SIZE = NEXT_OFFSET
    endif
    math SIZE -= OFFSET
    log "" OFFSET SIZE
    math OFFSET = NEXT_OFFSET
while NEXT_OFFSET != ""
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

Awesome thank you! this will come in handy. :D

When the string uses non ascii characters together with ascii characters i guess i would use \x with the byte value like this?

Code: Select all

findloc OFFSET string "\x5A\xE0\xC4\x00"
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: BMS script to split archive at byte pattern?

Post by aluigi »

yes, but specify binary instead of string.
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

Okay thanks again :)
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

Is there a way i can specify a custom extension for the split files instead of the generic .dat one? :oops:
i know i can rename them afterwards but i would like to streamline this if possible.
I'm using this to split model files from the archive but it gives them a dat extension instead of msh

Code: Select all

findloc OFFSET binary "\xA1\x03\xC2\xF8"
do
    goto OFFSET
    get DUMMY long
    findloc NEXT_OFFSET binary "\xA1\x03\xC2\xF8" 0 ""
    if NEXT_OFFSET == ""
        get SIZE asize
    else
        math SIZE = NEXT_OFFSET
    endif
    math SIZE -= OFFSET
    log "" OFFSET SIZE
    math OFFSET = NEXT_OFFSET
while NEXT_OFFSET != ""
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: BMS script to split archive at byte pattern?

Post by aluigi »

In that case you have to build the desired filename, for example by using the C printf syntax:
string NAME p "%08x.msh" OFFSET
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

Thanks, i can't seem to get that working in the script though. is there anything else needed to make it work?
I looked up printf for C and got this page
http://www.tutorialspoint.com/c_standar ... printf.htm
but it seem you have to compile the source to get those working. :?

i guess i could just keep using a batch file to rename the extension after splitting :|

Code: Select all

ren *.dat *.msh
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: BMS script to split archive at byte pattern?

Post by aluigi »

Have you replaced the following?
log "" OFFSET SIZE
with
string NAME p "%08x.msh" OFFSET
log NAME OFFSET SIZE

The 'p' operator of the String command allows to use that printf syntax, nothing to compile.
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

ah ha that works! thany you :D
at first i didn't change this
log "" OFFSET SIZE
to this
log NAME OFFSET SIZE
:oops:
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

Hi again, i have one more question about this script i use to split stx textures from the pak archives in Revenge of the Sith game. :D

Code: Select all

findloc OFFSET binary "\x53\x54\x58\x00"
do
    goto OFFSET
    get DUMMY long
    findloc NEXT_OFFSET binary "\x53\x54\x58\x00" 0 ""
    if NEXT_OFFSET == ""
        get SIZE asize
    else
        math SIZE = NEXT_OFFSET
    endif
    math SIZE -= OFFSET
   string NAME p "%08x.stx" OFFSET
   log NAME OFFSET SIZE
    math OFFSET = NEXT_OFFSET
while NEXT_OFFSET != ""


The script currently writes out texture filenames in the order they were split as hexadecimal, i would like to give the textures back their original name which happens to be included in the header for each texture as a string starting at 0x40 where 40 bytes of space is reserved for this string data. the unused bytes are 00 until 0x68.
How can i grab the string at 0x40 and prepend that to the extension during the splitting process? or will this require another script?

this is example of the first 7 lines of stx header which includes the file name string (S_Main_highlight_yellow)

Code: Select all

53 54 58 00 04 00 00 00 00 00 00 00 00 01 00 00 
20 00 00 00 00 01 00 00 20 00 00 00 E4 00 00 00
00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00
03 00 00 00 80 80 00 00 80 00 00 00 56 00 00 00
53 5F 4D 61 69 6E 5F 68 69 67 68 6C 69 67 68 74
5F 79 65 6C 6C 6F 77 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 02 00 00 00 0A 00 00 00


Thank you for any help :oops:
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: BMS script to split archive at byte pattern?

Post by aluigi »

you can add a code like the following at the place of "string NAME ...":

Code: Select all

savepos TMP
goto OFFSET
getdstring DUMMY 0x40
getdstring NAME 40
goto TMP
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

thanks! :D
That gives them correct names but now i lost the extensions
here si what i have now, where am i going wrong? :oops:

Code: Select all

findloc OFFSET binary "\x53\x54\x58\x00"
do
    goto OFFSET
    get DUMMY long
    findloc NEXT_OFFSET binary "\x53\x54\x58\x00" 0 ""
    if NEXT_OFFSET == ""
        get SIZE asize
    else
        math SIZE = NEXT_OFFSET
    endif
    math SIZE -= OFFSET
   string NAME p "%08x.stx" OFFSET
   savepos TMP
    goto OFFSET
    getdstring DUMMY 0x40
    getdstring NAME 40
    goto TMP
   log NAME OFFSET SIZE
    math OFFSET = NEXT_OFFSET
while NEXT_OFFSET != ""
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: BMS script to split archive at byte pattern?

Post by aluigi »

string NAME + ".stx"
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

thanks for the help so far! i'm finding this script very useful for different things and i would like to expand it more :D
How could i change it to search for more than one byte pattern? say 3 or 4 more at the same time :)
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: BMS script to split archive at byte pattern?

Post by aluigi »

I think you mean like searching different magic values at same time.
That's not easy unfortunately.
Acewell
Posts: 706
Joined: Fri Aug 08, 2014 1:06 am

Re: BMS script to split archive at byte pattern?

Post by Acewell »

Okay, how about this, how could i chnge it so it searches for a magic and then goes backward 48 bytes to get the file name where 32 bytes is reserved, then goes forward to the magic and splits the file while writing it out with the string name? :)
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: BMS script to split archive at byte pattern?

Post by aluigi »

findloc returns the offset of the string so you can use "math OFFSET - 48" and "goto OFFSET" to go there and read the filename.
Once you have the offset you have full power.
Dark Frost
Posts: 7
Joined: Tue Apr 26, 2022 5:34 am

Re: BMS script to split archive at byte pattern?

Post by Dark Frost »

Code: Select all

do
    findloc A_OFFSET binary "\x80\x00"
    goto A_OFFSET
    get A_SIZE asize
    findloc Q_OFFSET binary "\x43\x52\x49"
    goto Q_OFFSET
    get Q_SIZE asize
    if A_OFFSET == Q_OFFSET - 32
    findloc B_OFFSET binary "\x80\x01\x??\x??" 0 ""
    goto B_OFFSET
    if B_OFFSET == ""
        get B_SIZE asize
    else
       math B_OFFSET + 4 # 4 is B_OFFSET Byte
        math B_SIZE = B_OFFSET
    endif
    math B_SIZE - A_OFFSET
    string A_OFFSET + ".adx"
    log A_OFFSET A_OFFSET B_SIZE
    math A_OFFSET = B_OFFSET
    goto A_OFFSET
    else
    goto A_OFFSET
While NotEOF <> 0
cleanexit
How Can I return and after Q_OFFSET then A_OFFSET
I need Confirm, check A_OFFSET is how far from Q_OFFSET, Because Sometime A_OFFSET "\x80\x00" Data too far from Q_OFFSET
my data is
Image