diff --git a/.gitignore b/.gitignore index 4ce6fdd..9491a2f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# Mono auto generated files +mono_crash.* + # Build results [Dd]ebug/ [Dd]ebugPublic/ @@ -20,12 +23,15 @@ [Rr]eleases/ x64/ x86/ +[Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ +[Oo]ut/ [Ll]og/ +[Ll]ogs/ # Visual Studio 2015/2017 cache/options directory .vs/ @@ -39,9 +45,10 @@ Generated\ Files/ [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* -# NUNIT +# NUnit *.VisualState.xml TestResult.xml +nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ @@ -56,6 +63,9 @@ project.lock.json project.fragment.lock.json artifacts/ +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + # StyleCop StyleCopReport.xml @@ -122,9 +132,6 @@ _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user -# JustCode is a .NET coding add-in -.JustCode - # TeamCity is a build add-in _TeamCity* @@ -135,6 +142,11 @@ _TeamCity* .axoCover/* !.axoCover/settings.json +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + # Visual Studio code coverage results *.coverage *.coveragexml @@ -182,6 +194,8 @@ PublishScripts/ # NuGet Packages *.nupkg +# NuGet Symbol Packages +*.snupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. @@ -206,6 +220,8 @@ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx +*.appxbundle +*.appxupload # Visual Studio cache files # files ending in .cache can be ignored @@ -255,7 +271,9 @@ ServiceFabricBackup/ *.bim.layout *.bim_*.settings *.rptproj.rsuser -*- Backup*.rdl +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ @@ -291,10 +309,6 @@ paket-files/ # FAKE - F# Make .fake/ -# JetBrains Rider -.idea/ -*.sln.iml - # CodeRush personal settings .cr/personal @@ -337,4 +351,13 @@ ASALocalRun/ .localhistory/ # BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/Il2CppDumper.sln b/Il2CppDumper.sln index 2984437..2665871 100644 --- a/Il2CppDumper.sln +++ b/Il2CppDumper.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 17.1.32228.430 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Il2CppDumper", "Il2CppDumper\Il2CppDumper.csproj", "{2087F99A-A655-41C1-84BB-54798AEA4080}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Il2CppDumper-x86", "Il2CppDumper\Il2CppDumper-x86.csproj", "{D108619F-DD4C-4D70-ABC2-861E17DB5AC1}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -17,10 +15,6 @@ Global {2087F99A-A655-41C1-84BB-54798AEA4080}.Debug|Any CPU.Build.0 = Debug|Any CPU {2087F99A-A655-41C1-84BB-54798AEA4080}.Release|Any CPU.ActiveCfg = Release|Any CPU {2087F99A-A655-41C1-84BB-54798AEA4080}.Release|Any CPU.Build.0 = Release|Any CPU - {D108619F-DD4C-4D70-ABC2-861E17DB5AC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D108619F-DD4C-4D70-ABC2-861E17DB5AC1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D108619F-DD4C-4D70-ABC2-861E17DB5AC1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D108619F-DD4C-4D70-ABC2-861E17DB5AC1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Il2CppDumper/Il2CppDumper-x86.csproj b/Il2CppDumper/Il2CppDumper-x86.csproj deleted file mode 100644 index 6046921..0000000 --- a/Il2CppDumper/Il2CppDumper-x86.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - Exe - net472;net6.0;net7.0 - 1.0.0.0 - 1.0.0.0 - 1.0.0.0 - Copyright © Perfare 2016-2023 - true - AnyCPU - embedded - - - - - - - - - - - - diff --git a/Il2CppDumper/Il2CppDumper.csproj b/Il2CppDumper/Il2CppDumper.csproj index 1c96011..e0343f0 100644 --- a/Il2CppDumper/Il2CppDumper.csproj +++ b/Il2CppDumper/Il2CppDumper.csproj @@ -2,22 +2,17 @@ Exe - net472;net6.0;net7.0 + net6.0;net7.0 1.0.0.0 1.0.0.0 1.0.0.0 Copyright © Perfare 2016-2023 - AnyCPU embedded + true - - - - - diff --git a/Il2CppDumper/Outputs/ScriptJson.cs b/Il2CppDumper/Outputs/ScriptJson.cs index 83d680a..04cb992 100644 --- a/Il2CppDumper/Outputs/ScriptJson.cs +++ b/Il2CppDumper/Outputs/ScriptJson.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; +using System.Collections.Generic; namespace Il2CppDumper { diff --git a/Il2CppDumper/Outputs/StructGenerator.cs b/Il2CppDumper/Outputs/StructGenerator.cs index 83a89d0..fabd25b 100644 --- a/Il2CppDumper/Outputs/StructGenerator.cs +++ b/Il2CppDumper/Outputs/StructGenerator.cs @@ -1,9 +1,9 @@ -using Newtonsoft.Json; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Text.Json; using System.Text.RegularExpressions; using static Il2CppDumper.Il2CppConstants; @@ -372,9 +372,10 @@ namespace Il2CppDumper value = x.Value, address = $"0x{x.Address:X}" }).ToArray(); - File.WriteAllText(outputDir + "stringliteral.json", JsonConvert.SerializeObject(stringLiterals, Formatting.Indented), new UTF8Encoding(false)); + var jsonOptions = new JsonSerializerOptions() { WriteIndented = true, IncludeFields = true }; + File.WriteAllText(outputDir + "stringliteral.json", JsonSerializer.Serialize(stringLiterals, jsonOptions), new UTF8Encoding(false)); //写入文件 - File.WriteAllText(outputDir + "script.json", JsonConvert.SerializeObject(json, Formatting.Indented)); + File.WriteAllText(outputDir + "script.json", JsonSerializer.Serialize(json, jsonOptions)); //il2cpp.h for (int i = 0; i < genericClassList.Count; i++) { diff --git a/Il2CppDumper/Program.cs b/Il2CppDumper/Program.cs index 7755b05..03362f2 100644 --- a/Il2CppDumper/Program.cs +++ b/Il2CppDumper/Program.cs @@ -2,10 +2,7 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; -using Newtonsoft.Json; -#if NETFRAMEWORK -using System.Windows.Forms; -#endif +using System.Text.Json; namespace Il2CppDumper { @@ -16,7 +13,7 @@ namespace Il2CppDumper [STAThread] static void Main(string[] args) { - config = JsonConvert.DeserializeObject(File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"config.json")); + config = JsonSerializer.Deserialize(File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"config.json")); string il2cppPath = null; string metadataPath = null; string outputDir = null; @@ -60,30 +57,31 @@ namespace Il2CppDumper { outputDir = AppDomain.CurrentDomain.BaseDirectory; } -#if NETFRAMEWORK - if (il2cppPath == null) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var ofd = new OpenFileDialog(); - ofd.Filter = "Il2Cpp binary file|*.*"; - if (ofd.ShowDialog() == DialogResult.OK) + if (il2cppPath == null) { - il2cppPath = ofd.FileName; - ofd.Filter = "global-metadata|global-metadata.dat"; - if (ofd.ShowDialog() == DialogResult.OK) + var ofd = new OpenFileDialog(); + ofd.Filter = "Il2Cpp binary file|*.*"; + if (ofd.ShowDialog()) { - metadataPath = ofd.FileName; + il2cppPath = ofd.FileName; + ofd.Filter = "global-metadata|global-metadata.dat"; + if (ofd.ShowDialog()) + { + metadataPath = ofd.FileName; + } + else + { + return; + } } else { return; } } - else - { - return; - } } -#endif if (il2cppPath == null) { ShowHelp(); diff --git a/Il2CppDumper/Utils/FileDialogNative.cs b/Il2CppDumper/Utils/FileDialogNative.cs new file mode 100644 index 0000000..944b7f9 --- /dev/null +++ b/Il2CppDumper/Utils/FileDialogNative.cs @@ -0,0 +1,193 @@ +using System; +using System.Runtime.InteropServices; + +namespace Il2CppDumper +{ + static class FileDialogNative + { + [ComImport] + [ClassInterface(ClassInterfaceType.None)] + [TypeLibType(TypeLibTypeFlags.FCanCreate)] + [Guid(CLSIDGuid.FileOpenDialog)] + internal class FileOpenDialogRCW + { } + + internal class IIDGuid + { + private IIDGuid() { } // Avoid FxCop violation AvoidUninstantiatedInternalClasses + // IID GUID strings for relevant COM interfaces + internal const string IModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802"; + internal const string IFileDialog = "42f85136-db7e-439c-85f1-e4075d135fc8"; + internal const string IFileOpenDialog = "d57c7288-d4ad-4768-be02-9d969532d960"; + internal const string IFileSaveDialog = "84bccd23-5fde-4cdb-aea4-af64b83d78ab"; + internal const string IFileDialogEvents = "973510DB-7D7F-452B-8975-74A85828D354"; + internal const string IShellItem = "43826D1E-E718-42EE-BC55-A1E261C37BFE"; + internal const string IShellItemArray = "B63EA76D-1F85-456F-A19C-48159EFA858B"; + } + + internal class CLSIDGuid + { + private CLSIDGuid() { } // Avoid FxCop violation AvoidUninstantiatedInternalClasses + internal const string FileOpenDialog = "DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7"; + internal const string FileSaveDialog = "C0B4E2F3-BA21-4773-8DBA-335EC946EB8B"; + } + + [ComImport()] + [Guid(IIDGuid.IFileDialog)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface IFileDialog + { + [PreserveSig] + int Show([In] IntPtr parent); + + void SetFileTypes([In] uint cFileTypes, [In][MarshalAs(UnmanagedType.LPArray)] COMDLG_FILTERSPEC[] rgFilterSpec); + + void SetFileTypeIndex([In] uint iFileType); + + void GetFileTypeIndex(out uint piFileType); + + void Advise([In, MarshalAs(UnmanagedType.Interface)] IFileDialogEvents pfde, out uint pdwCookie); + + void Unadvise([In] uint dwCookie); + + void SetOptions([In] FOS fos); + + void GetOptions(out FOS pfos); + + void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); + + void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); + + void GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + void GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName); + + void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); + + void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle); + + void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText); + + void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel); + + void GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + void AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, int alignment); + + void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); + + void Close([MarshalAs(UnmanagedType.Error)] int hr); + + void SetClientGuid([In] ref Guid guid); + + void ClearClientData(); + + void SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter); + } + + [ComImport, + Guid(IIDGuid.IFileDialogEvents), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface IFileDialogEvents + { + // NOTE: some of these callbacks are cancelable - returning S_FALSE means that + // the dialog should not proceed (e.g. with closing, changing folder); to + // support this, we need to use the PreserveSig attribute to enable us to return + // the proper HRESULT + [PreserveSig] + int OnFileOk([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); + + [PreserveSig] + int OnFolderChanging([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psiFolder); + + void OnFolderChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); + + void OnSelectionChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); + + void OnShareViolation([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, out FDE_SHAREVIOLATION_RESPONSE pResponse); + + void OnTypeChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); + + void OnOverwrite([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, out FDE_OVERWRITE_RESPONSE pResponse); + } + + [ComImport, + Guid(IIDGuid.IShellItem), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface IShellItem + { + void BindToHandler([In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, [In] ref Guid bhid, [In] ref Guid riid, out IntPtr ppv); + + void GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + void GetDisplayName([In] SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName); + + void GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs); + + void Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder); + } + + internal enum SIGDN : uint + { + SIGDN_NORMALDISPLAY = 0x00000000, // SHGDN_NORMAL + SIGDN_PARENTRELATIVEPARSING = 0x80018001, // SHGDN_INFOLDER | SHGDN_FORPARSING + SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000, // SHGDN_FORPARSING + SIGDN_PARENTRELATIVEEDITING = 0x80031001, // SHGDN_INFOLDER | SHGDN_FOREDITING + SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, // SHGDN_FORPARSING | SHGDN_FORADDRESSBAR + SIGDN_FILESYSPATH = 0x80058000, // SHGDN_FORPARSING + SIGDN_URL = 0x80068000, // SHGDN_FORPARSING + SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001, // SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR + SIGDN_PARENTRELATIVE = 0x80080001 // SHGDN_INFOLDER + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] + internal struct COMDLG_FILTERSPEC + { + [MarshalAs(UnmanagedType.LPWStr)] + internal string pszName; + [MarshalAs(UnmanagedType.LPWStr)] + internal string pszSpec; + } + + [Flags] + internal enum FOS : uint + { + FOS_OVERWRITEPROMPT = 0x00000002, + FOS_STRICTFILETYPES = 0x00000004, + FOS_NOCHANGEDIR = 0x00000008, + FOS_PICKFOLDERS = 0x00000020, + FOS_FORCEFILESYSTEM = 0x00000040, // Ensure that items returned are filesystem items. + FOS_ALLNONSTORAGEITEMS = 0x00000080, // Allow choosing items that have no storage. + FOS_NOVALIDATE = 0x00000100, + FOS_ALLOWMULTISELECT = 0x00000200, + FOS_PATHMUSTEXIST = 0x00000800, + FOS_FILEMUSTEXIST = 0x00001000, + FOS_CREATEPROMPT = 0x00002000, + FOS_SHAREAWARE = 0x00004000, + FOS_NOREADONLYRETURN = 0x00008000, + FOS_NOTESTFILECREATE = 0x00010000, + FOS_HIDEMRUPLACES = 0x00020000, + FOS_HIDEPINNEDPLACES = 0x00040000, + FOS_NODEREFERENCELINKS = 0x00100000, + FOS_DONTADDTORECENT = 0x02000000, + FOS_FORCESHOWHIDDEN = 0x10000000, + FOS_DEFAULTNOMINIMODE = 0x20000000 + } + + internal enum FDE_SHAREVIOLATION_RESPONSE + { + FDESVR_DEFAULT = 0x00000000, + FDESVR_ACCEPT = 0x00000001, + FDESVR_REFUSE = 0x00000002 + } + + internal enum FDE_OVERWRITE_RESPONSE + { + FDEOR_DEFAULT = 0x00000000, + FDEOR_ACCEPT = 0x00000001, + FDEOR_REFUSE = 0x00000002 + } + } +} diff --git a/Il2CppDumper/Utils/OpenFileDialog.cs b/Il2CppDumper/Utils/OpenFileDialog.cs new file mode 100644 index 0000000..80e959f --- /dev/null +++ b/Il2CppDumper/Utils/OpenFileDialog.cs @@ -0,0 +1,46 @@ +using System; +using static Il2CppDumper.FileDialogNative; + +namespace Il2CppDumper +{ + public class OpenFileDialog + { + public string Title { get; set; } + public string Filter { get; set; } + public string FileName { get; set; } + + public bool ShowDialog() + { + var dialog = (IFileDialog)(new FileOpenDialogRCW()); + dialog.GetOptions(out var options); + options |= FOS.FOS_FORCEFILESYSTEM | FOS.FOS_NOVALIDATE | FOS.FOS_DONTADDTORECENT; + dialog.SetOptions(options); + if (!string.IsNullOrEmpty(Title)) + { + dialog.SetTitle(Title); + } + if (!string.IsNullOrEmpty(Filter)) + { + string[] filterElements = Filter.Split(new char[] { '|' }); + COMDLG_FILTERSPEC[] filter = new COMDLG_FILTERSPEC[filterElements.Length / 2]; + for (int x = 0; x < filterElements.Length; x += 2) + { + filter[x / 2].pszName = filterElements[x]; + filter[x / 2].pszSpec = filterElements[x + 1]; + } + dialog.SetFileTypes((uint)filter.Length, filter); + } + if (dialog.Show(IntPtr.Zero) == 0) + { + dialog.GetResult(out var shellItem); + shellItem.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var ppszName); + FileName = ppszName; + return true; + } + else + { + return false; + } + } + } +} \ No newline at end of file