Injecting and modifying C# executable - c#

I would like to ask if it is possible to somehow inject C# code to an existing *.exe file that is also written in C# without decompiling it.
In other words, I'm trying to make an "extension" to an already existing C# program, but I would like to modify it without any manipulation with the "base" code (the .*exe file).
Is there any way to accomplish this? Or is the decompilation process required to modify base code's methods, classes and/or add extensions to it, etc. ?

you can achieve it by using frameworks like Mono.Cecil or Microsoft CCI project. These frameworks allows you to read & modify/inject IL. But it's not easy to learn those frameworks and IL codes usage.
Thought there's a library available FluentIL which is build on top of Mono.Cecil provides C# wrapper for IL Code. It doesn't Decompile the assembly rather it loads it, inject the assembly can writes/generates a new one with injected code.
Here's a sample that I used to inject "Null Checking code" in methods where arguments are marked with [NotNull] in project assembly post compilation.
var assembly = AssemblyDefinition.ReadAssembly(SourceAssemblyPath);
var module = assembly.MainModule;
var q = from type in module.Types
from method in type.Methods
from parameter in method.Parameters
where parameter.HasCustomAttributes
from attribute in parameter.CustomAttributes
where attribute.AttributeType.FullName == NotNullAttribute.FullName
select new { Method = method, Parameter = parameter };
foreach (var item in q)
{
item.Method.InsertBefore()
.Ldarg(item.Parameter.Name)
.IfNull()
.Throw<ArgumentNullException>()
.EndIf();
}
SourceAssemblyPath = SourceAssemblyPath.Replace("\\debug\\", "\\release\\");
assembly.Write(SourceAssemblyPath, new WriterParameters { WriteSymbols = false });

Related

Good approach to determine the PEFileKind of an assembly?

In C# or VB.NET, I would like to know which would be the best approach to determine the PEFileKinds of an assembly loaded through Reflection. In other words, determine whether an assembly is a WinExe, Console application, or a Dynamic link library.
I found this solution (the other proposed solutions in that question are not effective), but If I'm not wrong I think it implies to assume that the file loaded is a .NET assembly, and, seems a little bit tidy to manually parse the PE header.
I also found this other solution but reading the comments it seem not effective in some circumstances.
For those reasons, I wonder if exists a truly safe, managed way, preferably through Reflection, to determine the PE file kind of a loaded assembly.
I'm sure the System.Reflection.Emit.PEFileKinds enumeration does not exists only for decorative purposes, if that enum exists then its logic to think that there could be a member/function that I missed inside the Reflection namespaces that internally use that enum to return the PE file kind of a Assembly object, however, I managed to look at the private members of the Assembly class through Reflection and other related classes and I found nothing relevant.
According to a search of the reference source, the PEFileKinds enum is only used in AssemblyBuilder and ModuleBuilder (and the non-public helper types for them). This enum and the classes are found in the System.Reflection.Emit namespace - e.g., they're intended for writing assemblies, not reading.
However, the official System.Reflection.Metadata NuGet package exposes the relevant values of an assembly's PE header in its System.Reflection.PortableExecutable namespace. You can use these headers to reverse engineer the equivalent PEFileKinds value. Here's an example in C#:
using (var stream = File.OpenRead(filenameAndExtension))
{
using (var peFile = new PEReader(stream))
{
var headers = peFile.PEHeaders;
Console.WriteLine($"Reading {filenameAndExtension} with System.Reflection.Metadata");
Console.WriteLine($" IsDll: {headers.IsDll}");
Console.WriteLine($" IsExe: {headers.IsExe}");
Console.WriteLine($" IsConsoleApplication: {headers.IsConsoleApplication}");
PEFileKinds reverseEngineeredKind;
// NOTE: the header values cause IsConsoleApplication to return
// true for DLLs, so we need to check IsDll first
if (headers.IsDll)
{
reverseEngineeredKind = PEFileKinds.Dll;
}
else if (headers.IsConsoleApplication)
{
reverseEngineeredKind = PEFileKinds.ConsoleApplication;
}
else
{
reverseEngineeredKind = PEFileKinds.WindowApplication;
}
Console.WriteLine($" Reverse-engineered kind: {reverseEngineeredKind}");
}
}
I ran this code on assemblies I generated with System.Reflection.Emit to ensure its accuracy. The full program is in this gist.
You can probably also get this information with third-party libraries, like Mono.Cecil or, as Lex Li mentioned, PeNet.

Is there a LINQ Query Provider for querying C# files?

Is there such a thing as a LINQ Query Provider for querying C# files?
I have a Winforms app that I use to assist me in generating code as well as to supplement Visual Studio's editing capabilities for existing code. One thing I would like to be able to do is to query a given class to see if a method exists. Or query for a list of classes, or query for classes with a particular type in the method signature, etc.
Further, I would love to be able to run the usual CRUDs on said C# files, but I realize that this may be out of scope for this question.
SOLVED!
Thanks to the folks who suggested Roslyn, and especially thanks to the code sample provided by Konrad Kokosa below, I was able to get exactly what I needed.
First thing you need to do is download the Roslyn DLLs (I used NuGet). Then query away. Here is another example for getting an alphabetized list of all methods in a class:
static List<string> GetMethodList(string filename, string className)
{
var syntaxTree = SyntaxTree.ParseFile(filename);
var root = syntaxTree.GetRoot();
var #class = root.DescendantNodes().OfType<ClassDeclarationSyntax>().FirstOrDefault(md => md.Identifier.ValueText.Equals(className));
return (List<string>) #class.DescendantNodes().OfType<MethodDeclarationSyntax>().ToList().OrderBy(m => m.Identifier.ValueText).Select(m => m.Identifier.ValueText);
}
I've found Roslyn very intuitive. Here is an example of parsing source file for a specified methodName within specified class className:
static void GetClassMethod(string filename, string className, string methodName)
{
var syntaxTree = SyntaxTree.ParseFile(filename);
var root = syntaxTree.GetRoot();
var #class = root.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.Where(md => md.Identifier.ValueText.Equals(className))
.FirstOrDefault();
var method = #class.DescendantNodes()
.OfType<MethodDeclarationSyntax>()
.Where(md => md.Identifier.ValueText.Equals(methodName))
.FirstOrDefault();
}
From this example you can easily build querying all classes withing a file.
Microsoft is working on a project called Roslyn which allows you to interact with C# code via ordinary .NET objects:
http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx
It hasn't been officially released, though, and I'm honestly not sure that it would include things like manipulating the source files (for example, to add a function to a class).
If you're working with code that is already compiled, you could probably use a combination of a few tricks, such as loading an assembly at runtime and then using reflection to interrogate it.
However, I would suggest taking a look at tools that are already available for generating code, like T4 Templates. There might be a better way to solve the underlying problem than interrogating C# source files.

Configuring Unity container using XML or web.config

I'm working with .net 4.5 and MVC4.
I implemented Unity IoC as described in the following post: http://kennytordeur.blogspot.com/2011/05/aspnet-mvc-3-and-unity-using.html
But I would like to be able to have "register" my repository types using an external XML or within web.config. Is that possible?, samples would be greatly appreciated.
thanks
Unless there is a really strong reason to, you should register as much as possible in code. XML configuration is much more error prone, verbose and can become a maintenance nightmare very quickly. Instead of registering (all) your repository types in XML (which is possible with Unity), just put the assembly name containing that contains the repository types in the config and register them dynamically in code. This saves you from having to change the configuration every time you add a new repository implementation.
Here is an example.
In your configuration file, add a new appSetting with the name of the assembly:
<appSettings>
<add key="RepositoryAssembly" value="AssemblyName" />
</appSettings>
In your composition root, you can do the following:
var assembly = Assembly.LoadFrom(
ConfigurationManager.AppSettings["RepositoryAssembly"]);
// Unity misses a batch-registration feature, so you'll have to
// do this by hand.
var repositoryRegistrations =
from type in assembly.GetExportedTypes()
where !type.IsAbstract
where !type.IsGenericTypeDefinition
let repositoryInterface = (
from _interface in type.GetInterfaces()
where _interface.IsGenericType
where typeof(IRepository<>).IsAssignable(
_interface.GetGenericTypeDefinition())
select _interface)
.SingleOrDefault()
where repositoryInterface != null
select new
{
service = repositoryInterface,
implemention = type
};
foreach (var reg in repositoryRegistrations)
{
container.RegisterType(reg.service, reg.implementation);
}
The LINQ query has a lot of subtle defects (for instance, it lacks checks for generic type constraints), but it will work for the common scenarios. If you work with generic type constraints, you should definitely switch to a framework that has support for this, because this is something that's really hard to get right.

How to determine the code-file filename from a compiled application at runtime

Let's say I have an application with two files.
Console.cs and Business.cs
Console.cs has program Main class.
Business.cs has three classes named Customer, Order and Orderline.
Is there anyway in C# to determine at runtime (maybe with reflection) that the business objects are in a file named Business.cs?
The C# compiler does not emit this information into the DLL, so it's not available through reflection. However, as you'll be aware from debugging, the debugger can match up compiled locations to source code locations. It does this through PDB files. So it might be theoertically possible for you to ship your PDB files, and invoke the unmanaged debugger or diagnostic symbol store API (see General Reference > Unmanaged API Reference in MSDN) to determine where a given method was defined. You can't really do this for a class, though, because a class could be spread across multiple files using partial classes.
If you compile in debug mode you can probably use Cecil (part of Mono project) to extract the source filenames from the debug symbols. But when you compile in release mode this information probably gets lost.
However, if you need to do this, for other purposes than for example static analysis of your software, you are probably on the wrong track and should think of another solution.
If you put the classes in a Business namespace you could use reflection to find if an object comes from that namespace:
namespace Business {
class Customer {}
class Order {}
class OrderLine {}
}
var myObject = new Customer();
Console.WriteLine(myObject.GetType().Namespace); // writes "Business"
I believe the closest you'll get is typeof(Customer).Assembly.Location. However, this will only give you the DLL, not the location of the source code (which makes sense, since the source code would normally not be included with the binaries).
*.PDB (debug info files) files should have that information. Otherwise I see no way to get it, since code files is just an abstraction which compiled code should not care about.
not sure what your use case is, however if some one is calling you then you can add
compiler directives
[CallerFilePath] string file = "", [CallerLineNumber] int LineNo = 0
in your method.
if not than your best way of accessing this is by using the .pdb file that get's generated. The format is published and a C++ dll is available that can be used to access the file however the easiest way to read the file (and possible line number) if included in the pdb file is using stacktrace
You can access the stack in an exception, so if a class allows you to throw an exception by passing null where you should not than try catch it and you have your stack trace.
if you need the calling file but do not want to add the compiler directives as some one can simply overwrite it you can do something like:
StackTrace st = new StackTrace(new StackFrame(1));
st.GetFrame(1).GetFileName());
Assuming :
You have a project (probably technical with some extension methods etc) that all other projects in your solution reference (let's name it "NameSpaceGloballyVisibleByAllProjects")
You are using SDK-style csproj for your project (otherwise you'll have a little more work)
People in your team code without doing fancy things (ie: "class" / "struct"/ "enum" keywords are at the beginning of their own line in your .cs files).
It means that, by adding this class in "NameSpaceGloballyVisibleByAllProjects":
using System;
using System.Runtime.CompilerServices;
namespace NameSpaceGloballyVisibleByAllProjects
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true, Inherited = false)]
public class MemorizeFilePathAttribute : Attribute
{
public string Path() { return _filepath; }
public MemorizeFilePathAttribute([CallerFilePath] string filepath = "")
{
_filepath = filepath;
}
readonly string _filepath;
}
}
You can simply use it like this:
using System.Reflection;
using NameSpaceGloballyVisibleByAllProjects;
Type type = typeof(Program);
var files = type.GetCustomAttributes<MemorizeFilePathAttribute>(false).Select(att => att.Path).ToList();
Note: As you notice there are more than one file! This is because of "partial" keyword in C#. So it's up to you to use "files.Single()" or not...
We just need to add this attribute above all types now
We can do that in Visual Studio with Ctr-H (Find-and-Replace).
Select All Solution
Check options "regex" & "case sensitive"
Find: "^( *)([a-z][a-z ]*)? (class|struct|enum) "
(without double quotes, but with the final ' '!)
Replace by: "$1 [NameSpaceGloballyVisibleByAllProjects.MemorizeFilePath]\r\n$1$2 $3 "
(without double quotes, but with the final ' '!)
Be ready for this to take a little time (Go get a coffe... or tea)

How to find all methods in assembly that instantiate object of class X?

Interesting question here: In my current project we're using a custom performance monitoring suite that is very config-heavy (it uses Perfmon so we have to manually register each performance counter. There is one performance counter for each method that we monitor, and there are a lot of those).
I was wondering if there are any tools that would, say, allow me to analyse the project assembly, find all methods that instantiate an instance of class XClass, then write them out to a file? This would allow me to cut down the amount of manual config I need to do by a large margin.
Thanks, Ed
EDIT
Sorry, the 'write them to a file' thing was a little contrived: really I need to reformat them with some extra data and write them in a config-specific XML format. This would be best if I can code it up so it can be set as a build task (so I don't have to run it manually) and any future changes can be made easily and documented etc.
Open the assembly in Reflector (the free version is fine); find the type (F3), then bring up the anaylyzer (Ctrl+R) and expand the "Instantiated By" node.
Then right-click on the "Instantiated By" node itself and click copy; for example:
System.Data.SqlClient.SqlConnectionStringBuilder
Depends On
Used By
Exposed By
Instantiated By
SqlDependencyProcessDispatcher.GetHashHelper(String, SqlConnectionStringBuilder&, DbConnectionPoolIdentity&, String&, String) : SqlConnectionContainerHashHelper
System.Data.SqlClient.SqlClientFactory.CreateConnectionStringBuilder() : DbConnectionStringBuilder
System.Web.Management.SqlWebEventProvider.Initialize(String, NameValueCollection) : Void
System.Web.SessionState.SqlSessionStateStore.CreatePartitionInfo(String) : IPartitionInfo
System.Web.SessionState.SqlSessionStateStore+SqlPartitionInfo.get_TracingPartitionString() : String
System.Web.SessionState.SqlSessionStateStore+SqlStateConnection..ctor(SqlPartitionInfo, TimeSpan)
If you need to write code to automate your task, it's easy to do it with Mono.Cecil. As an example, this code searches through all the methods of the top level types of an assembly for the instantiation of a class Foo.Bar.Baz:
using Mono.Cecil;
using Mono.Cecil.Cil;
// ...
static void SearchMethod (MethodDefinition method)
{
foreach (var instruction in method.Body.Instructions) {
if (instruction.OpCode != OpCodes.Newobj)
continue;
var constructor = (MethodReference) instruction.Operand;
if (constructor.DeclaringType.FullName != "Foo.Bar.Baz")
continue;
Console.WriteLine ("new Foo.Bar.Baz in {0}", method.FullName);
}
}
static void Main ()
{
var module = ModuleDefinition.ReadModule ("Foo.Bar.dll");
var methods = module.Types.SelectMany (t => t.Methods).Where (m => m.HasBody);
foreach (var method in methods)
SearchMethod (method);
}
Take a look at NDepend. It's a static analysis tool with a very powerful query language: CQL (Code Query Language).
Update
NDepend has a console application that can be prodded for automation (e.g. for use in a build systems) and can output reports to file.
An example query to find methods which instantiate a defined type:
SELECT METHODS WHERE CreateA "MyNamespace.MyClass"
You probably want to change your design so that they use a factory instead, such that the factory is responsible for the extra bookkeeping.
That said, you can look in the System.Reflection namespace, (from memory), where the Assembly class is used.

Categories

Resources