使用ZwSystemDebugControl的简易用户模式Rootkit检测器代码
2008-03-22 15:27
701 查看
NTSTATUS
ReadKernelMemory(IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG Length)
{
NTSTATUS Status;
SYSDBG_VIRTUAL DbgMemory;
//
// Setup the request
//
DbgMemory.Address = BaseAddress;
DbgMemory.Buffer = Buffer;
DbgMemory.Request = Length;
//
// Do the read
//
Status = NtSystemDebugControl(SysDbgReadVirtual,
&DbgMemory,
sizeof(DbgMemory),
NULL,
0,
NULL);
return Status;
}
PCHAR
FindDriverForAddress(IN PVOID Pointer)
{
NTSTATUS Status;
PRTL_PROCESS_MODULES ModuleInfo;
PRTL_PROCESS_MODULE_INFORMATION ModuleEntry;
ULONG ReturnedLength;
ULONG i;
//
// Figure out how much size we need
//
Status = NtQuerySystemInformation(SystemModuleInformation,
NULL,
0,
&ReturnedLength);
if (Status != STATUS_INFO_LENGTH_MISMATCH) return NULL;
//
// Allocate a buffer large enough
//
ModuleInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, ReturnedLength);
if (!ModuleInfo) return NULL;
//
// Now query the data again
//
Status = NtQuerySystemInformation(SystemModuleInformation,
ModuleInfo,
ReturnedLength,
&ReturnedLength);
if (!NT_SUCCESS(Status)) return NULL;
//
// Loop all the drivers
//
for (i = 0; i < ModuleInfo->NumberOfModules; i++)
{
//
// Get the current entry and check if the pointer is within it
//
ModuleEntry = &ModuleInfo->Modules[i];
if ((Pointer > ModuleEntry->ImageBase) &&
(Pointer < ((PVOID)((ULONG_PTR)ModuleEntry->ImageBase +
ModuleEntry->ImageSize))))
{
//
// Found a match, return it
//
return ModuleEntry->FullPathName;
}
}
}
PCHAR
DetectDriver(VOID)
{
BOOLEAN Old;
NTSTATUS Status;
ULONG_PTR MappedAddress;
PVOID KernelBase, TableBase;
UNICODE_STRING KernelName;
ANSI_STRING TableName = RTL_CONSTANT_STRING("KeServiceDescriptorTable");
RTL_PROCESS_MODULES ModuleInfo;
ULONG Flags;
KSERVICE_TABLE_DESCRIPTOR ServiceTable;
//
// Give our thread the debug privilege
//
Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &Old);
if (!NT_SUCCESS(Status)) return NULL;
//
// Query the kernel's module entry
//
Status = NtQuerySystemInformation(SystemModuleInformation,
&ModuleInfo,
sizeof(ModuleInfo),
NULL);
if (Status != STATUS_INFO_LENGTH_MISMATCH) return NULL;
//
// Initialize the kernel's full path name
//
Status = RtlCreateUnicodeStringFromAsciiz(&KernelName,
ModuleInfo.Modules[0].FullPathName);
if (!Status) return NULL;
//
// Keep only the short name
//
KernelName.Buffer = KernelName.Buffer +
(KernelName.Length / sizeof(WCHAR)) -
12;
//
// Map the kernel
//
Flags = IMAGE_FILE_EXECUTABLE_IMAGE;
Status = LdrLoadDll(NULL, &Flags, &KernelName, &KernelBase);
if (!NT_SUCCESS(Status)) return NULL;
//
// Find the address of KeServiceDescriptorTable
//
Status = LdrGetProcedureAddress(KernelBase, &TableName, 0, &TableBase);
if (!NT_SUCCESS(Status)) return NULL;
//
// Unload the kernel image, we're done with it
//
Status = LdrUnloadDll(KernelBase);
if (!NT_SUCCESS(Status)) return NULL;
//
// Get the virtual address we need
//
MappedAddress = (ULONG_PTR)ModuleInfo.Modules[0].ImageBase;
MappedAddress -= (ULONG_PTR)KernelBase;
MappedAddress += (ULONG_PTR)TableBase;
//
// Now read the SSDT
//
Status = ReadKernelMemory((PVOID)MappedAddress,
&ServiceTable,
sizeof(ServiceTable));
if (!NT_SUCCESS(Status)) return NULL;
//
// Setup the argument table
//
ArgumentTable = RtlAllocateHeap(RtlGetProcessHeap(),
0,
ServiceTable.Limit * sizeof(ULONG_PTR));
if (!ArgumentTable) return NULL;
//
// Now fill it up
//
Status = ReadKernelMemory(ServiceTable.Base,
ArgumentTable,
ServiceTable.Limit * sizeof(ULONG_PTR));
if (!NT_SUCCESS(Status)) return NULL;
//
// Now scan it
//
for (i = 0; i < ServiceTable.Limit; i++)
{
//
// Make sure no pointer is outside the kernel area
//
if (ArgumentTable[i] > 0x8FFFFFFF)
{
//
// Find the driver file that this belongs to
//
return FindDriverForAddress(UlongToPtr(ArgumentTable[i]));
}
}
//
// If we got here, then you don't have any rootkit
//
return NULL;
}
ReadKernelMemory(IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG Length)
{
NTSTATUS Status;
SYSDBG_VIRTUAL DbgMemory;
//
// Setup the request
//
DbgMemory.Address = BaseAddress;
DbgMemory.Buffer = Buffer;
DbgMemory.Request = Length;
//
// Do the read
//
Status = NtSystemDebugControl(SysDbgReadVirtual,
&DbgMemory,
sizeof(DbgMemory),
NULL,
0,
NULL);
return Status;
}
PCHAR
FindDriverForAddress(IN PVOID Pointer)
{
NTSTATUS Status;
PRTL_PROCESS_MODULES ModuleInfo;
PRTL_PROCESS_MODULE_INFORMATION ModuleEntry;
ULONG ReturnedLength;
ULONG i;
//
// Figure out how much size we need
//
Status = NtQuerySystemInformation(SystemModuleInformation,
NULL,
0,
&ReturnedLength);
if (Status != STATUS_INFO_LENGTH_MISMATCH) return NULL;
//
// Allocate a buffer large enough
//
ModuleInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, ReturnedLength);
if (!ModuleInfo) return NULL;
//
// Now query the data again
//
Status = NtQuerySystemInformation(SystemModuleInformation,
ModuleInfo,
ReturnedLength,
&ReturnedLength);
if (!NT_SUCCESS(Status)) return NULL;
//
// Loop all the drivers
//
for (i = 0; i < ModuleInfo->NumberOfModules; i++)
{
//
// Get the current entry and check if the pointer is within it
//
ModuleEntry = &ModuleInfo->Modules[i];
if ((Pointer > ModuleEntry->ImageBase) &&
(Pointer < ((PVOID)((ULONG_PTR)ModuleEntry->ImageBase +
ModuleEntry->ImageSize))))
{
//
// Found a match, return it
//
return ModuleEntry->FullPathName;
}
}
}
PCHAR
DetectDriver(VOID)
{
BOOLEAN Old;
NTSTATUS Status;
ULONG_PTR MappedAddress;
PVOID KernelBase, TableBase;
UNICODE_STRING KernelName;
ANSI_STRING TableName = RTL_CONSTANT_STRING("KeServiceDescriptorTable");
RTL_PROCESS_MODULES ModuleInfo;
ULONG Flags;
KSERVICE_TABLE_DESCRIPTOR ServiceTable;
//
// Give our thread the debug privilege
//
Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &Old);
if (!NT_SUCCESS(Status)) return NULL;
//
// Query the kernel's module entry
//
Status = NtQuerySystemInformation(SystemModuleInformation,
&ModuleInfo,
sizeof(ModuleInfo),
NULL);
if (Status != STATUS_INFO_LENGTH_MISMATCH) return NULL;
//
// Initialize the kernel's full path name
//
Status = RtlCreateUnicodeStringFromAsciiz(&KernelName,
ModuleInfo.Modules[0].FullPathName);
if (!Status) return NULL;
//
// Keep only the short name
//
KernelName.Buffer = KernelName.Buffer +
(KernelName.Length / sizeof(WCHAR)) -
12;
//
// Map the kernel
//
Flags = IMAGE_FILE_EXECUTABLE_IMAGE;
Status = LdrLoadDll(NULL, &Flags, &KernelName, &KernelBase);
if (!NT_SUCCESS(Status)) return NULL;
//
// Find the address of KeServiceDescriptorTable
//
Status = LdrGetProcedureAddress(KernelBase, &TableName, 0, &TableBase);
if (!NT_SUCCESS(Status)) return NULL;
//
// Unload the kernel image, we're done with it
//
Status = LdrUnloadDll(KernelBase);
if (!NT_SUCCESS(Status)) return NULL;
//
// Get the virtual address we need
//
MappedAddress = (ULONG_PTR)ModuleInfo.Modules[0].ImageBase;
MappedAddress -= (ULONG_PTR)KernelBase;
MappedAddress += (ULONG_PTR)TableBase;
//
// Now read the SSDT
//
Status = ReadKernelMemory((PVOID)MappedAddress,
&ServiceTable,
sizeof(ServiceTable));
if (!NT_SUCCESS(Status)) return NULL;
//
// Setup the argument table
//
ArgumentTable = RtlAllocateHeap(RtlGetProcessHeap(),
0,
ServiceTable.Limit * sizeof(ULONG_PTR));
if (!ArgumentTable) return NULL;
//
// Now fill it up
//
Status = ReadKernelMemory(ServiceTable.Base,
ArgumentTable,
ServiceTable.Limit * sizeof(ULONG_PTR));
if (!NT_SUCCESS(Status)) return NULL;
//
// Now scan it
//
for (i = 0; i < ServiceTable.Limit; i++)
{
//
// Make sure no pointer is outside the kernel area
//
if (ArgumentTable[i] > 0x8FFFFFFF)
{
//
// Find the driver file that this belongs to
//
return FindDriverForAddress(UlongToPtr(ArgumentTable[i]));
}
}
//
// If we got here, then you don't have any rootkit
//
return NULL;
}
相关文章推荐
- ZwSystemDebugControl函数列举系统PCI设备ID
- 基于windows PE文件的恶意代码分析;使用SystemInternal工具与内核调试器研究windows用户空间与内核空间
- ZwSystemDebugControl函数读取MSR寄存器值
- 使用用户模式linux(UML, User mode linux)来进行内核Debug
- IDEA 15:DeBug(调试)模式的使用,你应该学会找代码报错的地方
- ZwSystemDebugControl函数
- 遇到当试图还原 master 数据库时,必须以单用户模式使用 RESTORE DATABASE.的解决办法
- 任意用户模式下执行 ring 0 代码
- Spring Boot使用过滤器和拦截器分别实现REST接口简易安全认证示例代码详解
- 若要调试此模块,请将其项目生成配置更改为“调试”模式。若要取消显示此消息,请禁用“启动时若没有用户代码则发出警告”调试器选项。
- “System.NotSupportedException”类型的异常在 System.Data.Entity.dll 中发生,但未在用户代码中进行处理 其他信息: 在 LINQ to Entitie
- 计划任务中使用NT AUTHORITY\SYSTEM用户和普通管理员用户有什么区别
- 使用CSS3属性aspect-ratio做横屏检测优化用户体验,附demo完整代码
- ASP.NET 中使用计时器执行用户代码
- 演示事件(Event)怎样使用以及怎样为用户控件添加一个事件(示例代码下载)
- VS在代码中判断debug和release模式
- 对Native API NtSystemDebugControl的分析
- eclipse中的debug模式的使用
- 使用java代码判断用户使用哪种方式登录的。
- System.UnauthorizedAccessException: 拒绝访问 temp 目录。用来运行 XmlSerializer 的标识“NT AUTHORITY\NETWORK SERVICE”没有访问 temp 目录的足够权限。CodeDom 将使用进程正在使用的用户帐户进行编译,这样,如