📜 ⬆️ ⬇️

Features of the introduction of DLL and installation of hooks in Modern-applications Windows 8/10

Why do you need to inject your DLLs into other processes and install hooks there? In order to understand what functions this application will call, with what parameters and what these functions will be returned. Thus, we can understand the internal logic of this application, find out which files it is trying to gain access to, what data is being sent over the network, we can add logging, profiling, debug a bug, get some data from the application, or vice versa - add its interface anything we need. Hooks use the well-known Spy ++ utility for working with application windows, DirectX debuggers like RenderDoc , some utilities from SysInternals, programs like ApiMonitor , etc.

Some time ago I wrote introductory articles about using hooks using the examples of the Microsoft Detours and madCodeHook libraries (if you are not familiar with hooks at all - this is where to start). The technician described there is enough to work with ordinary applications, but time does not stand still, and today we already have Metro Modern-applications that come with Windows 8 and Windows 10, as well as third-party software distributed through Microsoft Store. For example, the new Spartan browser is a Modern application. The introduction of DLL in these processes has its own characteristics and at first glance it may even seem impossible, but it is not. In this article I will tell you how we can get inside the Modern-application and install hooks in it for our insidious purposes.


32-bit and 64-bit applications
The Windows operating system is 32-bit and 64-bit. Accordingly, Modern applications can also be 32-bit or 64-bit. When the application is downloaded to the Microsoft store, the developer builds both versions (plus, perhaps, ARM), and Windows itself decides which one to download to the user. This leads to the obvious conclusion that the DLL, which we will implement in the Modern-application, should also be in two versions. A less obvious conclusion is that the application that will “throw” our DLL-ku into someone else's process must also have corresponding bitness. After all, we need to start a thread inside another process that will load our library and call some function from it. This is done through a call to CreateRemoteThread (Ex), but now it requires the same bitness of the calling and called processes (and how else to pass addresses?).
')
Those. as a result, our kit will consist of two “implemented” libraries and two “injectors”:


Access to the DLL being implemented
As you may know, Modern-applications live in their sandboxes, from where they have access only to their own folder and some other (limited) OS resources available to them. For example, a Modern-application cannot simply take and open any file from a disk. For us, this means that by trying to force someone else's application to load our library into its address space, we will get an access error. This can be easily seen using, for example, the ProcMon utility.



What to do? Allow file access to the embedded library for Modern applications. For this there is a system utility icacls. This command opens access to the file on the disk for all Modern applications:

icacls.exe some_file.ext /grant *S-1-15-2-1:(F) 


Now we will not have access errors.

Link DLLs
But not everything is so simple. DLLs may have dependencies. And even if it seems to you that there are none, you may forget about the dependency on the VC ++ Runtime Library. By default, the library created in Visual Studio C ++ assumes dynamic linking with the C ++ runtime library. This means that when an application wants to load your library, the LoadLibrary () function first sees that you need, for example, the msvcp90r.dll library and will try to find it, which in general will work if we are talking about the usual ( non-modern application and the availability of the corresponding VC ++ Redistribution Package. As for Modern applications, the search order for a DLL is quite different . In short: being called from a Modern-application, LoadLibrary () will not find the VC ++ Redistribution Package library, even if they have been successfully installed before.

This is a bit unexpected and slightly surprising. Options out of the situation:


The first two methods are extremely ugly (and without an administrator account they are impossible), the third one will work, but it affects the global configuration of the OS, which can also be fraught with consequences. So the simplest option is static linking (/ MTd and / MT keys on the Code Generation tab).



Digital signature
Having solved all the issues with access to the DLL file, it may seem that everything worked out for us - ProcMon does not show any access errors. But the injection still does not work - DLL-ka does not appear in the list of loaded process modules. What went wrong? This question is answered by viewing the Windows Event Viewer.



The operating system does not want to load our DLL, because it is not signed. At this point, I became anxious, since I already thought that all modules loaded into the Modern-application should be digitally signed by one publisher (developer). But, fortunately, it is not. Windows requires that DLLs simply have a valid digital signature, but does not require its matching the signature of the application author. Those. we can take a signed DLL from Chrome and drop it into Spartan. What should we do? Get a certificate and sign our DLL.

Yes, it seriously complicates the work. But after all, in principle, if we develop a normal product, and not any viruses \ Trojans \ Malvari \ Keyloggers \ Lockers - we will not have problems with obtaining a certificate and using it to sign DLLs. In general, I consider this protection one of the most serious steps Microsoft takes in protecting user data and isolating Modern applications in the sandbox. In fact, those who wish to forward the bridge to the application are required to submit documents and identify themselves, and this will stop 99% of the script Kiddies.

Access rights to the communication channel
Ok, now our DLL is embedded in someone else's process, it can hang hooks on various system functions, do something useful, but ... It lives in the same sandbox as the parent process, that is, neither send the data "outside" , it cannot receive commands "from outside", because for this it is necessary to create a communication channel, to which it does not have rights by default. I have already described how to solve this problem separately in this article , but here I simply mention it as an item that is important not to forget.

Source: https://habr.com/ru/post/256829/


All Articles