Jump to content
Tuts 4 You

How to use valuetype in dnlib in order to insert Console.ReadKey()


BreakShoot

Recommended Posts

I am using the dnlib and I want to insert Console.ReadKey() at the end of the Console.WriteLines in another executable.

 

Note I am extremely new to dnlib and wish to learn more about it.

The code below partly works. Though the issue is. It produces the MSIL:

IL_0028: call void [mscorlib]System.Console::ReadKey()

When I want it to produce

IL_015a: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()

Code

            ModuleDefMD mod = ModuleDefMD.Load(args[0]);
            ModuleDef mode = new ModuleDefUser(args[0]);
            Importer importer = new Importer(mod);
            AssemblyDef asmr = mod.Assembly;
            foreach (TypeDef type in mod.GetTypes())
            {
                foreach (MethodDef Method in type.Methods)
                {

                    if (Method.Name == "Main")
                    {

                        TypeRef consoleRef = new TypeRefUser(mod, "System", "Console", mod.CorLibTypes.AssemblyRef);
                        MemberRef ReadAll = new MemberRefUser(mod, "ReadKey",
                                    MethodSig.CreateStatic(mod.CorLibTypes.Void),
                                    consoleRef);

                        var method = Method;
                        var instructions = method.Body.Instructions;
                        instructions.Insert(8, new Instruction(OpCodes.Call, ReadAll));
                    }

                }
            }
Link to comment
1 hour ago, XenocodeRCE said:

instructions.Insert(8, new Instruction(OpCodes.Call, mod.Import(typeof(System.ConsoleKeyInfo).GetMethod("ReadKey")));

Throws  Instruction operand is null

Link to comment
15 hours ago, XenocodeRCE said:

instructions.Insert(8, new Instruction(OpCodes.Call, mod.Import(typeof(System.ConsoleKeyInfo).GetMethod("ReadKey")));

LOL! :lol::D"ReadKey" is from System.Console not from System.ConsoleKeyInfo.
Proper code:
instructions.Insert(8, new Instruction(OpCodes.Call, mod.Import(typeof(System.Console).GetMethod("ReadKey")));

XenocodeRCE: the (source) code is the one who give error (I presume).
 

  • Like 1
  • Thanks 1
  • Haha 1
Link to comment
8 minutes ago, CodeCracker said:

LOL! :lol::D"ReadKey" is from System.Console not from System.ConsoleKeyInfo.
Proper code:
instructions.Insert(8, new Instruction(OpCodes.Call, mod.Import(typeof(System.Console).GetMethod("ReadKey")));

XenocodeRCE: the (source) code is the one who give error (I presume).

Thanks for helping! 

I will test this when I return home. Hopefully will work. 

XenocodeRCE:

The target file is a file that contains a few 

Console.WriteLine("random string"); in Main method.

You drag it in, and boom the output file doesn't immediately close when opening (ie, ReadKey). Anyways the program using dnlib was crashing on  mod.Write. And when I ignored errors and compiled anyways; DnSpy failed to decompile it.

Link to comment
1 hour ago, CodeCracker said:

LOL! :lol::D"ReadKey" is from System.Console not from System.ConsoleKeyInfo.
Proper code:
instructions.Insert(8, new Instruction(OpCodes.Call, mod.Import(typeof(System.Console).GetMethod("ReadKey")));

XenocodeRCE: the (source) code is the one who give error (I presume).
 

 

I misread his first message then because look : http://i.imgur.com/WXaxSsS.png

 

  • Like 1
Link to comment

When you don't know how something is done, just take dnlib's source and search for the appropriate keyword. In this case - search for "valuetype".

Fixed @BreakShoot's code:

            ModuleDefMD mod = ModuleDefMD.Load(args[0]);
            Importer importer = new Importer(mod);
            AssemblyDef asmr = mod.Assembly;
            foreach (TypeDef type in mod.GetTypes())
            {
                foreach (MethodDef Method in type.Methods)
                {
                    if (Method.Name == "Main")
                    {
                        TypeRef cki = new TypeRefUser(mod, "System", "ConsoleKeyInfo", mod.CorLibTypes.AssemblyRef);
                        TypeRef consoleRef = new TypeRefUser(mod, "System", "Console", mod.CorLibTypes.AssemblyRef);
                        MemberRef ReadAll = new MemberRefUser(mod, "ReadKey",
                                    MethodSig.CreateStatic(new ValueTypeSig(cki)),
                                    consoleRef);
                        var method = Method;
                        var instructions = method.Body.Instructions;
                        instructions.Insert(instructions.Count - 1, new Instruction(OpCodes.Call, ReadAll));
                        instructions.Insert(instructions.Count - 1, new Instruction(OpCodes.Pop));
                    }

                }
            }
            // Save the assembly to a file on disk
            mod.Write(args[1]);

End result:

    IL_000c:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
    IL_0011:  pop

 

Link to comment

I think you must add AssemblyResolver.

var moduleContext = new ModuleContext();
var asmResolver = new AssemblyResolver(moduleContext, true);
var resolver = new Resolver(asmResolver);
moduleContext.AssemblyResolver = asmResolver;
moduleContext.Resolver = resolver;
ModuleDefMD moduleDefMd = ModuleDefMD.Load(@"C:\File.exe", moduleContext);

foreach (TypeDef typeDef in moduleDefMd.GetTypes())
{
}

 

 

 

 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...