初始化提交

This commit is contained in:
Perfare 2016-12-31 02:33:34 +08:00
parent 8bde61638d
commit ef9e9de713
14 changed files with 1656 additions and 0 deletions

63
.gitattributes vendored Normal file
View file

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

242
.gitignore vendored Normal file
View file

@ -0,0 +1,242 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Xx]64/
[Xx]86/
[Bb]uild/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Un-comment the next line if you do not want to checkin
# your web deploy settings because they may include unencrypted
# passwords
#*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# LightSwitch generated files
GeneratedArtifacts/
ModelManifest.xml
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/

22
Il2CppDumper.sln Normal file
View file

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Il2CppDumper", "Il2CppDumper\Il2CppDumper.csproj", "{379715D4-4B7B-41F2-B78A-8B18D86320E2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{379715D4-4B7B-41F2-B78A-8B18D86320E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{379715D4-4B7B-41F2-B78A-8B18D86320E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{379715D4-4B7B-41F2-B78A-8B18D86320E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{379715D4-4B7B-41F2-B78A-8B18D86320E2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,20 @@
internal static class DefineConstants
{
public const int FIELD_ATTRIBUTE_PRIVATE = 0x0001;
public const int FIELD_ATTRIBUTE_PUBLIC = 0x0006;
public const int FIELD_ATTRIBUTE_STATIC = 0x0010;
public const int FIELD_ATTRIBUTE_INIT_ONLY = 0x0020;
public const int METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK = 0x0007;
public const int METHOD_ATTRIBUTE_PRIVATE = 0x0001;
public const int METHOD_ATTRIBUTE_PUBLIC = 0x0006;
public const int METHOD_ATTRIBUTE_STATIC = 0x0010;
public const int METHOD_ATTRIBUTE_VIRTUAL = 0x0040;
public const int TYPE_ATTRIBUTE_VISIBILITY_MASK = 0x00000007;
public const int TYPE_ATTRIBUTE_PUBLIC = 0x00000001;
public const int TYPE_ATTRIBUTE_INTERFACE = 0x00000020;
public const int TYPE_ATTRIBUTE_ABSTRACT = 0x00000080;
public const int TYPE_ATTRIBUTE_SEALED = 0x00000100;
public const int TYPE_ATTRIBUTE_SERIALIZABLE = 0x00002000;
public const int PARAM_ATTRIBUTE_OUT = 0x0002;
public const int PARAM_ATTRIBUTE_OPTIONAL = 0x0010;
}

130
Il2CppDumper/Elf.cs Normal file
View file

@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Il2CppDumper
{
class Elf : MyBinaryReader
{
public elf_header elf_header;
public Dictionary<string, elf_32_shdr> sectionWithName;
List<elf_32_shdr> sections;
public Elf(Stream stream) : base(stream)
{
elf_header = new elf_header();
elf_header.m_dwFormat = ReadUInt32();
if (elf_header.m_dwFormat != 0x464c457f)
{
throw new Exception("ERROR: il2cpp lib provided is not a valid ELF file.");
}
elf_header.m_arch = ReadByte();
elf_header.m_endian = ReadByte();
elf_header.m_version = ReadByte();
elf_header.m_osabi = ReadByte();
elf_header.m_osabi_ver = ReadByte();
elf_header.e_pad = ReadBytes(7);
elf_header.e_type = ReadUInt16();
elf_header.e_machine = ReadUInt16();
elf_header.e_version = ReadUInt32();
if (elf_header.m_arch == 1)//32
{
elf_header.e_entry = ReadUInt32();
elf_header.e_phoff = ReadUInt32();
elf_header.e_shoff = ReadUInt32();
elf_header.e_flags = ReadUInt32();
elf_header.e_ehsize = ReadUInt16();
elf_header.e_phentsize = ReadUInt16();
elf_header.e_phnum = ReadUInt16();
elf_header.e_shentsize = ReadUInt16();
elf_header.e_shnum = ReadUInt16();
elf_header.e_shtrndx = ReadUInt16();
}
else//64
{
elf_header.e_entry = ReadUInt64();
elf_header.e_phoff = ReadUInt64();
elf_header.e_shoff = ReadUInt64();
elf_header.e_flags = ReadUInt32();
elf_header.e_ehsize = ReadUInt16();
elf_header.e_phentsize = ReadUInt16();
elf_header.e_phnum = ReadUInt16();
elf_header.e_shentsize = ReadUInt16();
elf_header.e_shnum = ReadUInt16();
elf_header.e_shtrndx = ReadUInt16();
}
GetSectionWithName();
}
private void GetSectionWithName()
{
try
{
var section_name_block_off = (int)elf_header.e_shoff + (elf_header.e_shentsize * elf_header.e_shtrndx);
if (elf_header.m_arch == 1)//32
{
Position = section_name_block_off + 2 * 4 + 4 + 4;
section_name_block_off = ReadInt32();
}
else//Hmm...
{
Position = section_name_block_off + 2 * 4 + 8 + 8;
section_name_block_off = ReadInt32();
}
var sectionWithNametmp = new Dictionary<string, elf_32_shdr>();
var sectionstmp = new List<elf_32_shdr>();
for (int i = 0; i < elf_header.e_shnum; i++)
{
var section = GetSection(i);
sectionWithNametmp.Add(ReadStringToNull(section_name_block_off + section.sh_name), section);
sectionstmp.Add(section);
}
sectionWithName = sectionWithNametmp;
sections = sectionstmp;
}
catch
{
Console.WriteLine("ERROR: Unable to get section.");
}
}
private elf_32_shdr GetSection(int iSection)
{
return ReadClass<elf_32_shdr>((int)elf_header.e_shoff + (elf_header.e_shentsize * iSection));
}
public uint MapVATR(uint uiAddr)
{
if (sections == null)
return uiAddr;
elf_32_shdr pFirstSec = sections[0];
if (uiAddr < pFirstSec.sh_addr)
return 0;
for (int i = 1; i < elf_header.e_shnum; ++i)
{
elf_32_shdr pSection = sections[i];
if (pSection.sh_addr > uiAddr)
{
elf_32_shdr pRetSec = sections[i - 1];
uint uiResOffset = uiAddr - pRetSec.sh_addr;
return pRetSec.sh_offset + uiResOffset;
}
}
elf_32_shdr pRetSec2 = sections[elf_header.e_shnum - 1];
uint uiResOffset2 = uiAddr - pRetSec2.sh_addr;
return pRetSec2.sh_offset + uiResOffset2;
}
public T MapVATR<T>(uint uiAddr) where T : new()
{
return ReadClass<T>(MapVATR(uiAddr));
}
public T[] MapVATR<T>(uint uiAddr, int count) where T : new()
{
return ReadClassArray<T>(MapVATR(uiAddr), count);
}
}
}

71
Il2CppDumper/ElfClass.cs Normal file
View file

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Il2CppDumper
{
class elf_header
{
// 0x7f followed by ELF in ascii
public uint m_dwFormat;
// 1 - 32 bit
// 2 - 64 bit
public byte m_arch;
// 1 - little endian
// 2 - big endian
public byte m_endian;
// 1 is original elf format
public byte m_version;
// set based on OS, refer to OSABI enum
public byte m_osabi;
// refer to elf documentation
public byte m_osabi_ver;
// unused
public byte[] e_pad;//byte[7]
// 1 - relocatable
// 2 - executable
// 3 - shared
// 4 - core
public ushort e_type;
// refer to isa enum
public ushort e_machine;
public uint e_version;
//全部定义为64位
public ulong e_entry;
public ulong e_phoff;
public ulong e_shoff;
public uint e_flags;
public ushort e_ehsize;
public ushort e_phentsize;
public ushort e_phnum;
public ushort e_shentsize;
public ushort e_shnum;
public ushort e_shtrndx;
}
class elf_32_shdr
{
public uint sh_name;
public uint sh_type;
public uint sh_flags;
public uint sh_addr;
public uint sh_offset;
public uint sh_size;
public uint sh_link;
public uint sh_info;
public uint sh_addralign;
public uint sh_entsize;
}
}

118
Il2CppDumper/Il2Cpp.cs Normal file
View file

@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Il2CppDumper
{
class Il2Cpp : Elf
{
Il2CppMetadataRegistration pMetadataRegistration;
public Il2CppCodeRegistration pCodeRegistration;
public Il2Cpp(Stream stream) : base(stream)
{
if (!Auto())
{
throw new Exception("ERROR: Unable to process file automatically, try to use manual mode.");
}
}
public Il2Cpp(Stream stream, uint codeRegistration, uint metadataRegistration) : base(stream)
{
Init(codeRegistration, metadataRegistration);
}
private void Init(uint codeRegistration, uint metadataRegistration)
{
pCodeRegistration = MapVATR<Il2CppCodeRegistration>(codeRegistration);
pMetadataRegistration = MapVATR<Il2CppMetadataRegistration>(metadataRegistration);
pCodeRegistration.methodPointers = MapVATR<uint>(pCodeRegistration.pmethodPointers, (int)pCodeRegistration.methodPointersCount);
pMetadataRegistration.fieldOffsets = MapVATR<int>(pMetadataRegistration.pfieldOffsets, pMetadataRegistration.fieldOffsetsCount);
var types = MapVATR<uint>(pMetadataRegistration.ptypes, pMetadataRegistration.typesCount);
pMetadataRegistration.types = new Il2CppType[pMetadataRegistration.typesCount];
for (int i = 0; i < pMetadataRegistration.typesCount; ++i)
{
pMetadataRegistration.types[i] = MapVATR<Il2CppType>(types[i]);
pMetadataRegistration.types[i].Init();
}
}
public Il2CppType GetTypeFromTypeIndex(int idx)
{
return pMetadataRegistration.types[idx];
}
public int GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType)
{
var ptr = pMetadataRegistration.fieldOffsets[typeIndex];
Position = ptr + 4 * fieldIndexInType;
return ReadInt32();
}
public bool Auto()
{
if (sectionWithName != null)
{
var bytes = new byte[] { 0x1c, 0x0, 0x9f, 0xe5, 0x1c, 0x10, 0x9f, 0xe5, 0x1c, 0x20, 0x9f, 0xe5 };
//判断必要的section是否都在
if (sectionWithName.ContainsKey(".got") && sectionWithName.ContainsKey(".init_array") && sectionWithName.ContainsKey(".dynamic"))
{
var dynamic = sectionWithName[".dynamic"];
var got = sectionWithName[".got"];
//从.dynamic获取_GLOBAL_OFFSET_TABLE_
uint _GLOBAL_OFFSET_TABLE_ = 0;
Position = dynamic.sh_offset;
var dynamicend = dynamic.sh_offset + dynamic.sh_size;
var gotend = got.sh_offset + got.sh_size;
while (Position < dynamicend)
{
var tag = ReadInt32();
if (tag == 3)
{
var tmp = ReadUInt32();
if (tmp >= got.sh_offset && tmp <= gotend)
{
_GLOBAL_OFFSET_TABLE_ = tmp;
break;
}
}
Position += 4;
}
//从.init_array获取函数
var init_array = sectionWithName[".init_array"];
var addrs = ReadClassArray<uint>(init_array.sh_offset, (int)init_array.sh_size / 4);
foreach (var i in addrs)
{
if (i != 0)
{
Position = i;
var buff = ReadBytes(12);
if (bytes.SequenceEqual(buff))
{
Position = i + 0x2c;
var subaddr = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
Position = subaddr + 0x28;
var codeRegistration = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
Position = subaddr + 0x2C;
var ptr = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
Position = MapVATR(ptr);
var metadataRegistration = ReadUInt32();
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
Init(codeRegistration, metadataRegistration);
return true;
}
}
}
}
else
{
Console.WriteLine("ERROR: The necessary section is missing.");
}
}
return false;
}
}
}

208
Il2CppDumper/Il2CppClass.cs Normal file
View file

@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Il2CppDumper
{
public class Il2CppCodeRegistration
{
public uint methodPointersCount;
public uint pmethodPointers;
public uint delegateWrappersFromNativeToManagedCount;
public uint delegateWrappersFromNativeToManaged; // note the double indirection to handle different calling conventions
public uint delegateWrappersFromManagedToNativeCount;
public uint delegateWrappersFromManagedToNative;
public uint marshalingFunctionsCount;
public uint marshalingFunctions;
public uint ccwMarshalingFunctionsCount;
public uint ccwMarshalingFunctions;
public uint genericMethodPointersCount;
public uint genericMethodPointers;
public uint invokerPointersCount;
public uint invokerPointers;
public int customAttributeCount;
public uint customAttributeGenerators;
public int guidCount;
public uint guids; // Il2CppGuid
public uint[] methodPointers
{
get; set;
}
}
class Il2CppMetadataRegistration
{
public int genericClassesCount;
public uint genericClasses;
public int genericInstsCount;
public uint genericInsts;
public int genericMethodTableCount;
public uint genericMethodTable; // Il2CppGenericMethodFunctionsDefinitions
public int typesCount;
public uint ptypes;
public int methodSpecsCount;
public uint methodSpecs;
public int fieldOffsetsCount;
public uint pfieldOffsets;
public int typeDefinitionsSizesCount;
public uint typeDefinitionsSizes;
public uint metadataUsagesCount;
public uint metadataUsages;
public int[] fieldOffsets
{
get; set;
}
public Il2CppType[] types
{
get; set;
}
}
public enum Il2CppTypeEnum
{
IL2CPP_TYPE_END = 0x00, /* End of List */
IL2CPP_TYPE_VOID = 0x01,
IL2CPP_TYPE_BOOLEAN = 0x02,
IL2CPP_TYPE_CHAR = 0x03,
IL2CPP_TYPE_I1 = 0x04,
IL2CPP_TYPE_U1 = 0x05,
IL2CPP_TYPE_I2 = 0x06,
IL2CPP_TYPE_U2 = 0x07,
IL2CPP_TYPE_I4 = 0x08,
IL2CPP_TYPE_U4 = 0x09,
IL2CPP_TYPE_I8 = 0x0a,
IL2CPP_TYPE_U8 = 0x0b,
IL2CPP_TYPE_R4 = 0x0c,
IL2CPP_TYPE_R8 = 0x0d,
IL2CPP_TYPE_STRING = 0x0e,
IL2CPP_TYPE_PTR = 0x0f, /* arg: <type> token */
IL2CPP_TYPE_BYREF = 0x10, /* arg: <type> token */
IL2CPP_TYPE_VALUETYPE = 0x11, /* arg: <type> token */
IL2CPP_TYPE_CLASS = 0x12, /* arg: <type> token */
IL2CPP_TYPE_VAR = 0x13, /* Generic parameter in a generic type definition, represented as number (compressed unsigned integer) number */
IL2CPP_TYPE_ARRAY = 0x14, /* type, rank, boundsCount, bound1, loCount, lo1 */
IL2CPP_TYPE_GENERICINST = 0x15, /* <type> <type-arg-count> <type-1> \x{2026} <type-n> */
IL2CPP_TYPE_TYPEDBYREF = 0x16,
IL2CPP_TYPE_I = 0x18,
IL2CPP_TYPE_U = 0x19,
IL2CPP_TYPE_FNPTR = 0x1b, /* arg: full method signature */
IL2CPP_TYPE_OBJECT = 0x1c,
IL2CPP_TYPE_SZARRAY = 0x1d, /* 0-based one-dim-array */
IL2CPP_TYPE_MVAR = 0x1e, /* Generic parameter in a generic method definition, represented as number (compressed unsigned integer) */
IL2CPP_TYPE_CMOD_REQD = 0x1f, /* arg: typedef or typeref token */
IL2CPP_TYPE_CMOD_OPT = 0x20, /* optional arg: typedef or typref token */
IL2CPP_TYPE_INTERNAL = 0x21, /* CLR internal type */
IL2CPP_TYPE_MODIFIER = 0x40, /* Or with the following types */
IL2CPP_TYPE_SENTINEL = 0x41, /* Sentinel for varargs method signature */
IL2CPP_TYPE_PINNED = 0x45, /* Local var that points to pinned object */
IL2CPP_TYPE_ENUM = 0x55 /* an enumeration */
}
public class Il2CppType
{
public uint datapoint;
public Anonymous data { get; set; }
public uint bits;
public uint attrs { get; set; }
public Il2CppTypeEnum type { get; set; }
public uint num_mods { get; set; }
public uint byref { get; set; }
public uint pinned { get; set; }
public void Init()
{
var str = System.Convert.ToString(bits, 2);
if (str.Length != 32)
{
str = new string(Enumerable.Repeat('0', 32 - str.Length).Concat(str.ToCharArray()).ToArray());
}
attrs = Convert.ToUInt32(str.Substring(16, 16), 2);
type = (Il2CppTypeEnum)Convert.ToInt32(str.Substring(8, 8), 2);
num_mods = Convert.ToUInt32(str.Substring(2, 6), 2);
byref = Convert.ToUInt32(str.Substring(1, 1), 2);
pinned = Convert.ToUInt32(str.Substring(0, 1), 2);
data = new Anonymous() { dummy = datapoint };
}
public class Anonymous
{
public uint dummy;
public int klassIndex
{
get
{
return (int)dummy;
}
}
public uint type
{
get
{
return dummy;
}
}
public uint array
{
get
{
return dummy;
}
}
public int genericParameterIndex
{
get
{
return (int)dummy;
}
}
public uint generic_class
{
get
{
return dummy;
}
}
}
}
public class Il2CppGenericClass
{
public int typeDefinitionIndex; /* the generic type definition */
public Il2CppGenericContext context; /* a context that contains the type instantiation doesn't contain any method instantiation */
public uint cached_class; /* if present, the Il2CppClass corresponding to the instantiation. */
}
public class Il2CppGenericContext
{
/* The instantiation corresponding to the class generic parameters */
public uint class_inst;
/* The instantiation corresponding to the method generic parameters */
public uint method_inst;
}
public class Il2CppGenericInst
{
public uint type_argc;
public uint type_argv;
}
public class Il2CppArrayType
{
public uint etype;
public byte rank;
public byte numsizes;
public byte numlobounds;
public uint sizes;
public uint lobounds;
}
}

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{379715D4-4B7B-41F2-B78A-8B18D86320E2}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Il2CppDumper</RootNamespace>
<AssemblyName>Il2CppDumper</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DefineConstants.cs" />
<Compile Include="Elf.cs" />
<Compile Include="ElfClass.cs" />
<Compile Include="Il2Cpp.cs" />
<Compile Include="Il2CppClass.cs" />
<Compile Include="Metadata.cs" />
<Compile Include="MetadataClass.cs" />
<Compile Include="MyBinaryReader.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

85
Il2CppDumper/Metadata.cs Normal file
View file

@ -0,0 +1,85 @@
using System;
using System.IO;
using System.Linq;
namespace Il2CppDumper
{
class Metadata : MyBinaryReader
{
Il2CppGlobalMetadataHeader pMetadataHdr;
public int uiImageCount;
public int uiNumTypes;
public Il2CppImageDefinition[] imageDefs;
public Il2CppTypeDefinition[] typeDefs;
public Il2CppMethodDefinition[] methodDefs;
public Il2CppParameterDefinition[] parameterDefs;
public Il2CppFieldDefinition[] fieldDefs;
public Il2CppFieldDefaultValue[] fieldDefaultValues;
public Metadata(Stream stream) : base(stream)
{
pMetadataHdr = ReadClass<Il2CppGlobalMetadataHeader>();
if (pMetadataHdr.sanity != 0xFAB11BAF)
{
throw new Exception("ERROR: Metadata file supplied is not valid metadata file.");
}
if (pMetadataHdr.version != 21 && pMetadataHdr.version != 22)
{
throw new Exception($"ERROR: Metadata file supplied is not a supported version[{pMetadataHdr.version}].");
}
uiImageCount = pMetadataHdr.imagesCount / MySizeOf(typeof(Il2CppImageDefinition));
uiNumTypes = pMetadataHdr.typeDefinitionsCount / MySizeOf(typeof(Il2CppTypeDefinition));
imageDefs = ReadClassArray<Il2CppImageDefinition>(pMetadataHdr.imagesOffset, uiImageCount);
//GetTypeDefFromIndex
typeDefs = ReadClassArray<Il2CppTypeDefinition>(pMetadataHdr.typeDefinitionsOffset, uiNumTypes);
//GetMethodDefinition
methodDefs = ReadClassArray<Il2CppMethodDefinition>(pMetadataHdr.methodsOffset, pMetadataHdr.methodsCount / MySizeOf(typeof(Il2CppMethodDefinition)));
//GetParameterFromIndex
parameterDefs = ReadClassArray<Il2CppParameterDefinition>(pMetadataHdr.parametersOffset, pMetadataHdr.parametersCount / MySizeOf(typeof(Il2CppParameterDefinition)));
//GetFieldDefFromIndex
fieldDefs = ReadClassArray<Il2CppFieldDefinition>(pMetadataHdr.fieldsOffset, pMetadataHdr.fieldsCount / MySizeOf(typeof(Il2CppFieldDefinition)));
//GetFieldDefaultFromIndex
fieldDefaultValues = ReadClassArray<Il2CppFieldDefaultValue>(pMetadataHdr.fieldDefaultValuesOffset, pMetadataHdr.fieldDefaultValuesCount / MySizeOf(typeof(Il2CppFieldDefaultValue)));
}
public Il2CppFieldDefaultValue GetFieldDefaultFromIndex(int idx)
{
return fieldDefaultValues.FirstOrDefault(x => x.fieldIndex == idx);
}
public int GetDefaultValueFromIndex(int idx)
{
return pMetadataHdr.fieldAndParameterDefaultValueDataOffset + idx;
}
public string GetString(int idx)
{
return ReadStringToNull(pMetadataHdr.stringOffset + idx);
}
private int MySizeOf(Type type)
{
int size = 0;
foreach (var i in type.GetFields())
{
if (i.FieldType == typeof(int))
{
size += 4;
}
else if (i.FieldType == typeof(uint))
{
size += 4;
}
else if (i.FieldType == typeof(short))
{
size += 2;
}
else if (i.FieldType == typeof(ushort))
{
size += 2;
}
}
return size;
}
}
}

View file

@ -0,0 +1,180 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Il2CppDumper
{
class Il2CppGlobalMetadataHeader
{
public uint sanity;
public int version;
public int stringLiteralOffset; // string data for managed code
public int stringLiteralCount;
public int stringLiteralDataOffset;
public int stringLiteralDataCount;
public int stringOffset; // string data for metadata
public int stringCount;
public int eventsOffset; // Il2CppEventDefinition
public int eventsCount;
public int propertiesOffset; // Il2CppPropertyDefinition
public int propertiesCount;
public int methodsOffset; // Il2CppMethodDefinition
public int methodsCount;
public int parameterDefaultValuesOffset; // Il2CppParameterDefaultValue
public int parameterDefaultValuesCount;
public int fieldDefaultValuesOffset; // Il2CppFieldDefaultValue
public int fieldDefaultValuesCount;
public int fieldAndParameterDefaultValueDataOffset; // uint8_t
public int fieldAndParameterDefaultValueDataCount;
public int fieldMarshaledSizesOffset; // Il2CppFieldMarshaledSize
public int fieldMarshaledSizesCount;
public int parametersOffset; // Il2CppParameterDefinition
public int parametersCount;
public int fieldsOffset; // Il2CppFieldDefinition
public int fieldsCount;
public int genericParametersOffset; // Il2CppGenericParameter
public int genericParametersCount;
public int genericParameterConstraintsOffset; // TypeIndex
public int genericParameterConstraintsCount;
public int genericContainersOffset; // Il2CppGenericContainer
public int genericContainersCount;
public int nestedTypesOffset; // TypeDefinitionIndex
public int nestedTypesCount;
public int interfacesOffset; // TypeIndex
public int interfacesCount;
public int vtableMethodsOffset; // EncodedMethodIndex
public int vtableMethodsCount;
public int interfaceOffsetsOffset; // Il2CppInterfaceOffsetPair
public int interfaceOffsetsCount;
public int typeDefinitionsOffset; // Il2CppTypeDefinition
public int typeDefinitionsCount;
public int rgctxEntriesOffset; // Il2CppRGCTXDefinition
public int rgctxEntriesCount;
public int imagesOffset; // Il2CppImageDefinition
public int imagesCount;
public int assembliesOffset; // Il2CppAssemblyDefinition
public int assembliesCount;
public int metadataUsageListsOffset; // Il2CppMetadataUsageList
public int metadataUsageListsCount;
public int metadataUsagePairsOffset; // Il2CppMetadataUsagePair
public int metadataUsagePairsCount;
public int fieldRefsOffset; // Il2CppFieldRef
public int fieldRefsCount;
public int referencedAssembliesOffset; // int
public int referencedAssembliesCount;
public int attributesInfoOffset; // Il2CppCustomAttributeTypeRange
public int attributesInfoCount;
public int attributeTypesOffset; // TypeIndex
public int attributeTypesCount;
}
class Il2CppImageDefinition
{
public int nameIndex;
public int assemblyIndex;
public int typeStart;
public uint typeCount;
public int entryPointIndex;
public uint token;
}
public class Il2CppTypeDefinition
{
public int nameIndex;
public int namespaceIndex;
public int customAttributeIndex;
public int byvalTypeIndex;
public int byrefTypeIndex;
public int declaringTypeIndex;
public int parentIndex;
public int elementTypeIndex; // we can probably remove this one. Only used for enums
public int rgctxStartIndex;
public int rgctxCount;
public int genericContainerIndex;
public int delegateWrapperFromManagedToNativeIndex;
public int marshalingFunctionsIndex;
public int ccwFunctionIndex;
public int guidIndex;
public uint flags;
public int fieldStart;
public int methodStart;
public int eventStart;
public int propertyStart;
public int nestedTypesStart;
public int interfacesStart;
public int vtableStart;
public int interfaceOffsetsStart;
public ushort method_count;
public ushort property_count;
public ushort field_count;
public ushort event_count;
public ushort nested_type_count;
public ushort vtable_count;
public ushort interfaces_count;
public ushort interface_offsets_count;
// bitfield to portably encode boolean values as single bits
// 01 - valuetype;
// 02 - enumtype;
// 03 - has_finalize;
// 04 - has_cctor;
// 05 - is_blittable;
// 06 - is_import;
// 07-10 - One of nine possible PackingSize values (0, 1, 2, 4, 8, 16, 32, 64, or 128)
public uint bitfield;
public uint token;
}
public class Il2CppMethodDefinition
{
public int nameIndex;
public int declaringType;
public int returnType;
public int parameterStart;
public int customAttributeIndex;
public int genericContainerIndex;
public int methodIndex;
public int invokerIndex;
public int delegateWrapperIndex;
public int rgctxStartIndex;
public int rgctxCount;
public uint token;
public ushort flags;
public ushort iflags;
public ushort slot;
public ushort parameterCount;
}
public class Il2CppParameterDefinition
{
public int nameIndex;
public uint token;
public int customAttributeIndex;
public int typeIndex;
}
public class Il2CppFieldDefinition
{
public int nameIndex;
public int typeIndex;
public int customAttributeIndex;
public uint token;
}
public class Il2CppFieldDefaultValue
{
public int fieldIndex;
public int typeIndex;
public int dataIndex;
}
}

View file

@ -0,0 +1,139 @@
using System;
using System.IO;
namespace Il2CppDumper
{
class MyBinaryReader : BinaryReader
{
public MyBinaryReader(Stream stream) : base(stream) { }
public long Position
{
get
{
return BaseStream.Position;
}
set
{
BaseStream.Position = value;
}
}
public T ReadClass<T>(long addr) where T : new()
{
BaseStream.Position = addr;
return ReadClass<T>();
}
public T ReadClass<T>() where T : new()
{
var type = typeof(T);
if (type.IsPrimitive)
{
if (type == typeof(int))
{
return (T)(object)ReadInt32();
}
else if (type == typeof(uint))
{
return (T)(object)ReadUInt32();
}
else
{
return default(T);
}
}
else
{
T t = new T();
foreach (var i in t.GetType().GetFields())
{
if (i.FieldType == typeof(int))
{
i.SetValue(t, ReadInt32());
}
else if (i.FieldType == typeof(uint))
{
i.SetValue(t, ReadUInt32());
}
else if (i.FieldType == typeof(short))
{
i.SetValue(t, ReadInt16());
}
else if (i.FieldType == typeof(ushort))
{
i.SetValue(t, ReadUInt16());
}
else if (i.FieldType == typeof(byte))
{
i.SetValue(t, ReadByte());
}
else
{
var mi = GetType().GetMethod("ReadClass", Type.EmptyTypes);
var mi2 = mi.MakeGenericMethod(i.FieldType);
var o = mi2.Invoke(this, null);
i.SetValue(t, o);
}
}
return t;
}
}
public T[] ReadClassArray<T>(long addr, int count) where T : new()
{
BaseStream.Position = addr;
var type = typeof(T);
if (type.IsPrimitive)
{
if (type == typeof(int))
{
int[] t = new int[count];
for (int i = 0; i < count; i++)
{
t[i] = ReadInt32();
}
return t as T[];
}
else if (type == typeof(uint))
{
uint[] t = new uint[count];
for (int i = 0; i < count; i++)
{
t[i] = ReadUInt32();
}
return t as T[];
}
else
{
return null;
}
}
else
{
T[] t = new T[count];
for (int i = 0; i < count; i++)
{
t[i] = ReadClass<T>();
}
return t;
}
}
public string ReadStringToNull(long addr)
{
BaseStream.Position = addr;
string result = "";
char c;
for (int i = 0; i < base.BaseStream.Length; i++)
{
if ((c = (char)base.ReadByte()) == 0)
{
break;
}
result += c.ToString();
}
return result;
}
}
}

279
Il2CppDumper/Program.cs Normal file
View file

@ -0,0 +1,279 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Il2CppDumper
{
class Program
{
static Metadata metadata;
static Il2Cpp il2cpp;
static void Main(string[] args)
{
Console.WriteLine("Select Mode: 1. Manual 2.Auto");
var key = Console.ReadKey(true);
try
{
if (key.KeyChar == '2')
{
metadata = new Metadata(new MemoryStream(File.ReadAllBytes("global-metadata.dat")));
il2cpp = new Il2Cpp(new MemoryStream(File.ReadAllBytes("libil2cpp.so")));
}
else if (key.KeyChar == '1')
{
Console.Write("Input CodeRegistration(R0): ");
var codeRegistration = Convert.ToUInt32(Console.ReadLine(), 16);
Console.Write("Input MetadataRegistration(R1): ");
var metadataRegistration = Convert.ToUInt32(Console.ReadLine(), 16);
metadata = new Metadata(new MemoryStream(File.ReadAllBytes("global-metadata.dat")));
il2cpp = new Il2Cpp(new MemoryStream(File.ReadAllBytes("libil2cpp.so")), codeRegistration, metadataRegistration);
}
else
{
return;
}
var writer = new StreamWriter(new FileStream("dump.cs", FileMode.Create));
Console.WriteLine("Dumping...");
//dump_image();
for (int imageIndex = 0; imageIndex < metadata.uiImageCount; imageIndex++)
{
var imageDef = metadata.imageDefs[imageIndex];
writer.Write($"// Image {imageIndex}: {metadata.GetString(imageDef.nameIndex)} - {imageDef.typeStart}\n");
}
for (int idx = 0; idx < metadata.uiNumTypes; ++idx)
{
//dump_class(i);
var typeDef = metadata.typeDefs[idx];
writer.Write($"// Namespace: {metadata.GetString(typeDef.namespaceIndex)}\n");
if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_SERIALIZABLE) != 0)
writer.Write("[Serializable]\n");
if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_VISIBILITY_MASK) == DefineConstants.TYPE_ATTRIBUTE_PUBLIC)
writer.Write("public ");
if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_ABSTRACT) != 0)
writer.Write("abstract ");
if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_SEALED) != 0)
writer.Write("sealed ");
if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_INTERFACE) != 0)
writer.Write("interface ");
else
writer.Write("class ");
writer.Write($"{metadata.GetString(typeDef.nameIndex)} // TypeDefIndex: {idx}\n{{\n");
writer.Write("\t// Fields\n");
var fieldEnd = typeDef.fieldStart + typeDef.field_count;
for (int i = typeDef.fieldStart; i < fieldEnd; ++i)
{
//dump_field(i, idx, i - typeDef.fieldStart);
var pField = metadata.fieldDefs[i];
var pType = il2cpp.GetTypeFromTypeIndex(pField.typeIndex);
var pDefault = metadata.GetFieldDefaultFromIndex(i);
writer.Write("\t");
if ((pType.attrs & DefineConstants.FIELD_ATTRIBUTE_PRIVATE) == DefineConstants.FIELD_ATTRIBUTE_PRIVATE)
writer.Write("private ");
if ((pType.attrs & DefineConstants.FIELD_ATTRIBUTE_PUBLIC) == DefineConstants.FIELD_ATTRIBUTE_PUBLIC)
writer.Write("public ");
if ((pType.attrs & DefineConstants.FIELD_ATTRIBUTE_STATIC) != 0)
writer.Write("static ");
if ((pType.attrs & DefineConstants.FIELD_ATTRIBUTE_INIT_ONLY) != 0)
writer.Write("readonly ");
writer.Write($"{get_type_name(pType)} {metadata.GetString(pField.nameIndex)}");
if (pDefault != null && pDefault.dataIndex != -1)
{
var pointer = metadata.GetDefaultValueFromIndex(pDefault.dataIndex);
Il2CppType pTypeToUse = il2cpp.GetTypeFromTypeIndex(pDefault.typeIndex);
if (pointer > 0)
{
metadata.Position = pointer;
object multi = null;
switch (pTypeToUse.type)
{
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
multi = metadata.ReadBoolean();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_U1:
case Il2CppTypeEnum.IL2CPP_TYPE_I1:
multi = metadata.ReadByte();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
multi = metadata.ReadChar();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
multi = metadata.ReadUInt16();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_I2:
multi = metadata.ReadInt16();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
multi = metadata.ReadUInt32();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
multi = metadata.ReadInt32();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
multi = metadata.ReadUInt64();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
multi = metadata.ReadInt64();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
multi = metadata.ReadSingle();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
multi = metadata.ReadDouble();
break;
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
var uiLen = metadata.ReadInt32();
multi = Encoding.UTF8.GetString(metadata.ReadBytes(uiLen));
break;
}
if (multi is string)
writer.Write($" = \"{multi}\"");
else if (multi != null)
writer.Write($" = {multi}");
}
}
writer.Write("; // 0x{0:x}\n", il2cpp.GetFieldOffsetFromIndex(idx, i - typeDef.fieldStart));
}
writer.Write("\t// Methods\n");
var methodEnd = typeDef.methodStart + typeDef.method_count;
for (int i = typeDef.methodStart; i < methodEnd; ++i)
{
//dump_method(i);
var methodDef = metadata.methodDefs[i];
writer.Write("\t");
Il2CppType pReturnType = il2cpp.GetTypeFromTypeIndex(methodDef.returnType);
if ((methodDef.flags & DefineConstants.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == DefineConstants.METHOD_ATTRIBUTE_PRIVATE)
writer.Write("private ");
if ((methodDef.flags & DefineConstants.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == DefineConstants.METHOD_ATTRIBUTE_PUBLIC)
writer.Write("public ");
if ((methodDef.flags & DefineConstants.METHOD_ATTRIBUTE_VIRTUAL) != 0)
writer.Write("virtual ");
if ((methodDef.flags & DefineConstants.METHOD_ATTRIBUTE_STATIC) != 0)
writer.Write("static ");
writer.Write($"{get_type_name(pReturnType)} {metadata.GetString(methodDef.nameIndex)}(");
for (int j = 0; j < methodDef.parameterCount; ++j)
{
Il2CppParameterDefinition pParam = metadata.parameterDefs[methodDef.parameterStart + j];
string szParamName = metadata.GetString(pParam.nameIndex);
Il2CppType pType = il2cpp.GetTypeFromTypeIndex(pParam.typeIndex);
string szTypeName = get_type_name(pType);
if ((pType.attrs & DefineConstants.PARAM_ATTRIBUTE_OPTIONAL) != 0)
writer.Write("optional ");
if ((pType.attrs & DefineConstants.PARAM_ATTRIBUTE_OUT) != 0)
writer.Write("out ");
if (j != methodDef.parameterCount - 1)
{
writer.Write($"{szTypeName} {szParamName}, ");
}
else
{
writer.Write($"{szTypeName} {szParamName}");
}
}
if (methodDef.methodIndex >= 0)
writer.Write("); // {0:x} - {1}\n", il2cpp.pCodeRegistration.methodPointers[methodDef.methodIndex], methodDef.methodIndex);
else
writer.Write("); // 0 - -1\n");
}
writer.Write("}\n");
}
writer.Close();
Console.WriteLine("Done !");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
}
private static string get_type_name(Il2CppType pType)
{
string ret;
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_CLASS || pType.type == Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE)
{
Il2CppTypeDefinition klass = metadata.typeDefs[pType.data.klassIndex];
ret = metadata.GetString(klass.nameIndex);
}
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST)
{
Il2CppGenericClass generic_class = il2cpp.MapVATR<Il2CppGenericClass>(pType.data.generic_class);
Il2CppTypeDefinition pMainDef = metadata.typeDefs[generic_class.typeDefinitionIndex];
ret = metadata.GetString(pMainDef.nameIndex);
var typeNames = new List<string>();
Il2CppGenericInst pInst = il2cpp.MapVATR<Il2CppGenericInst>(generic_class.context.class_inst);
var pointers = il2cpp.MapVATR<uint>(pInst.type_argv, (int)pInst.type_argc);
for (int i = 0; i < pInst.type_argc; ++i)
{
var pOriType = il2cpp.MapVATR<Il2CppType>(pointers[i]);
pOriType.Init();
typeNames.Add(get_type_name(pOriType));
}
ret += $"<{string.Join(", ", typeNames)}>";
}
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_ARRAY)
{
Il2CppArrayType arrayType = il2cpp.MapVATR<Il2CppArrayType>(pType.data.array);
var type = il2cpp.MapVATR<Il2CppType>(arrayType.etype);
type.Init();
ret = $"{get_type_name(type)}[]";
}
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY)
{
var type = il2cpp.MapVATR<Il2CppType>(pType.data.type);
type.Init();
ret = $"{get_type_name(type)}[]";
}
else
{
if ((int)pType.type >= szTypeString.Length)
ret = "unknow";
else
ret = szTypeString[(int)pType.type];
}
return ret;
}
static string[] szTypeString =
{
"END",
"void",
"bool",
"char",
"sbyte",
"byte",
"short",
"ushort",
"int",
"uint",
"long",
"ulong",
"float",
"double",
"string",
"PTR",//eg. void*
"BYREF",
"VALUETYPE",
"CLASS",
"T",
"ARRAY",
"GENERICINST",
"TYPEDBYREF",
"None",
"IntPtr",
"UIntPtr",
"None",
"FNPTR",
"object",
"SZARRAY",
"T",
"CMOD_REQD",
"CMOD_OPT",
"INTERNAL",
};
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Il2CppDumper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Il2CppDumper")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//将 ComVisible 设置为 false 将使此程序集中的类型
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("379715d4-4b7b-41f2-b78a-8b18d86320e2")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]