EliotVU / Unreal-Library

UnrealScript decompiler library for Unreal package files (.upk, .u, .uasset; etc), with support for Unreal Engine 1, 2, and 3
MIT License
359 stars 85 forks source link

Splinter Cell Double Agent script load crash #50

Open lfricken opened 2 years ago

lfricken commented 2 years ago

When opening a Splinter Cell Double Agent script file, it crashes with the following exception:

Array dimensions exceeded supported range.

Thrown by:LoadPackage
   at UEExplorer.UI.Tabs.UC_PackageExplorer.LoadPackage()
   at UEExplorer.UI.ProgramForm.LoadFile(String fileName)System.OutOfMemoryException: Array dimensions exceeded supported range.
   at System.Collections.Generic.List`1..ctor(Int32 capacity)
   at UELib.UnrealStreamImplementations.ReadArray[T](IUnrealStream stream, UArray`1& array, Int32 count)
   at UELib.UnrealPackage.Deserialize(UPackageStream stream)
   at UELib.UnrealLoader.LoadPackage(String packagePath, FileAccess fileAccess)
   at UEExplorer.UI.Tabs.UC_PackageExplorer.LoadPack
age()

SCDA uses unreal version 2.5 according to wikipedia.

Example file: Core.txt

I'm a .Net developer. I could take a poke around with some pointers.

EliotVU commented 2 years ago

I've taken a quick look at it. The file package's version reads 275 and licensee version reads 0. That package version causes UELib to treat it as a UE3 package, which it clearly can't be, it's probably somewhere around 129 with the remainder being the actual LicenseeVersion.

So given that, the first step required in order to add support for the game is to configure the auto-detection for this game (See https://github.com/EliotVU/Unreal-Library/blob/01772a833d12af22391523ffb47ca2e01890e2ce/src/UnrealPackage.cs#L498)

I would recommend you override the package version, and then start debugging at https://github.com/EliotVU/Unreal-Library/blob/01772a833d12af22391523ffb47ca2e01890e2ce/src/UnrealPackage.cs#L865 keep track of the read data until it stops making any sense or crashes, that'll be the first indication of a package format mismatch, now you could either gamble/trail and error this along with an hex-editor, or use something like Ghidra to reverse engineer the game's .exe or Core.dll (varies from game to game).

When using Ghidra, you will have to locate the code that is responsible for the serialization of the FPackageFileSummary structure. This can usually be located by searching for an ASCII or Unicode error string. (for UE3 a Unicode string with "BinaryFormat" does the trick!).

I'll leave it at this for now, I wish you good luck!

lfricken commented 2 years ago

I did manage to debug it, but wasn't able to crack it.

VendorX commented 2 years ago

TIP: FPackageFileSummary ain't different from regular UE 2 / 2.5 except the name reference, which holds two indexes:

  1. to the NameMap in FPackageFileSummary
  2. to the Names in FName (array is loaded at engine initialisation from FNames.txt file.
EliotVU commented 2 years ago

@lfricken Unfortunately this one is more complicated, esp with the engine difference between the Offline and Online mode ... strange.

@VendorX Thanks! Sounds like you may have successfully reverse-engineered the format?

VendorX commented 2 years ago

Depends on which version is the target (PC, Xbox, Offline, Online) decompilation can be done with more or less success. Every version is highly modified and different from each other. Anyway, you can forget about Xbox version ... It's using .lin format (typical for Xbox) to store needed fragments of different packages - basically, in order to restore some package all '*.lin" archives need to be loaded in to memory because of the fragmentation. Then if you are lucky, you will be able to find all of those export fragments. Hint: Lin archive is treating an object reference not as a pointer but as a real object. Think about it as a memory block, which has its exact place / address in the memory where it needs to be in order to run the game.