01-08-2016, 09:06 PM
(This post was last modified: 01-08-2016, 09:37 PM by Struggleton!.)
(01-08-2016, 05:12 PM)Anexenaumoon Wrote:(01-08-2016, 05:07 PM)ThatTrueStruggle Wrote:(01-08-2016, 04:09 PM)Anexenaumoon Wrote: Thank you. I will look at it in a few!
I acutally figured out the format just now. If you need help, me or TGE can help you out
I'm looking at it haha I've got as far as the magic id right now xD trying to figure out endiness
EDIT: I'm absolute crap at this. I don't understand a single thing. I'm just not a script writer. I'm frustrated right now, I give up. This is embarrassing.
Here's my code for this file:
Code:
idstring "TGP0"
get unk long
get dummy long
get fileCount long
for i = 0 < fileCount
get filename string
do
get advance byte
while advance == 0
savepos pos
math pos - 1
goto pos
get offset long
get dummy long
get size long
get dummy long
log filename offset size
next i
I'll walk you through it, and help you to figure it out for yourself. Remember that reverse engineering is a process, and takes a while to learn the tools of the trades, keep at it, and remember to ask questions. Questions are essential to learning
First is the idstring. This is four bytes that make up the string, "TGP0". This goes down in our script. This prevents the script from being used with incompatible files.
Code:
idstring "TGP0"
Next is a unknown value. However we don't need to know all the values of a file to extract the contents, This value looks like a 4 byte value, so we list that down as "get unk long". A long, is a 4 byte value.
Code:
idstring "TGP0"
get unk long
Right here is a group of dummy bytes, with the value of zero. We read past this:
Code:
idstring "TGP0"
get unk long
get dummy long
So next value, We'll assume this is the file count. If you count the amount of filenames, you can see there are 139, which 0x8b, which is our filecount. So list this as "get FileCount long".
Code:
idstring "TGP0"
get unk long
get dummy long
get FileCount long
That's our file header. We've read through the header, so now to the file table. For reading our file data, we can use a for loop. This'll allow us to have a variable ("i" in this case) and keep looping the code until i equals FileCount, which is 139. So the code in our loop will loop 139 times. So let's get started on that.
Code:
idstring "TGP0"
get unk long
get dummy long
get FileCount long
for i = 0 < FileCount
CODE HERE
next i
So we create a variable called i, with the value of 0. FileCount is greater than zero, so it does the code in between the for and next tags once. Then QuickBMS increases i by one. It will do this until i equals FileCount or exceeds it.
Looks like the format goes like this: FileName, Null Bytes, then the Offset and Size of the file. FileName should be self explanatory. Null bytes are a group of bytes with the value of 0. Offset is the position of the data of the file, and the Size is the amount of bytes in the file. So our code will look like this:
Code:
idstring "TGP0"
get unk long
get dummy long
get FileCount long
for i = 0 < FileCount
get FileName string
do
get Advance byte
while Advance == 0
savepos Position
math Position - 1
goto Position
get Offset long
get Dummy long
get Size long
next i
You might be wondering what this part is:
Code:
do
get Advance byte
while Advance == 0
savepos Position
math Position - 1
goto Position
This is another type of loop, that in this case allows us to skip past all those null bytes. You might also wonder, since we read past those dummy/null bytes before, why can't we do it the same way here? Well the way the file works is that the dummy bytes adds padding to make the file align to a certain offset, which lets the game console's CPU load the data without modifying it. This allows for faster loading ingame. To make a long story short, the loop reads one byte at a time, and checks if it's equal to 0. Until it equals something other than 0, it will continue to go one byte at a time. Now that the byte doesn't equal 0, we save the our current position, and subtract 1. Since we had to read the byte to make sure it wasn't zero, we need to go back in order to properly read it. Then we go to the new position that we created.
So finally we're almost done. Now we need to make QuickBMS save the data to a file. We do this by using the "log"
command. It works like this: log filename offset size. All of those values, we read before. So we just need to feed those values to the log command:
Code:
idstring "TGP0"
get unk long
get dummy long
get FileCount long
for i = 0 < FileCount
get FileName string
do
get Advance byte
while Advance == 0
savepos Position
math Position - 1
goto Position
get Offset long
get Dummy long
get Size long
log FileName Offset Size
next i
Then finally we can save it to a file and load it up using QuickBMS, and it'll extract the files from the archive! If you have any questions on the script writing process, please post them. I'll try to answer them to the best of my ability!