Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Tell me why processes are hidden in the windows kernel.

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/03 Report--

  has not written a blog for a long time. Recently, he took the time to sort out these bits and pieces of knowledge and share them with more friends for fun. He still forgot to post them in the draft box for several days.

Next, let's talk about the theme of this article, hiding two words.

What does it mean to hide?

  doesn't want to be discovered, and so is human nature.

Second, why hide it?

  actually thinks that this is fundamental. Why do you want to hide your own processes and threads when you write a program? Why? It's just that you don't want others to know, or you shouldn't let others know. There are a lot of undisclosed things under windwos, which is hidden. In the face of object programming encapsulation, this is also hidden. Some viruses, actually called malicious code, are more friendly and prefer to hide or attach to normal processes to deceive computers and antivirus software, which are all hidden. Yeah, there are some dark secrets.

Third, hiding for the process can deceive antivirus software? Or system monitoring tools?

  at least at present I have not seen by hiding the process can be hidden, does not mean that there is no, the pattern is limited. After hiding the process, the windows system comes with the task manager can no longer see the process, but you can find an ARK to see the hidden process, you can also use procexp or velvet sword and other tools to check, why hide the process these tools can still be found?

IV. Talking about the hiding process

  because the windows user layer, that is, the task manager relies on the linked list structure (_ LIST_ENTRY) to traverse the processes under the operating system, in fact, earlier did not understand the importance of the linked list under widnows (at that time, I learned that the two-way linked list and tree under windows were very important), and later learned that, um, actually do not rely on winAPI to do what they want to do, it is really important. Two-way linked list Please see the previous blog two-way linked list: https://blog.51cto.com/13352079/2128624

The structure _ EPROCESS is populated when the   creates the process (see Snow Forum search for a detailed creation process), so that there will be data and content in our _ EPROCESS. Different operating systems may have different data about this structure. Enter: dt _ EPROCESS in windbg to view the content and offset of the structure.

The   windows kernel is divided into executor, microkernel and HAL (bottom layer). _ EPROCESS belongs to the executor layer, including process creation information, Imax O, security, handle table, virtual memory, and so on. Interestingly, there is a (offset 0) _ KPROCESS embedded in it, which belongs to the microkernel layer and is used for thread quota, call, priority and other information.

  Let's focus on the ActiveProcessLink in _ EPROCESS. You can see the active process chain just by its name, as shown in the following figure.

  is the key to hiding the process. It is a two-way circular linked list. We can traverse the entire system process through the linked list. It is so simple, as shown in the following figure:

  more structural information please see (I like an author, he translated some foreign articles are very rigorous and detailed), posted the address: https://bbs.pediy.com/thread-223858.htm has a detailed introduction of EPROCESS and other commonly used structures, highly recommended, maybe you have some doubts, if you carefully read the above link knowledge, your doubts will find the answer in his article.

5. Realization? Why should it be realized?

 , in fact, I used to think about this, why do you want to learn these things? Why do it? I don't have an answer. Curiosity? Specialize in research? Love? But there is no denying that when you do these things seriously, you have gained something and made progress. Maybe when you see that procexp or velvet sword can traverse those hidden processes, you know in your heart that you can enumerate violently or detect the recovery of broken chains, so it's possible, it's all possible.

  if you know two-way linked list, delete a node is not worth mentioning to you, if not, I want you to study hard, learn and use, this is knowledge. If you want to restore the hidden process (the original node location), remember to save the neighbor's pointer address.

In the end of   2019, I wish you all a new year and a new life. For 19 years, may the world enjoy a bowl of hot porridge.

The source code is shown as follows:

Both the user layer and driver layer header files need to contain:

# define CTL_PROCESS_HIDE\ CTL_CODE (FILE_DEVICE_UNKNOWN, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS) # define CTL_PROCESS_REST\ CTL_CODE (FILE_DEVICE_UNKNOWN, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS)

The above is the defined control code, which is used to control the programming function of the 3-ring to zero-ring kernel.

Driver layer:

# include "HideHeader.h" VOID UnLoadDriver (PDRIVER_OBJECT pDriverObj); / *-Declaration-* / NTSTATUS DefualtFunCtion (DEVICE_OBJECT* pDeviceObj, IRP* irp); NTSTATUS ControlCode (DEVICE_OBJECT* pDeviceObj, IRP* irp); NTSTATUS HideProcess (char* HideName); NTSTATUS RestoreProcess (char* RestorName) / *-entry point-* / NTSTATUS DriverEntry (DRIVER_OBJECT* pDriverObj, UNICODE_STRING* RegistryPath) {UNREFERENCED_PARAMETER (RegistryPath); / / DbgBreakPoint (); / / initialize device object and symbol object (exposed to 3 rings) UNICODE_STRING DeviceName; UNICODE_STRING SymbolicLinkName; DEVICE_OBJECT* pDeviceObj = NULL NTSTATUS nStatus = STATUS_SUCCESS; RtlInitUnicodeString (& DeviceName, L "\\ Device\\ HideProcess"); RtlInitUnicodeString (& SymbolicLinkName, L "\\ DosDevices\\ SymbolicLinkName"); / / create device object nStatus = IoCreateDevice (pDriverObj, 0, & DeviceName, FILE_DEVICE_UNKNOWN, 0,0, & pDeviceObj); if (FALSE = = NT_SUCCESS (nStatus)) {KdPrint (("IoCreateDevice Failuer!")); return nStatus } / / set the communication mode (0x3 ring), here use direct IO pDriverObj- > Flags = DO_DIRECT_IO; / / to create a symbolic object nStatus = IoCreateSymbolicLink (& SymbolicLinkName, & DeviceName); if (FALSE = = NT_SUCCESS (nStatus)) {KdPrint (("IoCreateSymboLicLink failuer!")); return nStatus;} / / initialize the dispatch function for (ULONG I = 0; I)

< IRP_MJ_MAXIMUM_FUNCTION; ++i) { pDriverObj->

MajorFunction [I] = DefualtFunCtion;} / / handle dispatch function and uninstall pDriverObj- > MajorFunction [IRP _ MJ_DEVICE_CONTROL] = ControlCode; pDriverObj- > DriverUnload = UnLoadDriver; return STATUS_SUCCESS;} / *-implement-* / NTSTATUS ControlCode (DEVICE_OBJECT* pDeviceObj, IRP * irp) {DbgBreakPoint (); UNREFERENCED_PARAMETER (pDeviceObj) NTSTATUS nStatus = STATUS_SUCCESS; / / get irp stack information PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation (irp); DbgBreakPoint (); / / get control code ULONG uControlCode = pIrpStack- > Parameters.DeviceIoControl.IoControlCode; / / get Out buffer / / pOutBuffer = MmGetSystemAddressForMdlSafe (irp- > MdlAddress, NormalPagePriority) Switch (uControlCode) {case CTL_PROCESS_HIDE: {/ * compatibility is lacking because the PEPROCESS structure offset may not be accurate * / HideProcess ("notepad.exe") because the current running environment is not detected;} break; case CTL_PROCESS_REST: {RestoreProcess ("notepad.exe");} break; default: break } irp- > IoStatus.Information = 0; irp- > IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest (irp, IO_NO_INCREMENT); return nStatus;} NTSTATUS DefualtFunCtion (DEVICE_OBJECT* pDeviceObj, IRP* irp) {UNREFERENCED_PARAMETER (pDeviceObj); / / completion status irp- > IoStatus.Status = STATUS_SUCCESS; / / completion byte irp- > IoStatus.Information = 0; / / processing irp IoCompleteRequest (irp, IO_NO_INCREMENT) Return STATUS_SUCCESS;} VOID UnLoadDriver (PDRIVER_OBJECT pDriverObj) {/ / when written as PDRIVER_OBJECT, it is convenient for UNICODE_STRING DeleteSymName; PDEVICE_OBJECT NextDriverObj = NULL; PDEVICE_OBJECT CurrDriverObj = NULL; / / first delete symbol object delete device object RtlInitUnicodeString (& DeleteSymName, L "\\ DosDevices\\ SymbolicLinkName"); / / delete symbol object IoDeleteSymbolicLink (& DeleteSymName); CurrDriverObj = pDriverObj- > DeviceObject / / there may be multiple device objects while (CurrDriverObj! = NULL) {NextDriverObj = CurrDriverObj- > NextDevice; IoDeleteDevice (CurrDriverObj); CurrDriverObj = NULL; CurrDriverObj = NextDriverObj;} return;} / / the variable LIST_ENTRY* ListCurrProc = NULL; LIST_ENTRY* LinkListTemp = NULL; PEPROCESS pEprocess = NULL used to hide the process NTSTATUS HideProcess (char* HideName) {/ / / / get ActiveProcessLink native environment win7 x64 offset to 0xb8 / / actually called IoGetCurrentProcess pEprocess = PsGetCurrentProcess () in EPROCESS structure; / / get ActiveProcessLinks ListCurrProc = (LIST_ENTRY *) ((ULONG) pEprocess + 0xb8); / / next pointer assignment LinkListTemp = ListCurrProc; / / ULONG Te = 0 The test uses the temporary variable / / loop to find the hidden process while (ListCurrProc! = LinkListTemp- > Flink) {/ / debug information output / / Te = ((ULONG) LinkListTemp- 0xb8 + 0x16c); / / KdPrint ((% s\ n\ n\ n), Te)) / / 0x16c is supposed to be ImageFileName, but the linked list position used is 0x16c-0xb8 if (0 = = strcmp ((char *) ((ULONG) LinkListTemp- 0xb8 + 0x16c), HideName)) {/ / DbgBreakPoint (); / / two-way linked list should be familiar with changing Previous Curr Next into Previous Next (LinkListTemp- > Blink)-> Flink = ListCurrProc- > Flink (LinkListTemp- > Flink)-> Blink = ListCurrProc- > Blink; LinkListTemp- > Blink = NULL; LinkListTemp- > Flink = NULL; KdPrint (("Sucess Hide Process!")); break;} LinkListTemp = LinkListTemp- > Flink;} return STATUS_SUCCESS;} / / restore process (not implemented) NTSTATUS RestoreProcess (char* RestorName) {UNREFERENCED_PARAMETER (RestorName) / / enumerate the current process name, get the process, and determine whether it exists in the linked list (loop), otherwise insert return STATUS_SUCCESS;} in the linked list

User layer:

Int main () {HANDLE hDriver = INVALID_HANDLE_VALUE HDriver = CreateFile (L "\\?\\ SymbolicLinkName", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) If (hDriver = = INVALID_HANDLE_VALUE) {if (GetLastError () = = 2) printf ("error Code (2): the specified file cannot be found\ n");} else printf ("driver loaded successfully\ n"); DWORD dSize = 0 / / send hidden process information to the zero ring. Here, the three rings can be controlled without testing because the test is convenient, so the parameter is NULL / / if the third parameter of the control code is passed into the buffer pointer of the driver layer (what needs to be passed in), the fourth parameter is the incoming size / / the fifth parameter is received (the information sent by the ring 0), the size DSize is the size DeviceIoControl returned by the 0 ring (hDriver, CTL_PROCESS_HIDE, NULL, 0, NULL, 0, & dSize, NULL) System ("pause"); CloseHandle (hDriver); return 0;}

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report