Exemple #1
0
        public override bool SymbolSearch()
        {
            ulong codeRegistration     = 0ul;
            ulong metadataRegistration = 0ul;
            ulong dynstrOffset         = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);

            foreach (var symbol in symbolTable)
            {
                var name = ReadStringToNull(dynstrOffset + symbol.st_name);
                switch (name)
                {
                case "g_CodeRegistration":
                    codeRegistration = symbol.st_value;
                    break;

                case "g_MetadataRegistration":
                    metadataRegistration = symbol.st_value;
                    break;
                }
            }
            if (codeRegistration > 0 && metadataRegistration > 0)
            {
                FormGUI.WriteLine("Detected Symbol !");
                FormGUI.WriteLine("CodeRegistration : {0:x}", codeRegistration);
                FormGUI.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
                Init(codeRegistration, metadataRegistration);
                return(true);
            }
            FormGUI.WriteLine("ERROR: No symbol is detected");
            return(false);
        }
Exemple #2
0
        private static readonly string X86FeatureBytes = "? 0x10 ? 0xE7 ? 0x00 ? 0xE0 ? 0x20 ? 0xE0"; //TODO

        public Elf(Stream stream) : base(stream)
        {
            Is32Bit        = true;
            elfHeader      = ReadClass <Elf32_Ehdr>();
            programSegment = ReadClassArray <Elf32_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
            if (!CheckSection())
            {
                GetDumpAddress();
            }
            if (IsDumped)
            {
                FixedProgramSegment();
            }
            pt_dynamic     = programSegment.First(x => x.p_type == PT_DYNAMIC);
            dynamicSection = ReadClassArray <Elf32_Dyn>(pt_dynamic.p_offset, pt_dynamic.p_filesz / 8u);
            if (IsDumped)
            {
                FixedDynamicSection();
            }
            ReadSymbol();
            if (!IsDumped)
            {
                RelocationProcessing();
                if (CheckProtection())
                {
                    FormGUI.WriteLine("ERROR: This file may be protected.");
                }
            }
        }
Exemple #3
0
        private bool CheckProtection()
        {
            //.init_proc
            if (dynamicSection.Any(x => x.d_tag == DT_INIT))
            {
                FormGUI.WriteLine("WARNING: find .init_proc");
                return(true);
            }
            //JNI_OnLoad
            ulong dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);

            foreach (var symbol in symbolTable)
            {
                var name = ReadStringToNull(dynstrOffset + symbol.st_name);
                switch (name)
                {
                case "JNI_OnLoad":
                    FormGUI.WriteLine("WARNING: find JNI_OnLoad");
                    return(true);
                }
            }
            if (sectionTable != null && sectionTable.Any(x => x.sh_type == SHT_LOUSER))
            {
                FormGUI.WriteLine("WARNING: find SHT_LOUSER section");
                return(true);
            }
            return(false);
        }
Exemple #4
0
 protected bool AutoPlusInit(ulong codeRegistration, ulong metadataRegistration)
 {
     if (codeRegistration != 0 && metadataRegistration != 0)
     {
         if (Version == 24.2)
         {
             pCodeRegistration = MapVATR <Il2CppCodeRegistration>(codeRegistration);
             if (pCodeRegistration.reversePInvokeWrapperCount > 0x30000) //TODO
             {
                 Version           = 24.4;
                 codeRegistration -= PointerSize * 3;
                 Console.WriteLine($"Change il2cpp version to: {Version}");
             }
             else
             {
                 pMetadataRegistration = MapVATR <Il2CppMetadataRegistration>(metadataRegistration);
                 genericMethodTable    = MapVATR <Il2CppGenericMethodFunctionsDefinitions>(pMetadataRegistration.genericMethodTable, pMetadataRegistration.genericMethodTableCount);
                 var genericMethodPointersCount = genericMethodTable.Max(x => x.indices.methodIndex) + 1;
                 if (pCodeRegistration.reversePInvokeWrapperCount == genericMethodPointersCount)
                 {
                     Version           = 24.3;
                     codeRegistration -= Is32Bit ? 8u : 16u;
                     FormGUI.Log($"Change il2cpp version to: {Version}");
                 }
             }
         }
         FormGUI.Log("CodeRegistration : {0:x}", codeRegistration);
         FormGUI.Log("MetadataRegistration : {0:x}", metadataRegistration);
         Init(codeRegistration, metadataRegistration);
         return(true);
     }
     FormGUI.Log("CodeRegistration : {0:x}", codeRegistration);
     FormGUI.Log("MetadataRegistration : {0:x}", metadataRegistration);
     return(false);
 }
Exemple #5
0
 private void RelocationProcessing()
 {
     FormGUI.WriteLine("Applying relocations...");
     try
     {
         var reldynOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_REL).d_un);
         var reldynSize   = dynamicSection.First(x => x.d_tag == DT_RELSZ).d_un;
         var relTable     = ReadClassArray <Elf32_Rel>(reldynOffset, reldynSize / 8);
         var isx86        = elfHeader.e_machine == 0x3;
         foreach (var rel in relTable)
         {
             var type = rel.r_info & 0xff;
             var sym  = rel.r_info >> 8;
             switch (type)
             {
             case R_386_32 when isx86:
             case R_ARM_ABS32 when !isx86:
             {
                 var symbol = symbolTable[sym];
                 Position = MapVATR(rel.r_offset);
                 Write(symbol.st_value);
                 break;
             }
             }
         }
     }
     catch
     {
         // ignored
     }
 }
Exemple #6
0
        public override bool Search()
        {
            var _GLOBAL_OFFSET_TABLE_ = dynamicSection.First(x => x.d_tag == DT_PLTGOT).d_un;
            var execs        = programSegment.Where(x => x.p_type == PT_LOAD && (x.p_flags & PF_X) == 1).ToArray();
            var resultList   = new List <int>();
            var featureBytes = elfHeader.e_machine == EM_ARM ? ARMFeatureBytes : X86FeatureBytes;

            foreach (var exec in execs)
            {
                Position = exec.p_offset;
                var buff = ReadBytes((int)exec.p_filesz);
                foreach (var temp in buff.Search(featureBytes))
                {
                    var bin = buff[temp + 2].HexToBin();
                    if (bin[3] == '1') //LDR
                    {
                        resultList.Add(temp);
                    }
                }
            }
            if (resultList.Count == 1)
            {
                uint codeRegistration     = 0;
                uint metadataRegistration = 0;
                var  result = (uint)resultList[0];
                if (Version < 24)
                {
                    if (elfHeader.e_machine == EM_ARM)
                    {
                        Position         = result + 0x14;
                        codeRegistration = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
                        Position         = result + 0x18;
                        var ptr = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
                        Position             = MapVATR(ptr);
                        metadataRegistration = ReadUInt32();
                    }
                }
                else if (Version >= 24)
                {
                    if (elfHeader.e_machine == EM_ARM)
                    {
                        Position         = result + 0x14;
                        codeRegistration = ReadUInt32() + result + 0xcu + (uint)DumpAddr;
                        Position         = result + 0x10;
                        var ptr = ReadUInt32() + result + 0x8;
                        Position             = MapVATR(ptr + DumpAddr);
                        metadataRegistration = ReadUInt32();
                    }
                }
                FormGUI.WriteLine("CodeRegistration : {0:x}", codeRegistration);
                FormGUI.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
                Init(codeRegistration, metadataRegistration);
                return(true);
            }
            return(false);
        }
Exemple #7
0
        public Macho(Stream stream) : base(stream)
        {
            Is32Bit   = true;
            Position += 16; //skip magic, cputype, cpusubtype, filetype
            var ncmds = ReadUInt32();

            Position += 8; //skip sizeofcmds, flags
            for (var i = 0; i < ncmds; i++)
            {
                var pos     = Position;
                var cmd     = ReadUInt32();
                var cmdsize = ReadUInt32();
                switch (cmd)
                {
                case 1:                      //LC_SEGMENT
                    var segname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
                    if (segname == "__TEXT") //__PAGEZERO
                    {
                        vmaddr = ReadUInt32();
                    }
                    else
                    {
                        Position += 4;
                    }
                    Position += 20;    //skip vmsize, fileoff, filesize, maxprot, initprot
                    var nsects = ReadUInt32();
                    Position += 4;     //skip flags
                    for (var j = 0; j < nsects; j++)
                    {
                        var section = new MachoSection();
                        sections.Add(section);
                        section.sectname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
                        Position        += 16; //skip segname
                        section.addr     = ReadUInt32();
                        section.size     = ReadUInt32();
                        section.offset   = ReadUInt32();
                        Position        += 12; //skip align, reloff, nreloc
                        section.flags    = ReadUInt32();
                        section.end      = section.addr + section.size;
                        Position        += 8; //skip reserved1, reserved2
                    }
                    break;

                case 0x21:     //LC_ENCRYPTION_INFO
                    Position += 8;
                    var cryptID = ReadUInt32();
                    if (cryptID != 0)
                    {
                        FormGUI.WriteLine("ERROR: This Mach-O executable is encrypted and cannot be processed.");
                    }
                    break;
                }
                Position = pos + cmdsize;//next
            }
        }
Exemple #8
0
        public FormGUI()
        {
            InitializeComponent();

            //I liked 3 digits better
            string[] versionArray = Assembly.GetExecutingAssembly().GetName().Version.ToString().Split('.');
            Version = string.Join(".", versionArray.Take(3));

            //Events
            settingsPicBox.MouseLeave += new EventHandler((sender, e) => settingsPicBox.BackColor = Color.FromArgb(0, 0, 0, 0));
            settingsPicBox.MouseEnter += new EventHandler((sender, e) => settingsPicBox.BackColor = Color.FromArgb(36, 93, 127));
            aboutPicBox.MouseLeave    += new EventHandler((sender, e) => aboutPicBox.BackColor = Color.FromArgb(0, 0, 0, 0));
            aboutPicBox.MouseEnter    += new EventHandler((sender, e) => aboutPicBox.BackColor = Color.FromArgb(36, 93, 127));

            aFormDump    = new FormDump(this);
            aFormOptions = new FormSettings(this);
            aFormAbout   = new FormAbout(this);

            //Force tls12
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            //Load custom fonts
            byte[] fontData = Resources.GOTHIC;
            IntPtr fontPtr  = Marshal.AllocCoTaskMem(fontData.Length);

            Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
            uint dummy = 0;

            fonts.AddMemoryFont(fontPtr, Resources.GOTHIC.Length);
            AddFontMemResourceEx(fontPtr, (uint)Resources.GOTHIC.Length, IntPtr.Zero, ref dummy);
            Marshal.FreeCoTaskMem(fontPtr);

            fontData = Resources.GOTHICB;
            fontPtr  = Marshal.AllocCoTaskMem(fontData.Length);
            Marshal.Copy(fontData, 0, fontPtr, fontData.Length);

            fonts.AddMemoryFont(fontPtr, Resources.GOTHICB.Length);
            AddFontMemResourceEx(fontPtr, (uint)Resources.GOTHICB.Length, IntPtr.Zero, ref dummy);
            Marshal.FreeCoTaskMem(fontPtr);

            SetAllControlsFont(Controls);

            //copy context menu
            ContextMenu contextMenu = new ContextMenu();
            MenuItem    menuItem    = new MenuItem();

            menuItem        = new MenuItem("Copy");
            menuItem.Click += new EventHandler(CopyAction);
            contextMenu.MenuItems.Add(menuItem);
            richTextBoxLogs.ContextMenu = contextMenu;

            main = this;
        }
Exemple #9
0
        public FormGUI()
        {
            InitializeComponent();

            settingsPicBox.MouseLeave += new EventHandler((sender, e) => settingsPicBox.BackColor = Color.FromArgb(0, 0, 0, 0));
            settingsPicBox.MouseEnter += new EventHandler((sender, e) => settingsPicBox.BackColor = Color.FromArgb(36, 93, 127));

            aFormDump     = new FormDump(this);
            aFormOptions  = new FormOptions(this);
            aFormRegistry = new FormRegistry(this);

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            byte[] fontData = Properties.Resources.GOTHIC;
            IntPtr fontPtr  = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(fontData.Length);

            System.Runtime.InteropServices.Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
            uint dummy = 0;

            fonts.AddMemoryFont(fontPtr, Properties.Resources.GOTHIC.Length);
            AddFontMemResourceEx(fontPtr, (uint)Properties.Resources.GOTHIC.Length, IntPtr.Zero, ref dummy);
            System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr);

            fontData = Properties.Resources.GOTHICB;
            fontPtr  = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(fontData.Length);
            System.Runtime.InteropServices.Marshal.Copy(fontData, 0, fontPtr, fontData.Length);

            fonts.AddMemoryFont(fontPtr, Properties.Resources.GOTHICB.Length);
            AddFontMemResourceEx(fontPtr, (uint)Properties.Resources.GOTHICB.Length, IntPtr.Zero, ref dummy);
            System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr);

            SetAllControlsFont(Controls);

            //copy context menu
            ContextMenu contextMenu = new ContextMenu();
            MenuItem    menuItem    = new MenuItem();

            menuItem        = new MenuItem("Copy");
            menuItem.Click += new EventHandler(CopyAction);
            contextMenu.MenuItems.Add(menuItem);
            richTextBoxLogs.ContextMenu = contextMenu;

            FormRegistry.Load();

            if (FormRegistry.CheckForUpdate)
            {
                CheckUpdate();
            }

            titleLbl.Text += " " + Version;

            main = this;
        }
Exemple #10
0
        public void GetDumpAddress()
        {
            FormGUI.Log("Detected this may be a dump file.");
            FormDump form = new FormDump();

            form.Message = 0;
            if (form.ShowDialog() == DialogResult.OK)
            {
                DumpAddr = Convert.ToUInt64(form.ReturnedText, 16);
                FormGUI.Log("Inputted address: " + DumpAddr.ToString("X"));
            }
            if (DumpAddr != 0)
            {
                IsDumped = true;
            }
        }
Exemple #11
0
 public Elf(Stream stream) : base(stream)
 {
     Is32Bit        = true;
     elfHeader      = ReadClass <Elf32_Ehdr>();
     programSegment = ReadClassArray <Elf32_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
     if (!CheckSection())
     {
         FormGUI.WriteLine("Detected this may be a dump file.");
         FormDump form = new FormDump();
         form.Message = 0;
         if (form.ShowDialog() == DialogResult.OK)
         {
             dumpAddr = Convert.ToUInt32(form.ReturnedText, 16);
             FormGUI.WriteLine("Inputted address: " + dumpAddr.ToString("X"));
         }
         if (dumpAddr != 0)
         {
             isDumped = true;
         }
     }
     if (isDumped)
     {
         FixedProgramSegment();
     }
     pt_dynamic     = programSegment.First(x => x.p_type == PT_DYNAMIC);
     dynamicSection = ReadClassArray <Elf32_Dyn>(pt_dynamic.p_offset, pt_dynamic.p_filesz / 8u);
     if (isDumped)
     {
         FixedDynamicSection();
     }
     ReadSymbol();
     if (!isDumped)
     {
         RelocationProcessing();
         if (CheckProtection())
         {
             FormGUI.WriteLine("ERROR: This file may be protected.");
         }
     }
 }
Exemple #12
0
        private void RelocationProcessing()
        {
            FormGUI.WriteLine("Applying relocations...");
            try
            {
                var relaOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_RELA).d_un);
                var relaSize   = dynamicSection.First(x => x.d_tag == DT_RELASZ).d_un;
                var relaTable  = ReadClassArray <Elf64_Rela>(relaOffset, (long)relaSize / 24L);
                foreach (var rela in relaTable)
                {
                    var type = rela.r_info & 0xffffffff;
                    var sym  = rela.r_info >> 32;
                    switch (type)
                    {
                    case R_AARCH64_ABS64:
                    {
                        var symbol = symbolTable[sym];
                        Position = MapVATR(rela.r_offset);
                        Write(symbol.st_value + (ulong)rela.r_addend);
                        break;
                    }

                    case R_AARCH64_RELATIVE:
                    {
                        Position = MapVATR(rela.r_offset);
                        Write(rela.r_addend);
                        break;
                    }
                    }
                }
            }
            catch
            {
                // ignored
            }
        }
 public FormOptions(FormGUI Main)
 {
     main = Main;
 }
Exemple #14
0
 public override bool Search()
 {
     if (Version < 21)
     {
         var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
         var addrs           = ReadClassArray <uint>(__mod_init_func.offset, __mod_init_func.size / 4u);
         foreach (var a in addrs)
         {
             if (a > 0)
             {
                 var i = a - 1;
                 Position  = MapVATR(i);
                 Position += 4;
                 var buff = ReadBytes(2);
                 if (FeatureBytes1.SequenceEqual(buff))
                 {
                     Position += 12;
                     buff      = ReadBytes(4);
                     if (FeatureBytes2.SequenceEqual(buff))
                     {
                         Position = MapVATR(i) + 10;
                         var subaddr  = DecodeMov(ReadBytes(8)) + i + 24u - 1u;
                         var rsubaddr = MapVATR(subaddr);
                         Position = rsubaddr;
                         var ptr = DecodeMov(ReadBytes(8)) + subaddr + 16u;
                         Position = MapVATR(ptr);
                         var metadataRegistration = ReadUInt32();
                         Position = rsubaddr + 8;
                         buff     = ReadBytes(4);
                         Position = rsubaddr + 14;
                         buff     = buff.Concat(ReadBytes(4)).ToArray();
                         var codeRegistration = DecodeMov(buff) + subaddr + 22u;
                         FormGUI.WriteLine("CodeRegistration : {0:x}", codeRegistration);
                         FormGUI.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
                         Init(codeRegistration, metadataRegistration);
                         return(true);
                     }
                 }
             }
         }
         return(false);
     }
     else
     {
         var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
         var addrs           = ReadClassArray <uint>(__mod_init_func.offset, __mod_init_func.size / 4u);
         foreach (var a in addrs)
         {
             if (a > 0)
             {
                 var i = a - 1;
                 Position  = MapVATR(i);
                 Position += 4;
                 var buff = ReadBytes(2);
                 if (FeatureBytes1.SequenceEqual(buff))
                 {
                     Position += 12;
                     buff      = ReadBytes(4);
                     if (FeatureBytes2.SequenceEqual(buff))
                     {
                         Position = MapVATR(i) + 10;
                         var subaddr  = DecodeMov(ReadBytes(8)) + i + 24u - 1u;
                         var rsubaddr = MapVATR(subaddr);
                         Position = rsubaddr;
                         var ptr = DecodeMov(ReadBytes(8)) + subaddr + 16u;
                         Position = MapVATR(ptr);
                         var metadataRegistration = ReadUInt32();
                         Position = rsubaddr + 8;
                         buff     = ReadBytes(4);
                         Position = rsubaddr + 14;
                         buff     = buff.Concat(ReadBytes(4)).ToArray();
                         var codeRegistration = DecodeMov(buff) + subaddr + 26u;
                         FormGUI.WriteLine("CodeRegistration : {0:x}", codeRegistration);
                         FormGUI.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
                         Init(codeRegistration, metadataRegistration);
                         return(true);
                     }
                 }
             }
         }
         return(false);
     }
 }
Exemple #15
0
        public override bool Search()
        {
            var codeRegistration     = 0ul;
            var metadataRegistration = 0ul;

            if (Version < 23)
            {
                var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
                var addrs           = ReadClassArray <ulong>(__mod_init_func.offset, (long)__mod_init_func.size / 8);
                foreach (var i in addrs)
                {
                    if (i > 0)
                    {
                        var flag    = false;
                        var subaddr = 0ul;
                        Position = MapVATR(i);
                        var buff = ReadBytes(4);
                        if (FeatureBytes1.SequenceEqual(buff))
                        {
                            buff = ReadBytes(4);
                            if (FeatureBytes2.SequenceEqual(buff))
                            {
                                Position += 8;
                                var inst = ReadBytes(4);
                                if (IsAdr(inst))
                                {
                                    subaddr = DecodeAdr(i + 16, inst);
                                    flag    = true;
                                }
                            }
                        }
                        else
                        {
                            Position += 0xc;
                            buff      = ReadBytes(4);
                            if (FeatureBytes2.SequenceEqual(buff))
                            {
                                buff = ReadBytes(4);
                                if (FeatureBytes1.SequenceEqual(buff))
                                {
                                    Position -= 0x10;
                                    var inst = ReadBytes(4);
                                    if (IsAdr(inst))
                                    {
                                        subaddr = DecodeAdr(i + 8, inst);
                                        flag    = true;
                                    }
                                }
                            }
                        }
                        if (flag)
                        {
                            var rsubaddr = MapVATR(subaddr);
                            Position              = rsubaddr;
                            codeRegistration      = DecodeAdrp(subaddr, ReadBytes(4));
                            codeRegistration     += DecodeAdd(ReadBytes(4));
                            Position              = rsubaddr + 8;
                            metadataRegistration  = DecodeAdrp(subaddr + 8, ReadBytes(4));
                            metadataRegistration += DecodeAdd(ReadBytes(4));
                        }
                    }
                }
            }
            if (Version == 23)
            {
                /* ADRP X0, unk
                 * ADD X0, X0, unk
                 * ADR X1, sub
                 * NOP
                 * MOV X2, #0
                 * MOV W3, #0
                 * B sub
                 */
                var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
                var addrs           = ReadClassArray <ulong>(__mod_init_func.offset, (long)__mod_init_func.size / 8);
                foreach (var i in addrs)
                {
                    if (i > 0)
                    {
                        Position = MapVATR(i) + 16;
                        var buff = ReadBytes(4);
                        if (FeatureBytes1.SequenceEqual(buff))
                        {
                            buff = ReadBytes(4);
                            if (FeatureBytes2.SequenceEqual(buff))
                            {
                                Position -= 16;
                                var subaddr  = DecodeAdr(i + 8, ReadBytes(4));
                                var rsubaddr = MapVATR(subaddr);
                                Position              = rsubaddr;
                                codeRegistration      = DecodeAdrp(subaddr, ReadBytes(4));
                                codeRegistration     += DecodeAdd(ReadBytes(4));
                                Position              = rsubaddr + 8;
                                metadataRegistration  = DecodeAdrp(subaddr + 8, ReadBytes(4));
                                metadataRegistration += DecodeAdd(ReadBytes(4));
                            }
                        }
                    }
                }
            }
            if (Version >= 24)
            {
                /* ADRP X0, unk
                 * ADD X0, X0, unk
                 * ADR X1, sub
                 * NOP
                 * MOV W3, #0
                 * MOV X2, #0
                 * B sub
                 */
                var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
                var addrs           = ReadClassArray <ulong>(__mod_init_func.offset, (long)__mod_init_func.size / 8);
                foreach (var i in addrs)
                {
                    if (i > 0)
                    {
                        Position = MapVATR(i) + 16;
                        var buff = ReadBytes(4);
                        if (FeatureBytes2.SequenceEqual(buff))
                        {
                            buff = ReadBytes(4);
                            if (FeatureBytes1.SequenceEqual(buff))
                            {
                                Position -= 16;
                                var subaddr  = DecodeAdr(i + 8, ReadBytes(4));
                                var rsubaddr = MapVATR(subaddr);
                                Position              = rsubaddr;
                                codeRegistration      = DecodeAdrp(subaddr, ReadBytes(4));
                                codeRegistration     += DecodeAdd(ReadBytes(4));
                                Position              = rsubaddr + 8;
                                metadataRegistration  = DecodeAdrp(subaddr + 8, ReadBytes(4));
                                metadataRegistration += DecodeAdd(ReadBytes(4));
                            }
                        }
                    }
                }
            }
            if (codeRegistration != 0 && metadataRegistration != 0)
            {
                FormGUI.Log("CodeRegistration : {0:x}", codeRegistration);
                FormGUI.Log("MetadataRegistration : {0:x}", metadataRegistration);
                Init(codeRegistration, metadataRegistration);
                return(true);
            }
            return(false);
        }
 public FormDump(FormGUI Main)
 {
     main = Main;
 }
Exemple #17
0
 public FormSettings(FormGUI Main)
 {
     main = Main;
 }
Exemple #18
0
 public FormRegistry(FormGUI Main)
 {
     main = Main;
 }
Exemple #19
0
        public void Decompile(Config config, string outputDir)
        {
            var writer = new StreamWriter(new FileStream(outputDir + "dump.cs", FileMode.Create), new UTF8Encoding(false));

            //dump image
            for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
            {
                var imageDef = metadata.imageDefs[imageIndex];
                writer.Write($"// Image {imageIndex}: {metadata.GetStringFromIndex(imageDef.nameIndex)} - {imageDef.typeStart}\n");
            }
            //dump type
            foreach (var imageDef in metadata.imageDefs)
            {
                try
                {
                    var imageName = metadata.GetStringFromIndex(imageDef.nameIndex);
                    var typeEnd   = imageDef.typeStart + imageDef.typeCount;
                    for (int typeDefIndex = imageDef.typeStart; typeDefIndex < typeEnd; typeDefIndex++)
                    {
                        var typeDef = metadata.typeDefs[typeDefIndex];
                        var extends = new List <string>();
                        if (typeDef.parentIndex >= 0)
                        {
                            var parent     = il2Cpp.types[typeDef.parentIndex];
                            var parentName = executor.GetTypeName(parent, false, false);
                            if (!typeDef.IsValueType && !typeDef.IsEnum && parentName != "object")
                            {
                                extends.Add(parentName);
                            }
                        }
                        if (typeDef.interfaces_count > 0)
                        {
                            for (int i = 0; i < typeDef.interfaces_count; i++)
                            {
                                var @interface = il2Cpp.types[metadata.interfaceIndices[typeDef.interfacesStart + i]];
                                extends.Add(executor.GetTypeName(@interface, false, false));
                            }
                        }
                        writer.Write($"\n// Namespace: {metadata.GetStringFromIndex(typeDef.namespaceIndex)}\n");
                        if (config.DumpAttribute)
                        {
                            writer.Write(GetCustomAttribute(imageDef, typeDef.customAttributeIndex, typeDef.token));
                        }
                        if (config.DumpAttribute && (typeDef.flags & TYPE_ATTRIBUTE_SERIALIZABLE) != 0)
                        {
                            writer.Write("[Serializable]\n");
                        }
                        var visibility = typeDef.flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
                        switch (visibility)
                        {
                        case TYPE_ATTRIBUTE_PUBLIC:
                        case TYPE_ATTRIBUTE_NESTED_PUBLIC:
                            writer.Write("public ");
                            break;

                        case TYPE_ATTRIBUTE_NOT_PUBLIC:
                        case TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM:
                        case TYPE_ATTRIBUTE_NESTED_ASSEMBLY:
                            writer.Write("internal ");
                            break;

                        case TYPE_ATTRIBUTE_NESTED_PRIVATE:
                            writer.Write("private ");
                            break;

                        case TYPE_ATTRIBUTE_NESTED_FAMILY:
                            writer.Write("protected ");
                            break;

                        case TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM:
                            writer.Write("protected internal ");
                            break;
                        }
                        if ((typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0 && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                        {
                            writer.Write("static ");
                        }
                        else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0)
                        {
                            writer.Write("abstract ");
                        }
                        else if (!typeDef.IsValueType && !typeDef.IsEnum && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                        {
                            writer.Write("sealed ");
                        }
                        if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0)
                        {
                            writer.Write("interface ");
                        }
                        else if (typeDef.IsEnum)
                        {
                            writer.Write("enum ");
                        }
                        else if (typeDef.IsValueType)
                        {
                            writer.Write("struct ");
                        }
                        else
                        {
                            writer.Write("class ");
                        }
                        var typeName = executor.GetTypeDefName(typeDef, false, true);
                        writer.Write($"{typeName}");
                        if (extends.Count > 0)
                        {
                            writer.Write($" : {string.Join(", ", extends)}");
                        }
                        if (config.DumpTypeDefIndex)
                        {
                            writer.Write($" // TypeDefIndex: {typeDefIndex}\n{{");
                        }
                        else
                        {
                            writer.Write("\n{");
                        }
                        //dump field
                        if (config.DumpField && typeDef.field_count > 0)
                        {
                            writer.Write("\n\t// Fields\n");
                            var fieldEnd = typeDef.fieldStart + typeDef.field_count;
                            for (var i = typeDef.fieldStart; i < fieldEnd; ++i)
                            {
                                var fieldDef  = metadata.fieldDefs[i];
                                var fieldType = il2Cpp.types[fieldDef.typeIndex];
                                var isStatic  = false;
                                var isConst   = false;
                                if (config.DumpAttribute)
                                {
                                    writer.Write(GetCustomAttribute(imageDef, fieldDef.customAttributeIndex, fieldDef.token, "\t"));
                                }
                                writer.Write("\t");
                                var access = fieldType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
                                switch (access)
                                {
                                case FIELD_ATTRIBUTE_PRIVATE:
                                    writer.Write("private ");
                                    break;

                                case FIELD_ATTRIBUTE_PUBLIC:
                                    writer.Write("public ");
                                    break;

                                case FIELD_ATTRIBUTE_FAMILY:
                                    writer.Write("protected ");
                                    break;

                                case FIELD_ATTRIBUTE_ASSEMBLY:
                                case FIELD_ATTRIBUTE_FAM_AND_ASSEM:
                                    writer.Write("internal ");
                                    break;

                                case FIELD_ATTRIBUTE_FAM_OR_ASSEM:
                                    writer.Write("protected internal ");
                                    break;
                                }
                                if ((fieldType.attrs & FIELD_ATTRIBUTE_LITERAL) != 0)
                                {
                                    isConst = true;
                                    writer.Write("const ");
                                }
                                else
                                {
                                    if ((fieldType.attrs & FIELD_ATTRIBUTE_STATIC) != 0)
                                    {
                                        isStatic = true;
                                        writer.Write("static ");
                                    }
                                    if ((fieldType.attrs & FIELD_ATTRIBUTE_INIT_ONLY) != 0)
                                    {
                                        writer.Write("readonly ");
                                    }
                                }
                                writer.Write($"{executor.GetTypeName(fieldType, false, false)} {metadata.GetStringFromIndex(fieldDef.nameIndex)}");
                                if (metadata.GetFieldDefaultValueFromIndex(i, out var fieldDefaultValue) && fieldDefaultValue.dataIndex != -1)
                                {
                                    if (TryGetDefaultValue(fieldDefaultValue.typeIndex, fieldDefaultValue.dataIndex, out var value))
                                    {
                                        writer.Write($" = ");
                                        if (value is string str)
                                        {
                                            writer.Write($"\"{str.ToEscapedString()}\"");
                                        }
                                        else if (value is char c)
                                        {
                                            var v = (int)c;
                                            writer.Write($"'\\x{v:x}'");
                                        }
                                        else if (value != null)
                                        {
                                            writer.Write($"{value}");
                                        }
                                    }
                                    else
                                    {
                                        writer.Write($" /*Metadata offset 0x{value:X}*/");
                                    }
                                }
                                if (config.DumpFieldOffset && !isConst)
                                {
                                    writer.Write("; // 0x{0:X}\n", il2Cpp.GetFieldOffsetFromIndex(typeDefIndex, i - typeDef.fieldStart, i, typeDef.IsValueType, isStatic));
                                }
                                else
                                {
                                    writer.Write(";\n");
                                }
                            }
                        }
                        //dump property
                        if (config.DumpProperty && typeDef.property_count > 0)
                        {
                            writer.Write("\n\t// Properties\n");
                            var propertyEnd = typeDef.propertyStart + typeDef.property_count;
                            for (var i = typeDef.propertyStart; i < propertyEnd; ++i)
                            {
                                var propertyDef = metadata.propertyDefs[i];
                                if (config.DumpAttribute)
                                {
                                    writer.Write(GetCustomAttribute(imageDef, propertyDef.customAttributeIndex, propertyDef.token, "\t"));
                                }
                                writer.Write("\t");
                                if (propertyDef.get >= 0)
                                {
                                    var methodDef = metadata.methodDefs[typeDef.methodStart + propertyDef.get];
                                    writer.Write(GetModifiers(methodDef));
                                    var propertyType = il2Cpp.types[methodDef.returnType];
                                    writer.Write($"{executor.GetTypeName(propertyType, false, false)} {metadata.GetStringFromIndex(propertyDef.nameIndex)} {{ ");
                                }
                                else if (propertyDef.set >= 0)
                                {
                                    var methodDef = metadata.methodDefs[typeDef.methodStart + propertyDef.set];
                                    writer.Write(GetModifiers(methodDef));
                                    var parameterDef = metadata.parameterDefs[methodDef.parameterStart];
                                    var propertyType = il2Cpp.types[parameterDef.typeIndex];
                                    writer.Write($"{executor.GetTypeName(propertyType, false, false)} {metadata.GetStringFromIndex(propertyDef.nameIndex)} {{ ");
                                }
                                if (propertyDef.get >= 0)
                                {
                                    writer.Write("get; ");
                                }
                                if (propertyDef.set >= 0)
                                {
                                    writer.Write("set; ");
                                }
                                writer.Write("}");
                                writer.Write("\n");
                            }
                        }
                        //dump method
                        if (config.DumpMethod && typeDef.method_count > 0)
                        {
                            writer.Write("\n\t// Methods\n");
                            var methodEnd = typeDef.methodStart + typeDef.method_count;
                            for (var i = typeDef.methodStart; i < methodEnd; ++i)
                            {
                                writer.Write("\n");
                                var methodDef = metadata.methodDefs[i];
                                if (config.DumpAttribute)
                                {
                                    writer.Write(GetCustomAttribute(imageDef, methodDef.customAttributeIndex, methodDef.token, "\t"));
                                }
                                if (config.DumpMethodOffset)
                                {
                                    var methodPointer = il2Cpp.GetMethodPointer(imageName, methodDef);
                                    if (methodPointer > 0)
                                    {
                                        var fixedMethodPointer = il2Cpp.GetRVA(methodPointer);
                                        writer.Write("\t// RVA: 0x{0:X} Offset: 0x{1:X} VA: 0x{2:X}", fixedMethodPointer, il2Cpp.MapVATR(methodPointer), methodPointer);
                                    }
                                    else
                                    {
                                        writer.Write("\t// RVA: -1 Offset: -1");
                                    }
                                    if (methodDef.slot != ushort.MaxValue)
                                    {
                                        writer.Write(" Slot: {0}", methodDef.slot);
                                    }
                                    writer.Write("\n");
                                }
                                writer.Write("\t");
                                writer.Write(GetModifiers(methodDef));
                                var methodReturnType = il2Cpp.types[methodDef.returnType];
                                var methodName       = metadata.GetStringFromIndex(methodDef.nameIndex);
                                if (methodDef.genericContainerIndex >= 0)
                                {
                                    var genericContainer = metadata.genericContainers[methodDef.genericContainerIndex];
                                    methodName += executor.GetGenericContainerParams(genericContainer);
                                }
                                if (methodReturnType.byref == 1)
                                {
                                    writer.Write("ref ");
                                }
                                writer.Write($"{executor.GetTypeName(methodReturnType, false, false)} {methodName}(");
                                var parameterStrs = new List <string>();
                                for (var j = 0; j < methodDef.parameterCount; ++j)
                                {
                                    var parameterStr      = "";
                                    var parameterDef      = metadata.parameterDefs[methodDef.parameterStart + j];
                                    var parameterName     = metadata.GetStringFromIndex(parameterDef.nameIndex);
                                    var parameterType     = il2Cpp.types[parameterDef.typeIndex];
                                    var parameterTypeName = executor.GetTypeName(parameterType, false, false);
                                    if (parameterType.byref == 1)
                                    {
                                        if ((parameterType.attrs & PARAM_ATTRIBUTE_OUT) != 0 && (parameterType.attrs & PARAM_ATTRIBUTE_IN) == 0)
                                        {
                                            parameterStr += "out ";
                                        }
                                        else if ((parameterType.attrs & PARAM_ATTRIBUTE_OUT) == 0 && (parameterType.attrs & PARAM_ATTRIBUTE_IN) != 0)
                                        {
                                            parameterStr += "in ";
                                        }
                                        else
                                        {
                                            parameterStr += "ref ";
                                        }
                                    }
                                    else
                                    {
                                        if ((parameterType.attrs & PARAM_ATTRIBUTE_IN) != 0)
                                        {
                                            parameterStr += "[In] ";
                                        }
                                        if ((parameterType.attrs & PARAM_ATTRIBUTE_OUT) != 0)
                                        {
                                            parameterStr += "[Out] ";
                                        }
                                    }
                                    parameterStr += $"{parameterTypeName} {parameterName}";
                                    if (metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j, out var parameterDefault) && parameterDefault.dataIndex != -1)
                                    {
                                        if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value))
                                        {
                                            parameterStr += " = ";
                                            if (value is string str)
                                            {
                                                parameterStr += $"\"{str.ToEscapedString()}\"";
                                            }
                                            else if (value is char c)
                                            {
                                                var v = (int)c;
                                                parameterStr += $"'\\x{v:x}'";
                                            }
                                            else if (value != null)
                                            {
                                                parameterStr += $"{value}";
                                            }
                                        }
                                        else
                                        {
                                            parameterStr += $" /*Metadata offset 0x{value:X}*/";
                                        }
                                    }
                                    parameterStrs.Add(parameterStr);
                                }
                                writer.Write(string.Join(", ", parameterStrs));
                                writer.Write(") { }\n");

                                if (il2Cpp.methodDefinitionMethodSpecs.TryGetValue(i, out var methodSpecs))
                                {
                                    writer.Write("\t/* GenericInstMethod :\n");
                                    var groups = methodSpecs.GroupBy(x => il2Cpp.methodSpecGenericMethodPointers[x]);
                                    foreach (var group in groups)
                                    {
                                        writer.Write("\t|\n");
                                        var genericMethodPointer = group.Key;
                                        if (genericMethodPointer > 0)
                                        {
                                            var fixedPointer = il2Cpp.GetRVA(genericMethodPointer);
                                            writer.Write($"\t|-RVA: 0x{fixedPointer:X} Offset: 0x{il2Cpp.MapVATR(genericMethodPointer):X} VA: 0x{genericMethodPointer:X}\n");
                                        }
                                        else
                                        {
                                            writer.Write("\t|-RVA: -1 Offset: -1\n");
                                        }
                                        foreach (var methodSpec in group)
                                        {
                                            (var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec);
                                            writer.Write($"\t|-{methodSpecTypeName}.{methodSpecMethodName}\n");
                                        }
                                    }
                                    writer.Write("\t*/\n");
                                }
                            }
                        }
                        writer.Write("}\n");
                    }
                }
                catch (Exception e)
                {
                    FormGUI.WriteLine("ERROR: Some errors in dumping");
                    writer.Write("/*");
                    writer.Write(e);
                    writer.Write("*/\n}\n");
                }
            }
            writer.Close();
        }
Exemple #20
0
        public virtual void Init(ulong codeRegistration, ulong metadataRegistration)
        {
            pCodeRegistration = MapVATR <Il2CppCodeRegistration>(codeRegistration);
            if (Version == 27)
            {
                if (pCodeRegistration.reversePInvokeWrapperCount > 0x30000) //TODO
                {
                    Version           = 27.1;
                    codeRegistration -= PointerSize;
                    FormGUI.Log($"Change il2cpp version to: {Version}");
                    FormGUI.Log("CodeRegistration : {0:x}", codeRegistration);
                    pCodeRegistration = MapVATR <Il2CppCodeRegistration>(codeRegistration);
                }
            }
            if (Version == 24.2)
            {
                if (pCodeRegistration.reversePInvokeWrapperCount > 0x30000) //TODO
                {
                    Version           = 24.4;
                    codeRegistration -= PointerSize * 3;
                    FormGUI.Log($"Change il2cpp version to: {Version}");
                    FormGUI.Log("CodeRegistration : {0:x}", codeRegistration);
                    pCodeRegistration = MapVATR <Il2CppCodeRegistration>(codeRegistration);
                }
                else
                {
                    if (pCodeRegistration.codeGenModules == 0) //TODO
                    {
                        Version = 24.3;
                        FormGUI.Log($"Change il2cpp version to: {Version}");
                        pCodeRegistration = MapVATR <Il2CppCodeRegistration>(codeRegistration);
                    }
                }
            }
            pMetadataRegistration = MapVATR <Il2CppMetadataRegistration>(metadataRegistration);
            genericMethodPointers = MapVATR <ulong>(pCodeRegistration.genericMethodPointers, pCodeRegistration.genericMethodPointersCount);
            invokerPointers       = MapVATR <ulong>(pCodeRegistration.invokerPointers, pCodeRegistration.invokerPointersCount);
            if (Version < 27)
            {
                customAttributeGenerators = MapVATR <ulong>(pCodeRegistration.customAttributeGenerators, pCodeRegistration.customAttributeCount);
            }
            if (Version > 16 && Version < 27)
            {
                metadataUsages = MapVATR <ulong>(pMetadataRegistration.metadataUsages, maxMetadataUsages);
            }
            if (Version >= 22)
            {
                if (pCodeRegistration.reversePInvokeWrapperCount != 0)
                {
                    reversePInvokeWrappers = MapVATR <ulong>(pCodeRegistration.reversePInvokeWrappers, pCodeRegistration.reversePInvokeWrapperCount);
                }
                if (pCodeRegistration.unresolvedVirtualCallCount != 0)
                {
                    unresolvedVirtualCallPointers = MapVATR <ulong>(pCodeRegistration.unresolvedVirtualCallPointers, pCodeRegistration.unresolvedVirtualCallCount);
                }
            }
            genericInstPointers     = MapVATR <ulong>(pMetadataRegistration.genericInsts, pMetadataRegistration.genericInstsCount);
            genericInsts            = Array.ConvertAll(genericInstPointers, MapVATR <Il2CppGenericInst>);
            fieldOffsetsArePointers = Version > 21;
            if (Version == 21)
            {
                var fieldTest = MapVATR <uint>(pMetadataRegistration.fieldOffsets, 6);
                fieldOffsetsArePointers = fieldTest[0] == 0 && fieldTest[1] == 0 && fieldTest[2] == 0 && fieldTest[3] == 0 && fieldTest[4] == 0 && fieldTest[5] > 0;
            }
            if (fieldOffsetsArePointers)
            {
                fieldOffsets = MapVATR <ulong>(pMetadataRegistration.fieldOffsets, pMetadataRegistration.fieldOffsetsCount);
            }
            else
            {
                fieldOffsets = Array.ConvertAll(MapVATR <uint>(pMetadataRegistration.fieldOffsets, pMetadataRegistration.fieldOffsetsCount), x => (ulong)x);
            }
            var pTypes = MapVATR <ulong>(pMetadataRegistration.types, pMetadataRegistration.typesCount);

            types = new Il2CppType[pMetadataRegistration.typesCount];
            for (var i = 0; i < pMetadataRegistration.typesCount; ++i)
            {
                types[i] = MapVATR <Il2CppType>(pTypes[i]);
                types[i].Init();
                typeDic.Add(pTypes[i], types[i]);
            }
            if (Version >= 24.2)
            {
                var pCodeGenModules = MapVATR <ulong>(pCodeRegistration.codeGenModules, pCodeRegistration.codeGenModulesCount);
                codeGenModules = new Dictionary <string, Il2CppCodeGenModule>(pCodeGenModules.Length, StringComparer.Ordinal);
                codeGenModuleMethodPointers = new Dictionary <string, ulong[]>(pCodeGenModules.Length, StringComparer.Ordinal);
                rgctxsDictionary            = new Dictionary <string, Dictionary <uint, Il2CppRGCTXDefinition[]> >(pCodeGenModules.Length, StringComparer.Ordinal);
                foreach (var pCodeGenModule in pCodeGenModules)
                {
                    var codeGenModule = MapVATR <Il2CppCodeGenModule>(pCodeGenModule);
                    var moduleName    = ReadStringToNull(MapVATR(codeGenModule.moduleName));
                    codeGenModules.Add(moduleName, codeGenModule);
                    ulong[] methodPointers;
                    try
                    {
                        methodPointers = MapVATR <ulong>(codeGenModule.methodPointers, codeGenModule.methodPointerCount);
                    }
                    catch
                    {
                        methodPointers = new ulong[codeGenModule.methodPointerCount];
                    }
                    codeGenModuleMethodPointers.Add(moduleName, methodPointers);

                    var rgctxsDefDictionary = new Dictionary <uint, Il2CppRGCTXDefinition[]>();
                    rgctxsDictionary.Add(moduleName, rgctxsDefDictionary);
                    if (codeGenModule.rgctxsCount > 0)
                    {
                        var rgctxs      = MapVATR <Il2CppRGCTXDefinition>(codeGenModule.rgctxs, codeGenModule.rgctxsCount);
                        var rgctxRanges = MapVATR <Il2CppTokenRangePair>(codeGenModule.rgctxRanges, codeGenModule.rgctxRangesCount);
                        foreach (var rgctxRange in rgctxRanges)
                        {
                            var rgctxDefs = new Il2CppRGCTXDefinition[rgctxRange.range.length];
                            Array.Copy(rgctxs, rgctxRange.range.start, rgctxDefs, 0, rgctxRange.range.length);
                            rgctxsDefDictionary.Add(rgctxRange.token, rgctxDefs);
                        }
                    }
                }
            }
            else
            {
                methodPointers = MapVATR <ulong>(pCodeRegistration.methodPointers, pCodeRegistration.methodPointersCount);
            }
            genericMethodTable = MapVATR <Il2CppGenericMethodFunctionsDefinitions>(pMetadataRegistration.genericMethodTable, pMetadataRegistration.genericMethodTableCount);
            methodSpecs        = MapVATR <Il2CppMethodSpec>(pMetadataRegistration.methodSpecs, pMetadataRegistration.methodSpecsCount);
            foreach (var table in genericMethodTable)
            {
                var methodSpec            = methodSpecs[table.genericMethodIndex];
                var methodDefinitionIndex = methodSpec.methodDefinitionIndex;
                if (!methodDefinitionMethodSpecs.TryGetValue(methodDefinitionIndex, out var list))
                {
                    list = new List <Il2CppMethodSpec>();
                    methodDefinitionMethodSpecs.Add(methodDefinitionIndex, list);
                }
                list.Add(methodSpec);
                methodSpecGenericMethodPointers.Add(methodSpec, genericMethodPointers[table.indices.methodIndex]);
            }
        }
Exemple #21
0
 public FormAbout(FormGUI Main)
 {
     main = Main;
 }