We know that there are many ways to inject dynamic connection libraries into other processes. The most common method is to use hook functions (hook), but this method mainly has two shortcomings: First, if a process does not load user32.dll, the Hook DLL will never be loaded. The timing problem loaded by the second HOOK DLL is only possible to load when the process issues a USER32 call. That is to say, the Hook DLL will not be loaded when the process is performing a complex numerical calculation without time for messaging. In theory, we have no precise approach to determine if our Hook DLL has been injected into the process we want. Another most common method is to use the function createremoteThread, and turn on a thread in other processes to load the DLL. It should be said that this is a relatively perfect solution, this method avoids all the shortcomings of the above-mentioned hook functions, but unfortunately this function can only be used under Winnt / 2000.
This article will discuss a new way to inject dynamic connection libraries into other processes. Its idea is similar to the method using the function createremoteThread, but can be used under operating systems such as Win9x, Win2K, WinXP. Here we will demonstrate how we are injecting DLL (InjectDll.dll) into the Explorer.exe process!
The idea of the program is as follows
1: Get the ID of any thread in the Explorer.exe process.
2: Depending on this thread, get this thread's handle handle
3: Hang this thread and save the current "context" of threads
4: Change the EIP pointer of this thread to point to our function (InjectCodefun), then restore this thread.
5: After the function of our load DLL is completed, hang this thread again, use the "context" we have saved before, restore this thread to the state before it is changed, and continues to run.
After several steps, the Explorer.exe process will load our DLL (Injectdll.dll), interesting is that Explorer.exe is not perpleted for this!
Below we will explain in detail how to program the above process.
The implementation of step 1 is easy, we only need to call the ToolHelp function to get what we have, here we don't explain, please refer to GetProcessID, GetThreadID in the source code.
Step 2 is more troublesome, and no function is provided in Win9x can get Thread Handle by Thread ID (fortunate is Win2K to provide this feature). Fortunately, we can find this function on some BBS abroad. It uses some undisclosed structures. The purpose of this article is not to discuss this problem. If you are interested, you can refer to our source code OpenThread2 function. The function of this function is to pass a Thread ID parameter to return the corresponding Thread Handle.
The implementation of step 3 is also easy and specified, we can easily complete the SDK functions such as SuspendThread, GetThreadContext.
Step 4 This step is the most important step. For convenience, we will reference the statement in our source code, please read the INJECTCODEINTHREAD function in the source code.
First change the EIP pointer of the thread, we can complete the following code
ThreadContext.eip = (dword) m_lpcodebase;
SetthreadContext (M_HINJECTTHREAD, & THREADCONTEXT);
Variable M_LPCodeBase points to our first address of the INJECTCODEFUN. The most critical part of this is how we produce our Load DLL function (InjectCodefun). Note that we cannot simply write a function in our program, then assign its first address to EIP. This is because the functions of the load DLL are to run in the Explorer.exe address space. If we use the functions in your address space, then it will inevitably lead to the system crash. The solution is to write the loaded DLL function (injectcodefun) to the address space shared by all programs, 0x800000 ~ 0xFFFFFFFF in Win9x is the address space we want, so how to write we write. DLL function placed in this address space? There are a lot of ways, we use a specification "memory image file" to solve this problem. We allocate a shared address space through function createFileMapping, then copy our loaded DLL function to this address space. The specific code Please invite the InitInject function in the source code.
There are two problems in the loading DLL function we write, we need to explain that in this function we can't use the variables defined in our own programs, the truth is the same as the above, because the address space is different. . And we can't call functions directly, such as directly using LoadLibray directly in INJECTCODEFUN. This is because if you use LoadLibray to use LoadLibray, you need to pass the program's IMPORT table, jump to reach the real Windows LoadLibray function. But different processes have different import, so we can't call functions directly. We can use a technology called "dynamic constructor" to create our functions. First get the direct address of the function loadLibray, and then use a special number to replace it as 0x11111111, and finally copy our function to the shared address space, search the shared memory find this special number, use The correct address we have received is replaced. The second interesting phenomenon is that the loading DLL function we have written (INJECTCODEFU) should not be returned. This is because this function is running in the thread of Explorer. We don't know the correct content of the stack. I don't know what the address pointed to by the ESP. If the function returns, we will lose control of the program. Our way is that after toning LoadLibray, send a custom message to our main program, and advertise our program has completed the load task, and then let the thread enter the dead cycle.
Step 5 When our program accepts a custom message, then hang this thread again, recover the "context" of our previously saved threads with function setthreadContext, and then restore this thread. The result is that Explorer.exe didn't feel it was interrupted.
The above is the method we introduced, and readers can refer to our source code to specifically understand the above methods. The function of the source code is to inject our DLL (InjectDll.dll) into Explorer.exe, which we created a new thread in INJECTDLL.DLL, and then display the current time on the upper left corner of the screen. The source code is divided into Win9x version and Win2K version. These two versions of the main differences are different from allocating shared memory. The source code has been compiled using VC6 under the operating system of PWN98, PWINME, WIN2K, WINXP.
The reader can find the source code in the "download" page of the following URL: http://webaide.myetang.com/ or http://netaide.top263.net/. Author: RobinHao (webaide2k@sina.com) reprint please obtain the author's consent.