【文章标题】: 逆向rainsafe.sys
【文章作者】: majinxin
【作者邮箱】: majinxin2003@126.com
【下载地址】: 附件
【作者声明】: 我知道有源码,纯属为了学习 禹盾hips是一款绿色的主机入侵防御系统,它从驱动层保护系统关键位置,拦截进程,注册表,驱动 等危险操作,从而达到保护电脑的目标。 从网上下来这个软件后,把它的驱动A掉,发现它hook了四个函数分别是ZwCreateProcessEx,ZwLoadDriver, ZwSetVlaueKey, ZwSetSystemTime。然后把这驱动,进程,注册表信息通过DeviceControl传递到用户层,但是后来在网上看到,原来早已经开源了, 不过权当是学习了吧 ,有些函数因为完成的是类似的工作就没逆出来,同时,我也上传上它的源码和我分析的IDB,有兴趣的朋友可以参考下。
首先非常感谢禹盾的作者大方地发布出源码!!
在最新发布的源码中可以看到hook了更多的函数:
IoVolumeDeviceToDosName=0;
ZwCreateProcess;
ZwCreateProcessEx;
NtCreateUserProcess;
ZwSetValueKey;
ZwLoadDriver;
ZwSetSystemTime;
NtSetSystemInformation;
NtSystemDebugControl;
NtOpenProcess;
NtOpenThread;
NtWriteFile;
NtUserSetInformationThread;
以下是我A出来的代码: #include <ntddk.h> ULONG g_ProcessOffset = 0;
PEPROCESS g_SelfPEProcess;
BOOL IsCreateProcessHooked;
BOOL IsSetValueKeyHooked;
BOOL IsLoadDricerHooked;
BOOL IsSetSystemTimeHooked;
ULONG g_NtProcessAddr;
ULONG g_NtSetValueKeyAddr;
ULONG g_NtLoadDriverAddr;
ULONG g_NtSetSystemTimeAddr;
ULONG g_CreateProcessID;
ULONG g_SetValueKeyID;
ULONG g_LoadDriverID;
ULONG g_SetSystemTimeID;
KEVENT Event;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
VOID WPOFF()
{
__asm{
cli
push eax
mov eax,cr0
and eax,not 10000h
mov cr0,eax
pop eax
}
}
VOID WPON()
{
__asm{
push eax
mov eax,cr0
or eax,10000h
mov cr0,eax
pop eax
sti
}
}
int __cdecl GetProcessOffset()
{
//get the offset from EPROCESS to ProcessName
PEPROCESS pp = IoGetCurrentProcess();
int i;
for(i = pp; i < 3000h; i++)
{
if(strncmp(i, "System", 6) == 0)
g_ProcessOffset = i - pp;
}
}
int __stdcall ZeroMemory(void *addr, unsigned int length)
{
memset(addr, 0, length);
} int __stdcall GetProcessAddr(PCSZ FunctionName, LSA_UNICODE_STRING *NtdllPath)
{
//Get the function address from the export table of the ntdll.dll
PHANDLE FileHandle;
ACCESS_MASK DesiredAccess = 0x10020;
POBJECT_ATTRIBUTES ObjectAttributes;
PIO_STATUS_BLOCK IoStatusBlock;
ULONG ShareAccess = 1;
ULONG OpenOptions = 0x20h;
ObjectAttributes.ObjectName = NtdllPath;
ObjectAttributes.Length = 0x18;
ObjectAttributes.RootDirectory = 0;
ObjectAttributes.Attributes = 0x40;
PHANDLE SectionHandle;
PLARGE_INTEGER MaximumSize;
ULONG SectionPageProtection;
ULONG AllocationAttributes;
PHANDLE SectionHandle;
HANDLE ProcessHandle = -1;
PVOID *BaseAddress;
ULONG* ZeroBits = 0;
SIZE_T CommitSize = 0x3E8;
SECTION_INHERIT InheritDisposition = 1;
PSIZE_T ViewSize;
ULONG AllocationType = 0x100000;
ULONG Win32Protect = 4;
PLARGE_INTEGER SectionOffset = 0;
int i = 0;
ULONG* pPeNtHeader;
IMAGE_EXPORT_DIRECTORY *Exp;
PSTRING pFunctionNameString;
ULONG* pNameAddr;
char* Name;
PSTRING pFindFunctionString;
ULONG Oridinal;
ULONG ExportID;
ULONG funcAddr;
ZwOpenFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, ShareAccess, OpenOptions); AllocationAttributes = 0x1000000;
SectionPageProtection = 0x10;
MaximumSize = 0;
ObjectAttributes.ObjectName = 0;
DesiredAccess = 0xF001F;
ZwCreateSection(SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle);
ZwMapViewOfSection(SectionHandle, ProcessHandle, *BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition,
AllocationType, Win32Protect);
ZwClose(FileHandle);
pPeNtHeader = *(BaseAddress + 0x3c);
Exp = *((IMAGE_EXPORT_DIRECTORY *)(BaseAddress + *(pPeNtHeader + 0x78)));
RtlInitString(pFindFunctionString, FunctionName);
pNameAddr = BaseAddress + Exp->AddressOfNames;
for(i = 0; i < Exp->NumberOfFunctions; i++)
{
Name = (char*)(BaseAddress + *(pNameAddr + i * 4));
RtlInitString(pFunctionNameString, Name);
if(!RtlCompareString(pFindFunctionString, pFunctionNameString, 1))
{
Oridinal = *(ULONG*)((BaseAddress + Exp->AddressOfNameOrdinals) + i * 2)
ExportID = Exp->Base + Oridinal;
funcAddr = BaseAddress + *(ULONG*)(Exp->AddressOfFunctions + (ExportID-1) * 4);
ZwClose(SectionHandle);
return funcAddr;
}
}
ZwClose(SectionHandle);
return 0;
} NTSTATUS __stdcall GetSectionFilePath(HANDLE SectionHandle, int OutputBuffer)
{
HANDLE Handle = SectionHandle;
ACCESS_MASK DesiredAccess = 0;
POBJECT_TYPE ObjectType = 0;
KPROCESSOR_MODE AccessMode = 0;
PFILE_OBJECT FileObject;
POBJECT_HANDLE_INFORMATION HandleInformation = 0;
NTSTATUS ntSatus;
POOL_TYPE PoolType = 1;
SIZE_T NumberOfBytes = 0x200;
ULONG Tag = 0x206B6444;
PUNICODE_STRING pString1;
PUNICODE_STRING DosName;
PANSI_STRING pString2;
PFILE_OBJECT FilePointer;
ntSatus = ObReferenceObjectByHandle(Handle, DesiredAccess, ObjectType, AccessMode, &FileObject, HandleInformation);
if(ntSatus != 0) return ntSatus;
pString1->Buffer = ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
pString1->MaximumLength = 0x200; FilePointer = *(*(FileObject->SectionObjectPointer->DataSectionObject) +0x24)
ObReferenceObjectByPointer(FilePointer, 0, 0, 0);
RtlVolumeDeviceToDosName(FilePointer->DeviceObject, DosName); RtlCopyUnicodeString(pString1, DosName);
RtlAppendUnicodeStringToString(pString1, FilePointer->FileName);
ObfDereferenceObject(FilePointer);
RtlUnicodeStringToAnsiString(pString1, pString2);
RtlCopyMemory(OutputBuffer, pString2->Buffer, pString2->Length); RtlFreeAnsiString(pString2);
ExFreePoolWithTag(pString1->Buffer, Tag);
return 1;
}
char __stdcall sub_107D6(HANDLE Object, int a2)
{ }
int __stdcall ToAnsiString(PCWSTR ProcessPath, ULONG OutBuff)
{
PUNICODE_STRING ProcessPathString;
PANSI_STRING OutSting;
RtlInitUnicodeString(&ProcessPathString, ProcessPath);
OutSting->Length = 0;
OutSting->MaximumLength = 256;
OutSting->Buffer = OutBuff;
RtlUnicodeStringToAnsiString((PANSI_STRING)&OutSting, &ProcessPathString, 0);
return 0;
} signed int __stdcall GetProcessPath(int Buff)
{
PEPROCESS pProcess = IoGetCurrentProcess();
ToAnsiString(pProcess->Peb->ProcessParameters->ImagePathName.Buff, Buff);
} int __stdcall CombineAndCopyString(char *PProcessPathA, const char *DriveNameString)
{
}
signed int __stdcall MyCreateProcess(int ProcessHandle, int DesiredAccess, int ObjectAttributes, int ParentProcess, int InheritObjectTable, HANDLE SectionHandle, int DebugPort, int ExceptionPort, int a9)
{
char *SectionFilePath;
char *ProcessPath;
if (g_SelfPEProcess == IoGetCurrentProcess())
return g_NtProcessAddr(ProcessHandle, DesiredAccess, ObjectAttributes, ParentProcess, InheritObjectTable, SectionHandle, DebugPort, ExceptionPort, a9);
ZeroMemory(ProcessPath, 0x100u);
GetSectionFilePath(SectionHandle, SectionFilePath);
GetProcessPath(ProcessPath);
CombineAndCopyString(ProcessPath, SectionFilePath);
return g_NtProcessAddr(ProcessHandle, DesiredAccess, ObjectAttributes, ParentProcess, InheritObjectTable, SectionHandle, DebugPort, ExceptionPort, a9);
}
signed int __stdcall MySetValueKey(HANDLE KeyHandle, PCUNICODE_STRING ValueName, int TitleIndex, int Type, int Data, int DataSize)
{
//类似MyCreateProcess,取得信息传递到全局变量地址,随后传递给用户层
}
int __stdcall MyLoaddriver(PCUNICODE_STRING DriverName)
{
//类似MyCreateProcess,取得信息传递到全局变量地址,随后传递给用户层
}
struct PEPROCESS __cdecl HookCreateProcess()
{
ULONG Address;
if(IsCreateProcessHooked == FALSE)
{
g_SelfPEProcess = IoGetCurrentProcess();
ULONG Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + g_CreateProcessID * 4;
WPOFF();
*((ULONG*)Address) = (ULONG)MyCreateProcess;
WPON();
IsCreateProcessHooked = TRUE;
}
return g_SelfPEProcess;
}
unsigned int __cdecl UnhookCreateProcess()
{
if (IsCreateProcessHooked == TRUE)
{
ULONG Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + g_CreateProcessID * 4;
WPOFF();
*((ULONG*)Address) = (ULONG)g_NtProcessAddr;
WPON();
}
IsCreateProcessHooked = FALSE;
return 0;
}
struct PEPROCESS __cdecl HookSetValueKey()
{
ULONG Address;
if(IsSetValueKeyHooked == FALSE)
{
g_SelfPEProcess = IoGetCurrentProcess();
ULONG Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + g_SetValueKeyID * 4;
WPOFF();
*((ULONG*)Address) = (ULONG)MySetValueKey;
WPON();
IsCreateProcessHooked = TRUE;
}
return g_SelfPEProcess;
}
unsigned int __cdecl UnhookSetValueKey()
{
if (IsSetValueKeyHooked == TRUE)
{
ULONG Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + g_SetValueKeyID * 4;
WPOFF();
*((ULONG*)Address) = (ULONG)g_NtSetValueKeyAddr;
WPON();
}
IsCreateProcessHooked = FALSE;
return 0;
}
struct PEPROCESS __cdecl HookLoadDriver()
{
ULONG Address;
if(IsLoadDricerHooked == FALSE)
{
g_SelfPEProcess = IoGetCurrentProcess();
ULONG Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + g_LoadDriverID * 4;
WPOFF();
*((ULONG*)Address) = (ULONG)MyLoaddriver;
WPON();
IsLoadDricerHooked = TRUE;
}
return g_SelfPEProcess;
}
unsigned int __cdecl UnhookLoadDriver()
{
if (IsLoadDricerHooked == TRUE)
{
ULONG Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + g_LoadDriverID * 4;
WPOFF();
*((ULONG*)Address) = (ULONG)g_NtLoadDriverAddr;
WPON();
}
IsLoadDricerHooked = FALSE;
return 0;
}
struct PEPROCESS __cdecl HookSetSystemTime()
{
ULONG Address;
if(IsSetSystemTimeHooked == FALSE)
{
g_SelfPEProcess = IoGetCurrentProcess();
ULONG Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + g_SetSystemTimeID * 4;
WPOFF();
*((ULONG*)Address) = (ULONG)sub_10CD2;
WPON();
IsSetSystemTimeHooked = TRUE;
}
return g_SelfPEProcess;
}
unsigned int __cdecl UnhookSetSystemTime()
{
if (IsSetSystemTimeHooked == TRUE)
{
ULONG Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + g_SetSystemTimeID * 4;
WPOFF();
*((ULONG*)Address) = (ULONG)g_NtSetSystemTimeAddr;
WPON();
}
IsSetSystemTimeHooked = FALSE;
return 0;
} int __stdcall DispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNICODE_STRING DestinationString;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = 0;
IofCompleteRequest(Irp, 0);
KeInitializeEvent(&Event, SynchronizationEvent, 1);
RtlInitUnicodeString(&DestinationString, L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntdll.dll");
g_CreateProcessID = GetProcessAddr("ZwCreateProcessEx", &DestinationString) + 1;
g_NtProcessAddr = KeServiceDescriptorTable->ServiceTableBase + g_CreateProcessID * 4; g_SetValueKeyID = *((char*)&ZwSetValueKey + 1);
g_NtSetValueKeyAddr = KeServiceDescriptorTable->ServiceTableBase + g_SetValueKeyID * 4;
g_LoadDriverID = GetProcessAddr("ZwLoadDriver", &DestinationString) + 1;
g_NtLoadDriverAddr = KeServiceDescriptorTable->ServiceTableBase + g_LoadDriverID * 4;
g_SetSystemTimeID = GetProcessAddr("ZwSetSystemTime", &DestinationString) + 1;
g_NtSetSystemTimeAddr = KeServiceDescriptorTable->ServiceTableBase + g_SetSystemTimeID * 4;
return 0;
} int __stdcall DispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = 0;
IofCompleteRequest(Irp, 0);
return 0;
} int __stdcall DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PVOID Irp)
{
//与用户层交互信息,略
} void __stdcall DriverUnload(PDRIVER_OBJECT driver)
{
UNICODE_STRING DestinationString;
UnhookCreateProcess();
UnhookSetValueKey();
UnhookLoadDriver();
UnhookSetSystemTime();
RtlInitUnicodeString(&DestinationString, L"\\DosDevices\\rainsafe");
IoDeleteSymbolicLink(&DestinationString);
IoDeleteDevice(driver->DeviceObject);
} NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;
UNICODE_STRING ntDeviceName, SymbolicLinkName;
BOOLEAN fSymbolicLink = FALSE;
RtlInitUnicodeString(&ntDeviceName, L"\\Device\\rainsafe");
ntStatus = IoCreateDevice(DriverObject, 4, &ntDeviceName, 0x8000u, 0, 1u, &DeviceObject);
if (!NT_SUCCESS(ntStatus))
{
goto __failed;
}
RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\rainsafe")
ntStatus = IoCreateSymbolicLink(&SymbolicLinkName, &ntDeviceName);
if (!NT_SUCCESS(ntStatus))
{
goto __failed;
}
fSymbolicLink = TRUE;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
DriverObject->DriverUnload = DriverUnload;
GetProcessOffset();
if (!NT_SUCCESS(ntStatus))
goto __failed;
return ntStatus;
__failed:
if (fSymbolicLink)
IoDeleteSymbolicLink(&dosDeviceName);
if (DeviceObject)
IoDeleteDevice(DeviceObject);
return ntStatus;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: