-
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
dnlib x64 exhausts all memory when read method body. #442
Comments
Can you paste the IL code? Could be a switch instruction. |
I don't have time to investigate at the moment. Let me know if you find something. I'd 'nop' out instructions, save, and check if x64 version still allocs too much memory. Eventually we'd know which instruction it is, probably one of those with a token operand (eg. offset |
its metadata is invalid. bp at line 'if (!reader.TryReadCompressedUInt32(out uint numParams))' |
@wwh1004 You are one step ahead of me. |
Since it throws, I assume that the signature is big too? What's the size of the signature blob? (see line 389 in SignatureReader.cs) |
@wtfsck This file is really broken file. |
No, it's better to detect it some other way. Limiting it to 0xFFFF or any other value will probably cause dnlib to fail to read real assemblies. |
Seems .NET use |
OK, I misunderstood you, thinking you were referring to blob size. 0xFFFF would be too small. It's true that you can only index up to 0xFFFF args and locals but I'm not sure what .NET (Core/Framework) will do if it finds a locals sig with more than 0xFFFF locals or a method with more than 0xFFFF args. It will probably throw an exception, in which case dnlib could also fail. Will have to check the source code later. |
@wtfsck Seems should limit more, such as: |
There are several places that allocate. AFAIK, the CLR has no generic param limit which means dnlib can't have any as well. |
I make a test:
When compile the output file Test.cs, C# compiler(VBCSCompiler.exe) will crash(IndexOutOfRangeException) when greater than 32768 exactly |
That's a limitation of the C# compiler, not the runtime. IIRC, the runtime has no such limit, but if you find one let me know. |
But the first parameter of |
readerModule.BlobStream.StreamLeng == 90696 ,is not very large, it's strange dnlib dont occur exception when no data can read, dnlib read so many data but still don't end of the stream? |
Yes but it doesn't mean the runtime will throw or report an error if the signature has > 0x10000 generic arguments. Have you tested this? If the runtime doesn't do anything and the code just runs, we need to support it too. |
Yes, I test it, when run the output var module = new ModuleDefUser("Test.exe");
new AssemblyDefUser("Test").Modules.Add(module);
module.Kind = ModuleKind.Console;
var type = new TypeDefUser("Program", module.CorLibTypes.Object.TypeDefOrRef);
var method = new MethodDefUser("Main", MethodSig.CreateStatic(module.CorLibTypes.Void), MethodAttributes.Public | MethodAttributes.Static);
module.EntryPoint = method;
method.Body = new CilBody();
var instrs = method.Body.Instructions;
var generic = new TypeDefUser("Generic", module.CorLibTypes.Object.TypeDefOrRef);
int max = 65536;
for (int i = 0; i < max; i++) {
ushort number = (ushort)i;
generic.GenericParameters.Add(new GenericParamUser(number, GenericParamAttributes.NonVariant, "T" + i));
}
module.Types.Add(generic);
instrs.Add(OpCodes.Ldtoken.ToInstruction(generic));
instrs.Add(OpCodes.Call.ToInstruction(new MemberRefUser(module, "GetTypeFromHandle", MethodSig.CreateStatic(new ClassSig(module.CorLibTypes.GetTypeRef("System", "Type")), new ValueTypeSig(module.CorLibTypes.GetTypeRef("System", "RuntimeTypeHandle"))), module.CorLibTypes.GetTypeRef("System", "Type"))));
instrs.Add(OpCodes.Call.ToInstruction(new MemberRefUser(module, "WriteLine", MethodSig.CreateStatic(module.CorLibTypes.Void, module.CorLibTypes.Object), module.CorLibTypes.GetTypeRef("System", "Console"))));
instrs.Add(OpCodes.Call.ToInstruction(new MemberRefUser(module, "ReadLine", MethodSig.CreateStatic(module.CorLibTypes.String), module.CorLibTypes.GetTypeRef("System", "Console"))));
instrs.Add(OpCodes.Ret.ToInstruction());
method.DeclaringType = type;
module.Types.Add(type);
module.Write("Test.exe");
Console.WriteLine("OK");
Console.ReadKey(); |
EDIT: .NET (Core) seems to have the same error message |
What happens if you change this code: dnlib/src/DotNet/MD/BlobStream.cs Lines 48 to 51 in 63a06e6
to return an empty |
Very well, it can resolve this issue even if no limitation for big number. |
Limitation for big number is still required when I enumerates all methods for this file |
Some code that could be updated:
Should return an empty reader here if method call fails dnlib/src/DotNet/MD/BlobStream.cs Lines 48 to 51 in 63a06e6
I think that will solve this issue. I don't have time to write the code at the moment, but send a PR if you want to fix one or more of the things listed above. |
@wtfsck If something else can not be limited, you can delete the argument new List<int>( |
@CreateAndInject Adding a |
test.zip
The text was updated successfully, but these errors were encountered: