During system-level security monitoring, remote code injection is often required to prevent Trojans.
The procedure is as follows:
1. Improve the process permissions. If the permissions are insufficient, OpenProcess may fail;
2. Determine your host process, that is, the process you want to inject code into. This is really easy to do. If you don't want your Trojan horse or virus to be ended at once,
It is best to select the process that must be enabled to run the system, such as the Resource Manager Process assumer.exe,
Windows subsystem process csrss.exe and so on, but here we note that the injection of the system process causes a failure,
So it is best not to experiment with system, and if you fail to inject, it will cause the host process to crash,
Wait until the next system process is crashed;
3. Open the host process (here I open the assumer.exe process). The idea is to first run all the processes running in the current system,
Traverse and obtain the PID of all processes, and then call the processisexplorer function to determine whether the process is a assumer.exe process,
If yes, you can record the PID of the process. In this way, the pid of the assumer.exe process is obtained,
Then open the assumer.exe process through OpenProcess;
4. Allocate a bucket in the host process. This bucket is used to store the thread processing routine of the remote thread we will create,
Note that the allocated memory must be labeled with execute, because the allocated memory is used to store thread processing routines,
The thread processing routine must be executed, so it must carry the execute mark. As for the write mark, it is obviously needed,
Because we must call writeprocessmemory in the subsequent code to write the thread processing routine to this memory, it must be writable;
5. Write the remote thread processing routine to 4 in the memory allocated in the host process. This can be achieved by directly calling writeprocessmemory;
6. Allocate a storage space in the host process. This storage space is used to store the parameters that we will pass to the remote thread processing routine,
The structure below shows that it consists of three parameters. The first parameter represents the content to be displayed in the dialog box,
The second parameter indicates the title to be displayed in the dialog box, and the third parameter is the address of the MessageBox API,
Because the address of MessageBox in assumer.exe is redirected, you need to pass the address to the thread processing routine through parameters;
7. Write the parameters to the memory allocated in the host process in step 6, and call writeprocessmemory to complete the process;
8. Call createremotethread to create a remote thread in assumer.exe (host process;
Note: When the remote thread is not executed, virtualfreeex cannot be used to release the memory in the remote process,
You think, all my fucking threads are still running in assumer.exe. You have to release the memory I occupied outside, and I am still running a fart!
So waitforsingleobject is called here to wait for the remote thread to complete the execution,
After it is executed, the storage space allocated in assumer.exe will be released!
See Code implementation and comments
/* Header file */# include <windows. h> # include <tlhelp32.h> /******************************** * ***** bool enableprivilege (pcstr name) * function to improve the permission ** the permission required by the pcstr name parameter ** returns the result *********************** * *************/DWORD enableprivilege (pcstr name) {handle htoken; bool RV; // set the token_privileges priv = {1, {0, 0, se_privilege_enabled}; // query the permission value lookupprivilegevalue (0, name, & priv. privileges [0]. luid); // open the process tokenope Nprocesstoken (getcurrentprocess (), token_adjust_privileges, & htoken); // adjusttokenprivileges (htoken, false, & priv, sizeof priv,); // return value, error message, if the operation succeeds, it should be error_success, Which is ORV = getlasterror (); // disable tokenclosehandle (htoken); Return RV ;} /************************************* bool loadrometedll (DWORD dwprocessid, lptstr lpszlibname) * function by creating a remote thread to load DLL to other processes ** parameter DWORD dwprocessid target process PID * lptstr lpszlibnamed Ll path * returns whether it is successful ********************************* * ***/bool loadrometedll (DWORD dwprocessid, lptstr lpszlibname) {bool bresult = false; handle hprocess = NULL; handle hthread = NULL; pstr pszlibfileremote = NULL; dword cch; pthread_start_routine pfnthreadrtn; __try {// obtain the handle of the process to inject code. hprocess = OpenProcess (process_all_access, false, dwprocessid); If (hprocess = NULL) _ leave; // calculate the number of bytes required for the dll path name. CCH = 1 + lstr Len (lpszlibname); // allocate space for the path name in a remote thread. pszlibfileremote = (pstr) virtualallocex (hprocess, null, CCH, mem_commit, page_readwrite); If (pszlibfileremote = NULL) _ leave; // copy the dll path name to the memory space of the remote process. if (! Writeprocessmemory (hprocess, (pvoid) pszlibfileremote, (pvoid) lpszlibname, CCH, null) _ leave; // obtain the real address of loadlibrarya in kernel32.dll. pfnthreadrtn = (pthread_start_routine) getprocaddress (getmodulehandle (text ("Kernel32"), text ("loadlibrarya"); If (pfnthreadrtn = NULL) _ leave; // create a remote thread and call the user's DLL file through the remote thread. hthread = createremotethread (hprocess, null, 0, pfnthreadrtn, (pvoid) pszlibfileremote, 0, null ); If (hthread = NULL) _ leave; // wait for the remote thread to terminate. waitforsingleobject (hthread, infinite); bresult = true ;}__ finally {// close the handle. if (pszlibfileremote! = NULL) virtualfreeex (hprocess, (pvoid) pszlibfileremote, 0, mem_release); If (hthread! = NULL) closehandle (hthread); If (hprocess! = NULL) closehandle (hprocess);} return bresult ;} /************************************* bool getprocessidbyname (lpstr szprocessname, lpdword lppid) * function: Obtain the PID of a process using the process name. ** the lpstr szprocessname process name * lpdword lppid points to the variable storing the PID * returns the result ************* * **********************/bool getprocessidbyname (lpstr szprocessname, lpdword lppid) {// variable and initialization startupinfo st; process_information PI; processentry32 pS; handle hsnapshot; Zeromemory (& St, sizeof (startupinfo); zeromemory (& Pi, sizeof (process_information); ST. CB = sizeof (startupinfo); zeromemory (& PS, sizeof (processentry32); PS. dwsize = sizeof (processentry32); // process hsnapshot = createconlhelp32snapshot (th32cs_snapprocess, 0); If (hsnapshot = invalid_handle_value) {return false;} If (! Process32first (hsnapshot, & PS) {return false;} do {// compare process name if (lstrcmpi (PS. szexefile, "assumer.exe") = 0) {// find * lppid = ps. th32processid; closehandle (hsnapshot); Return true ;}} while (process32next (hsnapshot, & PS); // No closehandle (hsnapshot) found; return false ;} /************************************* int winmain (* hinstance, * hinstance hprevinstance, * lpstr lpcmdline, * int ncmdshow *)********************* * ***************/INT winmain (hinstance, hinstance hprevinstance, lpstr lpcmdline, int ncmdshow) {DWORD dwpid; // raise the permission and obtain the se_debug_name permission. // you can write and create the thread if (0! = Enableprivilege (se_debug_name) return 0; // obtain the pidif (! Getprocessidbyname ("assumer.exe", & dwpid) return 0; // load the DLL by creating a remote thread // place MSG. dll in the system directory if (! Loadrometedll (dwpid, "MSG. dll") return 0; return 1 ;}