----------- Transfer from: http://antghazi.yeah.net
Fully hidden by implementing the process under Winnt & Win2k
In the face of many computer masters, consider for a long time, finally decided to come out
Try to use the most simple and easy words and examples in the article, I hope to be able to
Beginners are helped with advanceders.
Regarding the hidden process, 98 counts count counts. Hidden under Winnt / Win2k
Method, the masters of Xiqi SHOTGUN have released an example online last year.
The mystery of Mao Horse, I also read his article many times, to his computer
Horizontal and enthusiastic help friends feel admiring. Here is the text of SHOTGUN
The supplement and in-depth introduction of the chapter, well, gossip less.
In WinNT, "True Hidden Process", it can be found, it is impossible to achieve, only
We want our program to run in the form of the process kernel, it is impossible to flee Ctrl Alt
Del's mental eye. So strange, is this not with our title "WinNT & Win2k
Is there a contradiction of the fully hidden hidden? Yes, it should actually be: in non-process party
Implement the target code, and evade the process viewer's check, thereby reaching "process hidden"
purpose.
We used here, in the host process, perform our code in the way. real
It is very simple to get up. First, let's build a thread that does not perform any statement.
DWORD stdcall threadproc (lpvoid * lpvoid) {
Return 0;
}
Then, copy the thread code to anywhere in the host process (ie, the page belongs)
Sex PAGGE_EXECUTE_READWRITE, such as: sharing memory, within the host process
. Here we choose the host process, when you copy it, we need to make it in the host process.
Apply for a memory with the VirtualAllocEx function, then use WriteProcessMemory
Write the thread body into the host process.
After the above work is completed, we can activate its execution in the CreateremoteThread function. Let's give a complete example
// Remote thread executive
DWORD __STDCALL THREADPROC (Void * LPpara) {
Return 0;
}
INT Main (int Argc, char * argv []) {
Const dword threadsize = 1024 * 4; // Temporary wire consisting of 4K, actually
Not so big, I will introduce later.
DWORD BYTE_WRITE;
/ / Get the specified process ID handle, and set it to process_all_access, 992 is
The ID number of the casual process, the method of getting the ID number here, I don't talk much here.
Handle hwnd = :: OpenProcess (Process_all_Access, False, 992);
IF (! hWnd) Return 0;
Void * premothetread = :: virtualalocex (hwnd, 0, threadsize, mem_mit
| MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Application
IF (! premotethread) Return 0;
IF (! :: writeprocessmemory (hwnd, premothetread, & threadproc, threadsize
, 0) // Write process
Return 0;
// Start thread
Handle hthread = :: CreateremoteThread (hwnd, 0,0, (dword)
__stdcall *) (void *)) premotethread, null, 0, & byte_write); if (! hthread) {// There is memory allocation un release
Return 0;
}
Return 0;
}
Here, for hidden methods, I will tell a paragraph, I believe 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 us
Segment-type memory management Win2K operating system, compile all constant when compiling
In the .data section of the PE file, the code segment is in .text, so we copied to the host
The code in the process is the code in .text, MessageBox (NULL, (CHAR *) pointer
, p, 0); the pointing address is the memory virtual address of the process. And in the host process
Law visits. The method of solving is simple, pressing "Hello" to go to the target according to the old photo
In the process, then then reference. In the same way, the MessageBox function address is compiled, it is also saved.
In .import, friends who wrote Win2K virus know that all constants and functions are entry
The site needs to be defined and drawing in the code segment, and we are also a bit similar to him. Master-retired
Similarly, we also write the entry address of the function to the target process.
// Define the parameter structure
Typedef struct _remotepara {// parameter structure
Char PMessageBox [12];
DWORD DWMESSAGEBOX;
Remotepara;
// pay
Remotepara myremotepara;
:: ZeromeMory (& myRemotepara, Sizeof (Remotepara);
Hinstance huser32 = :: loadLibrary ("user32.dll");
MyRemotepara.dwMessageBox = (DWORD) :: getProcaddress (HUSER32, "MessageBoxa);
STRCAT (MyRemotepara.pMessageBox, "Hello / 0");
// Write into the target process
Remotepara * premotepara = (remotepara *) :: VirtualAllocex (hwnd
, 0, sizeof (transotepara), MEM_COMMIT, PAGE_READWRITE); // Note Application
Page Protection Properties at Space
IF (! premotepara) Return 0;
IF (! :: writeprocessmemory (hwnd, premotepara, & myremotepara, Sizeof
MYREMOTEPARA, 0) RETURN 0;
// Start transfer to pass the parameters into
Handle Hthread = :: CreateremoteThread (hwnd, 0,0, (dword (__stdcall)
*) (void *)) PremoteThread, PremotePara, 0, & Byte_write;
IF (! hthread) {
Return 0;
}
Ok, it is so 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;
// Remote thread
DWORD __STDCALL THREADPROC (Remotepara * LPPAR) {
Typedef int (__stdcall * mmessageboxa) (HWND, LPCTSTR, LPCTSTR
DWORD); / / Define the MessageBox function
MMessageBoxa mymessageboxa;
MyMessageBoxa = (MMessageBoxa) LPPARA-> dwMessageBox; // Get function entry address
MyMessageBoxa (Null, LPpara-> PMessagebox, LPpara-> PMessageBox, 0); // Call
Return 0;
}
Void enabledebugpriv (); // upgrade application level debug permissions
INT Main (int Argc, char * argv []) {
Const DWORD Threadsize = 1024 * 4;
DWORD BYTE_WRITE;
Enabledebugpriv (); // upgrade permissions
Handle hwnd = :: OpenProcess (Process_all_Access, False, 992);
IF (! hWnd) Return 0;
Void * premothetread = :: virtualallocex (hwnd, 0, threadsize,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE
IF (! premotethread) Return 0;
IF (! :: writeprocessmemory (hwnd, premothetread, & threadproc, threadsize, 0))
Return 0;
// pay more
Remotepara myremotepara;
:: ZeromeMory (& myRemotepara, Sizeof (Remotepara);
Hinstance huser32 = :: loadLibrary ("user32.dll");
MyRemotepara.dwMessageBox = (DWORD) :: getProcaddress (huser32
, "MessageBoxa");
STRCAT (MyRemotepara.pMessageBox, "Hello / 0");
// Write into the target process
Remotepara * premotepara = (Remotepara *) :: VirtualAllocex
(HWND, 0, SIZEOF (Remotepara), MEM_COMMIT, PAGE_READWRITE); // Note
Page attributes when applying for space
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 *)) PremoteThread, PremotePara, 0, & Byte_Write
);
IF (! hthread) {
Return 0;
}
Return 0;
}
// Extremely permission Void EnableDebugPriv (Void)
{
Handle htokeen;
Luid SedbugnameValue;
Token_Privileges TKP;
IF (! openprocesstoken (getCurrentProcess (),
Token_adjust_privileges | token_query, & htokeen))
Return;
IF (! LookupprivileGevalue (NULL, SE_DEBUG_NAME, & SEDEBUGNAMEVALUE) {
CloseHandle (HTOKEN);
Return;
}
Tkp.priVilegect = 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, after the program is executed, it will create a thread in the process of the process number 992, pop-up
Hello dialog. Is it very simple?
There are several places to pay attention to here:
1. When the remote thread applies for space in the host process, the space size is determined, I have been
Unable to solve problems. I used two closer threads to be large.
Small, plus the parameter size, as the application space, there will still be illegal operation, as follows
:
Static Void StartThread (LPVOID * LPPAR) {
Return;
}
Static void endthread (LPVOID * LPPARA) {
Return;
}
Then use dword dwlenght = (dword) ((char *) & startthread - (Char
*) & Endthread); // Get the length of the StartThread thread code,
DWLENGHT = SizeOf (threadpara);
I will still have illegal operations to make me confused. In Win2K, the thread's default stack of pages
Small is 4KB, here I applied for the size of the application for the thread, the application is temporarily used
The number, always 4KB multiple, try to get big, after the thread can be successfully run,
A little bit changed. The way is stupid. If the friends here have a better way, please don't give
teach.
2, what should be, what parameters need to be transferred from the outside? I haven't been here.
A very powerful answer, my understanding is: in the PE file except for the .TEXT section
If you have a section, you need to use external parameters to be delivered to the thread, such as: .rsrc, .data, RDATA
Waiting for other 15 festivals. In the process of our actual written, beginners don't know our
Where is the code compile? This time, we can run away Alt 8
(Middle shortcut "in vc) is compiled, generally there is Lea Eax P, Push Offset P
Address statement, this time, we must not pass in parameters. So everyone is
When writing, you must pay attention to the parameters, because the implementation of the thread is in other processes, one
A normal permission application is unable to span the process to debug other processes. Including VC,
It is also unable to debug our remote thread, familiar with the compilation of friends, can use Softice to debug, this requires a certain substrate.
3, permission, this is very important, SHOTGUN is also very clear in this regard, online
There are also many related articles, I will not say much. Enabledebugpriv function in the article
Create this process in the process of Internet, WinLogin, LSASS. Win2k
Process Viewer cannot kill it.
4, the process ID is more way, such as Enumprocesses, CreateToolhelp32Snapshot
/ Process32first / process32next, ntquerysysteminformation et al.
Number can, in order to reduce the code, the process ID in the example is directly obtained in the process viewer.
.
Finally, we will return to SHOTGUN's article, then we have been very clear because they are already very clear.
Why do you have a DLL file in the method. The thread of the remote thread itself is loadingLibrary
Function, ie, the entrance address of the thread is the entry address of LoadLibrary, which is the system.
Functions in kernel32.dll, any process can be called. Loadlibrary in thread
The function loads our DLL into the system space, the thread is executed, and our DLL starts.
Already working. After the thread execution is over, don't forget to use VirtualFreeex to apply it within it.
The storage area is released.
Two methods are compared, it is obvious:
1. When using the DLL, create is very simple, nor does it require too much operating system and memory
Be knowledgeable and you can debug DLL file directly. It is relatively simple to achieve.
2. The method directly copied into the process is slightly complicated, and it is easy to appear.
Illegal operation. Of course, I also removed the annoying DLL file. After the program is executed, it is very
It is difficult to find his source, which is the preferred method of hiding horses outside the virus.
Here I will refer to the source code of the nongmin.cn program, and his procedure is for me.
Help very much. Although there is no face, it is very admired with his computer level.
And respect the style of his style, all the non-commercial software or small code I have written later, all from the source code
Good computer, friends engaged in computer work.