Executing code in main thread via dll injection - c#

I need to inject a dll into the main thread of a process (otherwise my process will crash)
How would I go about doing this? My dll is in C++ obviously, my injection method though uses C# and CreateRemoteThread.
I've tried using std::thread(func) but that didn't work (of course it probably wouldn't since it most likely creates a new thread)
I don't know if this is a problem for my DLL or my injector, so all help and attempts to help is appreciated.

Your DllMain will run in the context of every thread... figure out which is the main thread.
Since you can't do much while the loader lock is held, create a callback with thread affinity (for example using SetTimer) and do all the work from that callback.

You can create the target process suspended and use CreateRemoteThread() for injection, but mind the following limitations:
You should copy the thread main routine for the remote thread to the address space of the target process.
This code cannot contain any external references (e.g. CRTL or direct WinApi calls). I would usually limit this code to loading of the DLL and either executing function from it, or relying on the DllMain to do the job you need. In order to call LoadLibrary and GetProcAddress methods, I obtain their addresses and copy structure containing this information to the target process and pass the address of the remote structure as an argument for the thread main routine in CreateRemoteThread(). You can use VirtualAllocEx() to allocate memory in the remote process,
Remote thread in this situation will be executed before main thread, including process and some Win32/64 initialization. Therefore, not every Win32 API is safe to call in this condition.
You can read more here: http://blogs.microsoft.co.il/pavely/2017/03/14/injecting-a-dll-without-a-remote-thread/

Related

How to handle blocking synchronous external DLL methods

Recently I worked with an external dll library where I have no influence on it.
Under some special circumstances, a method of this third party dll is blocking and never returning.
I tried to work around this issue by executing this method in a new AppDomain. After a custom timeout, I wanted to Unload the AppDomain and kill all this crap ;)
Unfortunately, it does not work - as someone would expect.
After some time it throws CannotUnloadAppDomainException since the blocking method does not allow aborting the thread gracefully.
I depend on using this library and it does not seem that there will be an update soon.
So can I work around this issue, even if it's not best practice?
Any bad hack appreciated :)
An AppDomain cannot typically solve that problem, it's only good to throw away the state of your program. The real issue is that your thread is stuck. In cases like these, calling Thread.Abort() is unlikely to work, it will just get stuck as well. A thread can only be aborted if it is a "alertable wait state", blocking on a CLR synchronization object. Or executing managed code. In a state that the CLR knows how to safely clean up. Most 3rd party code falls over like this when executing unmanaged code, no way to ever clean that up in a safe way. A decisive hint that this is the case is AppDomain.Unload failing to get the job done, it can only unload the AppDomain when it can abort the threads that are executing code in the domain.
The only good alternative is to run that code in a separate process. Which you can kill with Process.Kill(). Windows do the cleanup. You'd use a .NET interop mechanism to talk to that code. Like named pipes, sockets, remoting or WCF. Plus the considerable hassle of having to write the code that can detect the timeout, kills the process, starts it back up and recovers internal state since you now restart with an uninitialized instance of that 3rd party code.
Do not forget about the real fix. Create a small repro project that reproduces the problem. When it hangs, create a minidump of the process. Send both to the 3rd party support group.
after reading this (scroll down the end to Blocking Issues) I think your only solution is to run the method in a different process - this might involve quite a bit of refactoring and/or a 'host' project (eg Console application) that loads the method in question and makes it easy to call (eg reading args from command line) when launching the new process using the Process class
You can always use background worker, no need to create a new appdomain. This will ensure that you have complete control over the execution of the thread.
However, there is no way to ensure that you can gracefully abort the thread. As the dll is unmanaged, chances are there that it may cause memory leaks. However, spawning a new thread will ensure that your application does not crash when the Dll does not respond.

COM Interop hang freezes entire COM system. How to cancel COM call

I am using a third party dll that is exposed via a COM Interop wrapper. However, one of the COM calls often freezes (never returns at least). To try to at least make my code a little more robust, I wrapped the call asynchronously (_getDeviceInfoWaiter is a ManualResetEvent)
var backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork +=
(sender, eventArgs) =>
{
var deviceInfo = _myCom.get_DeviceInfo(0);
_serialNumber = deviceInfo.SerialNumber;
_getDeviceInfoWaiter.Set();
};
backgroundWorker.RunWorkerAsync();
var waitFifteenSecondsForGetInfo = new TimeSpan(0, 0, 0, 15);
_getDeviceInfoWaiter.WaitOne(waitFifteenSecondsForGetInfo, true);
if(String.IsNullOrEmpty(_serialNumber))
throw new ArgumentNullException("Null or empty serial number. " +
"This is most likely due to the get_DeviceInfo(0) COM call freezing.");
However, the very next call to any COM component will freeze the code. Is there something I am not thinking of, or is there some way to keep my main thread from dying?
UPDATE
Basically, this is a COM call that is called whenever a new device is plugged into the PC so that we can log the information appropriately. However, as I said, ANY COM component will freeze if this one is waiting (a custom COM of our own locks if the third party locked)
UPDATE 2
The above code DOES work, and delays the hanging of the UI thread until the next COM call. The reason for this attempted workaround was because var deviceInfo = _myCom.get_DeviceInfo(0); was already locking the UI thread. However, this info is not important and is only used for logging, so this approach is to allow for "give up and move on after 15 seconds" scenario
Another workaround here would be to find a way to cancel the COM call after x seconds?
UPDATE - after the second update from the OP
IF you have some problematic component you can always make your usage of it more robust by using the following approach:
Create a process (EXE) which wraps the usage of that component and exposes an API (for example via any IPC mechanism). You can then start that EXE as a separate process (from your main EXE) and use it... IF you need to kill that component after a certain time and/or when some condition is met you can always kill that "wrapper EXE" from your main EXE... depending on the specific component it might even be useful to implement some special "cleanup code" (possibly in a separate thread) within that "wrapper EXE" which gets executed when you need to kill that "wrapper EXE".
Since you are implementing this in .NET you can even have that "wrapper EXE" as "embedded resource" in your main executable and start it even from RAM without writing it to the filesystem...
The third party DLL has some kind of indefinite wait, loop or deadlock inside it. Attempts to work around it like this will not work. You may have farmed out the hanging call to a worker thread, but that thread doesn't go away; it keeps hanging in that call.
The next call to the COM component freezes most likely because the previous one froze. Maybe it's trying to acquire a lock that the previous one acquired before hanging. Or maybe it's hanging for exactly the same reason, rather than a dependent reason.
Better contact the developers/vendors of this third party thing and ask them if you're misusing it in some way. Is there some missing precondition. Some initialization that wasn't performed. Some necessary configuration, etc.

CLR managed threads: lightweight vs heavy process

I'm working on an application that process pipelines in separate threads. During my tests I have seen that if a process is "lightweight" or the CLR determines that this is going to end quickly CLR recycle this thread rapidly and various units of work can share at the same time the same thread.
On the contrary if a process take's some time or has more load CLR open different threads.
To me all that difficult TLS Thread local storage programming.
In fact my application pipelines take some time to process and it seems that CLR is always assigning one managed thread for each other. BTW if in some case two pipelines share one managed thread they will collide because they use TLS variables.
After all that here comes the real question... Can I do the assumption that If a process takes some time/load it will always use it's own thread, or am I crazy doing that?
For what I have been reading managed threads in .net 3.5 is like acting with a kind of black box. So perhaps this question can never really be responded.
EDIT:
With process I am refereing to the dictionary definition A series of actions, changes, or functions bringing about a result an not the computer process you identify in task manager.
Can I do the assumption that If a process takes some time/load it will
always use it's own thread, or am I crazy doing that
Process always uses its own threads. It's not possible access other process's thread, not that I'm aware of.
Code run from a threadpool thread should not place anything in thread-local storage which it is not going to remove via finally block. If you need to ensure that any thread-local storage used by a piece of code will die after that code finishes executing, you need to explicitly either clean up the storage or run that code in its own thread.

How do you handle a thread that has a hung call?

I have a thread that goes out and attempts to make a connection. In the thread, I make a call to a third party library. Sometimes, this call hangs, and never returns. On the UI thread, I want to be able to cancel the connection attempt by aborting the thread, which should abort the hung call to the third party library.
I've called Thread.Abort, but have now read that Thread.Abort only works when control returns to managed code. I have observed that this is true, because the thread never aborts, and I've been sitting on Thread.Join for ten minutes now. What should I do with this hung thread? Should I just null the reference and move on? I'd like to be as clean as possible--
Random thought: I wonder if you could write a second assembly as a small console exe that does this communication... launch it with Process.Start and capture results either via the file system or by intercepting stdout. Then if it hangs you can kill the process.
A bit harsh, maybe - and obviously it has overheads of spawning a process - but it should at least be possible to kill it.
This function in your third-party library doesn't have a timeout or cancel function? If so, that's pretty poor design. There's not going to be any pretty solution here, methinks...
Unfortunately, there's no way you're going to get around it, short of using the Win32 API to kill the thread manually, which is certainly not going to be clean. However, if this third-party library is not giving you any other options, it may be the thing to do. The TerminateThread function is what you'll want to use, but observe the warning! To get the thread ID to pass to this function, you have to use another Win32 API call (the Thread class doesn't expose it directly). The approach here will be to set the value of a volatile class variable to the result of GetCurrentThreadId at the start of the managed thread method, and then use this thread ID later to terminate the thread.
Not sure if this will do it or be acceptable, but its worth a shot.
[DllImport("kernel32.dll")]
private static extern bool TerminateThread (Int32 id, Int32 dwexit);
From the documentation
TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:
If the target thread owns a critical section, the critical section will not be released.
If the target thread is allocating memory from the heap, the heap lock will not be - released.
If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.
Managed threads can't directly stop native threads. So if the call is blocked in native code then the best you can do is have the managed thread check then terminate once it returns. If it never returns, maybe there's a version of the call with a timemout?
If not, killing the thread (through win32) is not usually a good idea...
Not a good solution to ever wait on a thread (in any language) indefinitely, especially if you are making external calls. Always use a join with a timeout, or a spin lock that monitors the state of a shared atomic variable until it changes, or you reach a timeout. I'm not a C# guy, but these are all sound concurrency practices.

Unmanaged thread running Managed Code

I made a software that loads external module made by clients.
This software is supposed to be HA (High availability) meaning it CAN'T be allowed to crash.
For that purpose, I created a class which creates a thread, run the client module function in it, and returns. The class allows a certain time to execute the function, and if it takes too long, it kills the thread. Like this, if the client screwed up his module by having an infinite loop or whatever in his code, the rest of the system doesn't freeze.
Now, the question I have...If the thread running the function is created in unmanaged code (C++) and the module function running in it is managed code, what kind of problem could I have by killing the thread?
Thanks,
In general, it's unsafe to kill a thread in a running process; see the warnings and notes in TerminateThread.
If I were doing such an app, I would be inclined to investigate ways to host the 3rd party module within a separate process with a well-defined communication interface; eg: inside a COM+ application. This would allow you to kill the entire process if it gets "out of control", without affecting the stability of the "host" process.

Categories