#include "stdafx.h"
#ifdef __cplusplus
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
#endif
extern "C" __declspec(dllimport) BOOLEAN KeRemoveSystemServiceTable (IN ULONG Index);
PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorShadowTable;
void DDK_UnLoad(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("Goodbye from DDK_UnLoad!\n");
}
extern "C" UCHAR *PsGetProcessImageFileName(__in PEPROCESS eprocess);
PSERVICE_DESCRIPTOR_TABLE GetKeServiceDescriptorShadowTableAddress()
{
PCHAR address = (PCHAR)KeRemoveSystemServiceTable;//赋值
ULONG add;
for (int i = 0; i < 0x1024;i++)//遍历第一页内存
{
add = *((PULONG)(address+i));//访问函数的每个字节,转换为Ulong指针类型
if (MmIsAddressValid((PVOID)add))//检查内存是否可以访问
{
if (memcmp((void *)add,KeServiceDescriptorTable,16) == 0)//如果前面16个字节相同的话
{
if (add == (DWORD)KeServiceDescriptorTable)
{
//如果相等的话,就返回
continue;
}else
{
return (PSERVICE_DESCRIPTOR_TABLE)(*((DWORD*)(address+i)));
}
}
}
}
return NULL;
}
typedef enum WIN_VER_DETAIL {
WINDOWS_VERSION_NONE, // 0
WINDOWS_VERSION_2K,
WINDOWS_VERSION_XP,
WINDOWS_VERSION_2K3,
WINDOWS_VERSION_2K3_SP1_SP2,
WINDOWS_VERSION_VISTA_2008,
WINDOWS_VERSION_7_7600_UP,
WINDOWS_VERSION_7_7000
} WIN_VER_DETAIL;
WIN_VER_DETAIL WinVersion;
WIN_VER_DETAIL GetWindowsVersion()
{
RTL_OSVERSIONINFOEXW osverinfo;
if (WinVersion)
return WinVersion;
memset(&osverinfo,0,sizeof(RTL_OSVERSIONINFOEXW));
osverinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
if (RtlGetVersion((RTL_OSVERSIONINFOW*)&osverinfo) != STATUS_SUCCESS){
return WINDOWS_VERSION_NONE;
}
// KdPrint(("[xxxxxxxx] OSVersion NT %d.%d:%d sp%d.%d\n",
// osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber,
// osverinfo.wServicePackMajor, osverinfo.wServicePackMinor));
if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0){
WinVersion = WINDOWS_VERSION_2K;
}
else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1){
WinVersion = WINDOWS_VERSION_XP;
}
else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2){
if (osverinfo.wServicePackMajor==0){
WinVersion = WINDOWS_VERSION_2K3;
}
else{
WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;
}
}
else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0){
WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;
}
else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1 && osverinfo.dwBuildNumber == 7000){
WinVersion = WINDOWS_VERSION_7_7000;
}
else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1 && osverinfo.dwBuildNumber >= 7600){
WinVersion = WINDOWS_VERSION_7_7600_UP;
}
return WinVersion;
}
NTSTATUS LookupProcessByName(
IN PCHAR pcProcessName,
OUT PEPROCESS *pEprocess
)
{
NTSTATUS status;
ULONG uCount = 0;
ULONG uLength = 0;
PLIST_ENTRY pListActiveProcess;
PEPROCESS pCurrentEprocess = NULL;
ULONG ulNextProcess = NULL;
ULONG g_Offset_Eprocess_Flink;
WIN_VER_DETAIL WinVer;
char lpszProName[100];
char *lpszAttackProName = NULL;
if (!ARGUMENT_PRESENT(pcProcessName) || !ARGUMENT_PRESENT(pEprocess))
{
return STATUS_INVALID_PARAMETER;
}
if (KeGetCurrentIrql() > PASSIVE_LEVEL)
{
return STATUS_UNSUCCESSFUL;
}
uLength = strlen(pcProcessName);
WinVer = GetWindowsVersion();
switch(WinVer)
{
case WINDOWS_VERSION_XP:
g_Offset_Eprocess_Flink = 0x88;
break;
case WINDOWS_VERSION_7_7600_UP:
case WINDOWS_VERSION_7_7000:
g_Offset_Eprocess_Flink = 0xb8;
break;
case WINDOWS_VERSION_VISTA_2008:
g_Offset_Eprocess_Flink = 0x0a0;
break;
case WINDOWS_VERSION_2K3_SP1_SP2:
g_Offset_Eprocess_Flink = 0x98;
break;
case WINDOWS_VERSION_2K3:
g_Offset_Eprocess_Flink = 0x088;
break;
}
if (!g_Offset_Eprocess_Flink){
return STATUS_UNSUCCESSFUL;
}
pCurrentEprocess = PsGetCurrentProcess();
ulNextProcess = (ULONG)pCurrentEprocess;
__try
{
memset(lpszProName,0,sizeof(lpszProName));//填充0
if (uLength > 15)//如果你传进来的字符串大于15
{
strncat(lpszProName,pcProcessName,15);//我就取前15个字符
uLength = 15;
}
while(1)
{
lpszAttackProName = NULL;
lpszAttackProName = (char *)PsGetProcessImageFileName(pCurrentEprocess);//取当前进程的EPROCESS
DbgPrint("%s",lpszAttackProName);//打印进程名称,中文不会被打印出来,有BUG
if (lpszAttackProName && strlen(lpszAttackProName) == uLength)
{
if(_strnicmp(pcProcessName,lpszAttackProName, uLength) == 0)//如果lenth大于15,因为我们前面已经裁去了
{
*pEprocess = pCurrentEprocess;
status = STATUS_SUCCESS;
break;
}
}
if ((uCount >= 1) && (ulNextProcess == (ULONG)pCurrentEprocess))
{
*pEprocess = 0x00000000;
status = STATUS_NOT_FOUND;
break;
}
pListActiveProcess = (LIST_ENTRY *)((ULONG)pCurrentEprocess + g_Offset_Eprocess_Flink);
pCurrentEprocess = (PEPROCESS)((ULONG(pListActiveProcess->Flink)) - g_Offset_Eprocess_Flink);
uCount++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("LookupProcessByName:%08x\r\n",GetExceptionCode()));
status = STATUS_NOT_FOUND;
}
return status;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
PEPROCESS eprocess_explorer;
KdPrint(("驱动被加载!!!"));//调试的时候可以用这个函数调试
DriverObject->DriverUnload=DDK_UnLoad;//设置卸载驱动函数
KeServiceDescriptorShadowTable = GetKeServiceDescriptorShadowTableAddress();
if (!KeServiceDescriptorShadowTable)
{
DbgPrint("获取影子地址失败");
}
else
{
DbgPrint("影子的地址是:%x",KeServiceDescriptorShadowTable[1]);
//我们得到一个gui进程的对象,因为我们切换进程的时候需要用到
if (LookupProcessByName("explorer.exe",&eprocess_explorer) == STATUS_SUCCESS)
{
KeAttachProcess(eprocess_explorer);//附加到目标进程
//遍历影子的地址
for (int i = 0; i < KeServiceDescriptorShadowTable[1].TableSize;i++)
{
DbgPrint("%d : %x",i+1,KeServiceDescriptorShadowTable[1].ServiceTable[i]);
}
DbgPrint("影子的地址是:%x",KeServiceDescriptorShadowTable[1]);
KeDetachProcess();//解除附加
}else{
DbgPrint("附加失败");
}
}
return STATUS_SUCCESS;
}