When I need to inject my code into another process, I write a DLL and only inject LoadLibrary function call. Much more reliable this way: the OS applies relocation table, I have C and C++ runtimes in the injected code, the result is compatible with ASLR, if my DLL has other DLL dependencies the OS will load them first, etc.
Never worked on any software which does that. Checking DLLs the way you described is a guaranteed way to break software after a windows update, or a driver update.
There’re many reasons why foreign DLLs can be loaded into your process. CreateRemoteThread is on the exotic side of things, other reasons are way more common.
Direct3D runtime loads user-mode DLLs implemented by nVidia/Intel/AMD/vmware/etc. MediaFoundation runtime loads quite a few DLLs, some of them third-party, implementing various transforms like codecs and containers. Many security-related software like firewalls load their DLLs into every process to check things. Some system software implements custom network protocols in DLLs, e.g. both HyperV and VMWare do that for their virtual networks. Apps like spy++ are using system-wide hooks, again that’s a foreign DLL loaded into every GUI program on that desktop. Many productivity apps like MS Office or Photoshop support scripting, users can often consume arbitrary DLLs in these scripts using LoadLibrary, COM and/or .NET.
Sorry to bother, just very interested in this stuff!
The code being injected doesn't need to hardcode any absolute addresses of the dependent functions. It works fine when the OS kernel randomizes virtual addresses of all DLLs.
> how injecting a DLL works, compared to what's being done here?
Very similar, the main difference is what's injected.
The OP is injecting code and running it. The injected code needs to be position-independent, in practice this means it needs to be written in assembly, which is very hard to do for non-trivial things.
I normally use VirtualAlloc to allocate a UTF-16 buffer for the path of a DLL I made, then use CreateRemoteThread to run LoadLibrary function.
This way I can use normal C++ with all the features in the code being injected.
Windows Defender (Win10) reports a severe threat in nim-1.4.8\bin\vccexe.exe - Trojan:Win32/Wacatac.B!ml - which allows remote code execution.
It may be a false positive - but the whole post is about exploits so I'll probably not risk it.
I'm very much averse to trusting the supplier of an installer enough to disable security checks, especially for a development toolkit where on the remote chance it is real it propagates into what I build on that toolchain, so I'll probably revisit at a later date.
As a fan of Modula-2 and Pascal I've always found the look of the Nim syntax appealing, so I'm quite looking forward to another way of coding cross-platform desktop apps (I avoid Electron and Mono, which usually leaves Lazarus) and your post reads quite interesting in that regard.