AAO25.com
Community => Games & Programming => Topic started by: -{DG}-_Shadow on Tuesday, April 07, 2015, 17:24:28 PM
-
Hi, I need a pascal programming expert to decompile the AAO Native functions. Does anyone know pascal here?
I looked at pascal and find it a strange programming language.
-
Must be 6-7 years since I did anything in Pascal and I wasn't even an expert back then. From what I remember it's a kind of basic language that requires quite a lot from the programmer.
-
Hi, I need a pascal programming expert to decompile the AAO Native functions. Does anyone know pascal here?
I looked at pascal and find it a strange programming language.
Contact ELiZ, he should know what you're looking for ;)
Messing with UTPT source?
-
Probably something you'd want to ask about on StackOverflow.
Glad to see you made it to the forums :)
-
Do you mean that you want to decompile the Calls in unrealscript like these by looking at the source of UTPT like possessed suggested?
native(4000) final Function InitRotRand (RotationRandomizer R);
native(4001) final Function Rotator CalcRotation (RotationRandomizer R);
native(4002) final Function Vector CalcDirection (RotationRandomizer R, Rotator BaseRot);
native final Function Int GetVersionWarfareEngine ();
native final Function Int GetVersionAGPMajor ();
native final Function Int GetVersionAGPMinor ();
native final Function Int GetVersionAGPTiny ();
native final Function Int GetPlatform ();
native final Function Bool IsDebugBuild ();
native final Function Int GetPrivateProfileInt (string Filename, string Section, string Key);
native final Function String GetPrivateProfileString (string Filename, string Section, string Key);
native final Function String GetBaseDir ();
native final Function Bool CreateDir (string sDirPath);
native final Function String GetSystemTimeForFileName ();
native final Function SetPrivateProfileInt (int Set, string Filename, string Section, string Key);
native final Function SetPrivateProfileString (string Set, string Filename, string Section, string Key);
native final Function SavePrivateProfile (string Filename);
native final Function String FLoad (string szInput);
native final Function String FUnload (string szInput);
native final Function Bool FOpen (string szFilename);
native final Function Bool FOpenWrite (string szFilename);
native final Function Bool FReadLine (out string szLine);
native final Function Bool FWriteLine (string szLine);
native final Function Bool FWrite (string szData);
native final Function Bool FClose ();
native final Function Bool FDelete (string Filename);
native final Function String Extract (string szInput, string szKey);
native final Function String Compress (string szInput, string szKey);
native final Function String GetInputKeyString (int iKey);
native final Function Int PrivateSet (string szCommand);
native final Function Bool LogFileOpen ();
native final Function Bool LogFileWrite (string szType, string szMessage, optional bool bFlush);
native final Function Bool LogFileClose ();
native final Function Bool PlatformIsMacOS ();
native final Function Bool PlatformIsUnix ();
native final Function Bool PlatformIsWindows ();
native final Function Bool PlatformIs64Bit ();
I see no other use, or do you have a c++ decompiler someone wrote in pascal?
-
what i basicly want is to know how the UT_Packages convert the array it generates to bytecodes.
The list i want: (can also be found in UnStack.h)
EX_LocalVariable = $00;
EX_InstanceVariable = $01;
EX_DefaultVariable = $02;
EX_UnknownVariable =$03; // TODO : {UT2003} unknown opcode
EX_Return = $04;
EX_Switch = $05;
EX_Jump = $06;
EX_JumpIfNot = $07;
EX_Stop = $08;
EX_Assert = $09;
EX_Case = $0A;
EX_Nothing = $0B;
EX_LabelTable = $0C;
EX_GotoLabel = $0D;
EX_EatString = $0E;
EX_Let = $0F;
EX_DynArrayElement = $10;
EX_New = $11;
EX_ClassContext = $12;
EX_Metacast = $13;
EX_LetBool = $14;
EX_Unknown_jumpover = $15; // ??? only seen on old packages (v61) at end of functions and in mid of code
EX_EndFunctionParms = $16;
EX_Self = $17;
EX_Skip = $18;
EX_Context = $19;
EX_ArrayElement = $1A;
EX_VirtualFunction = $1B;
EX_FinalFunction = $1C;
EX_IntConst = $1D;
EX_FloatConst = $1E;
EX_StringConst = $1F;
EX_ObjectConst = $20;
EX_NameConst = $21;
EX_RotationConst = $22;
EX_VectorConst = $23;
EX_ByteConst = $24;
EX_IntZero = $25;
EX_IntOne = $26;
EX_True = $27;
EX_False = $28;
EX_NativeParm = $29;
EX_NoObject = $2A;
EX_Unknown_jumpover2 = $2B; // ??? only seen on old packages (v61)
EX_IntConstByte = $2C;
EX_BoolVariable = $2D;
EX_DynamicCast = $2E;
EX_Iterator = $2F;
EX_IteratorPop = $30;
EX_IteratorNext = $31;
EX_StructCmpEq = $32;
EX_StructCmpNe = $33;
EX_UnicodeStringConst = $34;
// =$35
EX_StructMember = $36;
EX_Length = $37; // UT2003
EX_GlobalFunction = $38;
EX_RotatorToVector = $39; // maybe it is another thing??? an invisible conversion?
EX_ByteToInt = $3A;
EX_ByteToBool = $3B;
EX_ByteToFloat = $3C;
EX_IntToByte = $3D;
EX_IntToBool = $3E;
EX_IntToFloat = $3F;
EX_BoolToByte = $40;
EX_BoolToInt = $41;
EX_Remove = $41; // redefined?
EX_BoolToFloat = $42;
EX_FloatToByte = $43;
EX_DelegateCall = $43; // redefined?
EX_FloatToInt = $44;
EX_FloatToBool = $45;
EX_StringToName = $46; // not defined in UT source, but used in unrealscript
EX_ObjectToBool = $47;
EX_NameToBool = $48;
EX_StringToByte = $49;
EX_StringToInt = $4A;
EX_StringToBool = $4B;
EX_StringToFloat = $4C;
EX_StringToVector = $4D;
EX_StringToRotator = $4E;
EX_VectorToBool = $4F;
EX_VectorToRotator = $50;
EX_RotatorToBool = $51;
EX_ByteToString = $52;
EX_IntToString = $53;
EX_BoolToString = $54;
EX_FloatToString = $55;
EX_ObjectToString = $56;
EX_NameToString = $57;
EX_VectorToString = $58;
EX_RotatorToString = $59;
EX_StringToName2 = $5A; // a duplicated opcode found in XIII
EX_Unknown5B =$5B; // un
-
The list generated by utpt:
NativeFunctions_: array[0..228] of TNativeFunction = (
{0000} (Index:00112;Format:nffOperator ;OperatorPrecedence:040;Name:'$' ), // Core.u (aao)
{0001} (Index:00113;Format:nffFunction ;OperatorPrecedence:000;Name:'GotoState' ), // Core.u (aao)
{0002} (Index:00114;Format:nffOperator ;OperatorPrecedence:024;Name:'==' ), // Core.u (aao)
{0003} (Index:00115;Format:nffOperator ;OperatorPrecedence:024;Name:'<' ), // Core.u (aao)
...
);
-
The code that generates this array:
for a:=0 to package.ExportedCount-1 do
if lowercase(package.Exported[a].UTClassName)='function' then
begin
obj:=TUTObjectClassFunction(package.Exported[a].UTObject);
obj.UTClassName;
try
obj.ReadObject;
except
on e:exception do
begin
msg:=format('Exception in function %s.%s'#13#10+e.message,[extractfilename(sr.name),package.Exported[a].UTobjectname]);
memo.lines.add (msg);
//application.messagebox (pchar(msg),'ERROR',mb_ok);
end;
end;
if ((obj.functionflags and FUNC_Native)<>0) and
((obj.functionflags and FUNC_Event)=0){ and
(obj.NativeIndex<>0)} then
begin
indice:=inttostr(obj.NativeIndex);
precedence:=obj.OperatorPrecedence;
//if precedence=0 then precedence:=255;
nombre:=obj.friendlyname;
if (obj.functionflags and FUNC_Operator)<>0 then
begin
if (obj.functionflags and FUNC_PreOperator)<>0 then
formato:='nffPreOperator'
else if precedence=0 then
formato:='nffPostOperator'
else
formato:='nffOperator';
end
else
formato:='nffFunction';
if cuenta>high(juegos[high(juegos)]) then setlength(juegos[high(juegos)],length(juegos[high(juegos)])*2);
with juegos[high(juegos)][cuenta] do
begin
index:=strtointdef(indice,-1);
format:=formato;
operatorprecedence:=precedence;
name:=nombre;
package:=extractfilename(sr.name);
end;
inc(cuenta);
end;
obj.ReleaseObject;
end;
package.free;
e:=findnext(sr);
end;
However, this array is used further in the code and is propably converted to bytes. However i do not understand enough of pascal to decrypt it.
-
I have the tokens for 2.6 at home, I will try to find them elsewhere
-
I also have those, but 2.6 has different tokens. I think the tokens are simulair to unreal tournament, but not 100% sure.
-
I did some Pacal 25 years ago, along with another classic language Fortran as a part of a class I took.
However that will not help a lot since the pasted code is not all that is needed, there is more classes, as reading the code from the functions, and also the class definitions are missing.
I have a complete list of the 289 native functions, and the corresponding info(iNative,OperatorPrecedence and type).
But I will need some information first, the most critical would be, what do you need it for?
-
As seen here from a SS in UTPT, INative,OperatorPresedence and Functionflags are in the end of the function, so you will have to be able to read the code statements to be able to get to right location inside the function to be able to read those properties. The only "easy" part to read is the FriendlyName("++" or "--"), since that is the 6:th index from the start of the function.
(https://aao25.com/forum/proxy.php?request=http%3A%2F%2Fi61.tinypic.com%2F2iifm8p.png&hash=f72ff435515df0324c56f7e44ca807fe)
-
The code that generates this array:
for a:=0 to package.ExportedCount-1 do
if lowercase(package.Exported[a].UTClassName)='function' then
begin
obj:=TUTObjectClassFunction(package.Exported[a].UTObject);
obj.UTClassName;
try
obj.ReadObject;
except
on e:exception do
begin
msg:=format('Exception in function %s.%s'#13#10+e.message,[extractfilename(sr.name),package.Exported[a].UTobjectname]);
memo.lines.add (msg);
//application.messagebox (pchar(msg),'ERROR',mb_ok);
end;
end;
if ((obj.functionflags and FUNC_Native)<>0) and
((obj.functionflags and FUNC_Event)=0){ and
(obj.NativeIndex<>0)} then
begin
indice:=inttostr(obj.NativeIndex);
precedence:=obj.OperatorPrecedence;
//if precedence=0 then precedence:=255;
nombre:=obj.friendlyname;
if (obj.functionflags and FUNC_Operator)<>0 then
begin
if (obj.functionflags and FUNC_PreOperator)<>0 then
formato:='nffPreOperator'
else if precedence=0 then
formato:='nffPostOperator'
else
formato:='nffOperator';
end
else
formato:='nffFunction';
if cuenta>high(juegos[high(juegos)]) then setlength(juegos[high(juegos)],length(juegos[high(juegos)])*2);
with juegos[high(juegos)][cuenta] do
begin
index:=strtointdef(indice,-1);
format:=formato;
operatorprecedence:=precedence;
name:=nombre;
package:=extractfilename(sr.name);
end;
inc(cuenta);
end;
obj.ReleaseObject;
end;
package.free;
e:=findnext(sr);
end;
However, this array is used further in the code and is propably converted to bytes. However i do not understand enough of pascal to decrypt it.
I believe, this snippet comes from Antonio Cordero NativeFunctionArrayGenerator - you're trying to rewrite?
-
thanks for the replies,
it is indeed the NativeFunctionArrayGenerator from Antonio Cordero. I am not trying to rewrite, just trying to understand how it finds what the uscript bytes mean.
ELIZ, looks like you know a bit about this. so if we continue on your example the ++
{0025} (Index:00137;Format:nffPreOperator ;OperatorPrecedence:000;Name:'++' ), // Core.u (aao)
{0027} (Index:00139;Format:nffPostOperator;OperatorPrecedence:000;Name:'++' ), // Core.u (aao)
{0051} (Index:00163;Format:nffPreOperator ;OperatorPrecedence:000;Name:'++' ), // Core.u (aao)
{0053} (Index:00165;Format:nffPostOperator;OperatorPrecedence:000;Name:'++' ), // Core.u (aao)
How would i now know, looking at utpt and these native function, what the byte meaning is in uscript??
Does it mean 0x01, 0x34, 0x02 and 0x00 mean something in uscript bytes?
-
I think i almost got it. now just need to find a way to verify if the offsets are actually the byte opcodes
pFunction inative:0X70 int:112 offset:0X0 Fullname: Function Core.Object.Concat_StrStr
pFunction inative:0X71 int:113 offset:0X1 Fullname: Function Core.Object.GotoState
pFunction inative:0X72 int:114 offset:0X2 Fullname: Function Core.Object.EqualEqual_ObjectObject
pFunction inative:0X73 int:115 offset:0X3 Fullname: Function Core.Object.Less_StrStr
pFunction inative:0X74 int:116 offset:0X4 Fullname: Function Core.Object.Greater_StrStr
pFunction inative:0X75 int:117 offset:0X5 Fullname: Function Core.Object.Enable
pFunction inative:0X76 int:118 offset:0X6 Fullname: Function Core.Object.Disable
pFunction inative:0X77 int:119 offset:0X7 Fullname: Function Core.Object.NotEqual_ObjectObject
pFunction inative:0X78 int:120 offset:0X8 Fullname: Function Core.Object.LessEqual_StrStr
pFunction inative:0X79 int:121 offset:0X9 Fullname: Function Core.Object.GreaterEqual_StrStr
pFunction inative:0X7a int:122 offset:0Xa Fullname: Function Core.Object.EqualEqual_StrStr
pFunction inative:0X7b int:123 offset:0Xb Fullname: Function Core.Object.NotEqual_StrStr
pFunction inative:0X7c int:124 offset:0Xc Fullname: Function Core.Object.ComplementEqual_StrStr
pFunction inative:0X7d int:125 offset:0Xd Fullname: Function Core.Object.Len
pFunction inative:0X7e int:126 offset:0Xe Fullname: Function Core.Object.InStr
pFunction inative:0X7f int:127 offset:0Xf Fullname: Function Core.Object.Mid
pFunction inative:0X80 int:128 offset:0X10 Fullname: Function Core.Object.Left
pFunction inative:0X81 int:129 offset:0X11 Fullname: Function Core.Object.Not_PreBool
..... (more)
-
I think i almost got it. now just need to find a way to verify if the offsets are actually the byte opcodes
pFunction inative:0X70 int:112 offset:0X0 Fullname: Function Core.Object.Concat_StrStr
pFunction inative:0X71 int:113 offset:0X1 Fullname: Function Core.Object.GotoState
pFunction inative:0X72 int:114 offset:0X2 Fullname: Function Core.Object.EqualEqual_ObjectObject
pFunction inative:0X73 int:115 offset:0X3 Fullname: Function Core.Object.Less_StrStr
pFunction inative:0X74 int:116 offset:0X4 Fullname: Function Core.Object.Greater_StrStr
pFunction inative:0X75 int:117 offset:0X5 Fullname: Function Core.Object.Enable
pFunction inative:0X76 int:118 offset:0X6 Fullname: Function Core.Object.Disable
pFunction inative:0X77 int:119 offset:0X7 Fullname: Function Core.Object.NotEqual_ObjectObject
pFunction inative:0X78 int:120 offset:0X8 Fullname: Function Core.Object.LessEqual_StrStr
pFunction inative:0X79 int:121 offset:0X9 Fullname: Function Core.Object.GreaterEqual_StrStr
pFunction inative:0X7a int:122 offset:0Xa Fullname: Function Core.Object.EqualEqual_StrStr
pFunction inative:0X7b int:123 offset:0Xb Fullname: Function Core.Object.NotEqual_StrStr
pFunction inative:0X7c int:124 offset:0Xc Fullname: Function Core.Object.ComplementEqual_StrStr
pFunction inative:0X7d int:125 offset:0Xd Fullname: Function Core.Object.Len
pFunction inative:0X7e int:126 offset:0Xe Fullname: Function Core.Object.InStr
pFunction inative:0X7f int:127 offset:0Xf Fullname: Function Core.Object.Mid
pFunction inative:0X80 int:128 offset:0X10 Fullname: Function Core.Object.Left
pFunction inative:0X81 int:129 offset:0X11 Fullname: Function Core.Object.Not_PreBool
..... (more)
No idea what the value you call Index is, it's the iNative that is the bytecode
You are still missing some information needed if you want to decompile:
NativeFunctions(28).iNative = 237 : NativeFunctions(28).type = "Function" : NativeFunctions(28).Name = "Asc" : NativeFunctions(28).Precedence = 0 ' From Core.u
NativeFunctions(29).iNative = 236 : NativeFunctions(29).type = "Function" : NativeFunctions(29).Name = "Chr" : NativeFunctions(29).Precedence = 0 ' From Core.u
NativeFunctions(30).iNative = 235 : NativeFunctions(30).type = "Function" : NativeFunctions(30).Name = "Caps" : NativeFunctions(30).Precedence = 0 ' From Core.u
NativeFunctions(31).iNative = 234 : NativeFunctions(31).type = "Function" : NativeFunctions(31).Name = "Right" : NativeFunctions(31).Precedence = 0 ' From Core.u
NativeFunctions(32).iNative = 128 : NativeFunctions(32).type = "Function" : NativeFunctions(32).Name = "Left" : NativeFunctions(32).Precedence = 0 ' From Core.u
NativeFunctions(33).iNative = 127 : NativeFunctions(33).type = "Function" : NativeFunctions(33).Name = "Mid" : NativeFunctions(33).Precedence = 0 ' From Core.u
NativeFunctions(34).iNative = 126 : NativeFunctions(34).type = "Function" : NativeFunctions(34).Name = "InStr" : NativeFunctions(34).Precedence = 0 ' From Core.u
NativeFunctions(35).iNative = 125 : NativeFunctions(35).type = "Function" : NativeFunctions(35).Name = "Len" : NativeFunctions(35).Precedence = 0 ' From Core.u
NativeFunctions(36).iNative = 324 : NativeFunctions(36).type = "Operator" : NativeFunctions(36).Name = "-=" : NativeFunctions(36).Precedence = 45 ' From Core.u
NativeFunctions(37).iNative = 323 : NativeFunctions(37).type = "Operator" : NativeFunctions(37).Name = "@=" : NativeFunctions(37).Precedence = 44 ' From Core.u
NativeFunctions(38).iNative = 322 : NativeFunctions(38).type = "Operator" : NativeFunctions(38).Name = "$=" : NativeFunctions(38).Precedence = 44 ' From Core.u
NativeFunctions(39).iNative = 124 : NativeFunctions(39).type = "Operator" : NativeFunctions(39).Name = "~=" : NativeFunctions(39).Precedence = 24 ' From Core.u
NativeFunctions(40).iNative = 123 : NativeFunctions(40).type = "Operator" : NativeFunctions(40).Name = "!=" : NativeFunctions(40).Precedence = 26 ' From Core.u
NativeFunctions(41).iNative = 122 : NativeFunctions(41).type = "Operator" : NativeFunctions(41).Name = "==" : NativeFunctions(41).Precedence = 24 ' From Core.u
NativeFunctions(42).iNative = 121 : NativeFunctions(42).type = "Operator" : NativeFunctions(42).Name = ">=" : NativeFunctions(42).Precedence = 24 ' From Core.u
NativeFunctions(43).iNative = 120 : NativeFunctions(43).type = "Operator" : NativeFunctions(43).Name = "<=" : NativeFunctions(43).Precedence = 24 ' From Core.u
NativeFunctions(44).iNative = 116 : NativeFunctions(44).type = "Operator" : NativeFunctions(44).Name = ">" : NativeFunctions(44).Precedence = 24 ' From Core.u
NativeFunctions(45).iNative = 115 : NativeFunctions(45).type = "Operator" : NativeFunctions(45).Name = "<" : NativeFunctions(45).Precedence = 24 ' From Core.u
-
Thanks ELIZ,
pFunction inative:0X97 int:151 offset:0X27 type:nffOperator Precedence:0X18 Fullname: Function Core.Object.Greater_IntInt
pFunction inative:0X98 int:152 offset:0X28 type:nffOperator Precedence:0X18 Fullname: Function Core.Object.LessEqual_IntInt
I have gather the additional information. however, i think 0x27 = true and 0x28 is false, However, i can not extract that from this information. or can i?
Why do you need the Precedence??
-
i think 0x27 = true and 0x28 is false, However, i can not extract that from this information. or can i?
I don't undertstand, what do you get the 27 and 28 from?
Why do you need the Precedence??
I'm not 100% sure, I've been told that is influences what order to do multiple operations, like that mathematical rules state that multiplications are made before additions, it influences where to add parenthesis.
-
If you open agp.agp_weapon.fire in utpt. you will see at line 0x0133 badjust=true
If you then analyze raw object of agp.agp_weapon.fire and go to 0x138 you will see the 0x27, which with my best guess compared to true.
-
oh lord , i've read somehere the meanings of the offsets, i will look for it.
-
Haha i can also tell you,
the point of agp_weapon,fire is that it called the function ServerFire( !bAdjust,bRapid,bBreatheBonus); If you want to get a breathbonus or no adjustment you need to change those variables. which is what one of these offsets do
-
I was talking about False,True, etc :D I did a quick search but did not found the post, it was explaining the offsets for "(", True, False, operators etc.
-
If you open agp.agp_weapon.fire in utpt. you will see at line 0x0133 badjust=true
If you then analyze raw object of agp.agp_weapon.fire and go to 0x138 you will see the 0x27, which with my best guess compared to true.
Sure, 28 is the bytecode for False, and 27 is True.
Thought you were much further along than that, you have miles and miles to go.
Take a look on page 27 in this wonderful document:
https://www.dropbox.com/s/qeggl1x261xu0ce/UT_Package_File_Format.pdf?dl=0 (https://www.dropbox.com/s/qeggl1x261xu0ce/UT_Package_File_Format.pdf?dl=0)
The document was found here:
http://www.acordero.org/download/ut_package_file_format_pdf.zip (http://www.acordero.org/download/ut_package_file_format_pdf.zip)
But I'm having trouble downloading it again, that is why I linked to the dropbox instead