Because I have no idea why Eliot chose to make a de-compiler for a multi-platform system like Unreal in a platform dependent virtual machine like dotNet... (No offense) Here are the basic C Structures to get you started. Decompiler basics use heuristics based on a Control Flow Graph (CFG) in which you attempt to deconstruct an assembly of some sort into something similar to the languages Abstract Syntax Tree (AST). So read the UnrealScript API and model a tree before you bother with actual deconstruction. It's foolish to start with deconstruction and work up to an AST. If you need help understanding such things and how you should model it, I suggest you try something like: Backus–Naur Form? Maybe? It's really up to you. Personally I use a linked list/tree format. I'm super lazy so I try not to bother with anything overly unnecessary like making helper functions, etc. For the most part my deserialize function just casts the structures to the data, and then lazy links the pointers. (Please, if you don't understand lazy linking, you shouldn't be writing a decompiler.)
This is just something to get you started. I personally wrote mine in C.. Cause I really find C++ becomes far too extravagant for absolutely no reason except programmer preference half the time.
This is just something to get you started. I personally wrote mine in C.. Cause I really find C++ becomes far too extravagant for absolutely no reason except programmer preference half the time.
Code:
#pragma pack(push, 1)
/**
* If you really wanna bother going around and writing your own stream processor like Eliot just to ensure your endianness is correct, do it.
* Otherwise, let's use this compiler/preprocessor trick to so we can literally cast a block of memory to our structure and not have to write parsing code ourselves.
*/
#ifdef __INTEL__
#undef __INTEL__
#endif
#define __INTEL__ 1
#define __INTEL_BYTE_ORDER__ 1
typedef void* VPTR;
typedef unsigned __int32 DWORD, NAME_INDEX;
typedef signed __int32 INT, UBOOL;
typedef unsigned __int8 TCHAR;
struct FPair
{
VPTR Key;
VPTR Value;
};
struct FMap
{
FPair *Data;
DWORD ArrayNum;
DWORD ArrayMax;
DWORD *Hashes;
DWORD HashCount;
};
struct FArray
{
void *Data;
DWORD ArrayNum;
DWORD ArrayMax;
};
struct FGuid
{
DWORD A;
DWORD B;
DWORD C;
DWORD D;
};
struct FString
{
TCHAR *Data;
INT Length;
INT Limit;
};
struct FName
{
NAME_INDEX Index;
WORD Number;
WORD Size;
};
struct FPackageFileSummary
{
INT Tag;
INT FileVersion;
DWORD PackageFlags;
INT NameCount;
INT NameOffset;
INT ExportCount;
INT ExportOffset;
INT ImportCount;
INT ImportOffset;
FGuid Guid;
FArray Generations;
};
struct FArchiveItem
{
FString _Filename_;
DWORD Offset;
DWORD Size;
DWORD Flags;
};
struct FArchiveHeader
{
INT Magic;
INT TableOffset;
INT FileSize;
INT Ver;
INT CRC;
FArray _Items_;
};
struct FArchive
{
INT ArVer;
INT ArNetVer;
INT ArLicenseeVer;
UBOOL ArIsLoading;
UBOOL ArIsSaving;
UBOOL ArIsTrans;
UBOOL ArIsPersistent;
UBOOL ArForEdit;
UBOOL ArForClient;
UBOOL ArForServer;
UBOOL ArIsError;
UBOOL ArIsCriticalError;
UBOOL ArContainsCode;
INT ArMaxSerializeSize;
INT Stopper;
};
#pragma pop