-
Notifications
You must be signed in to change notification settings - Fork 587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why don't CreateGenericInstMethodSig #551
Comments
This is not a bug. |
Do you mean we can use |
Why do you think the MethodBase existing in reflection must be used as the operand of call? For whatever reason, there is a MethodBase which declaring type that is instantiated but the method itself does not get instantiated. It also cannot be used as the call operand in reflection. Why import as MethodSpec in this case? #466 has undergone very strict testing to ensure that objects existing in reflection can be mapped to dnlib objects with equivalent semantics. You can retrieve test cases in this PR. It covers all GAC assemblies and very complex generic nested cases that I constructed manually, which includes the situation you mentioned. foreach (var method in moduleDef.Enumerate<MemberRef>(t => t.IsMethodRef).Cast<IMethod>().Concat(moduleDef.Enumerate<MethodSpec>()).Concat(moduleDef.Enumerate<MethodDef>())) |
@wwh1004 class My<T>
{
public static void Test()
{
Activator.CreateInstance<T>();
}
} |
This is a MethodSpec :-) |
Yes, but your code import it as MethodDef/MemberRef |
I can't get this operand in reflection if I don't provide closed types. |
I made an example, your code import a generic method as MemberRef, old dnlib work fine: |
It is not a valid dynamic method. If you invoke it, you will get "InvalidProgramException: Common Language Runtime detected an invalid program". In this case, it is inherently invalid so dnlib is not required to give a valid output. |
You should check "FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig, Object *resolver)" in coreclr's runtimehandles.cpp. It just copy method body from managed side to unmanaged side. You can even fill in any invalid bytes in DynamicILInfo and GetMethodDescriptor will not throw an exception until you actually compile the method. |
Let's asssume we want to make an unpacker for a DynamicMethod obfusction, we don't have instantiated generic type, every method is like this, we can't support instantiated type in our unpacker : |
I think this question is off topic. If you do not pass the required generic parameters, the dynamic method is incomplete and invalid, whcih cannot be compiled by the JIT compiler. Then dnlib does not need support it. As my last comment said, you can populate any invalid code via DynamicILInfo. How does dnlib give correct import results when the code is invalid? Your example does not mean that the MethodSpec containing open generic arguments that can be represented in System.Reflection api. |
Don't agree, |
Then your needs are not related to the original topic. Why does dnlib create a MethodSpec when there are no generic method arguments? |
Many protectors based on DynamicMethod will encrypt all methods like this, so how can we make unpacker for those? Do you think we must support correct generic types for all methods? class My1<T, U> where T : new()
{
public static void Test()
{
new DynamicMethod("", typeof(void), Type.EmptyTypes).Invoke(null, null);
}
}
class My2<T, U> where T : Stream, ICloneable
{
public static void Test()
{
new DynamicMethod("", typeof(void), Type.EmptyTypes).Invoke(null, null);
}
}
class My3<T, U> where T : My1<int, T>
{
public static void Test()
{
new DynamicMethod("", typeof(void), Type.EmptyTypes).Invoke(null, null);
}
} |
I still don't know why does dnlib should create a MethodSpec when there are no generic method arguments. Assume that GTYPE is a type containing gp and GMETHOD is a method containing gp in GTYPE. |
Since |
By the way, we can't use instantiated type for decryption purpose, otherwise DynamicMethodBodyReader will generate instantiated type also, eg: class My<T>
{
public static void Test()
{
Activator.CreateInstance<int>(); // DynamicMethodHelper.ConvertFrom(typeof(My<int>).GetMethod("Test"))
}
} We should and must use uninstantiated type. |
@wwh1004 As you said, the imported result here can't be an operand, so how can we use the result? Where can this imported result appeared? |
I think our point of disagreement is whether the behavior of the existence of open generic parameters for instantiated generic |
var m = typeof(GTYPE).MakeGenericType(typeof(int)).GetMethod("GMETHOD"); |
I viewed AsmResolver, it uses |
@wwh1004 This issue isn't the only issue, seems these 2 PR #452 #466 have serious bugs. Another example: class My<T>
{
public static void Test()
{
Do();
}
public static void Do()
{
}
} I don't know why do you change |
I don't think the lack of support for importing an invalid method body is a serious bug. You can send a PR to fix it instead arguing whether this is a bug or not. |
A System.Type: So: Solution:
@wtfsck How do you think? |
…tion, with unpredictable problems) Fix 0xd4d#551
dnlib/src/DotNet/Importer.cs
Lines 490 to 491 in 0b2dc95
This code is from #466 by @wwh1004
@wtfsck @wwh1004 Is it buggy? Why don't CreateGenericInstMethodSig here?
The text was updated successfully, but these errors were encountered: