Mass Effect Andromeda script for extraction

Hello everyone.

Was wondering if anyone can help, and has more knowledge as to where I can find a python script to extract the Mass Effect Andromeda game assets like any other Frostbite3 game out there such as, Battlefield 4, Mirrors Edge Catalyst, Dragon Age inquisition, StarWarsBattleFront, etc.

I keep trying to extract with other scripts just by modifying the script with the required info, but nothing happens or only errors occur.

I did searched high and low all over and I couldn’t find anything for the game.

PS
My first time posting and although I read the rules I hope I got it in the right spot.
Thank you in advance for any help given.

I keep on searching and browsing the almighty Google and still no sign or info, anyone please?
Anyone knows how to dump all game files in chunks/ebx/res?

Check this tool out:

Thank you kindly, I found it as well, unfortunately for what I need it its useless, I need to actually dump the game files like any other FB3 game in to chunks/ebx/res.

I read that the TOCs are encrypted and uses a different compression format, and thus being so obfuscated, it doesn’t have its own script, I hope for now at least.

once again thank you kindly

I’ve been looking for extraction and audio conversion scripts for awhile now myself. No luck I’m afraid.

Yes indeed, all those explorers out there, obviously load the game files with ease, regardless of TOCs being encrypted, since as far as I know the code for decryption was implemented, they only miss the option to actually dump the game files as a script does, that’s all.

I think I am slowly getting on the right path, anyone knows how to fix this error?


Traceback (most recent call last):
  File "C:\MEADumper (2).py", line 319, in <module>
    dumpRoot(g_MainDataRoot)
  File "C:\MEADumper (2).py", line 289, in dumpRoot
    dump(fname, g_TargetDirectory)
  File "C:\MEADumper (2).py", line 203, in dump
    casPayload(entry, targetPath, sourcePath, entry.size)
  File "C:\MEADumper (2).py", line 263, in casPayload
    finalSize, magic, payloadLen = unpack(">IHH", cas.read(8))
error: unpack requires a string argument of length 8

At a glance, I’d look into giving unpack a string argument of length 8. :v:

In all seriousness, there’s not a lot we can help you with there, without some context.

Can you give us lines 260 to 266 in casPayload?


def casPayload(bundleEntry, targetPath, sourcePath, size):
    catEntry = cat[bundleEntry.sha1]

    # Open the cas file so we can read the payload.
    cas = open(catEntry.path, "rb")
    cas.seek(catEntry.offset)

    # Open the output file so we can write the final data.
    out = open2(targetPath, "wb")

    leftSize = size
      
    while leftSize > 0:
        finalData = None

        # Read the data we need.
        finalSize, magic, payloadLen = unpack(">IHH", cas.read(8))
        leftSize -= 8

 

PM me your Steam name so I can add you on Friends, and we can try to work this out together.

Looking at the Python documentation, though:

After a bit more digging, it seems that “>IHH” means that it wants a 4-byte integer, and then two 2-byte shorts. Which makes sense, since it’s also saying to explicitly interpret the next 8 bytes of data in that way.

So then if that line is erroring, then I would say that it means that the file is running out data. Similarly, finalSize is the integer, magic the first short, and payloadLen the second short.

What’s the context of this script? As in, where did you get it from, and does the original work?

Ok, so the game has encrypted TOCs, apparently no where else found but in the MEA game.
But even so, with out decrypted TOCs, if I use id-daemon script for swbf2full (since it uses as well zstd compression) I get this result as soon as it tries the first TOC:


ambsibling.toc

Traceback (most recent call last):
  File "D:\Mass Effect Andromeda\swbf2full\swbf2full.py", line 391, in <module>
    if "tocRoot" in locals():  dumpRoot(tocRoot)
  File "D:\Mass Effect Andromeda\swbf2full\swbf2full.py", line 329, in dumpRoot
    dump(fname,targetDirectory)
  File "D:\Mass Effect Andromeda\swbf2full\swbf2full.py", line 141, in dump
    toc=cas.readToc(tocPath)
  File "D:\Mass Effect Andromeda\swbf2full\cas.py", line 95, in readToc
    return Entry(unXor(tocPath))
  File "D:\Mass Effect Andromeda\swbf2full\cas.py", line 37, in __init__
    raise Exception("Entry does not start with \\x82 or (rare) \\x87 byte. Position: "+str(f.tell()))
Exception: Entry does not start with \x82 or (rare) \x87 byte. Position: 1

now, if I decrypt the TOCs, and I run it again I get this:


ambsibling.toc

Traceback (most recent call last):
  File "D:\Mass Effect Andromeda\swbf2full\swbf2full.py", line 391, in <module>
    if "tocRoot" in locals():  dumpRoot(tocRoot)
  File "D:\Mass Effect Andromeda\swbf2full\swbf2full.py", line 329, in dumpRoot
    dump(fname,targetDirectory)
  File "D:\Mass Effect Andromeda\swbf2full\swbf2full.py", line 152, in dump
    bundle=cas.Entry(sb)
  File "D:\Mass Effect Andromeda\swbf2full\cas.py", line 32, in __init__
    addField(f,self) #add fields to the entry using reflection
  File "D:\Mass Effect Andromeda\swbf2full\cas.py", line 66, in addField
    entries.append(Entry(f))
  File "D:\Mass Effect Andromeda\swbf2full\cas.py", line 37, in __init__
    raise Exception("Entry does not start with \\x82 or (rare) \\x87 byte. Position: "+str(f.tell()))
Exception: Entry does not start with \x82 or (rare) \x87 byte. Position: 815

And although this lien is correct in itself


finalSize, magic, payloadLen = unpack(">IHH", cas.read(8))


anyway
but while using NoFate’s JnWCrTIIrc\FB2Dumper.py script
it may be the case that it reaches end of file or offsets are wrong, I don’t know I am no expert nor understand all of this not a coder/programmer and such
All CATs are read correctly before dumping even begins.


Parsed 72999 entries in the catalog file 'Win32\streaminginstall\ayainstallpackage\cas.cat'.
Parsed 190 entries in the catalog file 'Win32\streaminginstall\ayainstallpackage\en\cas.cat'.
Parsed 283671 entries in the catalog file 'Win32\streaminginstall\eosinstallpackage\cas.cat'.
Parsed 417 entries in the catalog file 'Win32\streaminginstall\eosinstallpackage\en\cas.cat'.
Parsed 172524 entries in the catalog file 'Win32\streaminginstall\levelprereqinstallpackage\cas.cat'.
Parsed 70 entries in the catalog file 'Win32\streaminginstall\levelprereqinstallpackage\en\cas.cat'.
Parsed 453 entries in the catalog file 'Win32\streaminginstall\mecdefaultinstallpackage\cas.cat'.
Parsed 12859 entries in the catalog file 'Win32\streaminginstall\mppatchinstallpackage\cas.cat'.
Parsed 150385 entries in the catalog file 'Win32\streaminginstall\multiplayerinstallpackage\cas.cat'.
Parsed 42 entries in the catalog file 'Win32\streaminginstall\multiplayerinstallpackage\en\cas.cat'.
Parsed 914232 entries in the catalog file 'Win32\streaminginstall\restofthegameinstallpackage\cas.cat'.
Parsed 1166 entries in the catalog file 'Win32\streaminginstall\restofthegameinstallpackage\en\cas.cat'.
Parsed 239907 entries in the catalog file 'Win32\streaminginstall\spinitialinstallpackage\cas.cat'.
Parsed 428 entries in the catalog file 'Win32\streaminginstall\spinitialinstallpackage\en\cas.cat'.

if I add the following to check for CAS.CAT files, and they turn out ok all looking good no errors


def readCat(catDict, catPath, rootPath):

     print "
readCat..."
     print ("catPath: %s...

") % catPath

     entryCount = 0
     entryCounter = 0

     cat = dbo.UnXor(catPath)[0]
     cat.seek(16) # NyanNyanNyanNyan

     print("[%d]
") % cat.tell()

     entryCount = unpack("<Q",cat.read(8))[0]

     # Not sure where this came from. Maybe align-32?
     cat.read(16)

     print("[%d]
") % cat.tell()

     casDirectory = os.path.dirname(catPath) + "\\"

     print "entryCount: %d..." % (entryCount)

     while entryCounter < entryCount:
         entry = Stub()
         sha1 = cat.read(20)
         entry.offset, entry.size, unk01, casNum = unpack("<IIII",
 cat.read(16))
         entry.path = casDirectory + "cas_" + ("0" + str(casNum) if casNum <
 10 else str(casNum)) + ".cas"

         # TODO: Figure out what unk01 is at a later time.

         catDict[sha1] = entry
         entryCounter = entryCounter + 1

         print("sha1: %s") % hexlify(sha1).upper()

     print "Parsed %d entries in the catalog file '%s'." % (entryCounter,
 catPath.replace(rootPath, '')[1:])

I still get the same result


Traceback (most recent call last):
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (2).py", line 333, in <module>
    dumpRoot(g_MainDataRoot)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (2).py", line 303, in dumpRoot
    dump(fname, g_TargetDirectory)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (2).py", line 217, in dump
    casPayload(entry, targetPath, sourcePath, entry.size)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (2).py", line 277, in casPayload
    finalSize, magic, payloadLen = unpack(">IHH", cas.read(8))
error: unpack requires a string argument of length 8

I had a working script for it somewhere, dont remember any problems extracting it. Sure, i decrypted TOCs before that, and I used one of my scripts, not anyone else’s.

Any chance I could get it as well to dump the game data please?

[editline]15th December 2017[/editline]

Well, it seems more than one TOC is getting same error after is dumping some of the bundles from it,
removing it out of the folder structure, solves the issue temporarily, because it then continues BUT
other TOCs show same error, except one so far that has thrown a different error


Traceback (most recent call last):
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (3).py", line 311, in <module>
    dumpRoot(g_MainDataRoot)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (3).py", line 287, in dumpRoot
    dump(fname, g_TargetDirectory)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (3).py", line 179, in dump
    casPayload(entry, targetPath, sourcePath, entry.size)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (3).py", line 246, in casPayload
    catEntry = cat[bundleEntry.sha1]
KeyError: "\r\xf0>o\xa7-\xff\xf5)\xd5\x18J@_\xfa\xa7\xc1')o"

an after that other TOCs keep showing that same ol error


Traceback (most recent call last):
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (3).py", line 316, in <module>
    dumpRoot(g_MainDataRoot)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (3).py", line 292, in dumpRoot
    dump(fname, g_TargetDirectory)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (3).py", line 206, in dump
    casPayload(entry, targetPath, sourcePath, entry.size)
  File "C:\Users\User\Desktop\JnWCrTIIrc\FB2Dumper (3).py", line 266, in casPayload
    finalSize, magic, payloadLen = unpack(">IHH", cas.read(8))
error: unpack requires a string argument of length 8

now, I may be speculating, and I coud blame the MEADecrypt tool and some TOCs are not decrypted properly?
again, just speculating, not sure how to make them work, but from the looks of it seems that those with knowledge can make it work

its been two full days since I’ve been trying to dump game data, because of those error interruptions, the process is very slow for some reason, and I am still trying to dump it and as I type, finding all TOCs that throw any type of errors, and obviously the game extracts with incomplete data

anyone ???

ok i checked my drive, and it seems i was extracting chunks manually, because it was before i made UFBE and the script for SWBF2 with zstd.
So i have no script actually. And 2 days is nothing in compare to months and years people are waiting to get data from games sometimes.

Oh I know, hehe, I am not complaining, merely being a user like anyone else that doesn’t understand what’s going on with coding/programming/reverse engineering, and such, struggling with something that it was supposed to be a simple extraction following a script that a knowledgeable person made it.

I just couldn’t understand why wont work with my files, until I figured out while researching that it was more messy than I thought, plus all files I have tried to get dumped so far where because you modified lots of script by the original author, otherwise it would have not been possible.
so thank you.