Commit Graph

609 Commits

Author SHA1 Message Date
Katy Coe
c7cd6cca43 Update README.md 2020-06-24 10:49:42 +02:00
Katy Coe
955bc2a9ac Tests: Update expected results 2020-06-24 10:38:34 +02:00
Katy Coe
418fb7221c Update .gitignore 2020-06-24 10:38:24 +02:00
Katy Coe
5b62a72897 Tests: Save generated C++ in TestCpp 2020-06-24 10:38:13 +02:00
Katy Coe
ec922ac9ec Tests: Add ARM64 binary generation 2020-06-24 09:17:18 +02:00
Katy Coe
181d3ad600 CS: Don't output redundant interfaces in type declarations 2020-06-22 22:56:26 +02:00
Katy Coe
42310483af CS: Fix "Namespace used like type" (CS0118) (needs additional work) 2020-06-22 22:35:52 +02:00
Katy Coe
ef22c6628b CS: Fix enumeration scoping on default field values (CS0103) 2020-06-22 18:38:16 +02:00
Katy Coe
2791721dd1 Model: Implement MethodBase.GetMethodBody() 2020-06-22 17:35:23 +02:00
Katy Coe
5f0360dc0a Update README.md 2020-06-22 17:18:39 +02:00
Katy Coe
9c51e72cc2 CS: Fix representation of Infinity and NaN 2020-06-20 21:26:29 +02:00
Katy Coe
e0fe7fa1b9 CS: Add unsafe modifier to struct constructors where necessary (CS0214) 2020-06-20 21:11:03 +02:00
Katy Coe
d479431585 Model: Add FieldInfo.RequiresUnsafeContext 2020-06-20 20:43:06 +02:00
Katy Coe
ed1d80aa15 CS: "unsafe" goes after "static" to avoid IntelliSense notice 2020-06-20 20:34:51 +02:00
Katy Coe
ca113fb055 CLI: Handle attempted output to directory that is file gracefully 2020-06-20 19:34:34 +02:00
Robert Xiao
44df54b639 Suppress new on operator methods.
Per the C# language reference
(https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/basic-concepts#hiding-through-inheritance):

> The rules governing operator declarations (Operators) make it
> impossible for a derived class to declare an operator with the same
> signature as an operator in a base class. Thus, operators never hide
> one another.

Therefore, new is not necessary or permitted on operators, even if the
method signatures are identical. This situation can arise if, for
example, an explicit conversion operator from the same target class
exists in both a base class and a derived class.
2020-06-20 10:17:48 +02:00
Robert Xiao
6fff363c29 Fix bugs in testcase #11 and CSharp3.
Bug #1 is that in 32-bit programs, typeDefinitionIndex might be
0xffff_ffff_ffff_ffff instead (32-bit -1 sign-extended to 64 bits), so
we fix that by simply masking to get the low 32 bits.

Bug #2 is that, if the TypeRef points to no generic instance, we return
null, which wasn't being checked for in the IDAPythonScript generator.
Since that's the only time we could get a null type in Types, we simply
remove nulls from the Types collection.
2020-06-20 10:17:48 +02:00
Robert Xiao
5354d39181 Code reformatting 2020-06-20 10:17:48 +02:00
Robert Xiao
4207464208 Add events, fields and properties to concrete generics.
This basically finishes the concrete generics implementation. We can now
enumerate all members of a concrete generic type with full type
substitution implemented.

Also add a simple test to verify that we can obtain the correct type for
a field of a concrete generic type.
2020-06-20 10:17:48 +02:00
Robert Xiao
1a12567227 Fix method signature comparison.
Now that we generate methods in instantiated generic types, we were
getting test failures from methods that were being detected as new
methods. In actuality, they weren't new, but they differed only in
generic type parameters from some base type method, and
GetSignatureString ignores generic parameters completely.

This fix eliminates the hacky GetSignatureString and replaces it with
more-or-less proper signature comparison. This even manages to fix an
incorrect test case from Methods.cs (because GetSignatureString was
incorrectly incorporating the return type - when the return type should
not be examined for signature checking).
2020-06-20 10:17:48 +02:00
Robert Xiao
652d76d6fe Implement constructors & methods on constructed generics.
We adopt roughly the same approach as the C# Reflection API: a
GenericMethodDefinition is a method which has no method parameters
substituted, but lives in a open or closed type with some or all
type parameters substituted. To ensure the uniqueness of the MethodInfo,
we cache by the method type arguments, and also cache generated
DeclaredConstructors/DeclaredMethods in the TypeInfo.

This also enables MakeGenericMethod, albeit in a slightly different form
than the Reflection API: MakeGenericMethod lives in MethodBase, so it's
callable from a constructor (even though in C# constructors cannot be
generic). This slight violation of the spec reduces code duplication, so
it's probably worth it.

Finally, VirtualAddress gets set when populating GenericMethods, and so
it'll work whether or not the methods get cached/generated ahead of
time.
2020-06-20 10:17:48 +02:00
Robert Xiao
867f559f18 Support BaseType and ImplementedInterfaces on generic params
This has been a little TODO for a while, and happily it's easy enough to
implement with TypeRef arrays.

Also implement ImplementedInterfaces for generic type instances via
substitution.
2020-06-20 10:17:48 +02:00
Robert Xiao
a36c93514d Implement NestedTypes for generic instances
In the C# reflection API, DeclaredNestedTypes on concrete generic types
just returns the nested types of the type definition. Notably, type
parameters are not substituted, because nested types are not guaranteed
to use the same containing type's type parameters.
2020-06-20 10:17:48 +02:00
Robert Xiao
6fb95c52da Only include GenericMethod definers in Types
Including *every* generated type in Types defeats the purpose of the
Types property, which is to list all types directly referred to by the
Il2Cpp metadata. Therefore, we return to the previous implementation:
only list types referred to by DefinitionIndex, ReferenceIndex, and
classIndexIndex.
2020-06-20 10:17:48 +02:00
Robert Xiao
f395ed3ff5 Send FromTypeReference back to Il2CppModel
Now that FromTypeReference uses public Make* methods instead of private
TypeInfo constructors, it doesn't need to be in TypeInfo anymore. Move
it back to Il2CppModel, where it was before.
2020-06-20 10:17:48 +02:00
Robert Xiao
1970879e52 Implement proper generic parameter substitution
With this patch, generic parameters in BaseType and method param/return
types are substituted correctly and deeply. Next up will be to apply the
same substitution rules to fields, properties, events, ...
2020-06-20 10:17:48 +02:00
Robert Xiao
202a802274 Fix ContainsGenericParameters and IsGenericMethodDefinition
IsGenericMethodDefinition needs the same treatment as
IsGenericTypeDefinition, i.e. it should depend on whether the class is a
definition as opposed to merely checking if the type args are generic
parameters (which could happen in a partially specialized method).

Also, array/ref/pointer types of generic types are considered to have
generic parameters, so correct ContainsGenericParameters accordingly.
2020-06-20 10:17:48 +02:00
Robert Xiao
ec6018d012 Add non-generic methods to TestGenerics
In order to select the correct generic type, model.GetGenericMethod is
changed to use Name (which includes generic parameters) instead of
BaseName. The tests for GenericMethodDefinitionInGenericClass* are also
changed to reflect the fact that the chosen methods are fully concrete.

TestGenerics now passes in its entirety.
2020-06-20 10:17:48 +02:00
Robert Xiao
c73aad08b8 Add non-generic methods in generic types to GenericMethods
GenericMethods should contain all MethodSpec-referenced methods,
including those which are non-generic methods inside generic types. This
patch adds those methods, and also implements parameter substitution for
type arguments in parameters & return types.
2020-06-20 10:17:48 +02:00
Robert Xiao
50ea6dac36 Dedup param, array and byref/pointer types
We're aiming to make TypeInfo instances unique - no two TypeInfo
instances within a given model should refer to the same type. This will
allow us to use simple reference equality for comparing types.
2020-06-20 10:17:48 +02:00
Robert Xiao
193cdcdc4a Get rid of TypesByMethodSpecClassIndex.
classIndexIndex only indexes the genericInstance, not the actual generic
instance type. Therefore, for example, A<Int32,Int32> and B<Int32,Int32>
have the same classIndexIndex because the generic parameters are the
same, despite being otherwise unrelated.

Instead of TypesByMethodSpecClassIndex, we simply call MakeGenericType
each time, relying on genericTypeInstances to dedup the resulting
instances. This patch thus also adds all of the types from
genericTypeInstances to the Il2CppModel.Types listing.
2020-06-20 10:17:48 +02:00
Robert Xiao
a9f6e7b4e0 Generify reference indices to prepare for generic instances
We use indices into the TypesByReferenceIndex table to defer type lookup
during model construction. However, this won't support fully generic
instances (which might not be in the type table at all). This patch
introduces a new TypeRef abstraction which can either represent a fixed
index or an instantiated generic type.
2020-06-20 10:17:48 +02:00
Robert Xiao
3cd5af09fc Have TestRunner output IDA scripts too
This is done as a sanity check to make sure we aren't breaking IDA output.
2020-06-20 10:17:48 +02:00
Robert Xiao
ab5fc836a1 Introduce a cache for generic type instantiations.
Also add MakeGenericType, which creates type instances from a generic
type definition and arguments. We will use this later to build properly
fleshed out concrete generic types.
2020-06-20 10:17:48 +02:00
Robert Xiao
648840c714 Add generic type definition to list of type references 2020-06-20 10:17:48 +02:00
Robert Xiao
2c164aec02 Change generic params/args to arrays
The C# functions for GetGenericParameters/GetGenericArguments use
Type[], not lists, so we should conform to that.

Also fix the definition of IsGenericTypeDefinition - because it's
possible for a class to be instantiated with all generic parameters.
2020-06-20 10:17:48 +02:00
Robert Xiao
996fb1ff36 Avoid recreating ref'd types that already exist
Because TypesByReferenceIndex can be populated in two places
(Il2CppModel constructor and GetTypeFromVirtualAddress), we need to
avoid generating the same type multiple times.
2020-06-20 10:17:48 +02:00
Robert Xiao
71bf353ae0 Remove ResolveGenericArguments(int) entirely
It's not really needed anymore, and it is clearer without that method.
2020-06-20 10:17:48 +02:00
Robert Xiao
f0124d9290 Remove index from BaseType, DeclaringType
All types will need to eventually be fully generic. Therefore, we need
to eliminate indices when referring to types, and also be very lazy when
accessing TypeInfo properties so that we don't access uninitialized
types during model creation.
2020-06-20 10:17:48 +02:00
Robert Xiao
6ddb502e96 Refactor TypeInfo names and fix out/in
Replace the deeply nested ternaries in TypeInfo with if-statements for
clarity.
Remove in/out from CSharpName, keeping it only on immediate type params
in CSharpTypeDeclarationName (refactored to a method).
Rearrange name-related properties and methods to group them all together
into a region for easier navigation.
2020-06-20 10:17:48 +02:00
Robert Xiao
7797ac2506 Refactor TypeInfo constructors
This patch replaces Il2CppModel.resolveTypeReference by a static
TypeInfo constructor, and simultaneously refactors the TypeInfo
constructors to eliminate duplication between resolveTypeReference and
the original constructors. This will make future refactoring much
easier.
2020-06-20 10:17:48 +02:00
Robert Xiao
dfabe9235d Use CollectionAssert for better test feedback.
For minor problems with the test output (e.g. one-line changes),
CollectionAssert.AreEqual will show the exact line which is changed, for
much better test feedback.
2020-06-20 10:17:48 +02:00
Robert Xiao
d2b5f9d48b Enable test parallelization for a nice speedup 2020-06-20 10:17:48 +02:00
Katy Coe
e2f42bd137 Tests: Update expected results 2020-06-19 14:57:37 +02:00
Robert Xiao
1c1f542107 Tests: Add new test assemblies for C# features (#36)
* Add new test assemblies for C# features

Three of these test assemblies go over several important features of C#,
organized by C# language version. PartialGenericTypes stresses closed
and partially closed generics. Finally, VTablesAndLayout tests the
layout of classes when translated to C++, and also contains code which
calls vtable and interface functions to test reverse engineering.

* Tests: Update .csproj

* Tests: Update .csproj

Co-authored-by: Katy Coe <djkaty@users.noreply.github.com>
2020-06-19 14:52:09 +02:00
Katy Coe
ce4d2792b8 Update README.md 2020-06-18 17:12:12 +02:00
Katy Coe
f79d4b7aad Update README.md 2020-06-18 16:52:01 +02:00
Katy Coe
d38620a7d7 GUI: Add support for opening APK and IPA package files 2020-06-18 16:45:32 +02:00
Katy Coe
5bcce0ca0a CLI: Allow -i to accept APK or IPA package files 2020-06-18 16:44:31 +02:00
Katy Coe
5baf8cdc2d IL2CPP: Add APK and IPA package extraction API
Add LoadFromStream, LoadFromPackage, GetStreamsFromPackage
2020-06-18 16:43:48 +02:00