├── .gitignore ├── GTA V Script Decompiler.sdf ├── GTA V Script Decompiler.sln ├── GTA V Script Decompiler ├── App.config ├── CodePath.cs ├── FolderSelectDialog.cs ├── Function.cs ├── GTA V Icon.ico ├── GTA V Script Decompiler.csproj ├── Hashes.cs ├── INI.cs ├── IO.cs ├── InputBox.cs ├── Instruction.cs ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── Native Param Info.cs ├── NativeFiles.cs ├── NativeTables.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ ├── Entities.dat │ ├── native_translation.dat │ ├── natives.dat │ └── x64natives.dat ├── ScriptFile.cs ├── ScriptHeaders.cs ├── Stack.cs ├── StringTable.cs ├── Utils.cs ├── Vars Info.cs └── packages.config ├── README.md ├── build.bat ├── build.sh └── packages └── FCTB.2.16.11.0 ├── FCTB.2.16.11.0.nupkg └── lib ├── FastColoredTextBox.dll └── FastColoredTextBox.xml /.gitignore: -------------------------------------------------------------------------------- 1 | GTA V Script Decompiler/obj/ 2 | GTA V Script Decompiler/Release/ 3 | GTA V Script Decompiler/bin/ 4 | *.db 5 | GTA V Script Decompiler/Resources/Entities2.dat 6 | -------------------------------------------------------------------------------- /GTA V Script Decompiler.sdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njames93/GTA-V-Script-Decompiler/38ab830be6012bb807348229bc9ac39fe6a36c45/GTA V Script Decompiler.sdf -------------------------------------------------------------------------------- /GTA V Script Decompiler.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GTA V Script Decompiler", "GTA V Script Decompiler\GTA V Script Decompiler.csproj", "{399F1C85-D843-4F79-8920-4761EA2C1533}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Release|Any CPU = Release|Any CPU 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {399F1C85-D843-4F79-8920-4761EA2C1533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {399F1C85-D843-4F79-8920-4761EA2C1533}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {399F1C85-D843-4F79-8920-4761EA2C1533}.Debug|x64.ActiveCfg = Debug|x64 19 | {399F1C85-D843-4F79-8920-4761EA2C1533}.Debug|x64.Build.0 = Debug|x64 20 | {399F1C85-D843-4F79-8920-4761EA2C1533}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {399F1C85-D843-4F79-8920-4761EA2C1533}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {399F1C85-D843-4F79-8920-4761EA2C1533}.Release|x64.ActiveCfg = Release|x64 23 | {399F1C85-D843-4F79-8920-4761EA2C1533}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/CodePath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Decompiler 8 | { 9 | //Not a fan of this code, should really have been handled using a tree but too far into project to change this now 10 | internal class CodePath 11 | { 12 | public CodePath Parent; 13 | public int EndOffset; 14 | public int BreakOffset; 15 | public CodePathType Type; 16 | public List ChildPaths; 17 | 18 | public CodePath(CodePathType Type, int EndOffset, int BreakOffset) 19 | { 20 | Parent = null; 21 | this.Type = Type; 22 | this.EndOffset = EndOffset; 23 | this.BreakOffset = BreakOffset; 24 | ChildPaths = new List(); 25 | } 26 | 27 | public CodePath(CodePath Parent, CodePathType Type, int EndOffset, int BreakOffset) 28 | { 29 | this.Parent = Parent; 30 | this.Type = Type; 31 | this.EndOffset = EndOffset; 32 | this.BreakOffset = BreakOffset; 33 | ChildPaths = new List(); 34 | } 35 | 36 | public CodePath CreateCodePath(CodePathType Type, int EndOffset, int BreakOffset) 37 | { 38 | CodePath C = new CodePath(this, Type, EndOffset, BreakOffset); 39 | this.ChildPaths.Add(C); 40 | return C; 41 | } 42 | 43 | } 44 | 45 | internal enum CodePathType 46 | { 47 | While, 48 | If, 49 | Else, 50 | Main 51 | } 52 | 53 | internal class SwitchStatement 54 | { 55 | public Dictionary> Cases; 56 | public List Offsets; 57 | public int breakoffset; 58 | public SwitchStatement Parent; 59 | public List ChildSwitches; 60 | 61 | public SwitchStatement(Dictionary> Cases, int BreakOffset) 62 | { 63 | Parent = null; 64 | this.Cases = Cases; 65 | this.breakoffset = BreakOffset; 66 | ChildSwitches = new List(); 67 | Offsets = Cases == null ? new List() : Cases.Keys.ToList(); 68 | Offsets.Add(BreakOffset); 69 | } 70 | 71 | public SwitchStatement(SwitchStatement Parent, Dictionary> Cases, int BreakOffset) 72 | { 73 | this.Parent = Parent; 74 | this.Cases = Cases; 75 | this.breakoffset = BreakOffset; 76 | ChildSwitches = new List(); 77 | Offsets = Cases == null ? new List() : Cases.Keys.ToList(); 78 | Offsets.Add(BreakOffset); 79 | } 80 | 81 | public SwitchStatement CreateSwitchStatement(Dictionary> Cases, int BreakOffset) 82 | { 83 | SwitchStatement S = new SwitchStatement(this, Cases, BreakOffset); 84 | this.ChildSwitches.Add(S); 85 | return S; 86 | } 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/FolderSelectDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Reflection; 4 | 5 | namespace System.Windows.Forms 6 | { 7 | internal class FolderSelectDialog : IDisposable 8 | { 9 | // Wrapped dialog 10 | System.Windows.Forms.OpenFileDialog ofd = null; 11 | 12 | /// 13 | /// Default constructor 14 | /// 15 | public FolderSelectDialog(string initialdir = null) 16 | { 17 | ofd = new System.Windows.Forms.OpenFileDialog(); 18 | ofd.Filter = "Folders|\n"; 19 | ofd.AddExtension = false; 20 | ofd.CheckFileExists = false; 21 | ofd.DereferenceLinks = true; 22 | ofd.Multiselect = false; 23 | if (initialdir != null) ofd.InitialDirectory = initialdir; 24 | 25 | } 26 | 27 | #region Properties 28 | 29 | /// 30 | /// Gets/Sets the initial folder to be selected. A null value selects the current directory. 31 | /// 32 | public string InitialDirectory 33 | { 34 | get { return ofd.InitialDirectory; } 35 | set { ofd.InitialDirectory = value == null || value.Length == 0 ? Environment.CurrentDirectory : value; } 36 | } 37 | 38 | /// 39 | /// Gets/Sets the title to show in the dialog 40 | /// 41 | public string Title 42 | { 43 | get { return ofd.Title; } 44 | set { ofd.Title = value == null ? "Select a folder" : value; } 45 | } 46 | 47 | /// 48 | /// Gets the selected folder 49 | /// 50 | public string SelectedPath 51 | { 52 | get { return ofd.FileName; } 53 | } 54 | 55 | #endregion 56 | 57 | #region Methods 58 | 59 | /// 60 | /// Shows the dialog 61 | /// 62 | /// True if the user presses OK else false 63 | public DialogResult ShowDialog() 64 | { 65 | return ShowDialog(IntPtr.Zero); 66 | } 67 | 68 | /// 69 | /// Shows the dialog 70 | /// 71 | /// Handle of the control to be parent 72 | /// True if the user presses OK else false 73 | public DialogResult ShowDialog(IntPtr hWndOwner) 74 | { 75 | bool flag = false; 76 | 77 | if (Environment.OSVersion.Version.Major >= 6) 78 | { 79 | var r = new Reflector("System.Windows.Forms"); 80 | 81 | uint num = 0; 82 | Type typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); 83 | object dialog = r.Call(ofd, "CreateVistaDialog"); 84 | r.Call(ofd, "OnBeforeVistaDialog", dialog); 85 | 86 | uint options = (uint) r.CallAs(typeof(System.Windows.Forms.FileDialog), ofd, "GetOptions"); 87 | options |= (uint) r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); 88 | r.CallAs(typeIFileDialog, dialog, "SetOptions", options); 89 | 90 | object pfde = r.New("FileDialog.VistaDialogEvents", ofd); 91 | object[] parameters = new object[] {pfde, num}; 92 | r.CallAs2(typeIFileDialog, dialog, "Advise", parameters); 93 | num = (uint) parameters[1]; 94 | try 95 | { 96 | int num2 = (int) r.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); 97 | flag = 0 == num2; 98 | } 99 | finally 100 | { 101 | r.CallAs(typeIFileDialog, dialog, "Unadvise", num); 102 | GC.KeepAlive(pfde); 103 | } 104 | } 105 | else 106 | { 107 | var fbd = new FolderBrowserDialog(); 108 | fbd.Description = this.Title; 109 | fbd.SelectedPath = this.InitialDirectory; 110 | fbd.ShowNewFolderButton = false; 111 | if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK) return DialogResult.Cancel; 112 | ofd.FileName = fbd.SelectedPath; 113 | flag = true; 114 | } 115 | if (flag) return DialogResult.OK; 116 | else return DialogResult.Cancel; 117 | } 118 | 119 | /// 120 | /// Handle Disposing of the the OpenFileDialog behind this class 121 | /// 122 | public void Dispose() 123 | { 124 | Dispose(true); 125 | GC.SuppressFinalize(this); 126 | } 127 | 128 | /// 129 | /// Handle Disposing of the the OpenFileDialog behind this class 130 | /// 131 | protected virtual void Dispose(bool disposing) 132 | { 133 | if (disposing) 134 | { 135 | if (ofd != null) ofd.Dispose(); 136 | } 137 | } 138 | 139 | #endregion 140 | } 141 | 142 | /// 143 | /// Creates IWin32Window around an IntPtr 144 | /// 145 | internal class WindowWrapper : System.Windows.Forms.IWin32Window 146 | { 147 | /// 148 | /// Constructor 149 | /// 150 | /// Handle to wrap 151 | public WindowWrapper(IntPtr handle) 152 | { 153 | _hwnd = handle; 154 | } 155 | 156 | /// 157 | /// Original ptr 158 | /// 159 | public IntPtr Handle 160 | { 161 | get { return _hwnd; } 162 | } 163 | 164 | private IntPtr _hwnd; 165 | } 166 | 167 | internal class Reflector 168 | { 169 | #region variables 170 | 171 | string m_ns; 172 | Assembly m_asmb; 173 | 174 | #endregion 175 | 176 | #region Constructors 177 | 178 | /// 179 | /// Constructor 180 | /// 181 | /// The namespace containing types to be used 182 | public Reflector(string ns) 183 | : this(ns, ns) 184 | { 185 | } 186 | 187 | /// 188 | /// Constructor 189 | /// 190 | /// A specific assembly name (used if the assembly name does not tie exactly with the namespace) 191 | /// The namespace containing types to be used 192 | public Reflector(string an, string ns) 193 | { 194 | m_ns = ns; 195 | m_asmb = null; 196 | foreach (AssemblyName aN in Assembly.GetExecutingAssembly().GetReferencedAssemblies()) 197 | { 198 | if (aN.FullName.StartsWith(an)) 199 | { 200 | m_asmb = Assembly.Load(aN); 201 | break; 202 | } 203 | } 204 | } 205 | 206 | #endregion 207 | 208 | #region Methods 209 | 210 | /// 211 | /// Return a Type instance for a type 'typeName' 212 | /// 213 | /// The name of the type 214 | /// A type instance 215 | public Type GetType(string typeName) 216 | { 217 | Type type = null; 218 | string[] names = typeName.Split('.'); 219 | 220 | if (names.Length > 0) 221 | type = m_asmb.GetType(m_ns + "." + names[0]); 222 | 223 | for (int i = 1; i < names.Length; ++i) 224 | { 225 | type = type.GetNestedType(names[i], BindingFlags.NonPublic); 226 | } 227 | return type; 228 | } 229 | 230 | /// 231 | /// Create a new object of a named type passing along any params 232 | /// 233 | /// The name of the type to create 234 | /// 235 | /// An instantiated type 236 | public object New(string name, params object[] parameters) 237 | { 238 | Type type = GetType(name); 239 | 240 | ConstructorInfo[] ctorInfos = type.GetConstructors(); 241 | foreach (ConstructorInfo ci in ctorInfos) 242 | { 243 | try 244 | { 245 | return ci.Invoke(parameters); 246 | } 247 | catch 248 | { 249 | } 250 | } 251 | 252 | return null; 253 | } 254 | 255 | /// 256 | /// Calls method 'func' on object 'obj' passing parameters 'parameters' 257 | /// 258 | /// The object on which to excute function 'func' 259 | /// The function to execute 260 | /// The parameters to pass to function 'func' 261 | /// The result of the function invocation 262 | public object Call(object obj, string func, params object[] parameters) 263 | { 264 | return Call2(obj, func, parameters); 265 | } 266 | 267 | /// 268 | /// Calls method 'func' on object 'obj' passing parameters 'parameters' 269 | /// 270 | /// The object on which to excute function 'func' 271 | /// The function to execute 272 | /// The parameters to pass to function 'func' 273 | /// The result of the function invocation 274 | public object Call2(object obj, string func, object[] parameters) 275 | { 276 | return CallAs2(obj.GetType(), obj, func, parameters); 277 | } 278 | 279 | /// 280 | /// Calls method 'func' on object 'obj' which is of type 'type' passing parameters 'parameters' 281 | /// 282 | /// The type of 'obj' 283 | /// The object on which to excute function 'func' 284 | /// The function to execute 285 | /// The parameters to pass to function 'func' 286 | /// The result of the function invocation 287 | public object CallAs(Type type, object obj, string func, params object[] parameters) 288 | { 289 | return CallAs2(type, obj, func, parameters); 290 | } 291 | 292 | /// 293 | /// Calls method 'func' on object 'obj' which is of type 'type' passing parameters 'parameters' 294 | /// 295 | /// The type of 'obj' 296 | /// The object on which to excute function 'func' 297 | /// The function to execute 298 | /// The parameters to pass to function 'func' 299 | /// The result of the function invocation 300 | public object CallAs2(Type type, object obj, string func, object[] parameters) 301 | { 302 | MethodInfo methInfo = type.GetMethod(func, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 303 | return methInfo.Invoke(obj, parameters); 304 | } 305 | 306 | /// 307 | /// Returns the value of property 'prop' of object 'obj' 308 | /// 309 | /// The object containing 'prop' 310 | /// The property name 311 | /// The property value 312 | public object Get(object obj, string prop) 313 | { 314 | return GetAs(obj.GetType(), obj, prop); 315 | } 316 | 317 | /// 318 | /// Returns the value of property 'prop' of object 'obj' which has type 'type' 319 | /// 320 | /// The type of 'obj' 321 | /// The object containing 'prop' 322 | /// The property name 323 | /// The property value 324 | public object GetAs(Type type, object obj, string prop) 325 | { 326 | PropertyInfo propInfo = type.GetProperty(prop, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 327 | return propInfo.GetValue(obj, null); 328 | } 329 | 330 | /// 331 | /// Returns an enum value 332 | /// 333 | /// The name of enum type 334 | /// The name of the value 335 | /// The enum value 336 | public object GetEnum(string typeName, string name) 337 | { 338 | Type type = GetType(typeName); 339 | FieldInfo fieldInfo = type.GetField(name); 340 | return fieldInfo.GetValue(null); 341 | } 342 | 343 | #endregion 344 | 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/GTA V Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njames93/GTA-V-Script-Decompiler/38ab830be6012bb807348229bc9ac39fe6a36c45/GTA V Script Decompiler/GTA V Icon.ico -------------------------------------------------------------------------------- /GTA V Script Decompiler/GTA V Script Decompiler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {399F1C85-D843-4F79-8920-4761EA2C1533} 8 | WinExe 9 | Properties 10 | Decompiler 11 | GTA V Script Decompiler 12 | v4.5 13 | 512 14 | 15 | publish\ 16 | true 17 | Disk 18 | false 19 | Foreground 20 | 7 21 | Days 22 | false 23 | false 24 | true 25 | 0 26 | 1.0.0.%2a 27 | false 28 | false 29 | true 30 | 31 | 32 | AnyCPU 33 | true 34 | full 35 | false 36 | bin\Debug\ 37 | DEBUG;TRACE 38 | prompt 39 | 4 40 | false 41 | false 42 | 43 | 44 | AnyCPU 45 | pdbonly 46 | true 47 | bin\Release\ 48 | TRACE 49 | prompt 50 | 4 51 | false 52 | 53 | 54 | 55 | 56 | 57 | GTA V Icon.ico 58 | 59 | 60 | true 61 | bin\x64\Debug\ 62 | DEBUG;TRACE 63 | full 64 | x64 65 | prompt 66 | MinimumRecommendedRules.ruleset 67 | 68 | 69 | Release\ 70 | 71 | 72 | true 73 | pdbonly 74 | x64 75 | prompt 76 | MinimumRecommendedRules.ruleset 77 | true 78 | Off 79 | 80 | 81 | 82 | ..\packages\FCTB.2.16.11.0\lib\FastColoredTextBox.dll 83 | True 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | Form 99 | 100 | 101 | MainForm.cs 102 | 103 | 104 | 105 | 106 | 107 | Form 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | MainForm.cs 124 | 125 | 126 | ResXFileCodeGenerator 127 | Resources.Designer.cs 128 | Designer 129 | 130 | 131 | True 132 | Resources.resx 133 | True 134 | 135 | 136 | 137 | 138 | SettingsSingleFileGenerator 139 | Settings.Designer.cs 140 | 141 | 142 | True 143 | Settings.settings 144 | True 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | False 160 | Microsoft .NET Framework 4.5 %28x86 and x64%29 161 | true 162 | 163 | 164 | False 165 | .NET Framework 3.5 SP1 166 | false 167 | 168 | 169 | 170 | 177 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Hashes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.IO.Compression; 5 | 6 | namespace Decompiler 7 | { 8 | public class Hashes 9 | { 10 | Dictionary hashes; 11 | 12 | public Hashes() 13 | { 14 | hashes = new Dictionary(); 15 | StreamReader reader; 16 | if ( 17 | File.Exists(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 18 | "entities.dat"))) 19 | { 20 | reader = 21 | new StreamReader( 22 | File.OpenRead(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 23 | "entities.dat"))); 24 | } 25 | else 26 | { 27 | Stream Decompressed = new MemoryStream(); 28 | Stream Compressed = new MemoryStream(Properties.Resources.Entities); 29 | DeflateStream deflate = new DeflateStream(Compressed, CompressionMode.Decompress); 30 | deflate.CopyTo(Decompressed); 31 | deflate.Dispose(); 32 | Decompressed.Position = 0; 33 | reader = new StreamReader(Decompressed); 34 | } 35 | while (!reader.EndOfStream) 36 | { 37 | string line = reader.ReadLine(); 38 | string[] split = line.Split(new char[] {':'}, StringSplitOptions.RemoveEmptyEntries); 39 | if (split.Length != 2) 40 | continue; 41 | int hash = 0; 42 | try 43 | { 44 | hash = Convert.ToInt32(split[0]); 45 | } 46 | catch 47 | { 48 | hash = (int) Convert.ToUInt32(split[0]); 49 | } 50 | if (!hashes.ContainsKey(hash) && hash != 0) 51 | hashes.Add(hash, split[1]); 52 | } 53 | 54 | } 55 | 56 | public void Export_Entities() 57 | { 58 | Stream Decompressed = 59 | File.Create(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 60 | "entities_exp.dat")); 61 | Stream Compressed = new MemoryStream(Properties.Resources.Entities); 62 | DeflateStream deflate = new DeflateStream(Compressed, CompressionMode.Decompress); 63 | deflate.CopyTo(Decompressed); 64 | deflate.Dispose(); 65 | Decompressed.Close(); 66 | System.Diagnostics.Process.Start( 67 | Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location))); 68 | 69 | } 70 | 71 | public string GetHash(int value, string temp = "") 72 | { 73 | if (!Program.Reverse_Hashes) 74 | return inttohex(value); 75 | if (hashes.ContainsKey(value)) 76 | return "joaat(\"" + hashes[value] + "\")"; 77 | return inttohex(value) + temp; 78 | } 79 | 80 | public string GetHash(uint value, string temp = "") 81 | { 82 | if (!Program.Reverse_Hashes) 83 | return value.ToString(); 84 | int intvalue = (int) value; 85 | if (hashes.ContainsKey(intvalue)) 86 | return "joaat(\"" + hashes[intvalue] + "\")"; 87 | return value.ToString() + temp; 88 | } 89 | 90 | public bool IsKnownHash(int value) 91 | { 92 | return hashes.ContainsKey(value); 93 | } 94 | 95 | public static string inttohex(int value) 96 | { 97 | if (Program.getIntType == Program.IntType._hex) 98 | { 99 | string s = value.ToString("X"); 100 | while (s.Length < 8) s = "0" + s; 101 | return "0x" + s; 102 | } 103 | return value.ToString(); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/INI.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Text; 3 | 4 | namespace Ini 5 | { 6 | /// 7 | /// Create a New INI file to store or load data 8 | /// 9 | public class IniFile 10 | { 11 | public string path; 12 | 13 | [DllImport("kernel32")] 14 | private static extern int WritePrivateProfileString(string section, 15 | string key, string val, string filePath); 16 | 17 | [DllImport("kernel32")] 18 | private static extern int GetPrivateProfileString(string section, 19 | string key, string def, StringBuilder retVal, 20 | int size, string filePath); 21 | 22 | /// 23 | /// INIFile Constructor. 24 | /// 25 | /// 26 | public IniFile(string INIPath) 27 | { 28 | path = INIPath; 29 | } 30 | 31 | /// 32 | /// Write Data to the INI File 33 | /// 34 | /// 35 | /// Section name 36 | /// 37 | /// Key Name 38 | /// 39 | /// Value Name 40 | public void IniWriteValue(string Section, string Key, string Value) 41 | { 42 | WritePrivateProfileString(Section, Key, Value, this.path); 43 | } 44 | 45 | /// 46 | /// Read Data Value From the Ini File 47 | /// 48 | /// 49 | /// 50 | /// 51 | /// 52 | public string IniReadValue(string Section, string Key) 53 | { 54 | StringBuilder temp = new StringBuilder(255); 55 | int i = GetPrivateProfileString(Section, Key, "", temp, 56 | 255, this.path); 57 | return temp.ToString(); 58 | 59 | } 60 | 61 | public bool IniReadBool(string Section, string Key, bool defval = false) 62 | { 63 | StringBuilder temp = new StringBuilder(255); 64 | int i = GetPrivateProfileString(Section, Key, "", temp, 65 | 255, this.path); 66 | if (temp.ToString().Length == 0) return defval; 67 | switch (temp.ToString().ToLower().Trim(new char[] {' ', '\t', '"'})) 68 | { 69 | case "true": 70 | case "1": 71 | case "yes": 72 | return true; 73 | default: 74 | return false; 75 | } 76 | } 77 | 78 | public void IniWriteBool(string Section, string Key, bool Value) 79 | { 80 | WritePrivateProfileString(Section, Key, Value.ToString(), this.path); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /GTA V Script Decompiler/IO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace Decompiler.IO 8 | { 9 | public class Reader : BinaryReader 10 | { 11 | private readonly bool _consoleVer; 12 | public Reader(Stream stream, bool consoleVer) 13 | : base(stream) 14 | { 15 | _consoleVer = consoleVer; 16 | } 17 | 18 | public void Advance(int size = 4) 19 | { 20 | base.BaseStream.Position += size; 21 | } 22 | public UInt32 CReadUInt32() 23 | { 24 | if (_consoleVer) 25 | return SReadUInt32(); 26 | else 27 | return ReadUInt32(); 28 | 29 | } 30 | public Int32 CReadInt32() 31 | { 32 | if (_consoleVer) 33 | return SReadInt32(); 34 | else 35 | return ReadInt32(); 36 | } 37 | public UInt64 CReadUInt64() 38 | { 39 | if (_consoleVer) 40 | return SReadUInt64(); 41 | else 42 | return ReadUInt64(); 43 | } 44 | public Int64 CReadInt64() 45 | { 46 | if (_consoleVer) 47 | return SReadInt64(); 48 | else 49 | return ReadInt64(); 50 | } 51 | public UInt16 CReadUInt16() 52 | { 53 | if (_consoleVer) 54 | return SReadUInt16(); 55 | else 56 | return ReadUInt16(); 57 | } 58 | public Int16 CReadInt16() 59 | { 60 | if (_consoleVer) 61 | return SReadInt16(); 62 | else 63 | return ReadInt16(); 64 | } 65 | public Int32 CReadPointer() 66 | { 67 | if (_consoleVer) 68 | return SReadPointer(); 69 | else 70 | return ReadPointer(); 71 | } 72 | 73 | public UInt32 SReadUInt32() 74 | { 75 | return Utils.SwapEndian(ReadUInt32()); 76 | } 77 | public Int32 SReadInt32() 78 | { 79 | return Utils.SwapEndian(ReadInt32()); 80 | } 81 | public UInt64 SReadUInt64() 82 | { 83 | return Utils.SwapEndian(ReadUInt64()); 84 | } 85 | public Int64 SReadInt64() 86 | { 87 | return Utils.SwapEndian(ReadInt64()); 88 | } 89 | public UInt16 SReadUInt16() 90 | { 91 | return Utils.SwapEndian(ReadUInt16()); 92 | } 93 | public Int16 SReadInt16() 94 | { 95 | return Utils.SwapEndian(ReadInt16()); 96 | } 97 | public Int32 ReadPointer() 98 | { 99 | return (ReadInt32() & 0xFFFFFF); 100 | } 101 | public Int32 SReadPointer() 102 | { 103 | return (SReadInt32() & 0xFFFFFF); 104 | } 105 | public override string ReadString() 106 | { 107 | string temp = ""; 108 | byte next = ReadByte(); 109 | while (next != 0) 110 | { 111 | temp += (char)next; 112 | next = ReadByte(); 113 | } 114 | return temp; 115 | } 116 | } 117 | public class Writer : BinaryWriter 118 | { 119 | public Writer(Stream stream) 120 | : base(stream) 121 | { 122 | } 123 | 124 | public void SWrite(UInt16 num) 125 | { 126 | Write(Utils.SwapEndian(num)); 127 | } 128 | public void SWrite(UInt32 num) 129 | { 130 | Write(Utils.SwapEndian(num)); 131 | } 132 | public void SWrite(UInt64 num) 133 | { 134 | Write(Utils.SwapEndian(num)); 135 | } 136 | public void SWrite(Int16 num) 137 | { 138 | Write(Utils.SwapEndian(num)); 139 | } 140 | public void SWrite(Int32 num) 141 | { 142 | Write(Utils.SwapEndian(num)); 143 | } 144 | public void SWrite(Int64 num) 145 | { 146 | Write(Utils.SwapEndian(num)); 147 | } 148 | public void WritePointer(Int32 pointer) 149 | { 150 | if (pointer == 0) 151 | { 152 | Write((int)0); 153 | return; 154 | } 155 | Write((pointer & 0xFFFFFF) | 0x50000000); 156 | } 157 | public void SWritePointer(Int32 pointer) 158 | { 159 | if (pointer == 0) 160 | { 161 | Write((int)0); 162 | return; 163 | } 164 | Write(Utils.SwapEndian((pointer & 0xFFFFFF) | 0x50000000)); 165 | } 166 | public override void Write(string str) 167 | { 168 | Write(System.Text.Encoding.ASCII.GetBytes(str + "\0")); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/InputBox.cs: -------------------------------------------------------------------------------- 1 | namespace System.Windows.Forms 2 | { 3 | /// 4 | /// Base in-accessable class for listbox containing methods 5 | /// This Classes inteneded public methods are accessed through the InputBox Class Below 6 | /// This class along with InputBox prevents the user accessing the public methods inherited from Form 7 | /// 8 | internal class _InputBox : Form 9 | { 10 | #region designercode 11 | 12 | /// 13 | /// Required designer variable. 14 | /// 15 | private System.ComponentModel.IContainer components = null; 16 | 17 | /// 18 | /// Clean up any resources being used. 19 | /// 20 | /// true if managed resources should be disposed; otherwise, false. 21 | protected override void Dispose(bool disposing) 22 | { 23 | if (disposing && (components != null)) 24 | { 25 | components.Dispose(); 26 | } 27 | base.Dispose(disposing); 28 | } 29 | 30 | #region Windows Form Designer generated code 31 | 32 | /// 33 | /// Required method for Designer support - do not modify 34 | /// the contents of this method with the code editor. 35 | /// 36 | private void InitializeComponent() 37 | { 38 | this.btnOK = new System.Windows.Forms.Button(); 39 | this.btnCancel = new System.Windows.Forms.Button(); 40 | this.label1 = new System.Windows.Forms.Label(); 41 | this.textBox1 = new System.Windows.Forms.TextBox(); 42 | this.comboBox1 = new System.Windows.Forms.ComboBox(); 43 | this.richTextBox1 = new System.Windows.Forms.RichTextBox(); 44 | this.SuspendLayout(); 45 | // 46 | // btnOK 47 | // 48 | this.btnOK.Anchor = 49 | ((System.Windows.Forms.AnchorStyles) 50 | ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 51 | this.btnOK.BackColor = System.Drawing.SystemColors.Control; 52 | this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; 53 | this.btnOK.FlatStyle = System.Windows.Forms.FlatStyle.System; 54 | this.btnOK.Location = new System.Drawing.Point(131, 103); 55 | this.btnOK.Name = "btnOK"; 56 | this.btnOK.Size = new System.Drawing.Size(59, 29); 57 | this.btnOK.TabIndex = 0; 58 | this.btnOK.Text = "Ok"; 59 | this.btnOK.UseVisualStyleBackColor = false; 60 | // 61 | // btnCancel 62 | // 63 | this.btnCancel.Anchor = 64 | ((System.Windows.Forms.AnchorStyles) 65 | ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 66 | this.btnCancel.BackColor = System.Drawing.SystemColors.Control; 67 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 68 | this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.System; 69 | this.btnCancel.Location = new System.Drawing.Point(209, 103); 70 | this.btnCancel.Name = "btnCancel"; 71 | this.btnCancel.Size = new System.Drawing.Size(59, 29); 72 | this.btnCancel.TabIndex = 1; 73 | this.btnCancel.Text = "Cancel"; 74 | this.btnCancel.UseVisualStyleBackColor = false; 75 | // 76 | // label1 77 | // 78 | this.label1.AutoSize = true; 79 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, 80 | System.Drawing.GraphicsUnit.Point, ((byte) (0))); 81 | this.label1.Location = new System.Drawing.Point(12, 9); 82 | this.label1.Name = "label1"; 83 | this.label1.Size = new System.Drawing.Size(109, 20); 84 | this.label1.TabIndex = 2; 85 | this.label1.Text = "Enter Value:"; 86 | // 87 | // textBox1 88 | // 89 | this.textBox1.Anchor = 90 | ((System.Windows.Forms.AnchorStyles) 91 | (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 92 | | System.Windows.Forms.AnchorStyles.Right))); 93 | this.textBox1.Location = new System.Drawing.Point(15, 68); 94 | this.textBox1.Multiline = true; 95 | this.textBox1.Name = "textBox1"; 96 | this.textBox1.Size = new System.Drawing.Size(253, 20); 97 | this.textBox1.TabIndex = 3; 98 | this.textBox1.Visible = false; 99 | this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Input_KeyDown); 100 | // 101 | // comboBox1 102 | // 103 | this.comboBox1.Anchor = 104 | ((System.Windows.Forms.AnchorStyles) 105 | (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 106 | | System.Windows.Forms.AnchorStyles.Right))); 107 | this.comboBox1.FormattingEnabled = true; 108 | this.comboBox1.Location = new System.Drawing.Point(15, 67); 109 | this.comboBox1.Name = "comboBox1"; 110 | this.comboBox1.Size = new System.Drawing.Size(252, 21); 111 | this.comboBox1.TabIndex = 4; 112 | this.comboBox1.Visible = false; 113 | this.comboBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Input_KeyDown); 114 | // 115 | // richTextBox1 116 | // 117 | this.richTextBox1.Location = new System.Drawing.Point(15, 68); 118 | this.richTextBox1.Name = "richTextBox1"; 119 | this.richTextBox1.Size = new System.Drawing.Size(252, 142); 120 | this.richTextBox1.TabIndex = 5; 121 | this.richTextBox1.Text = ""; 122 | this.richTextBox1.Visible = false; 123 | // 124 | // _InputBox 125 | // 126 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 127 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 128 | this.ClientSize = new System.Drawing.Size(280, 144); 129 | this.Controls.Add(this.comboBox1); 130 | this.Controls.Add(this.textBox1); 131 | this.Controls.Add(this.label1); 132 | this.Controls.Add(this.btnCancel); 133 | this.Controls.Add(this.btnOK); 134 | this.Controls.Add(this.richTextBox1); 135 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 136 | this.MaximizeBox = false; 137 | this.MinimizeBox = false; 138 | this.Name = "_InputBox"; 139 | this.ShowIcon = false; 140 | this.ShowInTaskbar = false; 141 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.InputBox_FormClosing); 142 | this.ResumeLayout(false); 143 | this.PerformLayout(); 144 | 145 | } 146 | 147 | #endregion 148 | 149 | private System.Windows.Forms.Button btnOK; 150 | private System.Windows.Forms.Button btnCancel; 151 | private System.Windows.Forms.Label label1; 152 | private ComboBox comboBox1; 153 | private System.Windows.Forms.TextBox textBox1; 154 | 155 | #endregion 156 | 157 | private RichTextBox richTextBox1; 158 | private type inputtype; 159 | 160 | private enum type 161 | { 162 | text, 163 | dropdown, 164 | list 165 | } 166 | 167 | internal _InputBox() 168 | { 169 | InitializeComponent(); 170 | this.Focus(); 171 | } 172 | 173 | internal string Value 174 | { 175 | get 176 | { 177 | return this.DialogResult == DialogResult.OK 178 | ? (inputtype == type.dropdown ? comboBox1.Text : (inputtype == type.text ? textBox1.Text : null)) 179 | : Default; 180 | } 181 | } 182 | 183 | internal string[] ListValue 184 | { 185 | get { return this.DialogResult == DialogResult.OK && inputtype == type.list ? richTextBox1.Lines : null; } 186 | } 187 | 188 | private string Default = null; 189 | 190 | private void InputBox_FormClosing(object sender, FormClosingEventArgs e) 191 | { 192 | if (this.DialogResult != DialogResult.OK && this.DialogResult != DialogResult.Cancel) 193 | this.DialogResult = Forms.DialogResult.Abort; 194 | } 195 | 196 | internal bool Show(IWin32Window owner, string TitleMessage, string Message, string DefaultResponse) 197 | { 198 | textBox1.Visible = true; 199 | inputtype = type.text; 200 | textBox1.Focus(); 201 | this.Text = TitleMessage == null ? "Input Value" : TitleMessage; 202 | if (DefaultResponse != null) 203 | { 204 | textBox1.Text = DefaultResponse; 205 | textBox1.SelectAll(); 206 | Default = DefaultResponse; 207 | } 208 | label1.Text = Message == null ? "Enter Value:" : Message; 209 | if (owner == null) 210 | { 211 | return ShowDialog() == DialogResult.OK; 212 | } 213 | return ShowDialog(owner) == DialogResult.OK; 214 | } 215 | 216 | internal bool Show(IWin32Window owner, string TitleMessage, string Message, string[] StandardValues) 217 | { 218 | comboBox1.Visible = true; 219 | inputtype = type.dropdown; 220 | comboBox1.Focus(); 221 | this.Text = TitleMessage == null ? "Input Value" : TitleMessage; 222 | label1.Text = Message == null ? "Enter Value:" : Message; 223 | comboBox1.Items.Clear(); 224 | comboBox1.Items.AddRange(StandardValues); 225 | if (owner == null) 226 | { 227 | return ShowDialog() == DialogResult.OK; 228 | } 229 | return ShowDialog(owner) == DialogResult.OK; 230 | } 231 | 232 | internal bool Show(IWin32Window owner, string TitleMessage, string Message, AutoCompleteSource acs) 233 | { 234 | comboBox1.Visible = true; 235 | inputtype = type.dropdown; 236 | comboBox1.Focus(); 237 | this.Text = TitleMessage == null ? "Input Value" : TitleMessage; 238 | label1.Text = Message == null ? "Enter Value:" : Message; 239 | comboBox1.Items.Clear(); 240 | comboBox1.AutoCompleteSource = acs; 241 | comboBox1.AutoCompleteMode = AutoCompleteMode.Suggest; 242 | if (owner == null) 243 | { 244 | return ShowDialog() == DialogResult.OK; 245 | } 246 | return ShowDialog(owner) == DialogResult.OK; 247 | } 248 | 249 | internal bool ShowList(IWin32Window owner, string TitleMessage, string Message) 250 | { 251 | richTextBox1.Visible = true; 252 | this.Height = 300; 253 | inputtype = type.list; 254 | richTextBox1.Focus(); 255 | this.Text = TitleMessage == null ? "Input Value" : TitleMessage; 256 | label1.Text = Message == null ? "Enter Value:" : Message; 257 | if (owner == null) 258 | { 259 | return ShowDialog() == DialogResult.OK; 260 | } 261 | return ShowDialog(owner) == DialogResult.OK; 262 | } 263 | 264 | private void Input_KeyDown(object sender, KeyEventArgs e) 265 | { 266 | if (e.KeyCode == Keys.Enter) 267 | { 268 | this.DialogResult = DialogResult.OK; 269 | } 270 | } 271 | 272 | } 273 | 274 | /// 275 | /// A Class for displaying the user with a box for inputting data 276 | /// 277 | public class InputBox : IDisposable 278 | { 279 | private _InputBox _ibx; 280 | 281 | /// 282 | /// Initialises a new InputBox Class and enables access to the hidden base class 283 | /// 284 | public InputBox() 285 | { 286 | _ibx = new _InputBox(); 287 | } 288 | 289 | public string Value 290 | { 291 | get { return _ibx.Value; } 292 | } 293 | 294 | public string[] ListValue 295 | { 296 | get { return _ibx.ListValue; } 297 | } 298 | 299 | public bool Show(string TitleMessage = null, string Message = null, string DefaulResponse = null, 300 | IWin32Window owner = null) 301 | { 302 | return _ibx.Show(owner, TitleMessage, Message, DefaulResponse); 303 | } 304 | 305 | public bool Show(string TitleMessage, string Message, string[] StandardValues, IWin32Window owner = null) 306 | { 307 | return _ibx.Show(owner, TitleMessage, Message, StandardValues); 308 | } 309 | 310 | public bool Show(string TitleMessage, string Message, AutoCompleteSource acs, IWin32Window owner = null) 311 | { 312 | return _ibx.Show(owner, TitleMessage, Message, acs); 313 | } 314 | 315 | public bool ShowList(string TitleMessage = null, string Message = null, IWin32Window owner = null) 316 | { 317 | return _ibx.ShowList(owner, TitleMessage, Message); 318 | } 319 | 320 | public static string QuickShow(string TitleMessage, string Message, string[] StandardValues, IWin32Window owner = null) 321 | { 322 | _InputBox ibx = new _InputBox(); 323 | ibx.Show(owner, TitleMessage, Message, StandardValues); 324 | return ibx.Value; 325 | } 326 | 327 | public static string QuickShow(string TitleMessage, string Message, AutoCompleteSource acs, IWin32Window owner = null) 328 | { 329 | _InputBox ibx = new _InputBox(); 330 | ibx.Show(owner, TitleMessage, Message, acs); 331 | return ibx.Value; 332 | } 333 | 334 | public static string QuickShow(string TitleMessage = null, string Message = null, string DefaultResponse = null, 335 | IWin32Window owner = null) 336 | { 337 | _InputBox ibx = new _InputBox(); 338 | ibx.Show(owner, TitleMessage, Message, DefaultResponse); 339 | return ibx.Value; 340 | } 341 | 342 | public static string[] QuickShowList(string TitleMessage = null, string Message = null, IWin32Window owner = null) 343 | { 344 | _InputBox ibx = new _InputBox(); 345 | ibx.ShowList(owner, TitleMessage, Message); 346 | return ibx.ListValue; 347 | } 348 | 349 | /// 350 | /// Handle Disposing of the the OpenFileDialog behind this class 351 | /// 352 | public void Dispose() 353 | { 354 | Dispose(true); 355 | GC.SuppressFinalize(this); 356 | } 357 | 358 | /// 359 | /// Handle Disposing of the the OpenFileDialog behind this class 360 | /// 361 | protected virtual void Dispose(bool disposing) 362 | { 363 | if (disposing) 364 | { 365 | if (_ibx != null) _ibx.Dispose(); 366 | } 367 | } 368 | 369 | } 370 | } 371 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Instruction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Decompiler 6 | { 7 | internal class HLInstruction 8 | { 9 | int offset; 10 | Instruction instruction; 11 | byte[] operands; 12 | private bool _consoleVer; 13 | 14 | public HLInstruction(Instruction Instruction, IEnumerable Operands, int Offset, bool consoleVer) 15 | { 16 | instruction = Instruction; 17 | operands = Operands.ToArray(); 18 | offset = Offset; 19 | _consoleVer = consoleVer; 20 | } 21 | 22 | public HLInstruction(byte Instruction, IEnumerable Operands, int Offset, bool consoleVer) 23 | { 24 | instruction = (Instruction) Instruction; 25 | operands = Operands.ToArray(); 26 | offset = Offset; 27 | _consoleVer = consoleVer; 28 | } 29 | 30 | public HLInstruction(Instruction Instruction, int Offset, bool consoleVer) 31 | { 32 | instruction = Instruction; 33 | operands = new byte[0]; 34 | offset = Offset; 35 | _consoleVer = consoleVer; 36 | } 37 | 38 | public HLInstruction(byte Instruction, int Offset, bool consoleVer) 39 | { 40 | instruction = (Instruction) Instruction; 41 | operands = new byte[0]; 42 | offset = Offset; 43 | _consoleVer = consoleVer; 44 | } 45 | 46 | public Instruction Instruction 47 | { 48 | get { return instruction; } 49 | } 50 | 51 | public void NopInstruction() 52 | { 53 | instruction = Instruction.Nop; 54 | } 55 | 56 | public int Offset 57 | { 58 | get { return offset; } 59 | } 60 | 61 | public int InstructionLength 62 | { 63 | get { return 1 + operands.Count(); } 64 | } 65 | 66 | public int GetOperandsAsInt 67 | { 68 | get 69 | { 70 | if (_consoleVer) 71 | { 72 | switch (operands.Count()) 73 | { 74 | case 1: 75 | return operands[0]; 76 | case 2: 77 | return Utils.SwapEndian(BitConverter.ToInt16(operands, 0)); 78 | case 3: 79 | return operands[0] << 16 | operands[1] << 8 | operands[2]; 80 | case 4: 81 | return Utils.SwapEndian(BitConverter.ToInt32(operands, 0)); 82 | } 83 | } 84 | else 85 | { 86 | switch (operands.Count()) 87 | { 88 | case 1: 89 | return operands[0]; 90 | case 2: 91 | return BitConverter.ToInt16(operands, 0); 92 | case 3: 93 | return operands[2] << 16 | operands[1] << 8 | operands[0]; 94 | case 4: 95 | return BitConverter.ToInt32(operands, 0); 96 | } 97 | } 98 | throw new Exception("Invalid amount of operands (" + operands.Count().ToString() + ")"); 99 | } 100 | } 101 | 102 | public float GetFloat 103 | { 104 | get 105 | { 106 | if (operands.Count() != 4) 107 | throw new Exception("Not a Float"); 108 | if (_consoleVer) 109 | return Utils.SwapEndian(BitConverter.ToSingle(operands, 0)); 110 | else 111 | return BitConverter.ToSingle(operands, 0); 112 | } 113 | } 114 | 115 | public byte GetOperand(int index) 116 | { 117 | return operands[index]; 118 | } 119 | 120 | public uint GetOperandsAsUInt 121 | { 122 | get 123 | { 124 | if (_consoleVer) 125 | { 126 | switch (operands.Count()) 127 | { 128 | case 1: 129 | return operands[0]; 130 | case 2: 131 | return Utils.SwapEndian(BitConverter.ToUInt16(operands, 0)); 132 | case 3: 133 | return (uint) (operands[0] << 16 | operands[1] << 8 | operands[2]); 134 | case 4: 135 | return Utils.SwapEndian(BitConverter.ToUInt32(operands, 0)); 136 | } 137 | } 138 | else 139 | { 140 | switch (operands.Count()) 141 | { 142 | case 1: 143 | return operands[0]; 144 | case 2: 145 | return BitConverter.ToUInt16(operands, 0); 146 | case 3: 147 | return (uint) (operands[2] << 16 | operands[1] << 8 | operands[0]); 148 | case 4: 149 | return BitConverter.ToUInt32(operands, 0); 150 | } 151 | } 152 | throw new Exception("Invalid amount of operands (" + operands.Count().ToString() + ")"); 153 | } 154 | } 155 | 156 | public int GetJumpOffset 157 | { 158 | get 159 | { 160 | if (IsJumpInstruction) 161 | if (_consoleVer) 162 | return Utils.SwapEndian(BitConverter.ToInt16(operands, 0)) + offset + 3; 163 | else 164 | return BitConverter.ToInt16(operands, 0) + offset + 3; 165 | throw new Exception("Not A jump"); 166 | } 167 | } 168 | 169 | public byte GetNativeParams 170 | { 171 | get 172 | { 173 | if (instruction == Instruction.Native) 174 | { 175 | return (byte) (operands[0] >> 2); 176 | } 177 | throw new Exception("Not A Native"); 178 | } 179 | } 180 | 181 | public byte GetNativeReturns 182 | { 183 | get 184 | { 185 | if (instruction == Instruction.Native) 186 | { 187 | return (byte) (operands[0] & 0x3); 188 | } 189 | throw new Exception("Not A Native"); 190 | } 191 | } 192 | 193 | public ushort GetNativeIndex 194 | { 195 | get 196 | { 197 | if (instruction == Instruction.Native) 198 | { 199 | // if (_consoleVer) 200 | return Utils.SwapEndian(BitConverter.ToUInt16(operands, 1)); 201 | //else 202 | // return BitConverter.ToUInt16(operands, 1); 203 | } 204 | throw new Exception("Not A Native"); 205 | } 206 | } 207 | 208 | /*public int GetSwitchCase(int index) 209 | { 210 | if (instruction == Instruction.Switch) 211 | { 212 | int cases = GetOperand(0); 213 | if (index >= cases) 214 | throw new Exception("Out Or Range Script Case"); 215 | return Utils.SwapEndian(BitConverter.ToInt32(operands, 1 + index * 6)); 216 | } 217 | throw new Exception("Not A Switch Statement"); 218 | }*/ 219 | 220 | public string GetSwitchStringCase(int index) 221 | { 222 | if (instruction == Instruction.Switch) 223 | { 224 | int cases = GetOperand(0); 225 | if (index >= cases) 226 | throw new Exception("Out Or Range Script Case"); 227 | if (_consoleVer) 228 | return Program.getIntType == Program.IntType._uint 229 | ? ScriptFile.hashbank.GetHash(Utils.SwapEndian(BitConverter.ToUInt32(operands, 1 + index*6))) 230 | : ScriptFile.hashbank.GetHash(Utils.SwapEndian(BitConverter.ToInt32(operands, 1 + index*6))); 231 | else 232 | return Program.getIntType == Program.IntType._uint 233 | ? ScriptFile.hashbank.GetHash(BitConverter.ToUInt32(operands, 1 + index*6)) 234 | : ScriptFile.hashbank.GetHash(BitConverter.ToInt32(operands, 1 + index*6)); 235 | } 236 | throw new Exception("Not A Switch Statement"); 237 | } 238 | 239 | public int GetSwitchOffset(int index) 240 | { 241 | if (instruction == Instruction.Switch) 242 | { 243 | int cases = GetOperand(0); 244 | if (index >= cases) 245 | throw new Exception("Out of range script case"); 246 | if (_consoleVer) 247 | return offset + 8 + index*6 + Utils.SwapEndian(BitConverter.ToInt16(operands, 5 + index*6)); 248 | else 249 | return offset + 8 + index*6 + BitConverter.ToInt16(operands, 5 + index*6); 250 | } 251 | throw new Exception("Not A Switch Statement"); 252 | } 253 | 254 | public int GetImmBytePush 255 | { 256 | get 257 | { 258 | int _instruction = (int) Instruction; 259 | if (_instruction >= 109 && _instruction <= 117) 260 | { 261 | return _instruction - 110; 262 | } 263 | throw new Exception("Not An Immediate Int Push"); 264 | } 265 | } 266 | 267 | public float GetImmFloatPush 268 | { 269 | get 270 | { 271 | int _instruction = (int) Instruction; 272 | if (_instruction >= 118 && _instruction <= 126) 273 | { 274 | return (float) (_instruction - 119); 275 | } 276 | throw new Exception("Not An Immediate Float Push"); 277 | } 278 | } 279 | 280 | public bool IsJumpInstruction 281 | { 282 | get { return (int) instruction > 84 && (int) instruction < 93; } 283 | } 284 | 285 | public bool IsConditionJump 286 | { 287 | get { return (int) instruction > 85 && (int) instruction < 93; } 288 | } 289 | 290 | public bool IsWhileJump 291 | { 292 | get 293 | { 294 | if (instruction == Instruction.Jump) 295 | { 296 | if (GetJumpOffset <= 0) return false; 297 | return (GetOperandsAsInt < 0); 298 | } 299 | return false; 300 | } 301 | } 302 | 303 | public string GetGlobalString 304 | { 305 | get 306 | { 307 | switch (instruction) 308 | { 309 | case Instruction.pGlobal2: 310 | case Instruction.GlobalGet2: 311 | case Instruction.GlobalSet2: 312 | return "Global_" + 313 | (Program.Hex_Index ? GetOperandsAsUInt.ToString("X") : GetOperandsAsUInt.ToString()); 314 | case Instruction.pGlobal3: 315 | case Instruction.GlobalGet3: 316 | case Instruction.GlobalSet3: 317 | return "Global_" + 318 | (Program.Hex_Index ? GetOperandsAsUInt.ToString("X") : GetOperandsAsUInt.ToString()); 319 | } 320 | throw new Exception("Not a global variable"); 321 | } 322 | } 323 | } 324 | 325 | internal enum Instruction //opcodes reversed from gta v default.xex 326 | { 327 | Nop = 0, 328 | iAdd, //1 329 | iSub, //2 330 | iMult, //3 331 | iDiv, //4 332 | iMod, //5 333 | iNot, //6 334 | iNeg, //7 335 | iCmpEq, //8 336 | iCmpNe, //9 337 | iCmpGt, //10 338 | iCmpGe, //11 339 | iCmpLt, //12 340 | iCmpLe, //13 341 | fAdd, //14 342 | fSub, //15 343 | fMult, //16 344 | fDiv, //17 345 | fMod, //18 346 | fNeg, //19 347 | fCmpEq, //20 348 | fCmpNe, //21 349 | fCmpGt, //22 350 | fCmpGe, //23 351 | fCmpLt, //24 352 | fCmpLe, //25 353 | vAdd, //26 354 | vSub, //27 355 | vMult, //28 356 | vDiv, //29 357 | vNeg, //30 358 | And, //31 359 | Or, //32 360 | Xor, //33 361 | ItoF, //34 362 | FtoI, //35 363 | FtoV, //36 364 | iPushByte1, //37 365 | iPushByte2, //38 366 | iPushByte3, //39 367 | iPushInt, //40 368 | fPush, //41 369 | dup, //42 370 | pop, //43 371 | Native, //44 372 | Enter, //45 373 | Return, //46 374 | pGet, //47 375 | pSet, //48 376 | pPeekSet, //49 377 | ToStack, //50 378 | FromStack, //51 379 | pArray1, //52 380 | ArrayGet1, //53 381 | ArraySet1, //54 382 | pFrame1, //55 383 | GetFrame1, //56 384 | SetFrame1, //57 385 | pStatic1, //58 386 | StaticGet1, //59 387 | StaticSet1, //60 388 | Add1, //61 389 | Mult1, //62 390 | pStructStack, //63 391 | pStruct1, //64 392 | GetStruct1, //65 393 | SetStruct1, //66 394 | iPushShort, //67 395 | Add2, //68 396 | Mult2, //69 397 | pStruct2, //70 398 | GetStruct2, //71 399 | SetStruct2, //72 400 | pArray2, //73 401 | ArrayGet2, //74 402 | ArraySet2, //75 403 | pFrame2, //76 404 | GetFrame2, //77 405 | SetFrame2, //78 406 | pStatic2, //79 407 | StaticGet2, //80 408 | StaticSet2, //81 409 | pGlobal2, //82 410 | GlobalGet2, //83 411 | GlobalSet2, //84 412 | Jump, //85 413 | JumpFalse, //86 414 | JumpNe, //87 415 | JumpEq, //88 416 | JumpLe, //89 417 | JumpLt, //90 418 | JumpGe, //91 419 | JumpGt, //92 420 | Call, //93 421 | pGlobal3, //94 422 | GlobalGet3, //95 423 | GlobalSet3, //96 424 | iPushI24, //97 425 | Switch, //98 426 | PushString, //99 427 | GetHash, //100 428 | StrCopy, //101 429 | ItoS, //102 430 | StrConCat, //103 431 | StrConCatInt, //104 432 | MemCopy, //105 433 | Catch, //106 //No handling of these as Im unsure exactly how they work 434 | Throw, //107 //No script files in the game use these opcodes 435 | pCall, //108 436 | iPush_n1, //109 437 | iPush_0, //110 438 | iPush_1, //111 439 | iPush_2, //112 440 | iPush_3, //113 441 | iPush_4, //114 442 | iPush_5, //115 443 | iPush_6, //116 444 | iPush_7, //117 445 | fPush_n1, //118 446 | fPush_0, //119 447 | fPush_1, //120 448 | fPush_2, //121 449 | fPush_3, //122 450 | fPush_4, //123 451 | fPush_5, //124 452 | fPush_6, //125 453 | fPush_7 //126 454 | } 455 | } 456 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Decompiler 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | if (disposing && (highlight != null)) 21 | { 22 | highlight.Dispose(); 23 | } 24 | base.Dispose(disposing); 25 | } 26 | 27 | #region Windows Form Designer generated code 28 | 29 | /// 30 | /// Required method for Designer support - do not modify 31 | /// the contents of this method with the code editor. 32 | /// 33 | private void InitializeComponent() 34 | { 35 | this.components = new System.ComponentModel.Container(); 36 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 37 | this.fctb1 = new FastColoredTextBoxNS.FastColoredTextBox(); 38 | this.cmsText = new System.Windows.Forms.ContextMenuStrip(this.components); 39 | this.menuStrip1 = new System.Windows.Forms.MenuStrip(); 40 | this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 41 | this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 42 | this.openCFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 43 | this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); 44 | this.saveCFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 45 | this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 46 | this.directoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 47 | this.fileToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); 48 | this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); 49 | this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 50 | this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 51 | this.intStyleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 52 | this.intToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 53 | this.uintToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 54 | this.hexToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 55 | this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); 56 | this.showArraySizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 57 | this.reverseHashesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 58 | this.includeNativeNamespaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 59 | this.declareVariablesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 60 | this.shiftVariablesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 61 | this.globalAndStructHexIndexingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 62 | this.showFuncPointerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 63 | this.useMultiThreadingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 64 | this.includeFunctionPositionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 65 | this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); 66 | this.exportTablesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 67 | this.entitiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 68 | this.nativesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 69 | this.fullNativeInfoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 70 | this.consoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 71 | this.pCToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 72 | this.findHashFromStringsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 73 | this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 74 | this.expandAllBlocksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 75 | this.collaspeAllBlocksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 76 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); 77 | this.showLineNumbersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 78 | this.navigateForwardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 79 | this.navigateBackwardsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 80 | this.extractToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 81 | this.stringsTableToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 82 | this.nativeTableToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 83 | this.nativehFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 84 | this.panel1 = new System.Windows.Forms.Panel(); 85 | this.listView1 = new System.Windows.Forms.ListView(); 86 | this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 87 | this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 88 | this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 89 | this.timer1 = new System.Windows.Forms.Timer(this.components); 90 | this.timer2 = new System.Windows.Forms.Timer(this.components); 91 | this.toolStrip1 = new System.Windows.Forms.ToolStrip(); 92 | this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); 93 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 94 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 95 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 96 | this.toolStripStatusLabel3 = new System.Windows.Forms.ToolStripStatusLabel(); 97 | this.toolStripStatusLabel2 = new System.Windows.Forms.ToolStripStatusLabel(); 98 | this.timer3 = new System.Windows.Forms.Timer(this.components); 99 | this.uppercaseNativesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 100 | ((System.ComponentModel.ISupportInitialize)(this.fctb1)).BeginInit(); 101 | this.menuStrip1.SuspendLayout(); 102 | this.panel1.SuspendLayout(); 103 | this.toolStrip1.SuspendLayout(); 104 | this.statusStrip1.SuspendLayout(); 105 | this.SuspendLayout(); 106 | // 107 | // fctb1 108 | // 109 | this.fctb1.AutoCompleteBracketsList = new char[] { 110 | '(', 111 | ')', 112 | '{', 113 | '}', 114 | '[', 115 | ']', 116 | '\"', 117 | '\"', 118 | '\'', 119 | '\''}; 120 | this.fctb1.AutoIndentCharsPatterns = "\r\n^\\s*[\\w\\.]+(\\s\\w+)?\\s*(?=)\\s*(?[^;]+);\r\n^\\s*(case|default)\\s*[^:]" + 121 | "*(?:)\\s*(?[^;]+);\r\n"; 122 | this.fctb1.AutoScrollMinSize = new System.Drawing.Size(27, 14); 123 | this.fctb1.BackBrush = null; 124 | this.fctb1.BracketsHighlightStrategy = FastColoredTextBoxNS.BracketsHighlightStrategy.Strategy2; 125 | this.fctb1.CharHeight = 14; 126 | this.fctb1.CharWidth = 8; 127 | this.fctb1.ContextMenuStrip = this.cmsText; 128 | this.fctb1.Cursor = System.Windows.Forms.Cursors.IBeam; 129 | this.fctb1.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180))))); 130 | this.fctb1.Dock = System.Windows.Forms.DockStyle.Fill; 131 | this.fctb1.IsReplaceMode = false; 132 | this.fctb1.Language = FastColoredTextBoxNS.Language.CSharp; 133 | this.fctb1.LeftBracket = '('; 134 | this.fctb1.LeftBracket2 = '{'; 135 | this.fctb1.Location = new System.Drawing.Point(0, 24); 136 | this.fctb1.Name = "fctb1"; 137 | this.fctb1.Paddings = new System.Windows.Forms.Padding(0); 138 | this.fctb1.RightBracket = ')'; 139 | this.fctb1.RightBracket2 = '}'; 140 | this.fctb1.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255))))); 141 | this.fctb1.ServiceColors = ((FastColoredTextBoxNS.ServiceColors)(resources.GetObject("fctb1.ServiceColors"))); 142 | this.fctb1.Size = new System.Drawing.Size(561, 582); 143 | this.fctb1.TabIndex = 1; 144 | this.fctb1.Zoom = 100; 145 | this.fctb1.SelectionChanged += new System.EventHandler(this.fctb1_SelectionChanged); 146 | this.fctb1.LineInserted += new System.EventHandler(this.fctb1_LineInserted); 147 | this.fctb1.LineRemoved += new System.EventHandler(this.fctb1_LineRemoved); 148 | this.fctb1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.fctb1_MouseClick); 149 | // 150 | // cmsText 151 | // 152 | this.cmsText.Name = "cmsText"; 153 | this.cmsText.Size = new System.Drawing.Size(61, 4); 154 | this.cmsText.Opening += new System.ComponentModel.CancelEventHandler(this.cmsText_Opening); 155 | // 156 | // menuStrip1 157 | // 158 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 159 | this.fileToolStripMenuItem, 160 | this.optionsToolStripMenuItem, 161 | this.viewToolStripMenuItem, 162 | this.extractToolStripMenuItem}); 163 | this.menuStrip1.Location = new System.Drawing.Point(0, 0); 164 | this.menuStrip1.Name = "menuStrip1"; 165 | this.menuStrip1.Size = new System.Drawing.Size(810, 24); 166 | this.menuStrip1.TabIndex = 2; 167 | this.menuStrip1.Text = "menuStrip1"; 168 | // 169 | // fileToolStripMenuItem 170 | // 171 | this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 172 | this.openToolStripMenuItem, 173 | this.openCFileToolStripMenuItem, 174 | this.toolStripSeparator3, 175 | this.saveCFileToolStripMenuItem, 176 | this.exportToolStripMenuItem, 177 | this.toolStripSeparator2, 178 | this.closeToolStripMenuItem}); 179 | this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; 180 | this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); 181 | this.fileToolStripMenuItem.Text = "File"; 182 | // 183 | // openToolStripMenuItem 184 | // 185 | this.openToolStripMenuItem.Name = "openToolStripMenuItem"; 186 | this.openToolStripMenuItem.Size = new System.Drawing.Size(135, 22); 187 | this.openToolStripMenuItem.Text = "Open"; 188 | this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); 189 | // 190 | // openCFileToolStripMenuItem 191 | // 192 | this.openCFileToolStripMenuItem.Name = "openCFileToolStripMenuItem"; 193 | this.openCFileToolStripMenuItem.Size = new System.Drawing.Size(135, 22); 194 | this.openCFileToolStripMenuItem.Text = "Open C File"; 195 | this.openCFileToolStripMenuItem.Click += new System.EventHandler(this.openCFileToolStripMenuItem_Click); 196 | // 197 | // toolStripSeparator3 198 | // 199 | this.toolStripSeparator3.Name = "toolStripSeparator3"; 200 | this.toolStripSeparator3.Size = new System.Drawing.Size(132, 6); 201 | // 202 | // saveCFileToolStripMenuItem 203 | // 204 | this.saveCFileToolStripMenuItem.Name = "saveCFileToolStripMenuItem"; 205 | this.saveCFileToolStripMenuItem.Size = new System.Drawing.Size(135, 22); 206 | this.saveCFileToolStripMenuItem.Text = "Save C File"; 207 | this.saveCFileToolStripMenuItem.Click += new System.EventHandler(this.saveCFileToolStripMenuItem_Click); 208 | // 209 | // exportToolStripMenuItem 210 | // 211 | this.exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 212 | this.directoryToolStripMenuItem, 213 | this.fileToolStripMenuItem1}); 214 | this.exportToolStripMenuItem.Name = "exportToolStripMenuItem"; 215 | this.exportToolStripMenuItem.Size = new System.Drawing.Size(135, 22); 216 | this.exportToolStripMenuItem.Text = "Export"; 217 | // 218 | // directoryToolStripMenuItem 219 | // 220 | this.directoryToolStripMenuItem.Name = "directoryToolStripMenuItem"; 221 | this.directoryToolStripMenuItem.Size = new System.Drawing.Size(122, 22); 222 | this.directoryToolStripMenuItem.Text = "Directory"; 223 | this.directoryToolStripMenuItem.Click += new System.EventHandler(this.directoryToolStripMenuItem_Click); 224 | // 225 | // fileToolStripMenuItem1 226 | // 227 | this.fileToolStripMenuItem1.Name = "fileToolStripMenuItem1"; 228 | this.fileToolStripMenuItem1.Size = new System.Drawing.Size(122, 22); 229 | this.fileToolStripMenuItem1.Text = "File"; 230 | this.fileToolStripMenuItem1.Click += new System.EventHandler(this.fileToolStripMenuItem1_Click); 231 | // 232 | // toolStripSeparator2 233 | // 234 | this.toolStripSeparator2.Name = "toolStripSeparator2"; 235 | this.toolStripSeparator2.Size = new System.Drawing.Size(132, 6); 236 | // 237 | // closeToolStripMenuItem 238 | // 239 | this.closeToolStripMenuItem.Name = "closeToolStripMenuItem"; 240 | this.closeToolStripMenuItem.Size = new System.Drawing.Size(135, 22); 241 | this.closeToolStripMenuItem.Text = "Close"; 242 | this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click); 243 | // 244 | // optionsToolStripMenuItem 245 | // 246 | this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 247 | this.intStyleToolStripMenuItem, 248 | this.toolStripSeparator5, 249 | this.showArraySizeToolStripMenuItem, 250 | this.reverseHashesToolStripMenuItem, 251 | this.includeNativeNamespaceToolStripMenuItem, 252 | this.declareVariablesToolStripMenuItem, 253 | this.shiftVariablesToolStripMenuItem, 254 | this.globalAndStructHexIndexingToolStripMenuItem, 255 | this.showFuncPointerToolStripMenuItem, 256 | this.useMultiThreadingToolStripMenuItem, 257 | this.includeFunctionPositionToolStripMenuItem, 258 | this.uppercaseNativesToolStripMenuItem, 259 | this.toolStripSeparator4, 260 | this.exportTablesToolStripMenuItem, 261 | this.findHashFromStringsToolStripMenuItem}); 262 | this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; 263 | this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); 264 | this.optionsToolStripMenuItem.Text = "Options"; 265 | // 266 | // intStyleToolStripMenuItem 267 | // 268 | this.intStyleToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 269 | this.intToolStripMenuItem, 270 | this.uintToolStripMenuItem, 271 | this.hexToolStripMenuItem}); 272 | this.intStyleToolStripMenuItem.Name = "intStyleToolStripMenuItem"; 273 | this.intStyleToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 274 | this.intStyleToolStripMenuItem.Text = "IntStyle"; 275 | this.intStyleToolStripMenuItem.ToolTipText = "Choose how to display int32 data types"; 276 | // 277 | // intToolStripMenuItem 278 | // 279 | this.intToolStripMenuItem.Name = "intToolStripMenuItem"; 280 | this.intToolStripMenuItem.Size = new System.Drawing.Size(96, 22); 281 | this.intToolStripMenuItem.Text = "Int"; 282 | this.intToolStripMenuItem.Click += new System.EventHandler(this.intstylechanged); 283 | // 284 | // uintToolStripMenuItem 285 | // 286 | this.uintToolStripMenuItem.Name = "uintToolStripMenuItem"; 287 | this.uintToolStripMenuItem.Size = new System.Drawing.Size(96, 22); 288 | this.uintToolStripMenuItem.Text = "Uint"; 289 | this.uintToolStripMenuItem.Click += new System.EventHandler(this.intstylechanged); 290 | // 291 | // hexToolStripMenuItem 292 | // 293 | this.hexToolStripMenuItem.Name = "hexToolStripMenuItem"; 294 | this.hexToolStripMenuItem.Size = new System.Drawing.Size(96, 22); 295 | this.hexToolStripMenuItem.Text = "Hex"; 296 | this.hexToolStripMenuItem.Click += new System.EventHandler(this.intstylechanged); 297 | // 298 | // toolStripSeparator5 299 | // 300 | this.toolStripSeparator5.Name = "toolStripSeparator5"; 301 | this.toolStripSeparator5.Size = new System.Drawing.Size(233, 6); 302 | // 303 | // showArraySizeToolStripMenuItem 304 | // 305 | this.showArraySizeToolStripMenuItem.Name = "showArraySizeToolStripMenuItem"; 306 | this.showArraySizeToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 307 | this.showArraySizeToolStripMenuItem.Text = "Show Array Size"; 308 | this.showArraySizeToolStripMenuItem.ToolTipText = "Shows the size of the items in an array \r\nuLocal_5[index ]\r\nan array o" + 309 | "f vector3s would look like this\r\nvStatic_1[0 <3>];"; 310 | this.showArraySizeToolStripMenuItem.Click += new System.EventHandler(this.showArraySizeToolStripMenuItem_Click); 311 | // 312 | // reverseHashesToolStripMenuItem 313 | // 314 | this.reverseHashesToolStripMenuItem.Name = "reverseHashesToolStripMenuItem"; 315 | this.reverseHashesToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 316 | this.reverseHashesToolStripMenuItem.Text = "Reverse Hashes"; 317 | this.reverseHashesToolStripMenuItem.ToolTipText = "Reverse known hashes into their text equivalent\r\ne.g 0xB779A091 -> joaat(\"adder\")" + 318 | ""; 319 | this.reverseHashesToolStripMenuItem.Click += new System.EventHandler(this.reverseHashesToolStripMenuItem_Click); 320 | // 321 | // includeNativeNamespaceToolStripMenuItem 322 | // 323 | this.includeNativeNamespaceToolStripMenuItem.Name = "includeNativeNamespaceToolStripMenuItem"; 324 | this.includeNativeNamespaceToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 325 | this.includeNativeNamespaceToolStripMenuItem.Text = "Include Native Namespace"; 326 | this.includeNativeNamespaceToolStripMenuItem.Click += new System.EventHandler(this.includeNativeNamespaceToolStripMenuItem_Click); 327 | // 328 | // declareVariablesToolStripMenuItem 329 | // 330 | this.declareVariablesToolStripMenuItem.Name = "declareVariablesToolStripMenuItem"; 331 | this.declareVariablesToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 332 | this.declareVariablesToolStripMenuItem.Text = "Declare Variables"; 333 | this.declareVariablesToolStripMenuItem.ToolTipText = "Include Variable declarations at the start of file and functions"; 334 | this.declareVariablesToolStripMenuItem.Click += new System.EventHandler(this.declareVariablesToolStripMenuItem_Click); 335 | // 336 | // shiftVariablesToolStripMenuItem 337 | // 338 | this.shiftVariablesToolStripMenuItem.Name = "shiftVariablesToolStripMenuItem"; 339 | this.shiftVariablesToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 340 | this.shiftVariablesToolStripMenuItem.Text = "Shift Variables"; 341 | this.shiftVariablesToolStripMenuItem.ToolTipText = resources.GetString("shiftVariablesToolStripMenuItem.ToolTipText"); 342 | this.shiftVariablesToolStripMenuItem.Click += new System.EventHandler(this.shiftVariablesToolStripMenuItem_Click); 343 | // 344 | // globalAndStructHexIndexingToolStripMenuItem 345 | // 346 | this.globalAndStructHexIndexingToolStripMenuItem.Name = "globalAndStructHexIndexingToolStripMenuItem"; 347 | this.globalAndStructHexIndexingToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 348 | this.globalAndStructHexIndexingToolStripMenuItem.Text = "Global and Struct Hex Indexing"; 349 | this.globalAndStructHexIndexingToolStripMenuItem.Click += new System.EventHandler(this.globalAndStructHexIndexingToolStripMenuItem_Click); 350 | // 351 | // showFuncPointerToolStripMenuItem 352 | // 353 | this.showFuncPointerToolStripMenuItem.Name = "showFuncPointerToolStripMenuItem"; 354 | this.showFuncPointerToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 355 | this.showFuncPointerToolStripMenuItem.Text = "Show Func Pointer"; 356 | this.showFuncPointerToolStripMenuItem.Click += new System.EventHandler(this.showFuncPointerToolStripMenuItem_Click); 357 | // 358 | // useMultiThreadingToolStripMenuItem 359 | // 360 | this.useMultiThreadingToolStripMenuItem.Name = "useMultiThreadingToolStripMenuItem"; 361 | this.useMultiThreadingToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 362 | this.useMultiThreadingToolStripMenuItem.Text = "Use MultiThreading"; 363 | this.useMultiThreadingToolStripMenuItem.Click += new System.EventHandler(this.useMultiThreadingToolStripMenuItem_Click); 364 | // 365 | // includeFunctionPositionToolStripMenuItem 366 | // 367 | this.includeFunctionPositionToolStripMenuItem.Name = "includeFunctionPositionToolStripMenuItem"; 368 | this.includeFunctionPositionToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 369 | this.includeFunctionPositionToolStripMenuItem.Text = "Include Function Position"; 370 | this.includeFunctionPositionToolStripMenuItem.Click += new System.EventHandler(this.includeFunctionPositionToolStripMenuItem_Click); 371 | // 372 | // toolStripSeparator4 373 | // 374 | this.toolStripSeparator4.Name = "toolStripSeparator4"; 375 | this.toolStripSeparator4.Size = new System.Drawing.Size(233, 6); 376 | // 377 | // exportTablesToolStripMenuItem 378 | // 379 | this.exportTablesToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 380 | this.entitiesToolStripMenuItem, 381 | this.nativesToolStripMenuItem, 382 | this.fullNativeInfoToolStripMenuItem}); 383 | this.exportTablesToolStripMenuItem.Name = "exportTablesToolStripMenuItem"; 384 | this.exportTablesToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 385 | this.exportTablesToolStripMenuItem.Text = "Export Tables"; 386 | // 387 | // entitiesToolStripMenuItem 388 | // 389 | this.entitiesToolStripMenuItem.Name = "entitiesToolStripMenuItem"; 390 | this.entitiesToolStripMenuItem.Size = new System.Drawing.Size(154, 22); 391 | this.entitiesToolStripMenuItem.Text = "Entities"; 392 | this.entitiesToolStripMenuItem.ToolTipText = "Export The entites file (entities_exp.dat) built into the program so you can edit" + 393 | " it.\r\nThe program will search for entities.dat in its directory and use that for" + 394 | " reversing hashes"; 395 | this.entitiesToolStripMenuItem.Click += new System.EventHandler(this.entitiesToolStripMenuItem_Click); 396 | // 397 | // nativesToolStripMenuItem 398 | // 399 | this.nativesToolStripMenuItem.Name = "nativesToolStripMenuItem"; 400 | this.nativesToolStripMenuItem.Size = new System.Drawing.Size(154, 22); 401 | this.nativesToolStripMenuItem.Text = "Natives"; 402 | this.nativesToolStripMenuItem.ToolTipText = "Export The natives file (natives_exp.dat) built into the program so you can edit " + 403 | "it.\r\nThe program will search for natives.dat in its directory and use that for r" + 404 | "eversing natives"; 405 | this.nativesToolStripMenuItem.Click += new System.EventHandler(this.nativesToolStripMenuItem_Click); 406 | // 407 | // fullNativeInfoToolStripMenuItem 408 | // 409 | this.fullNativeInfoToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 410 | this.consoleToolStripMenuItem, 411 | this.pCToolStripMenuItem}); 412 | this.fullNativeInfoToolStripMenuItem.Name = "fullNativeInfoToolStripMenuItem"; 413 | this.fullNativeInfoToolStripMenuItem.Size = new System.Drawing.Size(154, 22); 414 | this.fullNativeInfoToolStripMenuItem.Text = "Full Native info"; 415 | this.fullNativeInfoToolStripMenuItem.ToolTipText = "Export a file containing definitions of natives to a h file in programs directory" + 416 | "\r\n"; 417 | // 418 | // consoleToolStripMenuItem 419 | // 420 | this.consoleToolStripMenuItem.Name = "consoleToolStripMenuItem"; 421 | this.consoleToolStripMenuItem.Size = new System.Drawing.Size(117, 22); 422 | this.consoleToolStripMenuItem.Text = "Console"; 423 | this.consoleToolStripMenuItem.Click += new System.EventHandler(this.fullNativeInfoToolStripMenuItem_Click); 424 | // 425 | // pCToolStripMenuItem 426 | // 427 | this.pCToolStripMenuItem.Name = "pCToolStripMenuItem"; 428 | this.pCToolStripMenuItem.Size = new System.Drawing.Size(117, 22); 429 | this.pCToolStripMenuItem.Text = "PC"; 430 | this.pCToolStripMenuItem.Click += new System.EventHandler(this.fullPCNativeInfoToolStripMenuItem_Click); 431 | // 432 | // findHashFromStringsToolStripMenuItem 433 | // 434 | this.findHashFromStringsToolStripMenuItem.Name = "findHashFromStringsToolStripMenuItem"; 435 | this.findHashFromStringsToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 436 | this.findHashFromStringsToolStripMenuItem.Text = "Reverse Hashes From Strings"; 437 | this.findHashFromStringsToolStripMenuItem.Click += new System.EventHandler(this.findHashFromStringsToolStripMenuItem_Click); 438 | // 439 | // viewToolStripMenuItem 440 | // 441 | this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 442 | this.expandAllBlocksToolStripMenuItem, 443 | this.collaspeAllBlocksToolStripMenuItem, 444 | this.toolStripSeparator1, 445 | this.showLineNumbersToolStripMenuItem, 446 | this.navigateForwardToolStripMenuItem, 447 | this.navigateBackwardsToolStripMenuItem}); 448 | this.viewToolStripMenuItem.Name = "viewToolStripMenuItem"; 449 | this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20); 450 | this.viewToolStripMenuItem.Text = "View"; 451 | // 452 | // expandAllBlocksToolStripMenuItem 453 | // 454 | this.expandAllBlocksToolStripMenuItem.Name = "expandAllBlocksToolStripMenuItem"; 455 | this.expandAllBlocksToolStripMenuItem.Size = new System.Drawing.Size(273, 22); 456 | this.expandAllBlocksToolStripMenuItem.Text = "Expand All Blocks"; 457 | this.expandAllBlocksToolStripMenuItem.Click += new System.EventHandler(this.expandAllBlocksToolStripMenuItem_Click); 458 | // 459 | // collaspeAllBlocksToolStripMenuItem 460 | // 461 | this.collaspeAllBlocksToolStripMenuItem.Name = "collaspeAllBlocksToolStripMenuItem"; 462 | this.collaspeAllBlocksToolStripMenuItem.Size = new System.Drawing.Size(273, 22); 463 | this.collaspeAllBlocksToolStripMenuItem.Text = "Collaspe All Blocks"; 464 | this.collaspeAllBlocksToolStripMenuItem.Click += new System.EventHandler(this.collaspeAllBlocksToolStripMenuItem_Click); 465 | // 466 | // toolStripSeparator1 467 | // 468 | this.toolStripSeparator1.Name = "toolStripSeparator1"; 469 | this.toolStripSeparator1.Size = new System.Drawing.Size(270, 6); 470 | // 471 | // showLineNumbersToolStripMenuItem 472 | // 473 | this.showLineNumbersToolStripMenuItem.Name = "showLineNumbersToolStripMenuItem"; 474 | this.showLineNumbersToolStripMenuItem.Size = new System.Drawing.Size(273, 22); 475 | this.showLineNumbersToolStripMenuItem.Text = "Show Line Numbers"; 476 | this.showLineNumbersToolStripMenuItem.Click += new System.EventHandler(this.showLineNumbersToolStripMenuItem_Click); 477 | // 478 | // navigateForwardToolStripMenuItem 479 | // 480 | this.navigateForwardToolStripMenuItem.Name = "navigateForwardToolStripMenuItem"; 481 | this.navigateForwardToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Oemplus))); 482 | this.navigateForwardToolStripMenuItem.Size = new System.Drawing.Size(273, 22); 483 | this.navigateForwardToolStripMenuItem.Text = "Navigate Forward"; 484 | this.navigateForwardToolStripMenuItem.Click += new System.EventHandler(this.navigateForwardToolStripMenuItem_Click); 485 | // 486 | // navigateBackwardsToolStripMenuItem 487 | // 488 | this.navigateBackwardsToolStripMenuItem.Name = "navigateBackwardsToolStripMenuItem"; 489 | this.navigateBackwardsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.OemMinus))); 490 | this.navigateBackwardsToolStripMenuItem.Size = new System.Drawing.Size(273, 22); 491 | this.navigateBackwardsToolStripMenuItem.Text = "Navigate Backwards"; 492 | this.navigateBackwardsToolStripMenuItem.Click += new System.EventHandler(this.navigateBackwardsToolStripMenuItem_Click); 493 | // 494 | // extractToolStripMenuItem 495 | // 496 | this.extractToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 497 | this.stringsTableToolStripMenuItem, 498 | this.nativeTableToolStripMenuItem, 499 | this.nativehFileToolStripMenuItem}); 500 | this.extractToolStripMenuItem.Enabled = false; 501 | this.extractToolStripMenuItem.Name = "extractToolStripMenuItem"; 502 | this.extractToolStripMenuItem.Size = new System.Drawing.Size(54, 20); 503 | this.extractToolStripMenuItem.Text = "Extract"; 504 | this.extractToolStripMenuItem.Visible = false; 505 | // 506 | // stringsTableToolStripMenuItem 507 | // 508 | this.stringsTableToolStripMenuItem.Name = "stringsTableToolStripMenuItem"; 509 | this.stringsTableToolStripMenuItem.Size = new System.Drawing.Size(139, 22); 510 | this.stringsTableToolStripMenuItem.Text = "Strings table"; 511 | this.stringsTableToolStripMenuItem.Click += new System.EventHandler(this.stringsTableToolStripMenuItem_Click); 512 | // 513 | // nativeTableToolStripMenuItem 514 | // 515 | this.nativeTableToolStripMenuItem.Name = "nativeTableToolStripMenuItem"; 516 | this.nativeTableToolStripMenuItem.Size = new System.Drawing.Size(139, 22); 517 | this.nativeTableToolStripMenuItem.Text = "Native table"; 518 | this.nativeTableToolStripMenuItem.Click += new System.EventHandler(this.nativeTableToolStripMenuItem_Click); 519 | // 520 | // nativehFileToolStripMenuItem 521 | // 522 | this.nativehFileToolStripMenuItem.Name = "nativehFileToolStripMenuItem"; 523 | this.nativehFileToolStripMenuItem.Size = new System.Drawing.Size(139, 22); 524 | this.nativehFileToolStripMenuItem.Text = "Native.h file"; 525 | this.nativehFileToolStripMenuItem.Click += new System.EventHandler(this.nativehFileToolStripMenuItem_Click); 526 | // 527 | // panel1 528 | // 529 | this.panel1.Controls.Add(this.listView1); 530 | this.panel1.Dock = System.Windows.Forms.DockStyle.Right; 531 | this.panel1.Location = new System.Drawing.Point(561, 24); 532 | this.panel1.Name = "panel1"; 533 | this.panel1.Size = new System.Drawing.Size(224, 582); 534 | this.panel1.TabIndex = 3; 535 | // 536 | // listView1 537 | // 538 | this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 539 | this.columnHeader1, 540 | this.columnHeader2, 541 | this.columnHeader3}); 542 | this.listView1.Dock = System.Windows.Forms.DockStyle.Fill; 543 | this.listView1.FullRowSelect = true; 544 | this.listView1.GridLines = true; 545 | this.listView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; 546 | this.listView1.ImeMode = System.Windows.Forms.ImeMode.NoControl; 547 | this.listView1.Location = new System.Drawing.Point(0, 0); 548 | this.listView1.MultiSelect = false; 549 | this.listView1.Name = "listView1"; 550 | this.listView1.Size = new System.Drawing.Size(224, 582); 551 | this.listView1.TabIndex = 0; 552 | this.listView1.UseCompatibleStateImageBehavior = false; 553 | this.listView1.View = System.Windows.Forms.View.Details; 554 | this.listView1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listView1_MouseDoubleClick); 555 | this.listView1.MouseEnter += new System.EventHandler(this.listView1_MouseEnter); 556 | this.listView1.MouseLeave += new System.EventHandler(this.listView1_MouseLeave); 557 | // 558 | // columnHeader1 559 | // 560 | this.columnHeader1.Text = "Function"; 561 | this.columnHeader1.Width = 96; 562 | // 563 | // columnHeader2 564 | // 565 | this.columnHeader2.Text = "Line"; 566 | this.columnHeader2.Width = 55; 567 | // 568 | // columnHeader3 569 | // 570 | this.columnHeader3.Text = "CodePos"; 571 | this.columnHeader3.Width = 70; 572 | // 573 | // timer1 574 | // 575 | this.timer1.Interval = 5000; 576 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 577 | // 578 | // timer2 579 | // 580 | this.timer2.Interval = 1; 581 | this.timer2.Tick += new System.EventHandler(this.timer2_Tick); 582 | // 583 | // toolStrip1 584 | // 585 | this.toolStrip1.Dock = System.Windows.Forms.DockStyle.Right; 586 | this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; 587 | this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 588 | this.toolStripButton1}); 589 | this.toolStrip1.Location = new System.Drawing.Point(785, 24); 590 | this.toolStrip1.Name = "toolStrip1"; 591 | this.toolStrip1.Size = new System.Drawing.Size(25, 582); 592 | this.toolStrip1.TabIndex = 1; 593 | this.toolStrip1.Text = "toolStrip1"; 594 | // 595 | // toolStripButton1 596 | // 597 | this.toolStripButton1.AutoToolTip = false; 598 | this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; 599 | this.toolStripButton1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 600 | this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); 601 | this.toolStripButton1.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; 602 | this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; 603 | this.toolStripButton1.Name = "toolStripButton1"; 604 | this.toolStripButton1.Padding = new System.Windows.Forms.Padding(2); 605 | this.toolStripButton1.Size = new System.Drawing.Size(22, 127); 606 | this.toolStripButton1.Text = "Function Locations"; 607 | this.toolStripButton1.TextDirection = System.Windows.Forms.ToolStripTextDirection.Vertical90; 608 | this.toolStripButton1.ToolTipText = "Show the line numbers for functions and lets you jump to them"; 609 | this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click); 610 | // 611 | // statusStrip1 612 | // 613 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 614 | this.toolStripStatusLabel1, 615 | this.toolStripStatusLabel3, 616 | this.toolStripStatusLabel2}); 617 | this.statusStrip1.Location = new System.Drawing.Point(0, 606); 618 | this.statusStrip1.Name = "statusStrip1"; 619 | this.statusStrip1.Size = new System.Drawing.Size(810, 22); 620 | this.statusStrip1.TabIndex = 4; 621 | this.statusStrip1.Text = "statusStrip1"; 622 | // 623 | // toolStripStatusLabel1 624 | // 625 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 626 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(39, 17); 627 | this.toolStripStatusLabel1.Text = "Ready"; 628 | // 629 | // toolStripStatusLabel3 630 | // 631 | this.toolStripStatusLabel3.Name = "toolStripStatusLabel3"; 632 | this.toolStripStatusLabel3.Size = new System.Drawing.Size(756, 17); 633 | this.toolStripStatusLabel3.Spring = true; 634 | this.toolStripStatusLabel3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 635 | // 636 | // toolStripStatusLabel2 637 | // 638 | this.toolStripStatusLabel2.Name = "toolStripStatusLabel2"; 639 | this.toolStripStatusLabel2.Size = new System.Drawing.Size(0, 17); 640 | this.toolStripStatusLabel2.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 641 | // 642 | // timer3 643 | // 644 | this.timer3.Interval = 5000; 645 | this.timer3.Tick += new System.EventHandler(this.timer3_Tick); 646 | // 647 | // uppercaseNativesToolStripMenuItem 648 | // 649 | this.uppercaseNativesToolStripMenuItem.Name = "uppercaseNativesToolStripMenuItem"; 650 | this.uppercaseNativesToolStripMenuItem.Size = new System.Drawing.Size(236, 22); 651 | this.uppercaseNativesToolStripMenuItem.Text = "Uppercase Natives"; 652 | this.uppercaseNativesToolStripMenuItem.Click += new System.EventHandler(this.uppercaseNativesToolStripMenuItem_Click); 653 | // 654 | // MainForm 655 | // 656 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 657 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 658 | this.ClientSize = new System.Drawing.Size(810, 628); 659 | this.Controls.Add(this.fctb1); 660 | this.Controls.Add(this.panel1); 661 | this.Controls.Add(this.toolStrip1); 662 | this.Controls.Add(this.statusStrip1); 663 | this.Controls.Add(this.menuStrip1); 664 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 665 | this.MainMenuStrip = this.menuStrip1; 666 | this.Name = "MainForm"; 667 | this.Text = "GTA V High Level Decompiler"; 668 | ((System.ComponentModel.ISupportInitialize)(this.fctb1)).EndInit(); 669 | this.menuStrip1.ResumeLayout(false); 670 | this.menuStrip1.PerformLayout(); 671 | this.panel1.ResumeLayout(false); 672 | this.toolStrip1.ResumeLayout(false); 673 | this.toolStrip1.PerformLayout(); 674 | this.statusStrip1.ResumeLayout(false); 675 | this.statusStrip1.PerformLayout(); 676 | this.ResumeLayout(false); 677 | this.PerformLayout(); 678 | 679 | } 680 | 681 | #endregion 682 | 683 | private FastColoredTextBoxNS.FastColoredTextBox fctb1; 684 | private System.Windows.Forms.MenuStrip menuStrip1; 685 | private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; 686 | private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; 687 | private System.Windows.Forms.ToolStripMenuItem exportToolStripMenuItem; 688 | private System.Windows.Forms.ToolStripMenuItem directoryToolStripMenuItem; 689 | private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem1; 690 | private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; 691 | private System.Windows.Forms.ToolStripMenuItem intStyleToolStripMenuItem; 692 | private System.Windows.Forms.ToolStripMenuItem intToolStripMenuItem; 693 | private System.Windows.Forms.ToolStripMenuItem uintToolStripMenuItem; 694 | private System.Windows.Forms.ToolStripMenuItem hexToolStripMenuItem; 695 | private System.Windows.Forms.ToolStripMenuItem showArraySizeToolStripMenuItem; 696 | private System.Windows.Forms.ToolStripMenuItem reverseHashesToolStripMenuItem; 697 | private System.Windows.Forms.ToolStripMenuItem declareVariablesToolStripMenuItem; 698 | private System.Windows.Forms.ToolStripMenuItem shiftVariablesToolStripMenuItem; 699 | private System.Windows.Forms.Panel panel1; 700 | private System.Windows.Forms.ListView listView1; 701 | private System.Windows.Forms.ColumnHeader columnHeader1; 702 | private System.Windows.Forms.ColumnHeader columnHeader2; 703 | private System.Windows.Forms.Timer timer1; 704 | private System.Windows.Forms.Timer timer2; 705 | private System.Windows.Forms.ToolStrip toolStrip1; 706 | private System.Windows.Forms.ToolStripButton toolStripButton1; 707 | private System.Windows.Forms.ToolStripMenuItem exportTablesToolStripMenuItem; 708 | private System.Windows.Forms.ToolStripMenuItem entitiesToolStripMenuItem; 709 | private System.Windows.Forms.ToolStripMenuItem nativesToolStripMenuItem; 710 | private System.Windows.Forms.ToolTip toolTip1; 711 | private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem; 712 | private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem; 713 | private System.Windows.Forms.ToolStripMenuItem expandAllBlocksToolStripMenuItem; 714 | private System.Windows.Forms.ToolStripMenuItem collaspeAllBlocksToolStripMenuItem; 715 | private System.Windows.Forms.StatusStrip statusStrip1; 716 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; 717 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel2; 718 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; 719 | private System.Windows.Forms.ToolStripMenuItem showLineNumbersToolStripMenuItem; 720 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel3; 721 | private System.Windows.Forms.Timer timer3; 722 | private System.Windows.Forms.ToolStripMenuItem openCFileToolStripMenuItem; 723 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; 724 | private System.Windows.Forms.ToolStripMenuItem saveCFileToolStripMenuItem; 725 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; 726 | private System.Windows.Forms.ContextMenuStrip cmsText; 727 | private System.Windows.Forms.ToolStripMenuItem fullNativeInfoToolStripMenuItem; 728 | private System.Windows.Forms.ToolStripMenuItem extractToolStripMenuItem; 729 | private System.Windows.Forms.ToolStripMenuItem stringsTableToolStripMenuItem; 730 | private System.Windows.Forms.ToolStripMenuItem nativeTableToolStripMenuItem; 731 | private System.Windows.Forms.ToolStripMenuItem nativehFileToolStripMenuItem; 732 | private System.Windows.Forms.ToolStripMenuItem navigateForwardToolStripMenuItem; 733 | private System.Windows.Forms.ToolStripMenuItem navigateBackwardsToolStripMenuItem; 734 | private System.Windows.Forms.ToolStripMenuItem useMultiThreadingToolStripMenuItem; 735 | private System.Windows.Forms.ToolStripMenuItem showFuncPointerToolStripMenuItem; 736 | private System.Windows.Forms.ToolStripMenuItem consoleToolStripMenuItem; 737 | private System.Windows.Forms.ToolStripMenuItem pCToolStripMenuItem; 738 | private System.Windows.Forms.ToolStripMenuItem findHashFromStringsToolStripMenuItem; 739 | private System.Windows.Forms.ToolStripMenuItem includeNativeNamespaceToolStripMenuItem; 740 | private System.Windows.Forms.ToolStripMenuItem globalAndStructHexIndexingToolStripMenuItem; 741 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; 742 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; 743 | private System.Windows.Forms.ColumnHeader columnHeader3; 744 | private System.Windows.Forms.ToolStripMenuItem includeFunctionPositionToolStripMenuItem; 745 | private System.Windows.Forms.ToolStripMenuItem uppercaseNativesToolStripMenuItem; 746 | } 747 | } 748 | 749 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.IO; 11 | using System.Reflection; 12 | using System.Runtime.InteropServices; 13 | using FastColoredTextBoxNS; 14 | using System.Text.RegularExpressions; 15 | using System.Threading; 16 | 17 | namespace Decompiler 18 | { 19 | 20 | public partial class MainForm : Form 21 | { 22 | bool loadingfile = false; 23 | string filename = ""; 24 | private bool scriptopen = false; 25 | ScriptFile fileopen; 26 | Style highlight; 27 | Queue> CompileList; 28 | List> FoundStrings; 29 | uint[] HashToFind; 30 | string SaveDirectory; 31 | 32 | public bool ScriptOpen 33 | { 34 | get { return scriptopen; } 35 | set { extractToolStripMenuItem.Visible = extractToolStripMenuItem.Enabled = scriptopen = value; } 36 | } 37 | 38 | 39 | public MainForm() 40 | { 41 | InitializeComponent(); 42 | ScriptFile.npi = new NativeParamInfo(); 43 | 44 | //ScriptFile.hashbank = temp; 45 | // ScriptFile.hashbank = new Hashes(); 46 | panel1.Size = new Size(0, panel1.Height); 47 | if (!File.Exists(Program.Config.path)) 48 | { 49 | Program.Config.IniWriteValue("Base", "IntStyle", "int"); 50 | Program.Config.IniWriteBool("Base", "Show_Array_Size", true); 51 | Program.Config.IniWriteBool("Base", "Reverse_Hashes", true); 52 | Program.Config.IniWriteBool("Base", "Declare_Variables", true); 53 | Program.Config.IniWriteBool("Base", "Shift_Variables", true); 54 | Program.Config.IniWriteBool("View", "Show_Nat_Namespace", true); 55 | Program.Config.IniWriteBool("Base", "Show_Func_Pointer", false); 56 | Program.Config.IniWriteBool("Base", "Use_MultiThreading", false); 57 | Program.Config.IniWriteBool("Base", "Include_Function_Position", false); 58 | Program.Config.IniWriteBool("Base", "Uppercase_Natives", false); 59 | Program.Config.IniWriteBool("Base", "Hex_Index", false); 60 | Program.Config.IniWriteBool("View", "Line_Numbers", true); 61 | } 62 | showArraySizeToolStripMenuItem.Checked = Program.Find_Show_Array_Size(); 63 | reverseHashesToolStripMenuItem.Checked = Program.Find_Reverse_Hashes(); 64 | declareVariablesToolStripMenuItem.Checked = Program.Find_Declare_Variables(); 65 | shiftVariablesToolStripMenuItem.Checked = Program.Find_Shift_Variables(); 66 | showFuncPointerToolStripMenuItem.Checked = Program.Find_Show_Func_Pointer(); 67 | useMultiThreadingToolStripMenuItem.Checked = Program.Find_Use_MultiThreading(); 68 | includeFunctionPositionToolStripMenuItem.Checked = Program.Find_IncFuncPos(); 69 | includeNativeNamespaceToolStripMenuItem.Checked = Program.Find_Nat_Namespace(); 70 | globalAndStructHexIndexingToolStripMenuItem.Checked = Program.Find_Hex_Index(); 71 | uppercaseNativesToolStripMenuItem.Checked = Program.Find_Upper_Natives(); 72 | 73 | showLineNumbersToolStripMenuItem.Checked = fctb1.ShowLineNumbers = Program.Config.IniReadBool("View", "Line_Numbers"); 74 | ToolStripMenuItem t = null; 75 | switch (Program.Find_getINTType()) 76 | { 77 | case Program.IntType._int: 78 | t = intToolStripMenuItem; 79 | break; 80 | case Program.IntType._uint: 81 | t = uintToolStripMenuItem; 82 | break; 83 | case Program.IntType._hex: 84 | t = hexToolStripMenuItem; 85 | break; 86 | } 87 | t.Checked = true; 88 | t.Enabled = false; 89 | highlight = (Style) new TextStyle(Brushes.Black, Brushes.Orange, fctb1.DefaultStyle.FontStyle); 90 | 91 | } 92 | 93 | void updatestatus(string text) 94 | { 95 | toolStripStatusLabel1.Text = text; 96 | Application.DoEvents(); 97 | } 98 | 99 | void ready() 100 | { 101 | updatestatus("Ready"); 102 | loadingfile = false; 103 | } 104 | 105 | private void openToolStripMenuItem_Click(object sender, EventArgs e) 106 | { 107 | OpenFileDialog ofd = new OpenFileDialog(); 108 | ofd.Filter = "GTA V Script Files|*.xsc;*.csc;*.ysc;*.ysc.full"; 109 | if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 110 | { 111 | DateTime Start = DateTime.Now; 112 | filename = Path.GetFileNameWithoutExtension(ofd.FileName); 113 | loadingfile = true; 114 | fctb1.Clear(); 115 | listView1.Items.Clear(); 116 | updatestatus("Opening Script File..."); 117 | string ext = Path.GetExtension(ofd.FileName); 118 | if (ext == ".full") //handle openIV exporting pc scripts as *.ysc.full 119 | { 120 | ext = Path.GetExtension(Path.GetFileNameWithoutExtension(ofd.FileName)); 121 | } 122 | #if !DEBUG 123 | try 124 | { 125 | #endif 126 | fileopen = new ScriptFile(ofd.OpenFile(), ext != ".ysc"); 127 | #if !DEBUG 128 | } 129 | catch (Exception ex) 130 | { 131 | updatestatus("Error decompiling script " + ex.Message); 132 | return; 133 | } 134 | #endif 135 | updatestatus("Decompiled Script File, Time taken: " + (DateTime.Now - Start).ToString()); 136 | MemoryStream ms = new MemoryStream(); 137 | 138 | fileopen.Save(ms, false); 139 | 140 | 141 | foreach (KeyValuePair> locations in fileopen.Function_loc) 142 | { 143 | listView1.Items.Add(new ListViewItem(new string[] {locations.Key, locations.Value.Item1.ToString(), locations.Value.Item2.ToString()})); 144 | } 145 | fileopen.Close(); 146 | StreamReader sr = new StreamReader(ms); 147 | ms.Position = 0; 148 | updatestatus("Loading Text in Viewer..."); 149 | fctb1.Text = sr.ReadToEnd(); 150 | SetFileName(filename); 151 | ScriptOpen = true; 152 | updatestatus("Ready, Time taken: " + (DateTime.Now - Start).ToString()); 153 | if (ext != ".ysc") 154 | ScriptFile.npi.savefile(); 155 | else 156 | ScriptFile.X64npi.savefile(); 157 | 158 | } 159 | } 160 | 161 | private void directoryToolStripMenuItem_Click(object sender, EventArgs e) 162 | { 163 | CompileList = new Queue>(); 164 | Program.ThreadCount = 0; 165 | FolderSelectDialog fsd = new FolderSelectDialog(); 166 | if (fsd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 167 | { 168 | DateTime Start = DateTime.Now; 169 | SaveDirectory = Path.Combine(fsd.SelectedPath, "exported"); 170 | if (!Directory.Exists(SaveDirectory)) 171 | Directory.CreateDirectory(SaveDirectory); 172 | this.Hide(); 173 | bool console = false, pc = false; 174 | 175 | foreach (string file in Directory.GetFiles(fsd.SelectedPath, "*.xsc")) 176 | { 177 | console = true; 178 | CompileList.Enqueue(new Tuple(file, true)); 179 | } 180 | foreach (string file in Directory.GetFiles(fsd.SelectedPath, "*.csc")) 181 | { 182 | console = true; 183 | CompileList.Enqueue(new Tuple(file, true)); 184 | } 185 | foreach (string file in Directory.GetFiles(fsd.SelectedPath, "*.ysc")) 186 | { 187 | pc = true; 188 | CompileList.Enqueue(new Tuple(file, false)); 189 | } 190 | foreach (string file in Directory.GetFiles(fsd.SelectedPath, "*.ysc.full")) 191 | { 192 | pc = true; 193 | CompileList.Enqueue(new Tuple(file, false)); 194 | } 195 | if (Program.Use_MultiThreading) 196 | { 197 | for (int i = 0; i < Environment.ProcessorCount - 1; i++) 198 | { 199 | Program.ThreadCount++; 200 | new System.Threading.Thread(Decompile).Start(); 201 | //System.Threading.Thread.Sleep(0); 202 | } 203 | Program.ThreadCount++; 204 | Decompile(); 205 | while (Program.ThreadCount > 0) 206 | { 207 | System.Threading.Thread.Sleep(10); 208 | } 209 | } 210 | else 211 | { 212 | Program.ThreadCount++; 213 | Decompile(); 214 | } 215 | 216 | updatestatus("Directory Extracted, Time taken: " + (DateTime.Now - Start).ToString()); 217 | if (console) 218 | ScriptFile.npi.savefile(); 219 | if (pc) 220 | ScriptFile.X64npi.savefile(); 221 | } 222 | this.Show(); 223 | } 224 | 225 | private void Decompile() 226 | { 227 | while (CompileList.Count > 0) 228 | { 229 | Tuple scriptToDecode; 230 | lock (Program.ThreadLock) 231 | { 232 | scriptToDecode = CompileList.Dequeue(); 233 | } 234 | try 235 | { 236 | ScriptFile scriptFile = new ScriptFile((Stream) File.OpenRead(scriptToDecode.Item1), scriptToDecode.Item2); 237 | scriptFile.Save(Path.Combine(SaveDirectory, Path.GetFileNameWithoutExtension(scriptToDecode.Item1) + ".c")); 238 | scriptFile.Close(); 239 | } 240 | catch (Exception ex) 241 | { 242 | MessageBox.Show("Error decompiling script " + Path.GetFileNameWithoutExtension(scriptToDecode.Item1) + " - " + ex.Message); 243 | } 244 | } 245 | Program.ThreadCount--; 246 | } 247 | 248 | private void fileToolStripMenuItem1_Click(object sender, EventArgs e) 249 | { 250 | OpenFileDialog ofd = new OpenFileDialog(); 251 | ofd.Filter = "GTA V Script Files|*.xsc;*.csc;*.ysc"; 252 | #if !DEBUG 253 | try 254 | { 255 | #endif 256 | if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 257 | { 258 | 259 | DateTime Start = DateTime.Now; 260 | ScriptFile file = new ScriptFile(ofd.OpenFile(), (Path.GetExtension(ofd.FileName) != ".ysc")); 261 | file.Save(Path.Combine(Path.GetDirectoryName(ofd.FileName), 262 | Path.GetFileNameWithoutExtension(ofd.FileName) + ".c")); 263 | file.Close(); 264 | if ((Path.GetExtension(ofd.FileName) != ".ysc")) 265 | ScriptFile.npi.savefile(); 266 | else 267 | ScriptFile.X64npi.savefile(); 268 | updatestatus("File Saved, Time taken: " + (DateTime.Now - Start).ToString()); 269 | } 270 | #if !DEBUG 271 | } 272 | catch (Exception ex) 273 | { 274 | updatestatus("Error decompiling script " + ex.Message); 275 | } 276 | #endif 277 | } 278 | 279 | #region Config Options 280 | 281 | private void intstylechanged(object sender, EventArgs e) 282 | { 283 | ToolStripMenuItem clicked = (ToolStripMenuItem) sender; 284 | foreach (ToolStripMenuItem t in intStyleToolStripMenuItem.DropDownItems) 285 | { 286 | t.Enabled = true; 287 | t.Checked = false; 288 | } 289 | clicked.Checked = true; 290 | clicked.Enabled = false; 291 | Program.Config.IniWriteValue("Base", "IntStyle", clicked.Text.ToLower()); 292 | Program.Find_getINTType(); 293 | } 294 | 295 | private void showArraySizeToolStripMenuItem_Click(object sender, EventArgs e) 296 | { 297 | showArraySizeToolStripMenuItem.Checked = !showArraySizeToolStripMenuItem.Checked; 298 | Program.Config.IniWriteBool("Base", "Show_Array_Size", showArraySizeToolStripMenuItem.Checked); 299 | Program.Find_Show_Array_Size(); 300 | } 301 | 302 | private void reverseHashesToolStripMenuItem_Click(object sender, EventArgs e) 303 | { 304 | reverseHashesToolStripMenuItem.Checked = !reverseHashesToolStripMenuItem.Checked; 305 | Program.Config.IniWriteBool("Base", "Reverse_Hashes", reverseHashesToolStripMenuItem.Checked); 306 | Program.Find_Reverse_Hashes(); 307 | } 308 | 309 | private void declareVariablesToolStripMenuItem_Click(object sender, EventArgs e) 310 | { 311 | declareVariablesToolStripMenuItem.Checked = !declareVariablesToolStripMenuItem.Checked; 312 | Program.Config.IniWriteBool("Base", "Declare_Variables", declareVariablesToolStripMenuItem.Checked); 313 | Program.Find_Declare_Variables(); 314 | } 315 | 316 | private void shiftVariablesToolStripMenuItem_Click(object sender, EventArgs e) 317 | { 318 | shiftVariablesToolStripMenuItem.Checked = !shiftVariablesToolStripMenuItem.Checked; 319 | Program.Config.IniWriteBool("Base", "Shift_Variables", shiftVariablesToolStripMenuItem.Checked); 320 | Program.Find_Shift_Variables(); 321 | } 322 | 323 | private void showLineNumbersToolStripMenuItem_Click(object sender, EventArgs e) 324 | { 325 | showLineNumbersToolStripMenuItem.Checked = !showLineNumbersToolStripMenuItem.Checked; 326 | Program.Config.IniWriteBool("View", "Line_Numbers", showLineNumbersToolStripMenuItem.Checked); 327 | fctb1.ShowLineNumbers = showLineNumbersToolStripMenuItem.Checked; 328 | } 329 | 330 | private void showFuncPointerToolStripMenuItem_Click(object sender, EventArgs e) 331 | { 332 | showFuncPointerToolStripMenuItem.Checked = !showFuncPointerToolStripMenuItem.Checked; 333 | Program.Config.IniWriteBool("Base", "Show_Func_Pointer", showFuncPointerToolStripMenuItem.Checked); 334 | Program.Find_Show_Func_Pointer(); 335 | } 336 | 337 | private void RebuildNativeFiles() 338 | { 339 | if(Program.nativefile != null) 340 | { 341 | string path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 342 | "natives.dat"); 343 | if(File.Exists(path)) 344 | Program.nativefile = new NativeFile(File.OpenRead(path)); 345 | else 346 | Program.nativefile = new NativeFile(new MemoryStream(Properties.Resources.natives)); 347 | } 348 | if (Program.x64nativefile != null) 349 | { 350 | string path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 351 | "x64natives.dat"); 352 | if(File.Exists(path)) 353 | Program.x64nativefile = new x64NativeFile(File.OpenRead(path)); 354 | else 355 | Program.x64nativefile = new x64NativeFile(new MemoryStream(Properties.Resources.x64natives)); 356 | } 357 | } 358 | 359 | private void includeNativeNamespaceToolStripMenuItem_Click(object sender, EventArgs e) 360 | { 361 | includeNativeNamespaceToolStripMenuItem.Checked = !includeNativeNamespaceToolStripMenuItem.Checked; 362 | Program.Config.IniWriteBool("Base", "Show_Nat_Namespace", includeNativeNamespaceToolStripMenuItem.Checked); 363 | Program.Find_Nat_Namespace(); 364 | RebuildNativeFiles(); 365 | } 366 | 367 | private void globalAndStructHexIndexingToolStripMenuItem_Click(object sender, EventArgs e) 368 | { 369 | globalAndStructHexIndexingToolStripMenuItem.Checked = !globalAndStructHexIndexingToolStripMenuItem.Checked; 370 | Program.Config.IniWriteBool("Base", "Hex_Index", globalAndStructHexIndexingToolStripMenuItem.Checked); 371 | Program.Find_Hex_Index(); 372 | } 373 | 374 | private void useMultiThreadingToolStripMenuItem_Click(object sender, EventArgs e) 375 | { 376 | useMultiThreadingToolStripMenuItem.Checked = !useMultiThreadingToolStripMenuItem.Checked; 377 | Program.Config.IniWriteBool("Base", "Use_MultiThreading", useMultiThreadingToolStripMenuItem.Checked); 378 | Program.Find_Use_MultiThreading(); 379 | } 380 | 381 | private void includeFunctionPositionToolStripMenuItem_Click(object sender, EventArgs e) 382 | { 383 | includeFunctionPositionToolStripMenuItem.Checked = !includeFunctionPositionToolStripMenuItem.Checked; 384 | Program.Config.IniWriteBool("Base", "Include_Function_Position", includeFunctionPositionToolStripMenuItem.Checked); 385 | Program.Find_IncFuncPos(); 386 | } 387 | 388 | private void uppercaseNativesToolStripMenuItem_Click(object sender, EventArgs e) 389 | { 390 | uppercaseNativesToolStripMenuItem.Checked = !uppercaseNativesToolStripMenuItem.Checked; 391 | Program.Config.IniWriteBool("Base", "Uppercase_Natives", uppercaseNativesToolStripMenuItem.Checked); 392 | Program.Find_Upper_Natives(); 393 | RebuildNativeFiles(); 394 | } 395 | 396 | #endregion 397 | 398 | #region Function Location 399 | 400 | bool opening = false; 401 | bool forceclose = false; 402 | 403 | private void listView1_MouseDoubleClick(object sender, MouseEventArgs e) 404 | { 405 | if (listView1.SelectedItems.Count == 1) 406 | { 407 | int num = Convert.ToInt32(listView1.SelectedItems[0].SubItems[1].Text); 408 | fctb1.Selection = new FastColoredTextBoxNS.Range(fctb1, 0, num, 0, num); 409 | fctb1.DoSelectionVisible(); 410 | } 411 | } 412 | 413 | private void listView1_MouseLeave(object sender, EventArgs e) 414 | { 415 | timer1.Start(); 416 | } 417 | 418 | private void timer1_Tick(object sender, EventArgs e) 419 | { 420 | if (panel1.ClientRectangle.Contains(panel1.PointToClient(Control.MousePosition))) 421 | { 422 | return; 423 | } 424 | opening = false; 425 | timer2.Start(); 426 | timer1.Stop(); 427 | } 428 | 429 | 430 | private void listView1_MouseEnter(object sender, EventArgs e) 431 | { 432 | if (forceclose) 433 | return; 434 | timer1.Stop(); 435 | opening = true; 436 | } 437 | 438 | private void timer2_Tick(object sender, EventArgs e) 439 | { 440 | if (opening) 441 | { 442 | if (panel1.Size.Width < 165) panel1.Size = new Size(panel1.Size.Width + 6, panel1.Size.Height); 443 | else 444 | { 445 | panel1.Size = new Size(170, panel1.Size.Height); 446 | timer2.Stop(); 447 | forceclose = false; 448 | } 449 | 450 | } 451 | if (!opening) 452 | { 453 | if (panel1.Size.Width > 2) panel1.Size = new Size(panel1.Size.Width - 2, panel1.Size.Height); 454 | else 455 | { 456 | panel1.Size = new Size(0, panel1.Size.Height); 457 | timer2.Stop(); 458 | forceclose = false; 459 | } 460 | 461 | } 462 | 463 | } 464 | 465 | private void toolStripButton1_Click(object sender, EventArgs e) 466 | { 467 | opening = !opening; 468 | if (!opening) 469 | forceclose = true; 470 | timer2.Start(); 471 | columnHeader1.Width = 80; 472 | columnHeader2.Width = 76; 473 | } 474 | 475 | #endregion 476 | 477 | private void entitiesToolStripMenuItem_Click(object sender, EventArgs e) 478 | { 479 | ScriptFile.hashbank.Export_Entities(); 480 | } 481 | 482 | private void nativesToolStripMenuItem_Click(object sender, EventArgs e) 483 | { 484 | string path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 485 | "natives_exp.dat"); 486 | FileStream fs = File.Create(path); 487 | new MemoryStream(Properties.Resources.natives).CopyTo(fs); 488 | fs.Close(); 489 | System.Diagnostics.Process.Start( 490 | Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)), "natives_exp.dat"); 491 | } 492 | 493 | private void closeToolStripMenuItem_Click(object sender, EventArgs e) 494 | { 495 | this.Close(); 496 | } 497 | 498 | private void expandAllBlocksToolStripMenuItem_Click(object sender, EventArgs e) 499 | { 500 | updatestatus("Expanding all blocks..."); 501 | fctb1.ExpandAllFoldingBlocks(); 502 | ready(); 503 | } 504 | 505 | private void collaspeAllBlocksToolStripMenuItem_Click(object sender, EventArgs e) 506 | { 507 | updatestatus("Collasping all blocks..."); 508 | fctb1.CollapseAllFoldingBlocks(); 509 | ready(); 510 | } 511 | 512 | private void fctb1_MouseClick(object sender, MouseEventArgs e) 513 | { 514 | opening = false; 515 | forceclose = true; 516 | timer2.Start(); 517 | timer1.Stop(); 518 | if (e.Button == System.Windows.Forms.MouseButtons.Right) 519 | { 520 | if (fctb1.SelectionLength == 0) 521 | { 522 | fctb1.SelectionStart = fctb1.PointToPosition(fctb1.PointToClient(Cursor.Position)); 523 | } 524 | cmsText.Show(); 525 | } 526 | } 527 | 528 | public string getfunctionfromline(int line) 529 | { 530 | if (listView1.Items.Count == 0) 531 | return ""; 532 | 533 | int temp; 534 | if (int.TryParse(listView1.Items[0].SubItems[1].Text, out temp)) 535 | { 536 | if (line < temp - 1) 537 | return "Local Vars"; 538 | } 539 | else return ""; 540 | int max = listView1.Items.Count - 1; 541 | for (int i = 0; i < max; i++) 542 | { 543 | if (!int.TryParse(listView1.Items[i].SubItems[1].Text, out temp)) 544 | continue; 545 | if (line >= temp) 546 | { 547 | if (!int.TryParse(listView1.Items[i + 1].SubItems[1].Text, out temp)) 548 | continue; 549 | if (line < temp - 1) 550 | { 551 | return listView1.Items[i].SubItems[0].Text; 552 | } 553 | } 554 | } 555 | if (int.TryParse(listView1.Items[max].SubItems[1].Text, out temp)) 556 | { 557 | if (line >= temp) 558 | return listView1.Items[max].SubItems[0].Text; 559 | } 560 | return ""; 561 | } 562 | 563 | private void fctb1_SelectionChanged(object sender, EventArgs e) 564 | { 565 | try 566 | { 567 | toolStripStatusLabel3.Text = getfunctionfromline(fctb1.Selection.Start.iLine + 1); 568 | fctb1.Range.ClearStyle(highlight); 569 | if (fctb1.SelectionLength > 0) 570 | { 571 | if (!fctb1.SelectedText.Contains('\n') && !fctb1.SelectedText.Contains('\n')) 572 | fctb1.Range.SetStyle(highlight, "\\b" + fctb1.Selection.Text + "\\b", RegexOptions.IgnoreCase); 573 | } 574 | getcontextitems(); 575 | } 576 | catch 577 | { 578 | } 579 | } 580 | 581 | public void fill_function_table() 582 | { 583 | try 584 | { 585 | loadingfile = true; 586 | Dictionary functionloc = new Dictionary(); 587 | for (int i = 0; i < fctb1.LinesCount; i++) 588 | { 589 | if (fctb1.Lines[i].Length == 0) 590 | continue; 591 | if (fctb1.Lines[i].Contains(' ')) 592 | { 593 | if (!fctb1.Lines[i].Contains('(')) 594 | continue; 595 | string type = fctb1.Lines[i].Remove(fctb1.Lines[i].IndexOf(' ')); 596 | switch (type.ToLower()) 597 | { 598 | case "void": 599 | case "var": 600 | case "float": 601 | case "bool": 602 | case "int": 603 | case "vector3": 604 | case "*string": 605 | string name = fctb1.Lines[i].Remove(fctb1.Lines[i].IndexOf('(')).Substring(fctb1.Lines[i].IndexOf(' ') + 1); 606 | functionloc.Add(name, i + 1); 607 | continue; 608 | default: 609 | if (type.ToLower().StartsWith("struct<")) 610 | goto case "var"; 611 | break; 612 | 613 | } 614 | } 615 | } 616 | listView1.Items.Clear(); 617 | foreach (KeyValuePair locations in functionloc) 618 | { 619 | listView1.Items.Add(new ListViewItem(new string[] {locations.Key, locations.Value.ToString()})); 620 | } 621 | loadingfile = false; 622 | } 623 | catch 624 | { 625 | loadingfile = false; 626 | } 627 | } 628 | 629 | private void timer3_Tick(object sender, EventArgs e) 630 | { 631 | timer3.Stop(); 632 | fill_function_table(); 633 | } 634 | 635 | private void fctb1_LineInserted(object sender, FastColoredTextBoxNS.LineInsertedEventArgs e) 636 | { 637 | if (!loadingfile) 638 | timer3.Start(); 639 | } 640 | 641 | private void fctb1_LineRemoved(object sender, FastColoredTextBoxNS.LineRemovedEventArgs e) 642 | { 643 | if (!loadingfile) 644 | timer3.Start(); 645 | } 646 | 647 | private void openCFileToolStripMenuItem_Click(object sender, EventArgs e) 648 | { 649 | OpenFileDialog ofd = new OpenFileDialog(); 650 | ofd.Filter = "C Source files *.c|*.c"; 651 | if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 652 | { 653 | loadingfile = true; 654 | filename = Path.GetFileNameWithoutExtension(ofd.FileName); 655 | fctb1.Clear(); 656 | listView1.Items.Clear(); 657 | updatestatus("Loading Text in Viewer..."); 658 | fctb1.OpenFile(ofd.FileName); 659 | updatestatus("Loading Functions..."); 660 | fill_function_table(); 661 | SetFileName(filename); 662 | ready(); 663 | ScriptOpen = false; 664 | } 665 | } 666 | 667 | private void SetFileName(string name) 668 | { 669 | if (name == null) 670 | this.Text = "GTA V High Level Decompiler"; 671 | if (name.Length == 0) 672 | this.Text = "GTA V High Level Decompiler"; 673 | else 674 | { 675 | if (name.Contains('.')) 676 | name = name.Remove(name.IndexOf('.')); 677 | this.Text = "GTA V High Level Decompiler - " + name; 678 | } 679 | } 680 | 681 | private void saveCFileToolStripMenuItem_Click(object sender, EventArgs e) 682 | { 683 | SaveFileDialog sfd = new SaveFileDialog(); 684 | sfd.Filter = "C Source files *.c|*.c"; 685 | sfd.FileName = filename + ".c"; 686 | if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 687 | { 688 | fctb1.SaveToFile(sfd.FileName, System.Text.Encoding.Default); 689 | MessageBox.Show("File Saved"); 690 | } 691 | } 692 | 693 | private void cmsText_Opening(object sender, CancelEventArgs e) 694 | { 695 | getcontextitems(); 696 | if (cmsText.Items.Count == 0) e.Cancel = true; 697 | } 698 | 699 | bool islegalchar(char c) 700 | { 701 | if (char.IsLetterOrDigit(c)) return true; 702 | return c == '_'; 703 | 704 | } 705 | 706 | string getwordatcursor() 707 | { 708 | string line = fctb1.Lines[fctb1.Selection.Start.iLine]; 709 | if (line.Length == 0) 710 | return ""; 711 | int pos = fctb1.Selection.Start.iChar; 712 | if (pos == line.Length) 713 | return ""; 714 | int min = pos, max = pos; 715 | while (min > 0) 716 | { 717 | if (islegalchar(line[min - 1])) 718 | min--; 719 | else 720 | break; 721 | } 722 | int len = line.Length; 723 | while (max < len) 724 | { 725 | if (islegalchar(line[max])) 726 | max++; 727 | else 728 | break; 729 | } 730 | return line.Substring(min, max - min); 731 | } 732 | 733 | private void getcontextitems() 734 | { 735 | string word = getwordatcursor(); 736 | cmsText.Items.Clear(); 737 | foreach (ListViewItem lvi in listView1.Items) 738 | { 739 | if (lvi.Text == word) 740 | { 741 | cmsText.Items.Add(new ToolStripMenuItem("Goto Declaration(" + lvi.Text + ")", null, 742 | new EventHandler(delegate(object o, EventArgs a) 743 | { 744 | int num = Convert.ToInt32(lvi.SubItems[1].Text); 745 | fctb1.Selection = new FastColoredTextBoxNS.Range(fctb1, 0, num, 0, num); 746 | fctb1.DoSelectionVisible(); 747 | }), Keys.F12)); 748 | } 749 | } 750 | 751 | } 752 | 753 | private void fullNativeInfoToolStripMenuItem_Click(object sender, EventArgs e) 754 | { 755 | ScriptFile.npi.exportnativeinfo(); 756 | } 757 | 758 | private void fullPCNativeInfoToolStripMenuItem_Click(object sender, EventArgs e) 759 | { 760 | ScriptFile.X64npi.exportnativeinfo(); 761 | } 762 | 763 | 764 | private void stringsTableToolStripMenuItem_Click(object sender, EventArgs e) 765 | { 766 | if (ScriptOpen) 767 | { 768 | SaveFileDialog sfd = new SaveFileDialog(); 769 | sfd.Title = "Select location to save string table"; 770 | sfd.Filter = "Text files|*.txt|All Files|*.*"; 771 | sfd.FileName = ((filename.Contains('.')) ? filename.Remove(filename.IndexOf('.')) : filename) + "(Strings).txt"; 772 | if (sfd.ShowDialog() != System.Windows.Forms.DialogResult.OK) 773 | return; 774 | StreamWriter sw = File.CreateText(sfd.FileName); 775 | foreach (string line in fileopen.GetStringTable()) 776 | { 777 | sw.WriteLine(line); 778 | } 779 | sw.Close(); 780 | MessageBox.Show("File Saved"); 781 | } 782 | else 783 | { 784 | MessageBox.Show("No script file is open"); 785 | } 786 | 787 | } 788 | 789 | private void nativeTableToolStripMenuItem_Click(object sender, EventArgs e) 790 | { 791 | if (ScriptOpen) 792 | { 793 | SaveFileDialog sfd = new SaveFileDialog(); 794 | sfd.Title = "Select location to save native table"; 795 | sfd.Filter = "Text files|*.txt|All Files|*.*"; 796 | sfd.FileName = ((filename.Contains('.')) ? filename.Remove(filename.IndexOf('.')) : filename) + "(natives).txt"; 797 | if (sfd.ShowDialog() != System.Windows.Forms.DialogResult.OK) 798 | return; 799 | StreamWriter sw = File.CreateText(sfd.FileName); 800 | foreach (string line in fileopen.GetNativeTable()) 801 | { 802 | sw.WriteLine(line); 803 | } 804 | sw.Close(); 805 | MessageBox.Show("File Saved"); 806 | } 807 | else 808 | { 809 | MessageBox.Show("No script file is open"); 810 | } 811 | } 812 | 813 | /// 814 | /// Generates a c like header for all the natives. made it back when i was first trying to recompile the files back to *.*sc 815 | /// 816 | /// 817 | /// 818 | private void nativehFileToolStripMenuItem_Click(object sender, EventArgs e) 819 | { 820 | if (ScriptOpen) 821 | { 822 | SaveFileDialog sfd = new SaveFileDialog(); 823 | sfd.Title = "Select location to save native table"; 824 | sfd.Filter = "C header files|*.h|All Files|*.*"; 825 | sfd.FileName = ((filename.Contains('.')) ? filename.Remove(filename.IndexOf('.')) : filename) + ".h"; 826 | if (sfd.ShowDialog() != System.Windows.Forms.DialogResult.OK) 827 | return; 828 | StreamWriter sw = File.CreateText(sfd.FileName); 829 | sw.WriteLine("/*************************************************************"); 830 | sw.WriteLine("******* Header file generated for " + filename + " *******"); 831 | sw.WriteLine("*************************************************************/\n"); 832 | sw.WriteLine( 833 | "#region Vectors\ntypedef struct Vector3{\n\tfloat x;\n\tfloat y;\n\tfloat z;\n} Vector3, *PVector3;\n\n"); 834 | sw.WriteLine("extern Vector3 VectorAdd(Vector3 v0, Vector3 v1);"); 835 | sw.WriteLine("extern Vector3 VectorSub(Vector3 v0, Vector3 v1);"); 836 | sw.WriteLine("extern Vector3 VectorMult(Vector3 v0, Vector3 v1);"); 837 | sw.WriteLine("extern Vector3 VectorDiv(Vector3 v0, Vector3 v1);"); 838 | sw.WriteLine("extern Vector3 VectorNeg(Vector3 v0);\n#endregion\n\n"); 839 | sw.WriteLine("#define TRUE 1\n#define FALSE 0\n#define true 1\n#define false 0\n"); 840 | sw.WriteLine("typedef unsigned int uint;"); 841 | sw.WriteLine("typedef uint bool;"); 842 | sw.WriteLine("typedef uint var;"); 843 | sw.WriteLine(""); 844 | foreach (string line in fileopen.GetNativeHeader()) 845 | { 846 | sw.WriteLine("extern " + line); 847 | } 848 | sw.Close(); 849 | MessageBox.Show("File Saved"); 850 | } 851 | else 852 | { 853 | MessageBox.Show("No script file is open"); 854 | } 855 | } 856 | 857 | private void navigateForwardToolStripMenuItem_Click(object sender, EventArgs e) 858 | { 859 | if (!fctb1.NavigateForward()) 860 | { 861 | MessageBox.Show("Error, cannont navigate forwards anymore"); 862 | } 863 | } 864 | 865 | private void navigateBackwardsToolStripMenuItem_Click(object sender, EventArgs e) 866 | { 867 | if (!fctb1.NavigateBackward()) 868 | { 869 | MessageBox.Show("Error, cannont navigate backwards anymore"); 870 | } 871 | } 872 | 873 | 874 | /// 875 | /// The games language files store items as hashes. This function will grab all strings in a all scripts in a directory 876 | /// and hash each string and them compare with a list of hashes supplied in the input box. Any matches get saved to a file STRINGS.txt in the directory 877 | /// 878 | /// 879 | /// 880 | private void findHashFromStringsToolStripMenuItem_Click(object sender, EventArgs e) 881 | { 882 | InputBox IB = new InputBox(); 883 | if (!IB.ShowList("Input Hash", "Input hash to find", this)) 884 | return; 885 | uint hash; 886 | List Hashes = new List(); 887 | foreach (string result in IB.ListValue) 888 | { 889 | 890 | if (result.StartsWith("0x")) 891 | { 892 | if (uint.TryParse(result.Substring(2), System.Globalization.NumberStyles.HexNumber, 893 | new System.Globalization.CultureInfo("en-gb"), out hash)) 894 | { 895 | Hashes.Add(hash); 896 | } 897 | else 898 | { 899 | MessageBox.Show($"Error converting {result} to hash value"); 900 | } 901 | } 902 | else 903 | { 904 | if (uint.TryParse(result, out hash)) 905 | { 906 | Hashes.Add(hash); 907 | } 908 | else 909 | { 910 | MessageBox.Show($"Error converting {result} to hash value"); 911 | } 912 | } 913 | } 914 | if (Hashes.Count == 0) 915 | { 916 | MessageBox.Show($"Error, no hashes inputted, please try again"); 917 | return; 918 | } 919 | HashToFind = Hashes.ToArray(); 920 | CompileList = new Queue>(); 921 | FoundStrings = new List>(); 922 | Program.ThreadCount = 0; 923 | FolderSelectDialog fsd = new FolderSelectDialog(); 924 | if (fsd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 925 | { 926 | DateTime Start = DateTime.Now; 927 | this.Hide(); 928 | 929 | foreach (string file in Directory.GetFiles(fsd.SelectedPath, "*.xsc")) 930 | { 931 | CompileList.Enqueue(new Tuple(file, true)); 932 | } 933 | foreach (string file in Directory.GetFiles(fsd.SelectedPath, "*.csc")) 934 | { 935 | CompileList.Enqueue(new Tuple(file, true)); 936 | } 937 | foreach (string file in Directory.GetFiles(fsd.SelectedPath, "*.ysc")) 938 | { 939 | CompileList.Enqueue(new Tuple(file, false)); 940 | } 941 | foreach (string file in Directory.GetFiles(fsd.SelectedPath, "*.ysc.full")) 942 | { 943 | CompileList.Enqueue(new Tuple(file, false)); 944 | } 945 | if (Program.Use_MultiThreading) 946 | { 947 | for (int i = 0; i < Environment.ProcessorCount - 1; i++) 948 | { 949 | Program.ThreadCount++; 950 | new System.Threading.Thread(FindString).Start(); 951 | System.Threading.Thread.Sleep(0); 952 | } 953 | Program.ThreadCount++; 954 | FindString(); 955 | while (Program.ThreadCount > 0) 956 | { 957 | System.Threading.Thread.Sleep(10); 958 | } 959 | } 960 | else 961 | { 962 | Program.ThreadCount++; 963 | FindString(); 964 | } 965 | 966 | if (FoundStrings.Count == 0) 967 | updatestatus($"No Strings Found, Time taken: {DateTime.Now - Start}"); 968 | else 969 | { 970 | updatestatus($"Found {FoundStrings.Count} strings, Time taken: {DateTime.Now - Start}"); 971 | FoundStrings.Sort((x, y) => x.Item1.CompareTo(y.Item1)); 972 | using (StreamWriter oFile = File.CreateText(Path.Combine(fsd.SelectedPath, "STRINGS.txt"))) 973 | { 974 | foreach (Tuple Item in FoundStrings) 975 | { 976 | oFile.WriteLine($"0x{Utils.FormatHexHash(Item.Item1)} : \"{Item.Item2}\""); 977 | } 978 | } 979 | } 980 | } 981 | this.Show(); 982 | } 983 | 984 | /// 985 | /// This does the actual searching of the hashes from the above function. Designed to run on multiple threads 986 | /// 987 | private void FindString() 988 | { 989 | while (CompileList.Count > 0) 990 | { 991 | Tuple scriptToSearch; 992 | lock (Program.ThreadLock) 993 | { 994 | scriptToSearch = CompileList.Dequeue(); 995 | } 996 | using (Stream ScriptFile = File.OpenRead(scriptToSearch.Item1)) 997 | { 998 | ScriptHeader header = ScriptHeader.Generate(ScriptFile, scriptToSearch.Item2); 999 | StringTable table = new StringTable(ScriptFile, header.StringTableOffsets, header.StringBlocks, header.StringsSize); 1000 | foreach (string str in table.Values) 1001 | { 1002 | if (HashToFind.Contains(Utils.jenkins_one_at_a_time_hash(str))) 1003 | { 1004 | if (IsLower(str)) 1005 | continue; 1006 | lock (Program.ThreadLock) 1007 | { 1008 | if (!FoundStrings.Any(item => item.Item2 == str)) 1009 | { 1010 | FoundStrings.Add(new Tuple(Utils.jenkins_one_at_a_time_hash(str), str)); 1011 | } 1012 | } 1013 | } 1014 | } 1015 | } 1016 | } 1017 | Program.ThreadCount--; 1018 | } 1019 | 1020 | private static bool IsLower(string s) 1021 | { 1022 | foreach (char c in s) 1023 | if (char.IsLower(c)) 1024 | { 1025 | return true; 1026 | } 1027 | return false; 1028 | } 1029 | } 1030 | } 1031 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Native Param Info.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Windows.Forms; 5 | 6 | namespace Decompiler 7 | { 8 | class NativeParamInfo 9 | { 10 | Dictionary> Natives; 11 | 12 | public NativeParamInfo() 13 | { 14 | loadfile(); 15 | } 16 | 17 | public void savefile() 18 | { 19 | Stream natfile = 20 | File.Create(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 21 | "nativeinfo.dat")); 22 | IO.Writer writer = new IO.Writer(natfile); 23 | foreach (KeyValuePair> native in Natives) 24 | { 25 | writer.Write(native.Key); 26 | writer.Write(Types.indexof(native.Value.Item1)); 27 | writer.Write((byte) native.Value.Item2.Length); 28 | for (int i = 0; i < native.Value.Item2.Length; i++) 29 | { 30 | writer.Write(Types.indexof(native.Value.Item2[i])); 31 | } 32 | } 33 | writer.Close(); 34 | } 35 | 36 | 37 | public void updatenative(uint hash, Stack.DataType returns, params Stack.DataType[] param) 38 | { 39 | lock (Program.ThreadLock) 40 | { 41 | if (!Natives.ContainsKey(hash)) 42 | { 43 | Natives.Add(hash, new Tuple(returns, param)); 44 | return; 45 | } 46 | } 47 | 48 | Stack.DataType curret = Natives[hash].Item1; 49 | Stack.DataType[] curpar = Natives[hash].Item2; 50 | 51 | if (Types.gettype(curret).precedence < Types.gettype(returns).precedence) 52 | { 53 | curret = returns; 54 | } 55 | for (int i = 0; i < curpar.Length; i++) 56 | { 57 | if (Types.gettype(curpar[i]).precedence < Types.gettype(param[i]).precedence) 58 | { 59 | curpar[i] = param[i]; 60 | } 61 | } 62 | Natives[hash] = new Tuple(curret, curpar); 63 | } 64 | 65 | public bool updateparam(uint hash, Stack.DataType type, int paramindex) 66 | { 67 | if (!Natives.ContainsKey(hash)) 68 | return false; 69 | Stack.DataType[] paramslist = Natives[hash].Item2; 70 | paramslist[paramindex] = type; 71 | Natives[hash] = new Tuple(Natives[hash].Item1, paramslist); 72 | return true; 73 | } 74 | 75 | public Stack.DataType getrettype(uint hash) 76 | { 77 | if (!Natives.ContainsKey(hash)) 78 | return Stack.DataType.Unk; 79 | return Natives[hash].Item1; 80 | } 81 | 82 | public Stack.DataType getparamtype(uint hash, int index) 83 | { 84 | if (!Natives.ContainsKey(hash)) 85 | return Stack.DataType.Unk; 86 | return Natives[hash].Item2[index]; 87 | } 88 | 89 | public void updaterettype(uint hash, Stack.DataType returns, bool over = false) 90 | { 91 | if (!Natives.ContainsKey(hash)) 92 | return; 93 | if (Types.gettype(Natives[hash].Item1).precedence < Types.gettype(returns).precedence || over) 94 | { 95 | Natives[hash] = new Tuple(returns, Natives[hash].Item2); 96 | } 97 | } 98 | 99 | public void loadfile() 100 | { 101 | Natives = new Dictionary>(); 102 | string file = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 103 | "nativeinfo.dat"); 104 | if (!File.Exists(file)) 105 | return; 106 | Stream natfile = File.OpenRead(file); 107 | IO.Reader reader = new IO.Reader(natfile, true); 108 | while (natfile.Position < natfile.Length) 109 | { 110 | uint native = reader.ReadUInt32(); 111 | Stack.DataType returntype = Types.getatindex(reader.ReadByte()); 112 | byte count = reader.ReadByte(); 113 | Stack.DataType[] param = new Stack.DataType[count]; 114 | for (byte i = 0; i < count; i++) 115 | { 116 | param[i] = Types.getatindex(reader.ReadByte()); 117 | } 118 | Natives.Add(native, new Tuple(returntype, param)); 119 | } 120 | 121 | } 122 | 123 | public string getnativeinfo(uint hash) 124 | { 125 | if (!Natives.ContainsKey(hash)) 126 | { 127 | throw new Exception("Native not found"); 128 | } 129 | string dec = Types.gettype(Natives[hash].Item1).returntype + Program.nativefile.nativefromhash(hash) + "("; 130 | int max = Natives[hash].Item2.Length; 131 | if (max == 0) 132 | return dec + ");"; 133 | for (int i = 0; i < max; i++) 134 | { 135 | dec += Types.gettype(Natives[hash].Item2[i]).vardec + i + ", "; 136 | } 137 | return dec.Remove(dec.Length - 2) + ");"; 138 | } 139 | 140 | public void exportnativeinfo() 141 | { 142 | Stream natfile = 143 | File.Create(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 144 | "natives.h")); 145 | StreamWriter sw = new StreamWriter(natfile); 146 | sw.WriteLine("/*************************************************************"); 147 | sw.WriteLine("****************** GTA V Native Header file ******************"); 148 | sw.WriteLine("*************************************************************/\n"); 149 | sw.WriteLine("#ifndef NATIVE_HEADER\n#define NATIVE_HEADER"); 150 | sw.WriteLine("typedef unsigned int uint;"); 151 | sw.WriteLine("typedef uint bool;"); 152 | sw.WriteLine("typedef uint var;"); 153 | sw.WriteLine(""); 154 | List> natives = new List>(); 155 | 156 | foreach (KeyValuePair> native in Natives) 157 | { 158 | string type = Types.gettype(native.Value.Item1).returntype; 159 | string line = Program.nativefile.nativefromhash(native.Key) + "("; 160 | 161 | int max = native.Value.Item2.Length; 162 | if (max == 0) 163 | { 164 | natives.Add(new Tuple(line + ");\n", type)); 165 | continue; 166 | } 167 | for (int i = 0; i < max; i++) 168 | { 169 | line += Types.gettype(native.Value.Item2[i]).vardec + i + ", "; 170 | } 171 | natives.Add(new Tuple(line.Remove(line.Length - 2) + ");\n", type)); 172 | } 173 | natives.Sort(); 174 | foreach (Tuple native in natives) 175 | { 176 | sw.Write("extern " + native.Item2 + native.Item1); 177 | } 178 | sw.WriteLine("#endif"); 179 | sw.Close(); 180 | } 181 | 182 | public string TypeToString(Stack.DataType type) 183 | { 184 | return Types.gettype(type).singlename; 185 | } 186 | 187 | public Stack.DataType StringToType(string _string) 188 | { 189 | foreach (Types.DataTypes type in Types._types) 190 | { 191 | if (type.singlename == _string) 192 | return type.type; 193 | } 194 | throw new Exception("Type not found"); 195 | } 196 | 197 | public bool StringTypeExists(string _string) 198 | { 199 | foreach (Types.DataTypes type in Types._types) 200 | { 201 | if (type.singlename == _string) 202 | return true; 203 | } 204 | return false; 205 | } 206 | 207 | } 208 | 209 | class x64BitNativeParamInfo 210 | { 211 | Dictionary> Natives; 212 | 213 | public x64BitNativeParamInfo() 214 | { 215 | loadfile(); 216 | } 217 | 218 | public void savefile() 219 | { 220 | try 221 | { 222 | string loc = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); 223 | Stream natfile = File.Create(Path.Combine(loc, "x64nativeinfonew.dat")); 224 | IO.Writer writer = new IO.Writer(natfile); 225 | foreach (KeyValuePair> native in Natives) 226 | { 227 | writer.Write(native.Key); 228 | writer.Write(Types.indexof(native.Value.Item1)); 229 | writer.Write((byte) native.Value.Item2.Length); 230 | for (int i = 0; i < native.Value.Item2.Length; i++) 231 | { 232 | writer.Write(Types.indexof(native.Value.Item2[i])); 233 | } 234 | } 235 | writer.Close(); 236 | if (File.Exists(Path.Combine(loc, "x64nativeinfo.dat"))) 237 | { 238 | File.Delete("x64nativeinfo.dat"); 239 | } 240 | File.Move(Path.Combine(loc, "x64nativeinfonew.dat"), Path.Combine(loc, "x64nativeinfo.dat")); 241 | } 242 | catch (Exception Exception) 243 | { 244 | MessageBox.Show(Exception.Message); 245 | } 246 | } 247 | 248 | 249 | public void updatenative(ulong hash, Stack.DataType returns, params Stack.DataType[] param) 250 | { 251 | lock (Program.ThreadLock) 252 | { 253 | if (!Natives.ContainsKey(hash)) 254 | { 255 | Natives.Add(hash, new Tuple(returns, param)); 256 | return; 257 | } 258 | } 259 | 260 | Stack.DataType curret = Natives[hash].Item1; 261 | Stack.DataType[] curpar = Natives[hash].Item2; 262 | if (param.Length != curpar.Length) 263 | { 264 | Stack.DataType[] Old = curpar; 265 | curpar = param; 266 | if (Old.Length < curpar.Length) 267 | { 268 | for (int i = 0; i < Old.Length; i++) 269 | { 270 | curpar[i] = Old[i]; 271 | } 272 | } 273 | } 274 | 275 | if (Types.gettype(curret).precedence < Types.gettype(returns).precedence) 276 | { 277 | curret = returns; 278 | } 279 | for (int i = 0; i < curpar.Length; i++) 280 | { 281 | if (Types.gettype(curpar[i]).precedence < Types.gettype(param[i]).precedence) 282 | { 283 | curpar[i] = param[i]; 284 | } 285 | } 286 | Natives[hash] = new Tuple(curret, curpar); 287 | } 288 | 289 | public void updateparam(ulong hash, Stack.DataType type, int paramindex) 290 | { 291 | if (!Natives.ContainsKey(hash)) 292 | return; 293 | Stack.DataType[] paramslist = Natives[hash].Item2; 294 | if (paramindex >= paramslist.Length) 295 | { 296 | Stack.DataType[] Old = paramslist; 297 | paramslist = new Stack.DataType[paramindex + 1]; 298 | for (int i = 0; i < Old.Length; i++) 299 | { 300 | paramslist[i] = Old[i]; 301 | } 302 | } 303 | paramslist[paramindex] = type; 304 | Natives[hash] = new Tuple(Natives[hash].Item1, paramslist); 305 | } 306 | 307 | public Stack.DataType getrettype(ulong hash) 308 | { 309 | if (!Natives.ContainsKey(hash)) 310 | return Stack.DataType.Unk; 311 | return Natives[hash].Item1; 312 | } 313 | 314 | public Stack.DataType getparamtype(ulong hash, int index) 315 | { 316 | if (!Natives.ContainsKey(hash)) 317 | return Stack.DataType.Unk; 318 | if (Natives[hash].Item2.Length <= index) 319 | return Stack.DataType.Unk; 320 | return Natives[hash].Item2[index]; 321 | } 322 | 323 | public void updaterettype(ulong hash, Stack.DataType returns, bool over = false) 324 | { 325 | if (!Natives.ContainsKey(hash)) 326 | return; 327 | if (Types.gettype(Natives[hash].Item1).precedence < Types.gettype(returns).precedence || over) 328 | { 329 | Natives[hash] = new Tuple(returns, Natives[hash].Item2); 330 | } 331 | } 332 | 333 | public void loadfile() 334 | { 335 | Natives = new Dictionary>(); 336 | string file = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 337 | "x64nativeinfo.dat"); 338 | if (!File.Exists(file)) 339 | return; 340 | Stream natfile = File.OpenRead(file); 341 | IO.Reader reader = new IO.Reader(natfile, false); 342 | while (natfile.Position < natfile.Length) 343 | { 344 | ulong native = reader.ReadUInt64(); 345 | Stack.DataType returntype = Types.getatindex(reader.ReadByte()); 346 | byte count = reader.ReadByte(); 347 | Stack.DataType[] param = new Stack.DataType[count]; 348 | for (byte i = 0; i < count; i++) 349 | { 350 | param[i] = Types.getatindex(reader.ReadByte()); 351 | } 352 | Natives.Add(native, new Tuple(returntype, param)); 353 | } 354 | 355 | } 356 | 357 | public string getnativeinfo(ulong hash) 358 | { 359 | if (!Natives.ContainsKey(hash)) 360 | { 361 | throw new Exception("Native not found"); 362 | } 363 | string dec = Types.gettype(Natives[hash].Item1).returntype + Program.x64nativefile.nativefromhash(hash) + "("; 364 | int max = Natives[hash].Item2.Length; 365 | if (max == 0) 366 | return dec + ");"; 367 | for (int i = 0; i < max; i++) 368 | { 369 | dec += Types.gettype(Natives[hash].Item2[i]).vardec + i + ", "; 370 | } 371 | return dec.Remove(dec.Length - 2) + ");"; 372 | } 373 | 374 | public void exportnativeinfo() 375 | { 376 | Stream natfile = 377 | File.Create(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 378 | "natives.h")); 379 | StreamWriter sw = new StreamWriter(natfile); 380 | sw.WriteLine("/*************************************************************"); 381 | sw.WriteLine("****************** GTA V Native Header file ******************"); 382 | sw.WriteLine("*************************************************************/\n"); 383 | sw.WriteLine("#define TRUE 1\n#define FALSE 0\n#define true 1\n#define false 0\n"); 384 | sw.WriteLine("typedef unsigned int uint;"); 385 | sw.WriteLine("typedef uint bool;"); 386 | sw.WriteLine("typedef uint var;"); 387 | sw.WriteLine(""); 388 | List> natives = new List>(); 389 | 390 | foreach (KeyValuePair> native in Natives) 391 | { 392 | string type = Types.gettype(native.Value.Item1).returntype; 393 | string line = Program.x64nativefile.nativefromhash(native.Key) + "("; 394 | 395 | int max = native.Value.Item2.Length; 396 | if (max == 0) 397 | { 398 | natives.Add(new Tuple(line + ");\n", type)); 399 | continue; 400 | } 401 | for (int i = 0; i < max; i++) 402 | { 403 | line += Types.gettype(native.Value.Item2[i]).vardec + i + ", "; 404 | } 405 | natives.Add(new Tuple(line.Remove(line.Length - 2) + ");\n", type)); 406 | } 407 | natives.Sort(); 408 | foreach (Tuple native in natives) 409 | { 410 | sw.Write("extern " + native.Item2 + native.Item1); 411 | } 412 | sw.Close(); 413 | } 414 | 415 | public string TypeToString(Stack.DataType type) 416 | { 417 | return Types.gettype(type).singlename; 418 | } 419 | 420 | public Stack.DataType StringToType(string _string) 421 | { 422 | foreach (Types.DataTypes type in Types._types) 423 | { 424 | if (type.singlename == _string) 425 | return type.type; 426 | } 427 | throw new Exception("Type not found"); 428 | } 429 | 430 | public bool StringTypeExists(string _string) 431 | { 432 | foreach (Types.DataTypes type in Types._types) 433 | { 434 | if (type.singlename == _string) 435 | return true; 436 | } 437 | return false; 438 | } 439 | 440 | } 441 | } 442 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/NativeFiles.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.IO; 5 | using System.IO.Compression; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Decompiler 11 | { 12 | class NativeFile : Dictionary 13 | { 14 | public string nativefromhash(uint hash) 15 | { 16 | if (Program.nativefile.ContainsKey(hash)) 17 | { 18 | return this[hash]; 19 | } 20 | else 21 | { 22 | string temps = hash.ToString("X"); 23 | while (temps.Length < 8) 24 | temps = "0" + temps; 25 | return "unk_0x" + temps; 26 | } 27 | } 28 | public Dictionary revmap = new Dictionary(); 29 | public NativeFile(Stream Nativefile) : base() 30 | { 31 | StreamReader sr = new StreamReader(Nativefile); 32 | while (!sr.EndOfStream) 33 | { 34 | string line = sr.ReadLine(); 35 | if (line.Length > 1) 36 | { 37 | string[] data = line.Split(':'); 38 | if (data.Length != 3) 39 | continue; 40 | string val = data[0]; 41 | if(val.StartsWith("0x")) 42 | { 43 | val = val.Substring(2); 44 | } 45 | uint value; 46 | if (uint.TryParse(val, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out value)) 47 | { 48 | if (!ContainsKey(value)) 49 | { 50 | string nat = (Program.Show_Nat_Namespace ? (data[1] + "::") : ""); 51 | if(Program.Upper_Natives) 52 | { 53 | nat = nat.ToUpper(); 54 | if(data[2].StartsWith("_0x")) 55 | { 56 | nat += data[2].Remove(3) + data[2].Substring(3).ToUpper(); 57 | } 58 | else 59 | { 60 | nat += data[2].ToUpper(); 61 | } 62 | } 63 | else 64 | { 65 | nat = nat.ToLower(); 66 | if(data[2].StartsWith("_0x")) 67 | { 68 | nat += data[2].Remove(3) + data[2].Substring(3).ToUpper(); 69 | } 70 | else 71 | { 72 | nat += data[2].ToLower(); 73 | } 74 | } 75 | Add(value, nat); 76 | revmap.Add(nat, value); 77 | } 78 | } 79 | } 80 | } 81 | sr.Close(); 82 | } 83 | } 84 | class x64NativeFile : Dictionary 85 | { 86 | public ulong TranslateHash(ulong hash) 87 | { 88 | while (TranslationTable.ContainsKey(hash)) 89 | { 90 | hash = TranslationTable[hash]; 91 | } 92 | return hash; 93 | } 94 | public string nativefromhash(ulong hash) 95 | { 96 | if (Program.x64nativefile.ContainsKey(hash)) 97 | { 98 | return this[hash]; 99 | } 100 | else 101 | { 102 | string temps = hash.ToString("X"); 103 | while (temps.Length < 8) 104 | temps = "0" + temps; 105 | return "unk_0x" + temps; 106 | } 107 | } 108 | public Dictionary revmap = new Dictionary(); 109 | public Dictionary TranslationTable = new Dictionary(); 110 | public x64NativeFile(Stream Nativefile) 111 | : base() 112 | { 113 | StreamReader sr = new StreamReader(Nativefile); 114 | while (!sr.EndOfStream) 115 | { 116 | string line = sr.ReadLine(); 117 | if (line.Length > 1) 118 | { 119 | string[] data = line.Split(':'); 120 | if (data.Length != 3) 121 | continue; 122 | string val = data[0]; 123 | if(val.StartsWith("0x")) 124 | { 125 | val = val.Substring(2); 126 | } 127 | ulong value; 128 | if (ulong.TryParse(val, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out value)) 129 | { 130 | string nat = (Program.Show_Nat_Namespace ? (data[1] + "::") : ""); 131 | if(Program.Upper_Natives) 132 | { 133 | nat = nat.ToUpper(); 134 | if(data[2].StartsWith("_0x")) 135 | { 136 | nat += data[2].Remove(3) + data[2].Substring(3).ToUpper(); 137 | } 138 | else 139 | { 140 | nat += data[2].ToUpper(); 141 | } 142 | } 143 | else 144 | { 145 | nat = nat.ToLower(); 146 | if(data[2].StartsWith("_0x")) 147 | { 148 | nat += data[2].Remove(3) + data[2].Substring(3).ToUpper(); 149 | } 150 | else 151 | { 152 | nat += data[2].ToLower(); 153 | } 154 | } 155 | if (!ContainsKey(value)) 156 | { 157 | Add(value, nat); 158 | revmap.Add(nat, value); 159 | } 160 | } 161 | } 162 | } 163 | sr.Close(); 164 | Stream Decompressed = new MemoryStream(); 165 | Stream Compressed = new MemoryStream(Properties.Resources.native_translation); 166 | DeflateStream deflate = new DeflateStream(Compressed, CompressionMode.Decompress); 167 | deflate.CopyTo(Decompressed); 168 | deflate.Dispose(); 169 | Decompressed.Position = 0; 170 | sr = new StreamReader(Decompressed); 171 | while (!sr.EndOfStream) 172 | { 173 | string line = sr.ReadLine(); 174 | if (line.Length > 1) 175 | { 176 | string val = line.Remove(line.IndexOfAny(new char[] { ':', '=' })); 177 | string nat = line.Substring(val.Length + 1); 178 | ulong newer; 179 | ulong older; 180 | if (ulong.TryParse(val, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out newer)) 181 | { 182 | if (!ContainsKey(newer)) 183 | { 184 | if (ulong.TryParse(nat, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out older)) 185 | { 186 | if (!TranslationTable.ContainsKey(newer)) 187 | { 188 | TranslationTable.Add(newer, older); 189 | } 190 | } 191 | } 192 | } 193 | } 194 | } 195 | sr.Close(); 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/NativeTables.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace Decompiler 6 | { 7 | //These classes are generated from a script and are used to translate the index a native is called with to its hash/reversed name 8 | //X64 corresponds to the PC version of the gane. Would likely include PS4/X1 version but no work has been done with those systems 9 | public class NativeTable 10 | { 11 | List _natives; 12 | List _nativehash; 13 | public NativeTable(Stream scriptFile, int position, int length) 14 | { 15 | IO.Reader reader = new IO.Reader(scriptFile, true); 16 | int count = 0; 17 | uint nat; 18 | reader.BaseStream.Position = position; 19 | _natives = new List(); 20 | _nativehash = new List(); 21 | while (count < length) 22 | { 23 | nat = reader.SReadUInt32(); 24 | _nativehash.Add(nat); 25 | if (Program.nativefile.ContainsKey(nat)) 26 | { 27 | _natives.Add(Program.nativefile[nat]); 28 | } 29 | else 30 | { 31 | string temps = nat.ToString("X"); 32 | while (temps.Length < 8) 33 | temps = "0" + temps; 34 | _natives.Add("unk_0x" + temps); 35 | } 36 | count++; 37 | } 38 | 39 | } 40 | public string[] GetNativeTable() 41 | { 42 | List table = new List(); 43 | int i = 0; 44 | foreach (string native in _natives) 45 | { 46 | table.Add(i++.ToString("X2") + ": " + native); 47 | } 48 | return table.ToArray(); 49 | } 50 | public string[] GetNativeHeader() 51 | { 52 | List NativesHeader = new List(); 53 | foreach (uint hash in _nativehash) 54 | { 55 | NativesHeader.Add(ScriptFile.npi.getnativeinfo(hash)); 56 | } 57 | 58 | return NativesHeader.ToArray(); 59 | } 60 | public string GetNativeFromIndex(int index) 61 | { 62 | if (index < 0) 63 | throw new ArgumentOutOfRangeException("Index must be a positive integer"); 64 | if (index >= _natives.Count) 65 | throw new ArgumentOutOfRangeException("Index is greater than native table size"); 66 | return _natives[index]; 67 | } 68 | public uint GetNativeHashFromIndex(int index) 69 | { 70 | if (index < 0) 71 | throw new ArgumentOutOfRangeException("Index must be a positive integer"); 72 | if (index >= _nativehash.Count) 73 | throw new ArgumentOutOfRangeException("Index is greater than native table size"); 74 | return _nativehash[index]; 75 | } 76 | public void dispose() 77 | { 78 | _natives.Clear(); 79 | } 80 | } 81 | public class X64NativeTable 82 | { 83 | List _natives; 84 | List _nativehash; 85 | public X64NativeTable(Stream scriptFile, int position, int length, int codeSize) 86 | { 87 | IO.Reader reader = new IO.Reader(scriptFile, false); 88 | int count = 0; 89 | ulong nat; 90 | reader.BaseStream.Position = position; 91 | _natives = new List(); 92 | _nativehash = new List(); 93 | while (count < length) 94 | { 95 | //GTA V PC natives arent stored sequentially in the table. Each native needs a bitwise rotate depending on its position and codetable size 96 | //Then the natives needs to go back through translation tables to get to their hash as defined in the vanilla game version 97 | //or the earliest game version that native was introduced in. 98 | //Just some of the steps Rockstar take to make reverse engineering harder 99 | nat = Program.x64nativefile.TranslateHash(rotl(reader.ReadUInt64(), codeSize + count)); 100 | _nativehash.Add(nat); 101 | if (Program.x64nativefile.ContainsKey(nat)) 102 | { 103 | _natives.Add(Program.x64nativefile[nat]); 104 | } 105 | else 106 | { 107 | string temps = nat.ToString("X"); 108 | while (temps.Length < 16) 109 | temps = "0" + temps; 110 | _natives.Add("unk_0x" + temps); 111 | } 112 | count++; 113 | } 114 | 115 | } 116 | public string[] GetNativeTable() 117 | { 118 | List table = new List(); 119 | int i = 0; 120 | foreach (string native in _natives) 121 | { 122 | table.Add(i++.ToString("X2") + ": " + native); 123 | } 124 | return table.ToArray(); 125 | } 126 | public string[] GetNativeHeader() 127 | { 128 | List NativesHeader = new List(); 129 | foreach (ulong hash in _nativehash) 130 | { 131 | NativesHeader.Add(ScriptFile.X64npi.getnativeinfo(hash)); 132 | } 133 | 134 | return NativesHeader.ToArray(); 135 | } 136 | public string GetNativeFromIndex(int index) 137 | { 138 | if (index < 0) 139 | throw new ArgumentOutOfRangeException("Index must be a positive integer"); 140 | if (index >= _natives.Count) 141 | throw new ArgumentOutOfRangeException("Index is greater than native table size"); 142 | return _natives[index]; 143 | } 144 | 145 | private ulong rotl(ulong hash, int rotate) 146 | { 147 | rotate %= 64; 148 | return hash << rotate | hash >> (64 - rotate); 149 | } 150 | public ulong GetNativeHashFromIndex(int index) 151 | { 152 | if (index < 0) 153 | throw new ArgumentOutOfRangeException("Index must be a positive integer"); 154 | if (index >= _nativehash.Count) 155 | throw new ArgumentOutOfRangeException("Index is greater than native table size"); 156 | return _nativehash[index]; 157 | } 158 | public void dispose() 159 | { 160 | _natives.Clear(); 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Windows.Forms; 4 | 5 | namespace Decompiler 6 | { 7 | static class Program 8 | { 9 | public static NativeFile nativefile; 10 | public static x64NativeFile x64nativefile; 11 | internal static Ini.IniFile Config; 12 | public static Object ThreadLock; 13 | public static int ThreadCount; 14 | 15 | /// 16 | /// The main entry point for the application. 17 | /// 18 | [STAThread] 19 | static void Main() 20 | { 21 | ThreadLock = new object(); 22 | Config = new Ini.IniFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini")); 23 | Find_Nat_Namespace(); 24 | Find_Upper_Natives(); 25 | //Build NativeFiles from Directory if file exists, if not use the files in the resources 26 | string path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 27 | "natives.dat"); 28 | if (File.Exists(path)) 29 | nativefile = new NativeFile(File.OpenRead(path)); 30 | else 31 | nativefile = new NativeFile(new MemoryStream(Properties.Resources.natives)); 32 | 33 | 34 | path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), 35 | "x64natives.dat"); 36 | if (File.Exists(path)) 37 | x64nativefile = new x64NativeFile(File.OpenRead(path)); 38 | else 39 | x64nativefile = new x64NativeFile(new MemoryStream(Properties.Resources.x64natives)); 40 | 41 | Application.EnableVisualStyles(); 42 | Application.SetCompatibleTextRenderingDefault(false); 43 | Application.Run(new MainForm()); 44 | } 45 | 46 | public enum IntType 47 | { 48 | _int, 49 | _uint, 50 | _hex 51 | } 52 | 53 | public static IntType Find_getINTType() 54 | { 55 | string s = Program.Config.IniReadValue("Base", "IntStyle").ToLower(); 56 | if (s.StartsWith("int")) return _getINTType = IntType._int; 57 | else if (s.StartsWith("uint")) return _getINTType = IntType._uint; 58 | else if (s.StartsWith("hex")) return _getINTType = IntType._hex; 59 | else 60 | { 61 | Program.Config.IniWriteValue("Base", "IntStyle", "int"); 62 | return _getINTType = IntType._int; 63 | } 64 | } 65 | 66 | private static IntType _getINTType = IntType._int; 67 | 68 | public static IntType getIntType 69 | { 70 | get { return _getINTType; } 71 | } 72 | 73 | public static bool Find_Show_Array_Size() 74 | { 75 | return _Show_Array_Size = Program.Config.IniReadBool("Base", "Show_Array_Size", true); 76 | } 77 | 78 | private static bool _Show_Array_Size = false; 79 | 80 | public static bool Find_Reverse_Hashes() 81 | { 82 | return _Reverse_Hashes = Program.Config.IniReadBool("Base", "Reverse_Hashes", true); 83 | } 84 | 85 | private static bool _Reverse_Hashes = false; 86 | 87 | public static bool Reverse_Hashes 88 | { 89 | get { return _Reverse_Hashes; } 90 | } 91 | 92 | public static bool Show_Array_Size 93 | { 94 | get { return _Show_Array_Size; } 95 | } 96 | 97 | public static bool Find_Declare_Variables() 98 | { 99 | return _Declare_Variables = Program.Config.IniReadBool("Base", "Declare_Variables", true); 100 | } 101 | 102 | private static bool _Declare_Variables = false; 103 | 104 | public static bool Declare_Variables 105 | { 106 | get { return _Declare_Variables; } 107 | } 108 | 109 | public static bool Find_Shift_Variables() 110 | { 111 | return _Shift_Variables = Program.Config.IniReadBool("Base", "Shift_Variables", true); 112 | } 113 | 114 | private static bool _Shift_Variables = false; 115 | 116 | public static bool Shift_Variables 117 | { 118 | get { return _Shift_Variables; } 119 | } 120 | 121 | public static bool Find_Use_MultiThreading() 122 | { 123 | return _Use_MultiThreading = Program.Config.IniReadBool("Base", "Use_MultiThreading", false); 124 | } 125 | 126 | private static bool _Use_MultiThreading = false; 127 | 128 | public static bool Use_MultiThreading 129 | { 130 | get { return _Use_MultiThreading; } 131 | } 132 | 133 | 134 | public static bool Find_IncFuncPos() 135 | { 136 | return _IncFuncPos = Program.Config.IniReadBool("Base", "Include_Function_Position", false); 137 | } 138 | 139 | private static bool _IncFuncPos = false; 140 | 141 | public static bool IncFuncPos 142 | { 143 | get { return _IncFuncPos; } 144 | } 145 | 146 | 147 | public static bool Find_Show_Func_Pointer() 148 | { 149 | return _Show_Func_Pointer = Program.Config.IniReadBool("Base", "Show_Func_Pointer", false); 150 | } 151 | 152 | private static bool _Show_Func_Pointer = false; 153 | 154 | public static bool Show_Func_Pointer 155 | { 156 | get { return _Show_Func_Pointer; } 157 | } 158 | 159 | public static bool Find_Nat_Namespace() 160 | { 161 | return _Show_Nat_Namespace = Program.Config.IniReadBool("Base", "Show_Nat_Namespace", false); 162 | } 163 | 164 | private static bool _Show_Nat_Namespace = false; 165 | 166 | public static bool Show_Nat_Namespace 167 | { 168 | get { return _Show_Nat_Namespace; } 169 | } 170 | 171 | public static bool Find_Hex_Index() 172 | { 173 | return _Hex_Index = Program.Config.IniReadBool("Base", "Hex_Index", false); 174 | } 175 | 176 | private static bool _Hex_Index = false; 177 | 178 | public static bool Hex_Index 179 | { 180 | get { return _Hex_Index; } 181 | } 182 | 183 | public static bool Find_Upper_Natives() 184 | { 185 | return _upper_Natives = Program.Config.IniReadBool("Base", "Uppercase_Natives", false); 186 | } 187 | 188 | private static bool _upper_Natives = false; 189 | 190 | public static bool Upper_Natives 191 | { 192 | get { return _upper_Natives; } 193 | } 194 | 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("GTA V Script Decompiler")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Nathan James")] 12 | [assembly: AssemblyProduct("GTA V Script Decompiler")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0bcb2532-e721-4632-a3ce-f212aea07af8")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Decompiler.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Decompiler.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Byte[]. 65 | /// 66 | internal static byte[] Entities { 67 | get { 68 | object obj = ResourceManager.GetObject("Entities", resourceCulture); 69 | return ((byte[])(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Byte[]. 75 | /// 76 | internal static byte[] native_translation { 77 | get { 78 | object obj = ResourceManager.GetObject("native_translation", resourceCulture); 79 | return ((byte[])(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized resource of type System.Byte[]. 85 | /// 86 | internal static byte[] natives { 87 | get { 88 | object obj = ResourceManager.GetObject("natives", resourceCulture); 89 | return ((byte[])(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// Looks up a localized resource of type System.Byte[]. 95 | /// 96 | internal static byte[] x64natives { 97 | get { 98 | object obj = ResourceManager.GetObject("x64natives", resourceCulture); 99 | return ((byte[])(obj)); 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\Entities.dat;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 123 | 124 | 125 | ..\Resources\natives.dat;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 126 | 127 | 128 | ..\Resources\native_translation.dat;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 129 | 130 | 131 | ..\Resources\x64natives.dat;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 132 | 133 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Decompiler.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Resources/Entities.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njames93/GTA-V-Script-Decompiler/38ab830be6012bb807348229bc9ac39fe6a36c45/GTA V Script Decompiler/Resources/Entities.dat -------------------------------------------------------------------------------- /GTA V Script Decompiler/Resources/native_translation.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njames93/GTA-V-Script-Decompiler/38ab830be6012bb807348229bc9ac39fe6a36c45/GTA V Script Decompiler/Resources/native_translation.dat -------------------------------------------------------------------------------- /GTA V Script Decompiler/ScriptFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.IO; 8 | using System.IO.Compression; 9 | using System.Threading; 10 | 11 | namespace Decompiler 12 | { 13 | public class ScriptFile 14 | { 15 | List CodeTable; 16 | public StringTable StringTable; 17 | public NativeTable NativeTable; 18 | public X64NativeTable X64NativeTable; 19 | private int offset = 0; 20 | public readonly bool ConsoleVer; 21 | public List Functions; 22 | public Dictionary FunctionLoc; 23 | public static Hashes hashbank = new Hashes(); 24 | private Stream file; 25 | public ScriptHeader Header; 26 | public string name; 27 | internal Vars_Info Statics; 28 | internal bool CheckNative = true; 29 | internal static NativeParamInfo npi = new NativeParamInfo(); 30 | internal static x64BitNativeParamInfo X64npi = new x64BitNativeParamInfo(); 31 | 32 | 33 | 34 | 35 | public Dictionary> Function_loc = new Dictionary>(); 36 | 37 | public ScriptFile(Stream scriptStream, bool Console) 38 | { 39 | ConsoleVer = Console; 40 | file = scriptStream; 41 | Header = ScriptHeader.Generate(scriptStream, Console); 42 | StringTable = new StringTable(scriptStream, Header.StringTableOffsets, Header.StringBlocks, Header.StringsSize); 43 | if (Console) 44 | NativeTable = new NativeTable(scriptStream, Header.NativesOffset + Header.RSC7Offset, Header.NativesCount); 45 | else 46 | X64NativeTable = new X64NativeTable(scriptStream, Header.NativesOffset + Header.RSC7Offset, Header.NativesCount, Header.CodeLength); 47 | name = Header.ScriptName; 48 | CodeTable = new List(); 49 | for (int i = 0; i < Header.CodeBlocks; i++) 50 | { 51 | int tablesize = ((i + 1) * 0x4000 >= Header.CodeLength) ? Header.CodeLength % 0x4000 : 0x4000; 52 | byte[] working = new byte[tablesize]; 53 | scriptStream.Position = Header.CodeTableOffsets[i]; 54 | scriptStream.Read(working, 0, tablesize); 55 | CodeTable.AddRange(working); 56 | } 57 | GetStaticInfo(); 58 | Functions = new List(); 59 | FunctionLoc = new Dictionary(); 60 | GetFunctions(); 61 | foreach (Function func in Functions) 62 | { 63 | func.PreDecode(); 64 | } 65 | Statics.checkvars(); 66 | foreach (Function func in Functions) 67 | { 68 | func.Decode(); 69 | } 70 | } 71 | 72 | 73 | public void Save(string filename) 74 | { 75 | Stream savefile = File.Create(filename); 76 | Save(savefile, true); 77 | } 78 | public void Save(Stream stream, bool close = false) 79 | { 80 | int i = 1; 81 | StreamWriter savestream = new StreamWriter(stream); 82 | if (Program.Declare_Variables) 83 | { 84 | if (Header.StaticsCount > 0) 85 | { 86 | savestream.WriteLine("#region Local Var"); 87 | i++; 88 | foreach (string s in Statics.GetDeclaration(ConsoleVer)) 89 | { 90 | savestream.WriteLine("\t" + s); 91 | i++; 92 | } 93 | savestream.WriteLine("#endregion"); 94 | savestream.WriteLine(""); 95 | i += 2; 96 | } 97 | } 98 | foreach (Function f in Functions) 99 | { 100 | string s = f.ToString(); 101 | savestream.WriteLine(s); 102 | Function_loc.Add(f.Name, new Tuple( i, f.Location)); 103 | i += f.LineCount; 104 | } 105 | savestream.Flush(); 106 | if (close) 107 | savestream.Close(); 108 | } 109 | public void Close() 110 | { 111 | file.Close(); 112 | } 113 | 114 | public string[] GetStringTable() 115 | { 116 | List table = new List(); 117 | foreach (KeyValuePair item in StringTable) 118 | { 119 | table.Add(item.Key.ToString() + ": " + item.Value); 120 | } 121 | return table.ToArray(); 122 | } 123 | 124 | public string[] GetNativeTable() 125 | { 126 | if (ConsoleVer) 127 | return NativeTable.GetNativeTable(); 128 | else 129 | return X64NativeTable.GetNativeTable(); 130 | } 131 | public string[] GetNativeHeader() 132 | { 133 | if (ConsoleVer) 134 | return NativeTable.GetNativeHeader(); 135 | else 136 | return X64NativeTable.GetNativeHeader(); 137 | } 138 | 139 | public void GetFunctionCode() 140 | { 141 | for (int i = 0; i < Functions.Count - 1; i++) 142 | { 143 | int start = Functions[i].MaxLocation; 144 | int end = Functions[i + 1].Location; 145 | Functions[i].CodeBlock = CodeTable.GetRange(start, end - start); 146 | } 147 | Functions[Functions.Count - 1].CodeBlock = CodeTable.GetRange(Functions[Functions.Count - 1].MaxLocation, CodeTable.Count - Functions[Functions.Count - 1].MaxLocation); 148 | foreach (Function func in Functions) 149 | { 150 | if (func.CodeBlock[0] != 45 && func.CodeBlock[func.CodeBlock.Count - 3] != 46) 151 | throw new Exception("Function has incorrect start/ends"); 152 | } 153 | } 154 | void advpos(int pos) 155 | { 156 | offset += pos; 157 | } 158 | void AddFunction(int start1, int start2) 159 | { 160 | byte namelen = CodeTable[start1 + 4]; 161 | string name = ""; 162 | if (namelen > 0) 163 | { 164 | for (int i = 0; i < namelen; i++) 165 | { 166 | name += (char)CodeTable[start1 + 5 + i]; 167 | } 168 | } 169 | else if (start1 == 0) 170 | { 171 | name = "__EntryFunction__"; 172 | } 173 | else name = "func_" + Functions.Count.ToString(); 174 | int pcount = CodeTable[offset + 1]; 175 | int tmp1 = CodeTable[offset + 2], tmp2 = CodeTable[offset + 3]; 176 | int vcount = ((ConsoleVer)? (tmp1 << 0x8) | tmp2 : (tmp2 << 0x8) | tmp1) ; 177 | if (vcount < 0) 178 | { 179 | throw new Exception("Well this shouldnt have happened"); 180 | } 181 | int temp = start1 + 5 + namelen; 182 | while (CodeTable[temp] != 46) 183 | { 184 | switch (CodeTable[temp]) 185 | { 186 | case 37: temp += 1; break; 187 | case 38: temp += 2; break; 188 | case 39: temp += 3; break; 189 | case 40: 190 | case 41: temp += 4; break; 191 | case 44: temp += 3; break; 192 | case 45: throw new Exception("Return Expected"); 193 | case 46: throw new Exception("Return Expected"); 194 | case 52: 195 | case 53: 196 | case 54: 197 | case 55: 198 | case 56: 199 | case 57: 200 | case 58: 201 | case 59: 202 | case 60: 203 | case 61: 204 | case 62: 205 | case 64: 206 | case 65: 207 | case 66: temp += 1; break; 208 | case 67: 209 | case 68: 210 | case 69: 211 | case 70: 212 | case 71: 213 | case 72: 214 | case 73: 215 | case 74: 216 | case 75: 217 | case 76: 218 | case 77: 219 | case 78: 220 | case 79: 221 | case 80: 222 | case 81: 223 | case 82: 224 | case 83: 225 | case 84: 226 | case 85: 227 | case 86: 228 | case 87: 229 | case 88: 230 | case 89: 231 | case 90: 232 | case 91: 233 | case 92: temp += 2; break; 234 | case 93: 235 | case 94: 236 | case 95: 237 | case 96: 238 | case 97: temp += 3; break; 239 | case 98: temp += 1 + CodeTable[temp + 1] * 6; break; 240 | case 101: 241 | case 102: 242 | case 103: 243 | case 104: temp += 1; break; 244 | } 245 | temp += 1; 246 | } 247 | int rcount = CodeTable[temp + 2]; 248 | int Location = start2; 249 | if (start1 == start2) 250 | { 251 | Functions.Add(new Function(this, name, pcount, vcount, rcount, Location)); 252 | } 253 | else 254 | Functions.Add(new Function(this, name, pcount, vcount, rcount, Location, start1)); 255 | } 256 | void GetFunctions() 257 | { 258 | int returnpos = -3; 259 | while (offset < CodeTable.Count) 260 | { 261 | switch (CodeTable[offset]) 262 | { 263 | case 37: advpos(1); break; 264 | case 38: advpos(2); break; 265 | case 39: advpos(3); break; 266 | case 40: 267 | case 41: advpos(4); break; 268 | case 44: advpos(3); break; 269 | case 45: AddFunction(offset, returnpos + 3); ; advpos(CodeTable[offset + 4] + 4); break; 270 | case 46: returnpos = offset; advpos(2); break; 271 | case 52: 272 | case 53: 273 | case 54: 274 | case 55: 275 | case 56: 276 | case 57: 277 | case 58: 278 | case 59: 279 | case 60: 280 | case 61: 281 | case 62: 282 | case 64: 283 | case 65: 284 | case 66: advpos(1); break; 285 | case 67: 286 | case 68: 287 | case 69: 288 | case 70: 289 | case 71: 290 | case 72: 291 | case 73: 292 | case 74: 293 | case 75: 294 | case 76: 295 | case 77: 296 | case 78: 297 | case 79: 298 | case 80: 299 | case 81: 300 | case 82: 301 | case 83: 302 | case 84: 303 | case 85: 304 | case 86: 305 | case 87: 306 | case 88: 307 | case 89: 308 | case 90: 309 | case 91: 310 | case 92: advpos(2); break; 311 | case 93: 312 | case 94: 313 | case 95: 314 | case 96: 315 | case 97: advpos(3); break; 316 | case 98: advpos(1 + CodeTable[offset + 1] * 6); break; 317 | case 101: 318 | case 102: 319 | case 103: 320 | case 104: advpos(1); break; 321 | } 322 | advpos(1); 323 | } 324 | offset = 0; 325 | GetFunctionCode(); 326 | } 327 | private void GetStaticInfo() 328 | { 329 | Statics = new Vars_Info(Vars_Info.ListType.Statics); 330 | Statics.SetScriptParamCount(Header.ParameterCount); 331 | IO.Reader reader = new IO.Reader(file, ConsoleVer); 332 | reader.BaseStream.Position = Header.StaticsOffset + Header.RSC7Offset; 333 | for (int count = 0; count < Header.StaticsCount; count++) 334 | { 335 | if (ConsoleVer) 336 | Statics.AddVar(reader.SReadInt32()); 337 | else 338 | Statics.AddVar(reader.ReadInt64()); 339 | } 340 | } 341 | 342 | } 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | } 353 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/ScriptHeaders.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Decompiler 5 | { 6 | public class ScriptHeader 7 | { 8 | //Header Start 9 | public Int32 Magic { get; set; } 10 | public Int32 SubHeader { get; set; } //wtf? 11 | public Int32 CodeBlocksOffset { get; set; } 12 | public Int32 GlobalsVersion { get; set; } //Not sure if this is the globals version 13 | public Int32 CodeLength { get; set; } //Total length of code 14 | public Int32 ParameterCount { get; set; } //Count of paremeters to the script 15 | public Int32 StaticsCount { get; set; } 16 | public Int32 GlobalsCount { get; set; } 17 | public Int32 NativesCount { get; set; } //Native count * 4 = total block length 18 | public Int32 StaticsOffset { get; set; } 19 | public Int32 GlobalsOffset { get; set; } 20 | public Int32 NativesOffset { get; set; } 21 | public Int32 Null1 { get; set; } //unknown 22 | public Int32 Null2 { get; set; } //Unknown 23 | public Int32 NameHash { get; set; } //Hash of the script name at ScriptNameOffset 24 | public Int32 Null3 { get; set; } 25 | public Int32 ScriptNameOffset { get; set; } 26 | public Int32 StringsOffset { get; set; } //Offset of the string table 27 | public Int32 StringsSize { get; set; } //Total length of the string block 28 | public Int32 Null4 { get; set; } 29 | //Header End 30 | 31 | //Other Vars 32 | public Int32 RSC7Offset; 33 | public Int32[] StringTableOffsets { get; set; } 34 | public Int32[] CodeTableOffsets { get; set; } 35 | public Int32 StringBlocks { get; set; } 36 | public Int32 CodeBlocks { get; set; } 37 | public string ScriptName { get; set; } 38 | public bool isRSC7 { get; private set; } 39 | 40 | static ScriptHeader GenerateConsoleHeader(Stream scriptStream) 41 | { 42 | ScriptHeader header = new ScriptHeader(); 43 | IO.Reader reader = new IO.Reader(scriptStream, true); 44 | scriptStream.Seek(0, SeekOrigin.Begin); 45 | header.RSC7Offset = (reader.SReadUInt32() == 0x52534337) ? 0x10 : 0x0; 46 | scriptStream.Seek(header.RSC7Offset, SeekOrigin.Begin); 47 | header.Magic = reader.SReadInt32(); //0x0 48 | header.SubHeader = reader.SReadPointer(); //0x4 49 | header.CodeBlocksOffset = reader.SReadPointer(); //0x8 50 | header.GlobalsVersion = reader.SReadInt32(); //0x C 51 | header.CodeLength = reader.SReadInt32(); //0x10 52 | header.ParameterCount = reader.SReadInt32(); //0x14 53 | header.StaticsCount = reader.SReadInt32(); //0x18 54 | header.GlobalsCount = reader.SReadInt32(); //0x1C 55 | header.NativesCount = reader.SReadInt32(); //0x20 56 | header.StaticsOffset = reader.SReadPointer(); //0x24 57 | header.GlobalsOffset = reader.SReadPointer(); //0x28 58 | header.NativesOffset = reader.SReadPointer(); //0x2C 59 | header.Null1 = reader.SReadInt32(); //0x30 60 | header.Null2 = reader.SReadInt32(); //0x34 61 | header.NameHash = reader.SReadInt32(); 62 | header.Null3 = reader.SReadInt32(); //0x38 63 | header.ScriptNameOffset = reader.SReadPointer(); //0x40 64 | header.StringsOffset = reader.SReadPointer(); //0x44 65 | header.StringsSize = reader.SReadInt32(); //0x48 66 | header.Null4 = reader.ReadInt32(); //0x4C 67 | 68 | header.StringBlocks = (header.StringsSize + 0x3FFF) >> 14; 69 | header.CodeBlocks = (header.CodeLength + 0x3FFF) >> 14; 70 | 71 | header.StringTableOffsets = new Int32[header.StringBlocks]; 72 | scriptStream.Seek(header.StringsOffset + header.RSC7Offset, SeekOrigin.Begin); 73 | for (int i = 0; i < header.StringBlocks; i++) 74 | header.StringTableOffsets[i] = reader.SReadPointer() + header.RSC7Offset; 75 | 76 | 77 | header.CodeTableOffsets = new Int32[header.CodeBlocks]; 78 | scriptStream.Seek(header.CodeBlocksOffset + header.RSC7Offset, SeekOrigin.Begin); 79 | for (int i = 0; i < header.CodeBlocks; i++) 80 | header.CodeTableOffsets[i] = reader.SReadPointer() + header.RSC7Offset; 81 | scriptStream.Position = header.ScriptNameOffset + header.RSC7Offset; 82 | int data = scriptStream.ReadByte(); 83 | header.ScriptName = ""; 84 | while (data != 0 && data != -1) 85 | { 86 | header.ScriptName += (char)data; 87 | data = scriptStream.ReadByte(); 88 | } 89 | return header; 90 | } 91 | 92 | static ScriptHeader GeneratePcHeader(Stream scriptStream) 93 | { 94 | ScriptHeader header = new ScriptHeader(); 95 | IO.Reader reader = new IO.Reader(scriptStream, false); 96 | scriptStream.Seek(0, SeekOrigin.Begin); 97 | header.RSC7Offset = (reader.ReadUInt32() == 0x37435352) ? 0x10 : 0x0; 98 | scriptStream.Seek(header.RSC7Offset, SeekOrigin.Begin); 99 | header.Magic = reader.ReadInt32(); //0x0 100 | reader.Advance(); 101 | header.SubHeader = reader.ReadPointer(); //0x8 102 | reader.Advance(); 103 | header.CodeBlocksOffset = reader.ReadPointer(); //0x10 104 | reader.Advance(); 105 | header.GlobalsVersion = reader.ReadInt32(); //0x18 106 | header.CodeLength = reader.ReadInt32(); //0x1C 107 | header.ParameterCount = reader.ReadInt32(); //0x20 108 | header.StaticsCount = reader.ReadInt32(); //0x24 109 | header.GlobalsCount = reader.ReadInt32(); //0x28 110 | header.NativesCount = reader.ReadInt32(); //0x2C 111 | header.StaticsOffset = reader.ReadPointer(); //0x30 112 | reader.Advance(); 113 | header.GlobalsOffset = reader.ReadPointer(); //0x38 114 | reader.Advance(); 115 | header.NativesOffset = reader.ReadPointer(); //0x40 116 | reader.Advance(); 117 | header.Null1 = reader.ReadInt32(); //0x48 118 | reader.Advance(); 119 | header.Null2 = reader.ReadInt32(); //0x50 120 | reader.Advance(); 121 | header.NameHash = reader.ReadInt32(); //0x58 122 | header.Null3 = reader.ReadInt32(); //0x5C 123 | header.ScriptNameOffset = reader.ReadPointer(); //0x60 124 | reader.Advance(); 125 | header.StringsOffset = reader.ReadPointer(); //0x68 126 | reader.Advance(); 127 | header.StringsSize = reader.ReadInt32(); //0x70 128 | reader.Advance(); 129 | header.Null4 = reader.ReadInt32(); //0x78 130 | reader.Advance(); 131 | 132 | header.StringBlocks = (header.StringsSize + 0x3FFF) >> 14; 133 | header.CodeBlocks = (header.CodeLength + 0x3FFF) >> 14; 134 | 135 | header.StringTableOffsets = new Int32[header.StringBlocks]; 136 | scriptStream.Seek(header.StringsOffset + header.RSC7Offset, SeekOrigin.Begin); 137 | for (int i = 0; i < header.StringBlocks; i++) 138 | { 139 | header.StringTableOffsets[i] = reader.ReadPointer() + header.RSC7Offset; 140 | reader.Advance(); 141 | } 142 | 143 | 144 | header.CodeTableOffsets = new Int32[header.CodeBlocks]; 145 | scriptStream.Seek(header.CodeBlocksOffset + header.RSC7Offset, SeekOrigin.Begin); 146 | for (int i = 0; i < header.CodeBlocks; i++) 147 | { 148 | header.CodeTableOffsets[i] = reader.ReadPointer() + header.RSC7Offset; 149 | reader.Advance(); 150 | } 151 | scriptStream.Position = header.ScriptNameOffset + header.RSC7Offset; 152 | int data = scriptStream.ReadByte(); 153 | header.ScriptName = ""; 154 | while (data != 0 && data != -1) 155 | { 156 | header.ScriptName += (char)data; 157 | data = scriptStream.ReadByte(); 158 | } 159 | return header; 160 | } 161 | 162 | public static ScriptHeader Generate(Stream scriptStream, bool consoleVersion) 163 | { 164 | return consoleVersion ? GenerateConsoleHeader(scriptStream) : GeneratePcHeader(scriptStream); 165 | } 166 | 167 | private ScriptHeader() 168 | { } 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/StringTable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Decompiler 9 | { 10 | /// 11 | /// Generates a dictionary of indexes and the strings at those given indexed for use with the PushString instruction 12 | /// 13 | public class StringTable 14 | { 15 | private byte[] _table; 16 | private static readonly byte[] _nl = {92, 110}, _cr = {92, 114}, _qt = {92, 34}; 17 | private Dictionary _dictionary; 18 | public StringTable(Stream scriptFile, int[] stringtablelocs, int blockcount, int wholesize) 19 | { 20 | _table = new byte[wholesize]; 21 | for (int i = 0, off = 0; i < blockcount; i++, off += 0x4000) 22 | { 23 | int tablesize = ((i + 1)*0x4000 >= wholesize) ? wholesize%0x4000 : 0x4000; 24 | scriptFile.Position = stringtablelocs[i]; 25 | scriptFile.Read(_table, off, tablesize); 26 | } 27 | _dictionary = new Dictionary(); 28 | List Working = new List(100); 29 | for (int i = 0, index = 0, max = _table.Length;i= 0 && index < _table.Length; 62 | } 63 | 64 | public string this[int index] 65 | { 66 | get 67 | { 68 | if (_dictionary.ContainsKey(index)) 69 | { 70 | return _dictionary[index];//keep the fast dictionary access 71 | } 72 | //enable support when the string index doesnt fall straight after a null terminator 73 | if (index < 0 || index >= _table.Length) 74 | { 75 | throw new IndexOutOfRangeException("The index given was outside the range of the String table"); 76 | } 77 | List Working = new List(100); 78 | for (int i = index, max = _table.Length; i < max; i++) 79 | { 80 | byte b = _table[i]; 81 | switch (b) 82 | { 83 | case 0: 84 | goto addString; 85 | case 10: 86 | Working.AddRange(_nl); 87 | break; 88 | case 13: 89 | Working.AddRange(_cr); 90 | break; 91 | case 34: 92 | Working.AddRange(_qt); 93 | break; 94 | default: 95 | Working.Add(b); 96 | break; 97 | } 98 | } 99 | addString: 100 | return Encoding.ASCII.GetString(Working.ToArray()); 101 | } 102 | } 103 | 104 | public IEnumerator> GetEnumerator() 105 | { 106 | return _dictionary.GetEnumerator(); 107 | } 108 | 109 | public int[] Keys 110 | { 111 | get { return _dictionary.Keys.ToArray(); } 112 | } 113 | public string[] Values 114 | { 115 | get { return _dictionary.Values.ToArray(); } 116 | } 117 | } 118 | } 119 | 120 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Decompiler 8 | { 9 | static class Utils 10 | { 11 | public static uint jenkins_one_at_a_time_hash(string str) 12 | { 13 | uint hash, i; 14 | char[] key = str.ToLower().ToCharArray(); 15 | for (hash = i = 0; i < key.Length; i++) 16 | { 17 | hash += key[i]; 18 | hash += (hash << 10); 19 | hash ^= (hash >> 6); 20 | } 21 | hash += (hash << 3); 22 | hash ^= (hash >> 11); 23 | hash += (hash << 15); 24 | return hash; 25 | } 26 | 27 | public static string Represent(long value, Stack.DataType type) 28 | { 29 | switch (type) 30 | { 31 | case Stack.DataType.Float: 32 | return BitConverter.ToSingle(BitConverter.GetBytes(value), 0).ToString() + "f"; 33 | case Stack.DataType.Bool: 34 | break;//return value == 0 ? "false" : "true"; //still need to fix bools 35 | case Stack.DataType.FloatPtr: 36 | case Stack.DataType.IntPtr: 37 | case Stack.DataType.StringPtr: 38 | case Stack.DataType.UnkPtr: 39 | return "NULL"; 40 | } 41 | if (value > Int32.MaxValue && value <= UInt32.MaxValue) 42 | return ((int) ((uint) value)).ToString(); 43 | return value.ToString(); 44 | } 45 | public static string FormatHexHash(uint hash) 46 | { 47 | return $"0x{hash:X8}"; 48 | } 49 | public static float SwapEndian(float num) 50 | { 51 | byte[] data = BitConverter.GetBytes(num); 52 | Array.Reverse(data); 53 | return BitConverter.ToSingle(data, 0); 54 | } 55 | public static uint SwapEndian(uint num) 56 | { 57 | byte[] data = BitConverter.GetBytes(num); 58 | Array.Reverse(data); 59 | return BitConverter.ToUInt32(data, 0); 60 | } 61 | public static int SwapEndian(int num) 62 | { 63 | byte[] data = BitConverter.GetBytes(num); 64 | Array.Reverse(data); 65 | return BitConverter.ToInt32(data, 0); 66 | } 67 | public static ulong SwapEndian(ulong num) 68 | { 69 | byte[] data = BitConverter.GetBytes(num); 70 | Array.Reverse(data); 71 | return BitConverter.ToUInt64(data, 0); 72 | } 73 | public static long SwapEndian(long num) 74 | { 75 | byte[] data = BitConverter.GetBytes(num); 76 | Array.Reverse(data); 77 | return BitConverter.ToInt64(data, 0); 78 | } 79 | public static ushort SwapEndian(ushort num) 80 | { 81 | byte[] data = BitConverter.GetBytes(num); 82 | Array.Reverse(data); 83 | return BitConverter.ToUInt16(data, 0); 84 | } 85 | public static short SwapEndian(short num) 86 | { 87 | byte[] data = BitConverter.GetBytes(num); 88 | Array.Reverse(data); 89 | return BitConverter.ToInt16(data, 0); 90 | } 91 | public static bool IntParse(string temp, out int value) 92 | { 93 | //fixes when a string push also has the same index as a function location and the decompiler adds /*func_loc*/ to the string 94 | if (temp.Contains("/*") && temp.Contains("*/")) 95 | { 96 | int index = temp.IndexOf("/*"); 97 | int index2 = temp.IndexOf("*/", index + 1); 98 | if (index2 == -1) 99 | { 100 | value = -1; 101 | return false; 102 | } 103 | temp = temp.Substring(0, index) + temp.Substring(index2 + 2); 104 | } 105 | //fixes the rare case when a string push has the same index as a known hash 106 | if (temp.StartsWith("joaat(\"")) 107 | { 108 | temp = temp.Remove(temp.Length - 2).Substring(7); 109 | uint val = jenkins_one_at_a_time_hash(temp); 110 | value = unchecked((int) val); 111 | return true; 112 | } 113 | if (Program.getIntType == Program.IntType._hex) 114 | { 115 | return int.TryParse(temp.Substring(2), System.Globalization.NumberStyles.HexNumber, new System.Globalization.CultureInfo("en-gb"), out value); 116 | } 117 | else 118 | return int.TryParse(temp, out value); 119 | } 120 | 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/Vars Info.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Decompiler 7 | { 8 | /// 9 | /// This is what i use for detecting if a variable is a int/float/bool/struct/array etc 10 | /// ToDo: work on proper detection of Vector3 and Custom script types(Entities, Ped, Vehicles etc) 11 | /// 12 | public class Vars_Info 13 | { 14 | ListType Listtype;//static/function_var/parameter 15 | List Vars; 16 | Dictionary VarRemapper; //not necessary, just shifts variables up if variables before are bigger than 1 DWORD 17 | private int count; 18 | private int scriptParamCount = 0; 19 | private int scriptParamStart { get { return Vars.Count - scriptParamCount; } } 20 | public Vars_Info(ListType type, int varcount) 21 | { 22 | Listtype = type; 23 | Vars = new List(); 24 | for (int i = 0; i < varcount; i++) 25 | { 26 | Vars.Add(new Var(i)); 27 | } 28 | count = varcount; 29 | } 30 | public Vars_Info(ListType type) 31 | { 32 | Listtype = type; 33 | Vars = new List(); 34 | } 35 | public void AddVar(int value) 36 | { 37 | Vars.Add(new Var(Vars.Count, value));//only used for static variables that are pre assigned 38 | } 39 | 40 | public void AddVar(long value) 41 | { 42 | Vars.Add(new Var(Vars.Count, value)); 43 | } 44 | public void checkvars() 45 | { 46 | unusedcheck(); 47 | } 48 | //This shouldnt be needed but in gamever 1.0.757.2 49 | //It seems a few of the scripts are accessing items from the 50 | //Stack frame that they havent reserver 51 | void broken_check(uint index) 52 | { 53 | if (index >= Vars.Count) 54 | { 55 | for (int i = Vars.Count; i <= index; i++) 56 | { 57 | Vars.Add(new Var(i)); 58 | } 59 | } 60 | } 61 | public string GetVarName(uint index) 62 | { 63 | string name = ""; 64 | Var var = Vars[(int)index]; 65 | if (var.DataType == Stack.DataType.String) 66 | { 67 | name = "c"; 68 | } 69 | else if (var.Immediatesize == 1) 70 | { 71 | name = Types.gettype(var.DataType).varletter; 72 | } 73 | else if (var.Immediatesize == 3) 74 | { 75 | name = "v"; 76 | } 77 | 78 | switch (Listtype) 79 | { 80 | case ListType.Statics: name += (index >= scriptParamStart ? "ScriptParam_" : "Local_"); break; 81 | case ListType.Vars: name += "Var"; break; 82 | case ListType.Params: name += "Param"; break; 83 | } 84 | 85 | if (Program.Shift_Variables) return name + VarRemapper[(int)index].ToString(); 86 | else 87 | { 88 | return name + (Listtype == ListType.Statics && index >= scriptParamStart ? index - scriptParamStart : index).ToString(); 89 | } 90 | 91 | } 92 | public void SetScriptParamCount(int count) 93 | { 94 | if (Listtype == ListType.Statics) 95 | { 96 | scriptParamCount = count; 97 | } 98 | } 99 | public string[] GetDeclaration(bool console) 100 | { 101 | List Working = new List(); 102 | string varlocation = ""; 103 | string datatype = ""; 104 | 105 | int i = 0; 106 | int j = -1; 107 | foreach (Var var in Vars) 108 | { 109 | switch(Listtype) 110 | { 111 | case ListType.Statics: 112 | varlocation = (i >= scriptParamStart ? "ScriptParam_" : "Local_"); 113 | break; 114 | case ListType.Vars: 115 | varlocation = "Var"; 116 | break; 117 | case ListType.Params: 118 | throw new DecompilingException("Parameters have different declaration"); 119 | } 120 | j++; 121 | if (!var.Is_Used) 122 | { 123 | if (!Program.Shift_Variables) 124 | i++; 125 | continue; 126 | } 127 | if (Listtype == ListType.Vars && !var.Is_Called) 128 | { 129 | if (!Program.Shift_Variables) 130 | i++; 131 | continue; 132 | } 133 | if (var.Immediatesize == 1) 134 | { 135 | datatype = Types.gettype(var.DataType).vardec; 136 | 137 | } 138 | else if (var.Immediatesize == 3) 139 | { 140 | datatype = "vector3 v"; 141 | } 142 | else if (var.DataType == Stack.DataType.String) 143 | { 144 | datatype = "char c"; 145 | } 146 | else 147 | { 148 | datatype = "struct<" + var.Immediatesize.ToString() + "> "; 149 | } 150 | string value = ""; 151 | if (!var.Is_Array) 152 | { 153 | if (Listtype == ListType.Statics) 154 | { 155 | if (var.Immediatesize == 1) 156 | { 157 | value = " = " + Utils.Represent(Vars[j].Value, var.DataType); 158 | } 159 | else if (var.DataType == Stack.DataType.String) 160 | { 161 | 162 | List data = new List(); 163 | for (int l = 0; l < var.Immediatesize; l++) 164 | { 165 | data.AddRange(BitConverter.GetBytes(Vars[j + l].Value)); 166 | } 167 | int len = data.IndexOf(0); 168 | data.RemoveRange(len, data.Count - len); 169 | value = " = \"" + Encoding.ASCII.GetString(data.ToArray()) + "\""; 170 | 171 | } 172 | else if (var.Immediatesize == 3) 173 | { 174 | 175 | value += " = { " + Utils.Represent(Vars[j].Value, Stack.DataType.Float) + ", "; 176 | value += Utils.Represent(Vars[j + 1].Value, Stack.DataType.Float) + ", "; 177 | value += Utils.Represent(Vars[j + 2].Value, Stack.DataType.Float) + " }"; 178 | } 179 | else if (var.Immediatesize > 1) 180 | { 181 | value += " = { " + Utils.Represent(Vars[j].Value, Stack.DataType.Int); 182 | for (int l = 1; l < var.Immediatesize; l++) 183 | { 184 | value += ", " + Utils.Represent(Vars[j + l].Value, Stack.DataType.Int); 185 | } 186 | value += " } "; 187 | } 188 | } 189 | } 190 | else 191 | { 192 | if (Listtype == ListType.Statics) 193 | { 194 | if (var.Immediatesize == 1) 195 | { 196 | value = " = { "; 197 | for (int k = 0; k < var.Value; k++) 198 | { 199 | value += Utils.Represent(Vars[j + 1 + k].Value, var.DataType) + ", "; 200 | } 201 | if (value.Length > 2) 202 | { 203 | value = value.Remove(value.Length - 2); 204 | } 205 | value += " }"; 206 | } 207 | else if (var.DataType == Stack.DataType.String) 208 | { 209 | value = " = { "; 210 | for (int k = 0; k < var.Value; k++) 211 | { 212 | List data = new List(); 213 | for (int l = 0; l < var.Immediatesize; l++) 214 | { 215 | if (console) 216 | { 217 | data.AddRange(BitConverter.GetBytes((int)Vars[j + 1 + var.Immediatesize * k + l].Value)); 218 | } 219 | else 220 | { 221 | data.AddRange(BitConverter.GetBytes(Vars[j + 1 + var.Immediatesize * k + l].Value)); 222 | } 223 | } 224 | value += "\"" + Encoding.ASCII.GetString(data.ToArray()) + "\", "; 225 | } 226 | if (value.Length > 2) 227 | { 228 | value = value.Remove(value.Length - 2); 229 | } 230 | value += " }"; 231 | } 232 | else if (var.Immediatesize == 3) 233 | { 234 | value = " = {"; 235 | for (int k = 0; k < var.Value; k++) 236 | { 237 | value += "{ " + Utils.Represent(Vars[j + 1 + 3 * k].Value, Stack.DataType.Float) + ", "; 238 | value += Utils.Represent(Vars[j + 2 + 3 * k].Value, Stack.DataType.Float) + ", "; 239 | value += Utils.Represent(Vars[j + 3 + 3 * k].Value, Stack.DataType.Float) + " }, "; 240 | } 241 | if (value.Length > 2) 242 | { 243 | value = value.Remove(value.Length - 2); 244 | } 245 | value += " }"; 246 | } 247 | } 248 | } 249 | string decl = datatype + varlocation + (Listtype == ListType.Statics && i >= scriptParamStart ? i - scriptParamStart : i).ToString(); 250 | if (var.Is_Array) 251 | { 252 | decl += "[" + var.Value.ToString() + "]"; 253 | } 254 | if (var.DataType == Stack.DataType.String) 255 | { 256 | decl += "[" + (var.Immediatesize*(console ? 4 : 8)).ToString() + "]"; 257 | } 258 | Working.Add(decl + value + ";"); 259 | i++; 260 | } 261 | return Working.ToArray(); 262 | } 263 | public string GetPDec() 264 | { 265 | if (Listtype != ListType.Params) 266 | throw new DecompilingException("Only params use this declaration"); 267 | string decl = ""; 268 | int i = 0; 269 | foreach (Var var in Vars) 270 | { 271 | if (!var.Is_Used) 272 | { 273 | if (!Program.Shift_Variables) 274 | { 275 | i++; 276 | } 277 | continue; 278 | } 279 | string datatype = ""; 280 | if (!var.Is_Array) 281 | { 282 | if (var.DataType == Stack.DataType.String) 283 | { 284 | datatype = "char[" + (var.Immediatesize * 4).ToString() + "] c"; 285 | } 286 | else if (var.Immediatesize == 1) 287 | datatype = Types.gettype(var.DataType).vardec; 288 | else if (var.Immediatesize == 3) 289 | { 290 | datatype = "vector3 v"; 291 | } 292 | else datatype = "struct<" + var.Immediatesize.ToString() + "> "; 293 | } 294 | else 295 | { 296 | if (var.DataType == Stack.DataType.String) 297 | { 298 | datatype = "char[" + (var.Immediatesize * 4).ToString() + "][] c"; 299 | } 300 | else if (var.Immediatesize == 1) 301 | datatype = Types.gettype(var.DataType).vararraydec; 302 | else if (var.Immediatesize == 3) 303 | { 304 | datatype = "vector3[] v"; 305 | } 306 | else datatype = "struct<" + var.Immediatesize.ToString() + ">[] "; 307 | } 308 | decl += datatype + "Param" + i.ToString() + ", "; 309 | i++; 310 | } 311 | if (decl.Length > 2) 312 | decl = decl.Remove(decl.Length - 2); 313 | return decl; 314 | } 315 | /// 316 | /// Remove unused vars from declaration, and shift var indexes down 317 | /// 318 | private void unusedcheck() 319 | { 320 | VarRemapper = new Dictionary(); 321 | for (int i = 0, k=0; i < Vars.Count; i++) 322 | { 323 | if (!Vars[i].Is_Used) 324 | continue; 325 | if (Listtype == ListType.Vars && !Vars[i].Is_Called) 326 | continue; 327 | if (Vars[i].Is_Array) 328 | { 329 | for (int j = i + 1; j < i + 1 + Vars[i].Value * Vars[i].Immediatesize; j++) 330 | { 331 | Vars[j].dontuse(); 332 | } 333 | } 334 | else if (Vars[i].Immediatesize > 1) 335 | { 336 | for (int j = i + 1; j < i + Vars[i].Immediatesize; j++) 337 | { 338 | broken_check((uint)j); 339 | Vars[j].dontuse(); 340 | } 341 | } 342 | VarRemapper.Add(i, k); 343 | k++; 344 | } 345 | } 346 | public Stack.DataType GetTypeAtIndex(uint index) 347 | { 348 | return Vars[(int)index].DataType; 349 | } 350 | public void SetTypeAtIndex(uint index, Stack.DataType type) 351 | { 352 | Vars[(int)index].DataType = type; 353 | } 354 | public Var GetVarAtIndex(uint index) 355 | { 356 | broken_check(index); 357 | return Vars[(int)index]; 358 | } 359 | 360 | public class Var 361 | { 362 | public Var(int index) 363 | { 364 | this.index = index; 365 | value = 0; 366 | immediatesize = 1; 367 | isArray = false; 368 | is_used = true; 369 | Datatype = Stack.DataType.Unk; 370 | } 371 | public Var(int index, long Value) 372 | { 373 | this.index = index; 374 | value = Value; 375 | immediatesize = 1; 376 | isArray = false; 377 | is_used = true; 378 | Datatype = Stack.DataType.Unk; 379 | isstruct = false; 380 | } 381 | int index; 382 | long value; 383 | int immediatesize; 384 | bool isArray; 385 | bool is_used; 386 | bool isstruct; 387 | bool iscalled = false; 388 | Stack.DataType Datatype; 389 | public int Index { get { return index; } } 390 | public long Value { get { return value; } set { this.value = value; } } 391 | public int Immediatesize { get { return immediatesize; } set { immediatesize = value; } } 392 | public void makearray() 393 | { 394 | if (!isstruct) 395 | isArray = true; 396 | } 397 | public void call() 398 | { 399 | iscalled = true; 400 | } 401 | public void makestruct() 402 | { 403 | DataType = Stack.DataType.Unk; 404 | isArray = false; 405 | isstruct = true; 406 | } 407 | public void dontuse() 408 | { 409 | is_used = false; 410 | } 411 | public bool Is_Used { get { return is_used; } } 412 | public bool Is_Called { get { return iscalled; } } 413 | public bool Is_Array { get { return isArray; } } 414 | public Stack.DataType DataType { get { return Datatype; } set { Datatype = value; } } 415 | } 416 | public enum ListType 417 | { 418 | Statics, 419 | Params, 420 | Vars 421 | } 422 | } 423 | } 424 | -------------------------------------------------------------------------------- /GTA V Script Decompiler/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GTA-V-Script-Decompiler 2 | A Program that will decompile the script resources (xsc,csc,ysc) files from the X360, PS3 and PC versions of Grand Theft Auto V. You are not allowed to use this tool for the purpose of creating modification in GTA:Online 3 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" x64 2 | msbuild /verbosity:diagnostic /m /p:Configuration=Release /clp:Summary /nologo 3 | 4 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cmd /c build.bat 3 | -------------------------------------------------------------------------------- /packages/FCTB.2.16.11.0/FCTB.2.16.11.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njames93/GTA-V-Script-Decompiler/38ab830be6012bb807348229bc9ac39fe6a36c45/packages/FCTB.2.16.11.0/FCTB.2.16.11.0.nupkg -------------------------------------------------------------------------------- /packages/FCTB.2.16.11.0/lib/FastColoredTextBox.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njames93/GTA-V-Script-Decompiler/38ab830be6012bb807348229bc9ac39fe6a36c45/packages/FCTB.2.16.11.0/lib/FastColoredTextBox.dll --------------------------------------------------------------------------------