c# Call a method by memory address - c#

I am trying to call a function at a specified memory address in c#, here is how I would go about it in C:
typedef void _do(int i);
auto doActor = (_do*)0xAAAABEEF;
doActor(1);
How do I replicate this behavior in C# if at all possible? Very new to C# all help is appreciated.
More in depth explanation of my situation: I am trying to create a tool that helps me automate certain processes within an executable. I decompiled the assembly of the main API and added my functionality (for the most part) by intercepting network packets/spoofing my own. I do not have control over the client side of things, stored in an obfuscated assembly that I can't de-/recompile. I seldomly need to call one or two functions out of this obfuscated assembly and I found the memory addresses of those relevant functions using a debugger but don't know where to go from here in c#.

The closest equivalent to a C function pointer in C# is a delegate. Delegates are managed, but you can convert one from the other with the Marshal.GetDelegateForFunctionPointer method:
public delegate void _do(int i); // the delegate type
var ptr = new IntPtr(0xAAAABEEF);
var doActor = Marshal.GetDelegateForFunctionPointer<_do>(ptr);
doActor(1);
There are limitations tied to this API, however. I suggest you take a look at the documentation.
If you're stuck with a version of .NET older than 4.5, you're going to have to use a different version of GetDelegateForFunctionPointer:
var doActor = (_do)Marshal.GetDelegateForFunctionPointer(ptr, typeof(_do));

Related

What is the equivalent of Type Statement from VBA in C#?

What is the equivalent of Type from VBA in C#?
I am asking, because I have some code in Excel which I am trying to turn into a standalone C# application. I have a function, which comes from a .dll, which takes in a Type with some strings and longs as an argument. How would I replicate this in C#? Will this even work, or the will the function from .dll not even work in C#?
I haven't yet experimented with this, because it is all connected to a working database, and I want to know how this would work before I mess something up.
You say that you use a Type in VBA to pass data to a function contained in some DLL. Seeing some code would help, but this technique is usually used to call a (Windows API or third-party) DLL expecting some C-type struct.
In C#, you would use P/Invoke to call functions in unmanaged DLLs, and you would typically use a struct for complex types required by the DLL. Using a class is also possible, but there are some subtleties to be aware of.
A simple example can be found in this SO answer:
https://stackoverflow.com/a/47429104/87698
If your DLL is part of the Windows API, you can use http://pinvoke.net/ to find ready-to-use C# declarations for the functions as well as the data structures.
The example in the linked documentation would be rewritten as:
struct StateData
{
int[] CityCode;
string County;
}
var Washington = new StateData[100];
Although at some point you'd have to initialize CityCode. In VBA you could do it implicitly but in c# you'd have to write something like:
foreach (var w in Washington) w.CityCode = new int[100];
The closest will be the Struct datatype. It is similar in that it is a user-defined data type containing one or more elements (members) of various data types, and these elements are accessed as fields of the Type/Struct.
Both are values types and use stack allocation (usually).

Passing Structure to C#

I am writing code to parse a complicated string in C++ and create a tree from it. I would like to use C# in Visual Studio 2017 to call a native c++ method that returns a vector of nodes.
A Node looks like:
class node
{
public:
std::vector<node> subnodes;
std::string name;
};
and the c++ function might look like:
class noderizer
{
public:
node getNodes(std::string str);
};
what is the most efficient (coding time with secondary consideration for speed) way to call the noderizer::getNodes(...) member and create a equivalent class for c#?
I am assuming that the best route is to create a duplicate class definition in c# and then copy marshal the native std::strings into managed Strings"
public class node
{
public string name = string.Empty;
List<node> integers = new List<node>();
}
It's not clear if this article contains the latest information for c++ interop, but a related article on wrapping c++ native classes for use in c# indicates that I could most likely just wrap noderizer native c++ as noderizer * m_Impl; and then call the getNodes member and copy over each parameter. Is this the correct methodology?
You could use pInvoke as per your first referenced article, but the objects you are returning seem quite complicated. I think you will have a heck of a time with data marshalling if you're not already well versed (and even then). pInvoke is great for simple calls to C libraries where data marshalling is basic, but it gets very complicated very fast. This is not good for your situation.
The second article is closer to where you want to look. That being said, you have to consider whether you want to be wrapping a managed class or just calling a function that takes a string and returns your tree in managed format (i.e. it makes a copy rather than wrap unmanaged data). By your post it seems like you just need the latter.
Your best option is to use C++/CLI. Check out this tutorial. I am confident that taking this approach will make light work of your task. I won't attempt to explain the subject as the article above does a very good job. In essence, you will be able write functions with both managed and unmanaged data types, where all the data marshalling is built into the environment. A simple cast will marshal the data for you behind the scenes. As a big bonus, debugging is great as you can step from C# to C++/CLI to C++ code and back.
In the article above, the author does describe how to wrap an unmanaged class, which you can well do, but your problem will still be with data conversion.
I would approach your problem in 4 steps:
Write a static function getNodes() in C++/CLI that you can call from C# as any regular static method, passing a string as an argument. The article above will help you with that. Also See Here when creating the C++/CLI project.
getNodes() will use your C++ code to create a tree in its unmanaged form.
Use getNodes() to convert the tree from unmanaged to managed form.
Return the result to the caller in C#.
your declaration will look something like this, where the Node is your managed calss, ref keyword signifies that the class is managed, and ^ is the managed version of *.
public ref class noderizer
{
public:
static Node^ getNodes(String ^mStr);
};
Here getNodes() calls your C++ function and does the data conversion. I don't think it will take you long to figure it out.
Once you get a hang of the syntax, I think you will find it quite intuitive to use if you are already familiar with C# and C++.
As for performance, unless you're making thousands of consecutive calls or need critical real time data, it should not be an issue. One thing I would say though, if you're concerned with performance, you should write the pure C++ code in a separate purely unmanaged dll. I can't find the article for the life of me, but I remember looking at some benchmarks of executing purely unmanaged long running code block that was compiled inside the C++/CLI dll vs calling the exact same code that was compiled inside its own purely unmanaged dll. If I recall correctly, the separate dll was something like 3x faster.

C++ CLI unable to delete the pointer passed to a dll

I am writing a c# (c++ cli) wrapper to get data from a dll (Written in C++). I am passing a CStringArray * to a function in the dll which fills up an array of string back to me. I can read the contents of it. But when I try to delete the pointer created by me (I do a new and pass that pointer to the dll function), I get access voilation exception. After going multiple threads discussed in SO, I feel that this might be happening due to version difference in dll and my wrapper. The dll is built using VS 2012 and the wrapper that I am writing is developed in VS 2010. Could this be a problem? I spoke to developer of dll and he confimed that he is just added some string and not doing any allocation in the dll.
I wrote a test code (everything is vs2010) where in I have created a dll, a wrapper and test application. I can call delete without any problem.
Request you experts to confirm if this is the actual root cause of the problem. Here is the code snippet (my test code). Production code is almost the same but crashes the moment I call RemoveAll().
void MyDllWrapper::getLabels()
{
CStringArray* data = new CStringArray;
//FYI - mClass = new MyClass()
mClass->getLabels(data); //Call dll to get the data
this->m_strLabels = gcnew List<String^>;
for(int i = 0; i < data->GetCount(); i++)
{
Console::WriteLine("Added string {0}", gcnew String(data->GetAt(i)));
m_strLabels->Add(gcnew String(data->GetAt(i)));
}
data->RemoveAll(); //works fine
delete data;
}
There is no ABI support in MFC, except for MFC extension DLLS and their consumers built in the same MFC version and configuration (Unicode/MBCS, Debug/Release etc). Mixing MFC versions definitely won't work.
A better way to pass the string array to you is to use a C style interface like a VARIANT of type VT_BSTR|VT_ARRAY or a string buffer containing double-null-terminated strings.

talking to C from C#

I have a legacy code implemented in C (not C++). I would like to be able to call a few methods in this C code from my C# code (on Windows). What would be the best approach to interface between the two language? Please note that the method in C is not stateless. We need to call two methods:
initialization() => this will initialize the data structure and load data from files into memory. This method will be called once.
ComputeSomething(parameters) => there will be several calls from C# to this method.
Note: These two methods actually call several other methods but these are only the two methods that we would like to expose to C# (the code is quite complicated, that's why we do not want to port to C#)
I have been able to import the c code into visual studio and able to compile the code successfully. I know that we can probably implement the C code as windows service but I am looking for a solution that allow us to call C method from C# directly. Any pointers is highly appreciated! (is COM interop related to what I am looking to do?)
Sounds like you can use P/Invoke for this. Check out this site for tips:
http://www.pinvoke.net/
Also, try searching SO for advice on P/Invoke and Google for
c# pinvoke calling c code
I don't have any technical examples at hand, but I have written some .NET code which called Win32 API's via P/Invoke. The tricky part is getting the method signatures correct when passing parameters. This might help you out there.
Recent version of Visual Studio allow you to write C++ code that can call unsafe functions but still interface with CLR managed code. They call this "Implicit PInvoke," or "C++/CLR." Check out the MSDN article "Using C++ Interop" to learn more.
Managed code can't call unmanaged directly, so you need wrapper functions to handle the memory management issues and to translate between .NET objects and the data structures of your application. From the link above, check out the section on "How to: Wrap Native Class for Use by C#."
Here is a solution. The solution allows to call C# function from C by decorating your function with [DllExport] attribute (opposite of P/Invoke DllImport).
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
C# code
class Test
{
[DllExport("add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int left, int right)
{
return left + right;
}
}
C code
int main()
{
int z = add(5,10);
printf("The solution is found!!! Z is %i",z);
return 0;
}

tStringList passing in C# to Delphi DLL

I have a Delphi DLL with a function defined as:
function SubmitJobStringList(joblist: tStringList; var jobno: Integer): Integer;
I am calling this from C#. How do I declare the first parameter as a tStringList does not exist in C#. I currently have the declaration as:
[DllImport("opt7bja.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int SubmitJobStringList(string[] tStringList, ref int jobno);
But when I call it I get a memory access violation exception.
Anyone know how to pass to a tStringList correctly from C#?
You'll most likely not have any luck with this. The TStringList is more than just an array, it's a full-blown class, and the exact implementation details may differ from what is possible with .NET. Take a look at the Delphi VCL source code (that is, if you have it) and try to find out if you can rebuild the class in C#, and pass it with the help of your best friend, the Interop Marshaller. Note that even the Delphi string type is different from the .NET string type, and passing it without telling the marshaller what he should do, he will pass it as a char-array, most likely.
Other than that, I would suggest changing the Delphi DLL. It's never a good thing to expose anything Delphi-specific in a DLL that is to be used by non-Delphi clients. Make the parameter an array of PChar and you should be fine.
If this is your DLL, I'd rewrite the function to accept an array of strings instead. Avoid passing classes as DLL parameters.
Or, if you really want to use a TStringList for some reason, Delphi's VCL.Net can be used from any .Net language.
An old example using TIniFile: http://cc.codegear.com/Item/22691
The example uses .Net 1.1 in Delphi 2005. Delphi 2006 and 2007 support .Net 2.0.
If you don't control the DLL and they can't or won't change it, you could always write your own Delphi wrapper in a separate DLL with parameters that are more cross-language friendly.
Having a class as a parameter of a DLL function really is bad form.
I am not exactly clear your way of using delphi and C#. It seems you have created a Win32 DLL which you want to call from C#. Offcourse you must be using PInvoke for this.
I would suggest that you create a .NET DLL using your source code since complete porting of VCL is available. I can further elaborate if you wish....
In theory, you could do something like this by using pointers (casting them as the C# IntPtr type) instead of strongly typed object references (or perhaps wrapping them in some other type to avoid having to declare unsafe blocks), but the essential catch is this: The Delphi runtime must be the mechanism for allocating and deallocating memory for the objects. To that end, you must declare functions in your Delphi-compiled DLL which invoke the constructors and destructors for the TStringList class, you must make sure that your Delphi DLL uses the ShareMem unit, and you must take responsibility for incrementing and decrementing the reference count for your Delphi AnsiStrings before they leave the DLL and after they enter it, preferably also as functions exported from your Delphi DLL.
In short, it's a lot of work since you must juggle two memory managers in the same process (the .NET CLR and Delphi's allocators) and you must both manage the memory manually and "fool" the Delphi memory manager and runtime. Is there a particular reason you are bound to this setup? Could you describe the problem you are trying to solve at a higher level?
As Hemant Jangid said, you should easily be able to do this by compiling your code as a .NET dll and then referring to that assembly in your c# project.
Of course, you'll only be able to do this if the version of Delphi you have has Delphi.NET.
I don't know a lot about c#, but a technique that I use for transporting stringlists across contexts is using the .text property to get a string representing the list, then assigning that property on "the other side".
It's usually easier to get a string over the wall that it is a full blown object.

Categories