Embed .net binary in a native executable - c#

Is there a way to embed my .net executable (C#/VB.Net) in a ntive binary like a C/C++ file which will load the .net assembly on startup?
Like building a native wall arround the .net assembly?

You could embed your .Net binary in the C++ project as a resource and load it runtime, but I doubt that is a recommended way to increase security.
Edit:
Someone asked for source code and suggested that I make a comment instead of an answer. I've just signed up for StackOverflow and I don't have enough reputation to make comments yet.
But here's some source I used at some point:
public static int RunInternalExe(byte[] rawData, params string[] args)
{
Assembly asm = Assembly.Load(rawData);
MethodInfo mi = asm.EntryPoint;
if (mi == null)
throw new Exception("Entry point not found");
ParameterInfo[] prms = mi.GetParameters();
object[] mtd_args = null;
if (prms.Length > 0)
mtd_args = new object[] { args };
object result = mi.Invoke(null, mtd_args);
if (result is int)
return (int)result;
return 0;
}
Embed the managed .exe in your wrapper .exe and pass the raw data to the proc above.
MyTools.RunInternalExe(Resources.ExeData);
Ofcourse, if you want your wrapper .exe to be non-managed you'd have to translate the code above to C++ or some other language of your choice, that's kind of above my head right now...

Related

Getting full name and usage of gpu using nvapi

i am trying to get the full name of my gpu and my gpu usage using nvapi.dll.
i have encounter this post on this website: C# Performance Counter Help, Nvidia GPU.
he uses 2 sources, one in the dll itself (for getting the usage) and for full name he uses the header file of nvapi downloaded from the nevidia website.
There is any way i can avoid this duplication in my project?
using only the dll or using only the header files brought by nevidia.
Thanks for all the helpers
you can load DLL file dynamically when you need it,
in c# you can use .Net Reflection (if dll is developed in .Net framework), for example :
var DLL = Assembly.LoadFile(#"path\to\your.dll");
Type t = DLL.GetType("myAssembly.ClassName");
CustomType result = t.InvokeMember("methodName", BindingFlags.InvokeMethod, null, t, new object[] { #"method argument" });
if mentioned dll is not developed under .Net framework but you are forced to use .Net framework (for more information see this) :
int hModule = LoadLibrary(#"path\to\your.dll");
if (hModule == 0) return false;
IntPtr intPtr = GetProcAddress(hModule, "yourmethod_PTR");
if you want to use in c/c++ you can use following code :
HINSTANCE hGetProcIDDLL = LoadLibrary("path\\to\\your.dll");
if (hGetProcIDDLL == NULL) {
std::cout << "dll not found" << std::endl;
}
int a = function_to_call("arguments");
NOTE: if you want to load dll from unknown source I recommend to use c/c++, because in c/c++ you can manage your memory easier and free all your resources after dll loading,
I have found the list of functions id in https://github.com/processhacker/plugins-extra/blob/master/NvGpuPlugin/nvidia.c
In addition to
http://eliang.blogspot.com/2011/05/getting-nvidia-gpu-usage-in-c.html
i declared
typedef int(*nvAPI_GPU_getFullName_t)(int *handle , char* name); nvAPI_GPU_getFullName_t nvAPI_GPU_getFullName=NULL; nvAPI_GPU_getFullName=(nvAPI_GPU_getFullName_t)(*NvAPI_QueryInterface)(0xCEEE8e9FUL);

Is it possible to patch a dotnet function on the fly

Recently I found an architect-often-used .net program has implemented a function wrongly. So I successfully patched it using ILSpy and Reflexil in a static way of modifying binaries. However, it is annoying that you need to patch it and remove StrongNameCheck again when new minor version releases. (btw, the author believes it is a feature instead of a bug)
Hopefully, the program fully supports assemblies as a plugin. And my target is a public non-static member function in a public class which can be directly called by plugins. Is there a way to patch the function on the fly?
I usually use some APIHook tricks in unmanaged C++ but dotnet is really a different thing. In this case, I want the modification still valid after my assembly unloads (so more similar to a patch, not a hook).
Yes you can do it with code injection. But you need to know some MSIL. There is also a library for that which is called Mono.Cecil.
Here is a example code
Console.WriteLine("> INJECTING INTO 12345.EXE..." + Environment.NewLine);
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(#"C:\dummy.exe");
var writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
var writeLineRef = asm.MainModule.Import(writeLineMethod);
var pStartMethod = typeof(Process).GetMethod("Start", new Type[] { typeof(string) });
var pStartRef = asm.MainModule.Import(pStartMethod);
foreach (var typeDef in asm.MainModule.Types)
{
foreach (var method in typeDef.Methods)
{
//Let's push a string using the Ldstr Opcode to the stack
method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldstr, "INJECTED!"));
//We add the call to the Console.WriteLine() method. It will read from the stack
method.Body.Instructions.Insert(1, Instruction.Create(OpCodes.Call, writeLineRef));
//We push the path of the executable you want to run to the stack
method.Body.Instructions.Insert(2, Instruction.Create(OpCodes.Ldstr, #"calc.exe"));
//Adding the call to the Process.Start() method, It will read from the stack
method.Body.Instructions.Insert(3, Instruction.Create(OpCodes.Call, pStartRef));
//Removing the value from stack with pop
method.Body.Instructions.Insert(4, Instruction.Create(OpCodes.Pop));
}
}
asm.Write("12345.exe"); //Now we just save the new assembly
Don't monkey patch code. Add the functionality to your code base and call that function. Or write an adapter class that wraps the underlying assembly, which is much neater.
If the author of the code thinks it's not a bug then it may be in there for reasons you don't understand and could be part of any number of bug fixes.

Compile Brotli into a DLL .NET can reference

So I'd like to take advantage of Brotli but I am not familiar with Python and C++..
I know someone had compiled it into a Windows .exe. But how do I wrap it into a DLL or something that a .NET app can reference? I know there's IronPython, do I just bring in all the source files into an IronPython project and write a .NET adapter that calls into the Brotli API and exposes them? But actually, I'm not even sure if the Brotli API is Python or C++..
Looking at tools/bro.cc, it looks like the "entry" methods are defined in encode.c and decode.c as BrotliCompress(), BrotliDecompressBuffer(), BrotliDecompressStream() methods. So I suppose a DLL can be compiled from the C++ classes.
To avoid the need for Python, I have forked the original brotli source here https://github.com/smourier/brotli and created a Windows DLL version of it that you can use with .NET.
I've added a directory that contains a "WinBrotli" Visual Studio 2015 solution with two projects:
WinBrotli: a Windows DLL (x86 and x64) that contains original unchanged C/C++ brotli code.
Brotli: a Windows Console Application (Any Cpu) written in C# that contains P/Invoke interop code for WinBrotli.
To reuse the Winbrotli DLL, just copy WinBrotli.x64.dll and WinBrotli.x86.dll (you can find already built release versions in the WinBrotli/binaries folder) aside your .NET application, and incorporate the BrotliCompression.cs file in your C# project (or port it to VB or another language if C# is not your favorite language). The interop code will automatically pick the right DLL that correspond to the current process' bitness (X86 or X64).
Once you've done that, using it is fairly simple (input and output can be file paths or standard .NET Streams):
// compress
BrotliCompression.Compress(input, output);
// decompress
BrotliCompression.Decompress(input, output);
To create WinBrotli, here's what I've done (for others that would want to use other Visual Studio versions)
Created a standard DLL project, removed the precompiled header
Included all encoder and decoder original brotli C/C++ files (never changed anything in there, so we can update the original files when needed)
Configured the project to remove dependencies on MSVCRT (so we don't need to deploy other DLL)
Disabled the 4146 warning (otherwise we just can't compile)
Added a very standard dllmain.cpp file that does nothing special
Added a WinBrotli.cpp file that exposes brotli compression and decompression code to the outside Windows world (with a very thin adaptation layer, so it's easier to interop in .NET)
Added a WinBrotli.def file that exports 4 functions
I'll show one way to do that via calling python native library from .NET code. What you need:
You need to intall python 2.7 (hope that is obvious)
You need to compile brotli from source. Hopefully that is easy. First install Microsoft Visual C++ compiler for Python 2.7. Then clone brotli repository via git clone https://github.com/google/brotli.git and compile using python setup.py build_ext. When it's done, in build\lib.win32-2.7 directory you will find brotli.pyd file. This is python c++ module - we will need it later.
You need to either download pythonnet binaries or compile it from source. The reason we use pythonnet here, and not for example Iron Python is because Iron Python does not support native (C\C++) python modules, and that is what we need here. So, to compile from source, clone via git clone https://github.com/pythonnet/pythonnet.git then compile via python setup.py build. In result you will get Python.Runtime.dll (in build\lib.win32-2.7 directory), which is what we need.
When you have all that in place, create console project, reference Python.Runtime.dll and then:
public static void Main()
{
PythonEngine.Initialize();
var gs = PythonEngine.AcquireLock();
try {
// import brotli module
dynamic brotli = PythonEngine.ImportModule(#"brotli");
// this is a string we will compress
string original = "XXXXXXXXXXYYYYYYYYYY";
// compress and interpret as byte array. This array you can save to file for example
var compressed = (byte[]) brotli.compress(original);
// little trick to pass byte array as python string
dynamic base64Encoded = new PyString(Convert.ToBase64String(compressed));
// decompress and interpret as string
var decompressed = (string) brotli.decompress(base64Encoded.decode("base64"));
// works
Debug.Assert(decompressed == original);
}
finally {
PythonEngine.ReleaseLock(gs);
PythonEngine.Shutdown();
}
Console.ReadKey();
}
Then build that and put brotli.pyc you get above in the same directory with your .exe file. After all that manipulations you will be able to compress and decompress from .NET code, as you see above.
You may use Brotli.NET which provides full stream support.
github: https://github.com/XieJJ99/brotli.net/.
Nuget: https://www.nuget.org/packages/Brotli.NET/.
To compress a stream to brotli data:
public Byte[] Encode(Byte[] input)
{
Byte[] output = null;
using (System.IO.MemoryStream msInput = new System.IO.MemoryStream(input))
using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream())
using (BrotliStream bs = new BrotliStream(msOutput, System.IO.Compression.CompressionMode.Compress))
{
bs.SetQuality(11);
bs.SetWindow(22);
msInput.CopyTo(bs);
bs.Close();
output = msOutput.ToArray();
return output;
}
}
To decompress a brotli stream:
public Byte[] Decode(Byte[] input)
{
using (System.IO.MemoryStream msInput = new System.IO.MemoryStream(input))
using (BrotliStream bs = new BrotliStream(msInput, System.IO.Compression.CompressionMode.Decompress))
using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream())
{
bs.CopyTo(msOutput);
msOutput.Seek(0, System.IO.SeekOrigin.Begin);
output = msOutput.ToArray();
return output;
}
}
To support dynamic compress in web applications,add the code like this in the Global.asax.cs:
protected void Application_PostAcquireRequestState(object sender, EventArgs e)
{
var app = Context.ApplicationInstance;
String acceptEncodings = app.Request.Headers.Get("Accept-Encoding");
if (!String.IsNullOrEmpty(acceptEncodings))
{
System.IO.Stream baseStream = app.Response.Filter;
acceptEncodings = acceptEncodings.ToLower();
if (acceptEncodings.Contains("br") || acceptEncodings.Contains("brotli"))
{
app.Response.Filter = new Brotli.BrotliStream(baseStream, System.IO.Compression.CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "br");
}
else
if (acceptEncodings.Contains("deflate"))
{
app.Response.Filter = new System.IO.Compression.DeflateStream(baseStream, System.IO.Compression.CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "deflate");
}
else if (acceptEncodings.Contains("gzip"))
{
app.Response.Filter = new System.IO.Compression.GZipStream(baseStream, System.IO.Compression.CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "gzip");
}
}
}

Load x64 or a x86 DLL depending upon the platform? [duplicate]

This question already has answers here:
Using Side-by-Side assemblies to load the x64 or x32 version of a DLL
(5 answers)
Closed 9 years ago.
I have an application built as 'Any CPU' and have two third party Dlls of the same library targeted to x86 and x64. I would like to include one of these libraries at runtime depending upon the platform it would run on the client machine. What would be the best way to go about it ?.
If we are talking about unmanaged DLLs, declare the p/invokes like this:
[DllImport("DllName.dll")]
static extern foo();
Note that we are not specifying a path to the DLL, just its name, which I presume is the same for both 32 and 64 bit versions.
Then, before you call any of your p/invokes, load the library into your process. Do that by p/invoking to the LoadLibrary API function. At this point you will determine whether your process is 32 or 64 bit and build the full path to the DLL accordingly. That full path is what you pass to LoadLibrary.
Now, when you call your p/invokes for the library, they will be resolved by the module that you have just loaded.
For managed assemblies then you can use Assembly.LoadFile to specify the path of the assembly. This can be a little tricky to orchestrate, but this excellent article shows you how: Automatically Choose 32 or 64 Bit Mixed Mode DLLs. There are a lot of details relating to mixed mode and the native DLL dependencies that are probably not relevant to you. The key is the AppDomain.CurrentDomain.AssemblyResolve event handler.
I'm actually kind of experienced about this topic, so I thought I would post the answer according to the ways I used in Pencil.Gaming. Firstly, you have to "DllImport" two functions, one from the 32-bit dll, and one from the 64-bit dll (or so, or dylib, whatever your platform uses).
static class Foo32 {
[DllImport("32bitdll.dll")]
internal static extern void Foo();
}
static class Foo64 {
[DllImport("64bitdll.dll")]
internal static extern void Foo();
}
Then you need an intermediate class containing delegates, and importing them from the 32 or 64-bit interop according to the size of an IntPtr (I don't use Environment.Is64BitProcess, since that's a .NET 4 function):
internal delegate void FooDelegate();
static class FooDelegates {
internal static FooDelegate Foo;
static FooDelegates() {
Type interop = (IntPtr.Size == 8) ? typeof(Foo64) : typeof(Foo32);
FieldInfo[] fields = typeof(FooDelegates).GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
foreach (FieldInfo fi in fields) {
MethodInfo mi = glfwInterop.GetMethod(fi.Name, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
Delegate function = Delegate.CreateDelegate(fi.FieldType, mi);
fi.SetValue(null, function);
}
}
}
And then I generally use a "real" class, containing the function you imported (though this is not technically required):
public static class FooApi {
public static void Foo() {
FooDelegates.Foo();
}
}
This is a real pain if you only need one or two functions, but the way of importing delegates is really efficient for larger scale libraries/applications. You might want to check out Pencil.Gaming on github, as it uses this method quite extensively (here is an example of it being used a lot).
Another benefit of this method is that it's 100% cross-platform, and doesn't rely on any WinAPI functions.
My complete solution to my problem was by using the second link provided by David Heffernan.
What I did was
1. Referenced a dummy dll in the project.
2. Specified two pre-build events
xcopy /y "$(SolutionDir)\Assemblies\Lib\x86\(Assembly name)*" "$(TargetDir)"
xcopy /y "$(SolutionDir)\Assemblies\Lib\x64\(Assemble name)*" "$(TargetDir)"
3. and on startup of the app in the assembly resolve event changed the corresponding assembly depending upon the platform.
var currentDomain = AppDomain.CurrentDomain;
var location = Assembly.GetExecutingAssembly().Location;
var assemblyDir = Path.GetDirectoryName(location);
if (assemblyDir != null && (File.Exists(Path.Combine(assemblyDir, "(Assembly name).proxy.dll"))
|| !File.Exists(Path.Combine(assemblyDir, "(Assembly name).x86.dll"))
|| !File.Exists(Path.Combine(assemblyDir, "(Assembly name).x64.dll"))))
{
throw new InvalidOperationException("Found (Assembly name).proxy.dll which cannot exist. "
+ "Must instead have (Assembly name).x86.dll and (Assembly name).x64.dll. Check your build settings.");
}
currentDomain.AssemblyResolve += (sender, arg) =>
{
if (arg.Name.StartsWith("(Assembly name),", StringComparison.OrdinalIgnoreCase))
{
string fileName = Path.Combine(assemblyDir,
string.Format("(Assembly).{0}.dll", (IntPtr.Size == 4) ? "x86" : "x64"));
return Assembly.LoadFile(fileName);
}
return null;
};

Call function from DLL with non-static path

I have a DLL that I need to access methods from.
In most cases like this I just use [DllImport] to access methods from unmanaged assemblies, but the problem with that in this situation is that it requires the path to the DLL at instantiation time, so a constant string.
This particular DLL is one that gets installed with my application and I can't guarantee where it will be after the program is installed (I'd rather not put it somewhere static like %SystemRoot%).
So is there a way in C# that I can declare and use a method from a DLL at runtime with a variable path?
Any ideas or suggestions would be greatly appreciated!
This is a bit of hack, but since you say that you can find the path to the dll at runtime, why not copy it to your current working directory before you use any of the functions? That way, the dll will exist next to your exe and will be found by LoadLibrary. No need for any additional path in your DllImport.
The only other way to use a method from a dynamic path is to do this:
1) Do the necessary P/Invoke signatures for LoadLibrary & GetProcAddress
2) Load the library from the desired path (LoadLibrary)
3) Find the desired function (GetProcAddress)
4) Cast the pointer to a delegate Marshal.GetDelegateForFunctionPointer
5) Invoke it.
Of course, you will need to declare a delegate for each function you want to "import" in this way since you have to cast the pointer to a delegate.
Don't use a path at all. Windows uses a default method of searching for DLLs when trying to dynamically or statically load a function from it.
The exact search logic is documented at MSDN in the docs for LoadLibrary - basically, if the DLL is just used by your app, put in the same folder as your application during the install and don't worry about it. If it's a commonly used DLL, put it somewhere in the folder structure searched by LoadLibrary() and it'll get found.
I had a similar situation. I use DLLs from a SDK that is installed on the machine. I get the directory location of the DLLs from that SDKs registry key. I set the DLL location on the executing users PATH variable (only temporary modification). Basically it allows you to set a dynamic path for the DLL you want to invoke, so it don't have to be from registry. Mind that the PATH var is the last place Windows looks for DLLs. But on the other hand, it does not change the other places Windows looks for DLLs.
Example:
API i want to call, on the DLL:
[DllImport("My.DLL")]
private static extern IntPtr ApiCall(int param);
Get the registry key (you need using Microsoft.Win32;):
private static string GetRegistryKeyPath() {
string environmentPath = null;
using (var rk = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\SOMENNAME"))
{
if (rk != null)
{
environmentPath = rk.GetValue("Path(or whatever your key is)").ToString();
}
if (string.IsNullOrEmpty(environmentPath))
{
Log.Warn(
string.Format("Path not found in Windows registry, using key: {0}. Will default to {1}",
#"SOFTWARE\SOMETHING", #"C:\DefaultPath"));
environmentPath = #"C:\DefaultPath";
}
}
return environmentPath;
}
Add the path of the DLL on the PATH var (Concat() is found in Linq):
void UpdatePath(IEnumerable<string> paths){
var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? "" };
path = path.Concat(paths);
string modified = string.Join(Path.PathSeparator.ToString(), path);
Environment.SetEnvironmentVariable("PATH", modified);
}
Start Using the API call:
var sdkPathToAdd = GetRegistryKeyPath();
IList<string> paths = new List<string>
{
Path.Combine(sdkPathToAdd),
Path.Combine("c:\anotherPath")
};
UpdatePath(paths);
//Start using
ApiCall(int numberOfEyes);

Categories