Call a function from C# .exe with unmanaged C++ .dll - c#

So, I have an executable file that was made with C#, I don't have its source code but I have disassembled it with IDA, and it gave me a lot of object oriented assembly.
I've made an .exe file that injects a .dll into another .exe, and I've injected this new C++ DLL into the C# .exe, with no problems, the DLLMain is called and so...
But when I inject this DLL into a normal .exe file made with C++, I can call a function in the .exe with its memory address which I can take on IDA.
The problem is, that object oriented assembly doesn't have addresses on its function, even with the function names being disassembled.
So, is there any way I can call this function with my injected DLL on the C# .exe file?
If possible, is there a way I can use the namespace declared in the C# .exe file and all its functions and variables, even being private?
Sample disassembled code:
.namespace MyCSharpApp
{
.class public auto ansi Test extends [mscorlib]System.Object
{
.field public value class [Microsoft.Xna.Framework]Microsoft.Xna.Framework.Vector2 pos
.field public int32 foo
....

You are trying to do something tricky and I'm not perfectly clear on what it is. From your description you have at least four things:
Managed EXE
Managed DLL
Unmanaged EXE
Unmanaged DLL
some of which you have control over (i.e. source code for), and some of which don't.
You want to use a process you call "injecting" to change a module you don't have control over to call a module you do have control over. In order to do this you are using a tool that requires you to have an unmanaged entry point in the address space of the process.
If you are getting what you want with unmanaged modules, then all you need to do is write a new mixed-mode module (over which you obviously have control) to call the managed DLL that you don't control. Now you effective have an unmanaged DLL (for export purposes) and the problem of it being managed has gone away.
To call managed code from your new unmanaged wrapper module, you can use the techniques described in this introductory article:
An Overview of Managed/Unmanaged Code Interoperability
Basically you need a C++/CLI project that references your black-box managed DLL and calls it and exports an unmanaged entry point that you can "take the address of" for your injection. Searching will find you a whole lot more ideas.
Finally, can you call private methods in the managed DLL (over which you have no control) using this method? No, not directly. However, its a managed DLL so it must have some public entry points to have ever been useful to anybody and you can call those. If that's not enough, you can use reflection from C++/CLI to call private methods and access private members.

You'll need to use the unmanaged hosting/debugging APIs. If you could inject a managed DLL, this would be much easier, you could just use Reflection.

Related

Call functions on an instantiated C++ class returned by a PInvoke to a C function

I have an unmanaged DLL that exports C style non-member functions for creating (say CreateObject) and destroying objects (DestroyObject). CreateObject returns a C++ class as a void*, which in the unmanaged code is cast to a known interface (defined only in a header file) and worked with. Is there a way to call methods on the IntPtr that is returned to me by CreateObject?
Dumpbin /EXPORT doesn't show me any methods of the C++ class, just the exported C functions (mentioned above).
I would like to avoid having to write C++ CLI code or a purely unmanaged DLL that simply exposes methods on this class as function wrappers if possible
This is Windows/MSVC only, so answers that restrict compatibility to Windows/MSVC are fine.
NOTE: I'm talking about invoking C++ methods on a void*/IntPtr returned by a C function - not P/Invoking the C functions.
Thanks!
If you are ruling out C++/CLI, and only have an IntPtr containing the address of the instance then you have few options remaining.
As I see it you are left with p/invoke. In order to call a method you'll need to export it from your unmanaged code. You'll also need to be careful about the calling convention. Commonly it will be __thiscall. When you write the p/invoke, you must explicitly add the this pointer as the first parameter.
This is fine so far as it goes. But you'll not be able to export virtual methods this way. You cannot call them using p/invoke.
Frankly though the cleanest and simplest way to do this interop is with our old friend, tried and tested COM. This very scenario is just what it was designed for. C++ classes are not designed for interop across compiler/language boundaries. That's what COM is for.

How to call methods from a C++ library in C#

I have a vendor's DLL that is meant to be called from C++, but I need to call it from C#.
Using an app called PE Explorer I can see the list of exported methods in the DLL (call it Protocol.dll for now) and even get an 'Undecorated C++ Function' signature like this:
public: unsigned int __thiscall Myco::Protocol::tMultiThingClient::GetThings(char (* const)[16],unsigned int)
How do I use something like that in C#? I know I use DllImport, I just don't know how to go from the signature above to a proper DllImport signature.
Total WAG:
[DllImport("Protocol.dll", EntryPoint="GetThings")]
public static extern void GetThings(ref string[], uint);
Is that even close? Is there a reference somewhere that translates between C++ declarations like char (* const)[16] and their C# equivalents?
You need to create a seperate project containing mixed assembly using C++ CLI. For this, you need to enable the CLR compiler switch in your project properties. Since, the project allows mixed assembly, you can call the C++ function, and also create a C# interface for your main program to call.
So, your main program will call the interface you implement inside your C++ CLI project, which will in turn call the C++ funtion inside the DLL.
Please beware of Marshalling and Thunking while you do this, if it applies to your system considerations.

C# DLL Missing Public Functions

I am attempting to write a DLL using the C# .NET Framework 2.0. Everything compiles okay, but when I try to access the DLL from my application, it fails when attempting to get the procedure address. So, I oped the DLL in Dependency Walker, and all of my public functions are missing!
My DLL, so far, is fairly straightforward:
namespace MyDll_Namespace
{
public class MyDllClass
{
public static int Func1( /* params */ ) { /* ... */ }
public static int Func2( /* params */ ) { /* ... */ }
public static int Func3( /* params */ ) { /* ... */ }
public static int Func4( /* params */ ) { /* ... */ }
}
}
There's not much else, just a few constants and delegates defined inside the class, as well as outside the class in the namespace. Any thoughts or suggestions would be much appreciated. Thanks.
Dependency walker is for win32 DLLs (which is native code), not .NET assemblies (which is managed code). It won't find methods in an arbitrary class (even if they are static). If you need to call managed code from native code, there are ways of doing that, but it's not pretty.
If you want to use your dll from managed code, it's a lot easier. Check out System.Assembly and Activator.
An example of this:
var assembly = Assembly.LoadFile(#"\path\to\your.dll");
var mydllclass_type = assembly.GetType("MyDllClass");
var instance = Activator.CreateInstance(mydllclass_type);
The instance will be an object. To call the methods, you need to use reflection, because the interface is not known at compile-time.
If you are creating a plugin system, the best way is to have a common interface or abstract base for all plugins, and have that referenced by your program. Those third parties who implement a plugin, will also reference this contract. In this case, the last line changes a bit:
var instance = (IMyDllClass)Activator.CreateInstance(mydllclass_type);
Now you can use the methods like in a regularly constructed object.
Part of the problem here is that dependency walker is a tool for native applications. It doesn't understand managed code and hence won't display any of the managed types + methods that you've defined.
I'm confused by this line in your question
when I try to access the DLL from my application, it fails when attempting to get the procedure address
This sounds a bit like an error I would see in a native application, not a managed one. Are you trying to access the C# code from a native application? If so this can only be done via COM magic and not via direct calling. Can you explain in more detail what is going on here?
Try .net Reflector to see exactly what's inside your built DLL (in order to make sure everything is the way it is supposed to).
Also make sure you're in release mode while building your DLL before referencing it... I don't know if it's going to change anything, but it worths the try =)
You need to add a reference to your dll and the runtime will automatically allow you to call your function. Here is a little tutorial on writing a .net class library.
I decided to write my DLLs in C++. However, here is a bunch of useful information I found for using managed code from unmanaged code:
Is it possible to use a DLL created using C# in an unmanaged VC++ application?
How do I call C++/CLI (.NET) DLLs from standard, unmanaged non-.NET applications?
Using managed code in an unmanaged application
Using Managed Components from Unmanaged Code
An Overview of Managed/Unmanaged Code Interoperability
Unmanaged Exports
Calling Managed .NET C# COM Objects from Unmanaged C++ Code
All-In-One Code Framework
CLR Hosting APIs
How To: Migrate to /clr
How to call a managed DLL from native Visual C++ code in Visual Studio.NET or in Visual Studio 2005

Launching a C# dialog from an unmanaged C++ mfc active x dll

I've been told to write a dialog in C# which must be instantiated from an unmanaged c++ dll. We do this in other places in our code by simply adding a managed c++ class to the C++ project, then calling the C# dll from the managed c++ class. However I'm finding that doesn't work for me from where I have to do it. I think because the c++ dll is an MFCActiveX project. As soon as i set the clr on any file in this project, it will no longer register correctly. When i attempt to register it, i get three errors, then a message that it registered. However when i try to use it i get a 0x80040111 "ClassFactory cannot supply requested class" error.
If anyone has any idea what the problem is here i would greatly appreciate it. I either need to be able to accomplish this (preferred) or prove that it's not possible.
Thanks
I can't see how a MFCActiveX project would prevent you from creating the C# class in this way. Unless it simply does not allow for a managed class to be added.
If you can't get the managed C++ class trick to work, another option is to use COM. It's possible to register a factory of sorts in the C# project as a COM object. Say give it the following interface
[ComVisible(true)]
[Guid("babe87fc-1467-4913-a1d3-47eeedf1afb5")]
public interface IDialogFactory {
void Create();
}
You'd also have to create a backing class as well. But then you could register the managed assembly and use COM to access it.
You must now register it with "regasm" instead of "regsvr32".

How do I call a .NET assembly from C/C++?

Suppose I am writing an application in C++ and C#. I want to write the low level parts in C++ and write the high level logic in C#. How can I load a .NET assembly from my C++ program and start calling methods and accessing the properties of my C# classes?
You should really look into C++/CLI. It makes tasks like this nearly trivial.
Otherwise, you'll have to generate COM wrappers around the C# code and have your C++ app call the COM wrappers.
[Guid("123565C4-C5FA-4512-A560-1D47F9FDFA20")]
public interface IConfig
{
[DispId(1)]
string Destination{ get; }
[DispId(2)]
void Unserialize();
[DispId(3)]
void Serialize();
}
[ComVisible(true)]
[Guid("12AC8095-BD27-4de8-A30B-991940666927")]
[ClassInterface(ClassInterfaceType.None)]
public sealed class Config : IConfig
{
public Config()
{
}
public string Destination
{
get { return ""; }
}
public void Serialize()
{
}
public void Unserialize()
{
}
}
After that, you need to regasm your assembly. Regasm will add the necessary registry entries to allow your .NET component to be see as a COM Component. After, you can call your .NET Component in C++ in the same way as any other COM component.
I would definitely investigate C++/CLI for this and avoid COM and all the registration hassles that tends to produce.
What is the motivation for using C++? If it is simply style then you might find you can write everything in C++/CLI. If it is performance then calling back and forth between managed C++ and unmanaged code is relatively straight forward. But it is never going to be transparent. You can't pass a managed pointer to unmanaged code first without pinning it so that the garbage collector won't move it, and of course unmanaged code won't know about your managed types. But managed (C++) code can know about your unmanaged types.
One other thing to note is that C++/CLI assemblies that include unmanaged code will be architecture specific. You will need separates builds for x86 and x64 (and IA64).
If you can have both managed and unmanaged code in your process, you can create a C++ class with virtual functions. Implement the class with mixed mode C++/CLI. Inject the implementation to your C++ code, so that the (high-level) implementation can be called from your (low-level) C++ code.
You can wrap the .NET component in a COM component - which is quite easy with the .NET tools - and call it via COM.
If the low level parts in in C++ then typically you call that from the C# code passing in the values that are needed. This should work in the standard way that you're probably accustomed to. You'll need to read up on marshalling for example.
You could look at this blog to get some concrete details.
Create your .NET assembly as normal, but be sure to mark the class with the ClassInterface(ClassInterfaceType.AutoDual) and be sure an assembly info SetAssemblyAtribute to ComVisible( true ).
Then, create the COM wrapper with REGASM:
regasm mydll.dll /tlb:mydll.tbl /codebase f:_code\ClassLibraryForCom
be sure to use the /codebase directive -- it is necessary if you aren't going to give the assembly a strong name.
rp
Since C# can import C++ standard exports, it might be easier to load up your C++ dll inside of a C# application instead of using COM from C++.
See documentation for System.Runtime.InteropServices.DllImport.
Also, here is a complete list of the types of Interop that you can do between managed and unmanaged code:
http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx
In a nutshell:
(a) Using COM-Interop
(b) Using imports/pinvoke (explicit method calls)
(c) IJW and MC++ apps : MC++ & IJW apps can freely call back and forth to each other.
(d) Hosting. This is rare, but the CLR can be hosted by an unmanaged app which means that the runtime invokes a bunch of hosting callbacks.
I found this link to embedding Mono:
http://www.mono-project.com/Embedding_Mono
It provides what seems to be a pretty straightforward interface for interacting with assemblies. This could be an attractive option, especially if you want to be cross-platform

Categories