How to use Easyhook with non managed executable - c#

I am trying to do some hooking in c# (I'd rather not use Detours or c++) so i have been using EasyHook.
https://easyhook.github.io/
However When i'm doing this
Config.Register( "This description can be anything.", #"SomePathToAnExecutable.exe", "MyInjectionDll.dll");
I get the error:
There was an error while connecting to
target:
System.BadImageFormatException: Unable
to load given assembly
[SomePathToAnExecutable.exe] for
reflection.
Is this a valid NET assembly? --->
System.BadImageFormatException: Could
not load file or assembly
[SomePathToAnExecutable.exe] or one of
its dependencies. The module was
expected to contain an assembly
manifest.
Question 1) Am I right in thinking that SomePathToAnExecutable is the process that you want to hook into???
Question 2) Does the executable have to be managed code then??
I've also asked at on the codeplex project site, but no response.
http://easyhook.codeplex.com/Thread/View.aspx?ThreadId=235616

Answer 1) No. Config.Register registers managed assemblies with the GAC. Thus you register all assemblies participating from your code. This includes the dll you want to inject and the assembly that provides the common interface for the IPCServer. For my it looks like this one for example:
Config.Register("MyHook",
Path.Combine(startupPath, "HookManager.dll"),
Path.Combine(startupPath, "NetworkIncomingHook.dll"),
Path.Combine(startupPath, "NetworkOutgoingHook.dll")
);
The HookManager.dll contains the interface I use to create the IPCServer (and where all messages are send to from the hooked functions). The NetworkIncomingHook.dll and NetworkOutgoingHook.dll are both dlls I inject into my programm. This is done by RemoteHooking.Inject.
2) No. You can hook unmanaged assemblies aswell.

Related

Why does instantiating COM object in C# throw exception

I'm trying to instantiate a COM object, defined in a x86 dll written in Borland C++, in a testing program i write in C# (.net 4.7.2). The COM dll (server) is working, I have a windows service also written in C++ Borland that can use it and instantiate a COM object from the class (using CoCreateInstance). The dll is registered and the InprocServer32 entry has the correct path to the dll. There is no coclass existing in a typelib, only interfaces (those exist in the typelib). I have used the TlbImp to create dll:s which i reference in the c# project. In the project the target platform is set to x86. The way i try to instantiate an object is:
var comType = Type.GetTypeFromProgID("ins.MyComType");
object comObj = Activator.CreateInstance(comType);
however the second line gives me
"Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll"
with the message 'Retrieving the COM class factory for component with
CLSID {C4363C5E-3831-46DF-8701-60C8D1B612BA} failed due to the
following error: 8007007e The specified module could not be found.
(Exception from HRESULT: 0x8007007E).".
It does not matter if i try to run the app as administrator. I have a vague memory of trying out a similar thing a couple of years ago and that it at that time worked. It was probably on a Win 7 machine (might even have been a 32-bit system). I have tried to open the project in DependencyWalker but i'm not sure what i'm looking at. I get a couple of errors:
*Error: At least one required implicit or forwarded dependency was not found.
*Error: Modules with different CPU types were found.
*Error: A circular dependency was detected.
*Warning: At least one delay-load dependency module was not found.
*Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
Does any one have any idea on what it could be causing the exception? Or if i could get some hints as of how to dig deeper into dependencywalker? I get a gigantic tree of systemassembly stuff but i cannot see any obvious assembly standing out, though DW refers to many of them as being 64 bit. My guess is some dependent dll(s) somewhere should be x86 but which one(s). Is there a redist similar thingi i should have installed for this to work?
best regards
/Erik
You should write a simple VBScript that contains these lines:
set obj = CreateObject("ins.MyComType")
MsgBox TypeName(obj)
Name the file test.vbs
Execute the command:
c:\windows\syswow64\wscript.exe test.vbs
Using the version from syswow64 ensures that it uses the 32-bit version of wscript.exe which can instantiate 32-bit COM objects. The version in c:\windows\system32 can only instantiate 64-bit In-process COM objects in DLLs...you said your object is a 32-bit COM DLL server.
If the vbscript fails, it could be that the object is not automation compatible--implements IDispatch. Otherwise you will get an error message why it fails.
If it succeeds, you will know there is probably nothing on the C++ side causing problems. You THINK this is the case...but where is the runtime for Borland C++? Is everything statically linked, or is some of it dynamically linked? If it is dynamically linked, where is it in the path? It could be that the C++ service you have has the library in its path so that when it loads your COM object, the library is available. But, when you try to load from a 3rd party, like .NET or VBScript then the path to the library manifests itself. Who knows? I'm just making suggestions.
If you use ProcMon, it can see where the problems are. It will show you what registry entries are being read and which files are trying to be loaded.

AssemblyLoadContext.Default in netcore 3.1 resolve the plugin type but can't excute its instance when the plugin use transitive dependency

I have a console application in netcoreapp3.1 that use a netstandard2.0 plugin.
The plugin reference a class library and implement an interface
All dll dependencies are in the the plugin folder and the plugin.dep.json include all referenced library.
When I run:
AssemblyLoadContext.Default.LoadFromAssemblyPath("path/to/main_myplugin.dll");//load plugin
it resolve the type of interface
When i try to run an instance as given below it fail:
if (type != null) //type is resolved and not null
{
var instance = (IContract)Activator.CreateInstance(type); //instance is created
Console.WriteLine($"Create instance : {instance.GetType()}"); // ok instance is created
var ret = instance.Execute(); //!!!fire exception here
Console.WriteLine(ret);
}
and fire error message:
System.IO.FileNotFoundException: 'Could not load file or assembly 'MyLibObjectsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.'
If I loaded all dependencies, it works fine.
Should I load all dependencies when using AssemblyLoadContext.Default or it's a bug?
I asked this question in the dotnet project
All credit go to #vitek-karas.
The detailed answer is:
Currently this is by design. LoadFromAssemblyPath as well as any other LoadAssembly-like methods only ever load that assembly, they don't try to load a "plugin". For this case to work you would need the AssemblyDependencyResolver and hook it up to the Default ALC (probably via the Resolving event), and hope that there are no collisions between the host app and the plugin (since they will share all dependencies) and so on. Generally this is why it's better to load plugins into their own ALCs as that creates the necessary isolation and also makes it easy to hook up AssemblyDependencyResolver.
Higher-level answer - in 3.0 we didn't try to provide a "plugin load" API as there were too many open questions in how it should behave (the exact isolation behavior is very tricky to get right so that it would work for most use cases). Instead we provided the necessary building blocks (ALC, ADR, diag improvements, ...) and rely on users to write the cca 20 lines of code to implement the custom ALC. In 5.0 we are improving diagnostics by adding detailed tracing around the entire assembly binding process, that should help debugging issues when loading assemblies in general, but specifically when implementing custom ALCs.

Referencing library using Windows.winmd

What I'm trying to do
I'm trying to create a library (Arduino.dll) to interact with my Bluetooth device from a laptop (Windows 10). This library is intended to be used by a desktop application.
To achieve that, I had to reference both Windows.winmd and System.Runtime.WindowsRuntime.
What's working
I did write the library and tested it on a console application which was on another project in the same solution. To make it work, I had to reference the project and Windows.winmd in the test project. Note that this test project is used to test all of my libraries, so it is heavily manipulated and I tinkered with the settings a lot for years.
What's not working
I finished to write my dll, and wanted to use it in my desktop application. Therefore, I referenced both Arduino.dll and Windows.winmd as in my test project, expecting to work the same way. Sadly, on running the application, I got a "dll not found" when instantiating a class for Arduino.dll :
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in LuxAFX4.exe
Additional information: Could not load file or assembly 'System.Runtime.WindowsRuntime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.
Strange, but well, I tried to reference the (same) System.Runtime.WindowsRuntime as in Arduino.dll but no luck, I now got an even weirder error :
An unhandled exception of type 'System.BadImageFormatException' occurred in LuxAFX4.exe
Additional information: Could not load file or assembly 'System.Runtime.WindowsRuntime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)
During my search for a solution, I understood that I shouldn't try to load this "reference library" and if it is not found, it must be because it is not installed on the system. But then, why would it work in my test project?
Another thing I may have understand, is that if my library doesn't expose members of referenced 'sub'-libraries, they won't be needed when referencing my library. Should I try to 'hide' all references? If so, is there a way to catch all exposed members? Source : How to to avoid referencing a dll's referenced dll
Side note : I use C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5.1\System.Runtime.WindowsRuntime.dll and C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Windows.winmd.
May be related : Could not load file or assembly Windows.winmd and How to reference Windows.winmd from a .NET Core library?
After some more research, and with the hint given by Hans Passant, I finally understood that I had chosen the wrong System.Runtime.WindowsRuntime.dll to start with. Changing it to use C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.WindowsRuntime.dll instead in both the project with the DLL and the project using it, resolved my problem.
I got the new file location here : C# “await” error when using WinRT from Desktop app

Why does Powershell error importing a module by demanding a specific assembly version?

I have a PowerShell module (.NET assembly) that references the Autofac v3.5.2 and Autofac Configuration v3.3.0 libraries. When I load this module in PowerShell:
PowerShell.exe -NoExit -Command "& {Import-Module -Name .\MyModule.dll }
PowerShell opens, but displays the error:
"Could not load file or assembly 'Autofac, Version=3.3.0.0,
Culture=neutral, PublicKeyToken=17863af14b0044da' or one of its
dependencies. The system cannot find the file specified."
However, making the same Autofac references from within a Forms or WPF app does not result in an error - everything loads correctly. Note that both the module and UI apps invoke AutoFac Configuration code - they aren't just making reference to those two libraries.
I double checked all the assembly references and they're all set to "Specific Version=False". What then about PowerShell is telling it to require a specific version of the assembly?
Based on your most recent comment, you might also have some luck handling AppDomain.CurrentDomain.AssemblyResolve as per the article linked below. I've only ever used this when creating proxies that load an appropriate x86 or x64 assembly at runtime, but it does appear you can use it for version forwarding too.
http://blog.slaks.net/2013-12-25/redirecting-assembly-loads-at-runtime/

Dynamic Assembly Loading in .Net 4.0

My problem begins with moving a .Net 2.0 application to .Net 4.0. The reason I had to do this was that Windows 8 does not enable the earlier .Net versions by default and my application cannot ask the user to enable it.
The application is a NPAPI plugin which uses .Net components via UnmanagedExports. I designed it as a low integrity application and therefore it has to reside in the users 'LocalLow' directory.
In my application I used a dynamic assembly loading mechanism to load several assemblies at runtime. I used the following method to load an assembly,
MyInterface Instance;
Assembly assembly = Assembly.LoadFrom(AssemblyFile);
Type type = assembly.GetType(Identifier); // Identifier is implementing the MyInterface
Instance = Activator.CreateInstance(type) as MyInterface;
// Do something with the Instance
After modifying the project to .Net 4.0, I noticed that the plugin crashes when the binaries are placed inside the LocalLow directory (It works in other places). My next step was to create a minimalistic plugin with least possible code to figure out the issue. I noticed that the dynamic assembly loading failed with the following exception,
System.IO.FileLoadException: Could not load file or assembly '<assemblyPath>' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515 (COR_E_NOTSUPPORTED)) --->
System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=131738 for more information.
I tried the following approaches to create a separate domain and load the assemblies but with no luck,
http://blogs.msdn.com/b/shawnfa/archive/2009/06/08/more-implicit-uses-of-cas-policy-loadfromremotesources.aspx
http://www.west-wind.com/weblog/posts/2009/Jan/19/Assembly-Loading-across-AppDomains
Adding the configuration 'loadFromRemoteSources' did not work either. It seems that the .Net component does not load .dll.config files. (Could be because of UnmanagedExporting)
My questions are,
Is it possible to dynamically load an assembly from LocalLow?
Does the new CAS policy in CLR 4.0 apply to LocalLow as well? From what I understood so far it should affect only assemblies loaded over the network
Is there any other way to overcome this issue?
While it doesn't address your LocalLow issue specifically, if you are able to "read a file" from the directory, you might be able to use the "work around" detailed here:
How can I get LabView to stop locking my .NET DLL?

Categories