一、项目说明

这次项目是这样设计的,首先 inline hook NtTerminateProcess 函数,使其他进程不能关闭受保护的进程,这里选择记事本。

然后编写一个普通的程序,调用 TerminateProcess 函数关闭记事本,如无意外是关不掉的。

然后编写驱动,从文件系统中加载一份新内核到内存,拉伸PE,修复重定位表,IAT表,SSDT表;HOOK KiFastCallEntry 函数,让我们的程序系统调用走新内核,这样就可以关掉记事本了。

二、前置任务

首先把保护记事本和关闭记事本的程序给出,这两个没什么难度,不想解释。

效果就是加载保护驱动后,无法 TerminateProcess 关闭记事本。

调用 TerminateProcess 关闭记事本的程序

// KillNotepad.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <Windows.h>// 提权函数:提升为DEBUG权限
BOOL EnableDebugPrivilege()
{HANDLE hToken;BOOL fOk=FALSE;if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)){TOKEN_PRIVILEGES tp;tp.PrivilegeCount=1;LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);fOk=(GetLastError()==ERROR_SUCCESS);CloseHandle(hToken);}return fOk;
}int _tmain(int argc, _TCHAR* argv[])
{EnableDebugPrivilege();HWND hWnd = FindWindowA(NULL, "无标题 - 记事本");DWORD dwPid = -1;GetWindowThreadProcessId(hWnd, &dwPid);HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);TerminateProcess(hProcess,0);return 0;
}

保护记事本的驱动

//#include <ntddk.h>
#include <ntifs.h>
#include <ntimage.h>//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------typedef struct _LDR_DATA_TABLE_ENTRY
{LIST_ENTRY InLoadOrderLinks;LIST_ENTRY InMemoryOrderLinks;LIST_ENTRY InInitializationOrderLinks;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;UINT16 LoadCount;UINT16 TlsIndex;LIST_ENTRY HashLinks;PVOID SectionPointer;ULONG CheckSum;ULONG TimeDateStamp;PVOID LoadedImports;PVOID EntryPointActivationContext;PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;typedef NTSTATUS (*NTTERMINATEPROCESS) (HANDLE ProcessHandle, NTSTATUS ExitStatus);// 系统服务表
typedef struct _KSYSTEM_SERVICE_TABLE
{PULONG ServiceTableBase;           // 函数地址表PULONG ServiceCounterTableBase;     // SSDT 函数被调用的次数ULONG NumberOfService;              // 函数个数PULONG ParamTableBase;               // 函数参数表
} KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;// SSDT表
typedef struct _KSERVICE_TABLE_DESCRIPTOR
{KSYSTEM_SERVICE_TABLE ntoskrnl;        // 内核函数KSYSTEM_SERVICE_TABLE win32k;        // win32k.sys 函数KSYSTEM_SERVICE_TABLE unUsed1;KSYSTEM_SERVICE_TABLE unUsed2;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path);
VOID DriverUnload(PDRIVER_OBJECT driver);
VOID PageProtectOff();
VOID PageProtectOn();
VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID *pKrnlBase, PULONG uKrnlImageSize);
PVOID MemorySearch(PVOID bytecode, ULONG bytecodeLen, PVOID pBeginAddress, PVOID pEndAddress);
VOID HookNtTerminateProcess();
VOID UnhookNtTerminateProcess();
VOID HbgNtTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus);//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------PDRIVER_OBJECT g_Driver;
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable; // 内核导出的全局变量PVOID pNtTerminateProcess;
PVOID pNtTerminateProcessHookRet;// NtTerminateProcess 系统调用号
#define NTTERMINATEPROCESS_INDEX 0x101//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{   g_Driver = driver;driver->DriverUnload = DriverUnload;HookNtTerminateProcess();return STATUS_SUCCESS;
}// 卸载驱动
VOID DriverUnload(PDRIVER_OBJECT driver)
{UnhookNtTerminateProcess();DbgPrint("Kernel Unload Successfully.\n");
}// 关闭页保护
VOID PageProtectOff()
{__asm{cli; // 关闭中断mov eax, cr0;and eax, not 0x10000; // WP位置0mov cr0, eax;}
}// 开启页保护
VOID PageProtectOn()
{__asm{mov eax, cr0;or eax, 0x10000; // WP位置1mov cr0, eax;sti; // 恢复中断}
}// 获取内核基址,大小
VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID *pKrnlBase, PULONG uKrnlImageSize)
{PLDR_DATA_TABLE_ENTRY pLdteHead; // 内核模块链表头PLDR_DATA_TABLE_ENTRY pLdteCur; // 遍历指针UNICODE_STRING usKrnlBaseDllName; // 内核模块名RtlInitUnicodeString(&usKrnlBaseDllName,L"ntoskrnl.exe");pLdteHead = (PLDR_DATA_TABLE_ENTRY)driver->DriverSection;pLdteCur = pLdteHead;do {PLDR_DATA_TABLE_ENTRY pLdte = CONTAINING_RECORD(pLdteCur, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);//DbgPrint("DllBase: %p, SizeOfImage: %08X %wZ\n", pLdteCur->DllBase, pLdteCur->SizeOfImage, &(pLdteCur->FullDllName));if (RtlCompareUnicodeString(&pLdteCur->BaseDllName, &usKrnlBaseDllName, TRUE) == 0){*pKrnlBase = pLdteCur->DllBase;*uKrnlImageSize = pLdteCur->SizeOfImage;return;}pLdteCur = (PLDR_DATA_TABLE_ENTRY)pLdteCur->InLoadOrderLinks.Flink;} while (pLdteHead != pLdteCur);return;
}// 特征码搜索
PVOID MemorySearch(PVOID bytecode, ULONG bytecodeLen, PVOID pBeginAddress, PVOID pEndAddress)
{PVOID pCur = pBeginAddress;while (pCur != pEndAddress){if (RtlCompareMemory(bytecode,pCur,bytecodeLen) == bytecodeLen){return pCur;}((ULONG)pCur)++;}return 0;
}// hook NtTerminateProcess
VOID HookNtTerminateProcess()
{   pNtTerminateProcess = (PVOID)KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[NTTERMINATEPROCESS_INDEX];PageProtectOff();// hook NtTerminateProcess ,采取短跳+长跳的方式*(PUCHAR)((ULONG)pNtTerminateProcess - 5) = 0xE9;*(PULONG)((ULONG)pNtTerminateProcess - 4) = (ULONG)HbgNtTerminateProcess - (ULONG)pNtTerminateProcess;*(PUSHORT)pNtTerminateProcess = (USHORT)0xF9EB;PageProtectOn();
}// unhook NtTerminateProcess
VOID UnhookNtTerminateProcess()
{*(PUSHORT)pNtTerminateProcess = (USHORT)0xFF8B;*(PUCHAR)((ULONG)pNtTerminateProcess - 5) = 0xCC;*(PULONG)((ULONG)pNtTerminateProcess - 4) = 0xCCCCCCCC;
}// 被修改的 NtTerminateProcess 函数,简单打印参数
__declspec(naked) VOID HbgNtTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus)
{PEPROCESS pEprocess;NTSTATUS status;PCHAR ImageFileName;__asm{mov edi,edi;push ebp;mov ebp,esp;pushad;pushfd;sub esp,0x20;}status = ObReferenceObjectByHandle(ProcessHandle,FILE_ANY_ACCESS,*PsProcessType,KernelMode,&pEprocess,NULL);if (!NT_SUCCESS(status)){goto ReturnToNtTerminateProcess;}// 根据镜像文件名判断是不是要保护的进程,字符串最大长度是16,超过就会截断,所以不用担心越界ImageFileName = (PCHAR)pEprocess + 0x174;if (strcmp(ImageFileName, "notepad.exe") == 0){if (ProcessHandle == (HANDLE)0xFFFFFFFF){// 通过关闭按钮关闭goto ReturnToNtTerminateProcess;            }else{// 通过任务管理器或其他进程调用TerminateProcess关闭//DbgPrint("Terminate denied. %s: NtTerminateProcess(%x, %x)\n", ImageFileName, ProcessHandle, ExitStatus);goto ReturnAccessDenied;}}
ReturnToNtTerminateProcess:pNtTerminateProcessHookRet = (PVOID)((ULONG)pNtTerminateProcess + 5);__asm{add esp,0x20;popfd;popad;jmp pNtTerminateProcessHookRet;}
ReturnAccessDenied:__asm{               add esp,0x20;popfd;popad;leave;mov eax,0xC0000022; // STATUS_ACCESS_DENIEDretn 0x08;}
}

三、内核重载

写不出来,一是能力不足,二是动机不足。

动机方面,后面会学自建调用框架,完美替代内核重载。

能力方面,目前主要存在以下疑问:

  • MDL 是什么,不清楚,ExAllocatePool 申请出来的内存似乎还不能执行?
  • 修复 IAT 的方式?是否从当前内核内存镜像中复制过来?
  • 修复重定位的方式?用老办法修复,还是从当前内核镜像中拷贝?是否必须共用一份全局变量?
  • 修复SSDT表,是否是拷贝现有的SSDT表,然后减去新旧内核镜像的地址差?

下面给出目前唯一的成果,0环读写文件的API。

// 读取文件到内存中,返回读取的字节数;读取失败返回0
ULONG FileToMemory(LPCWSTR lpszFile, PVOID *pFileBuffer)
{OBJECT_ATTRIBUTES objectAttributes;IO_STATUS_BLOCK iostatus;HANDLE hfile;UNICODE_STRING KernelFileUnicodeString;NTSTATUS ntStatus;FILE_STANDARD_INFORMATION fsi;PUCHAR pBuffer;//初始化UNICODE_STRING字符串//RtlInitUnicodeString( &KernelFileUnicodeString, L"\\??\\C:\\Windows\\System32\\ntkrnlpa.exe");RtlInitUnicodeString( &KernelFileUnicodeString, lpszFile);//初始化objectAttributesInitializeObjectAttributes(&objectAttributes, &KernelFileUnicodeString,OBJ_CASE_INSENSITIVE, NULL, NULL );//创建文件ntStatus = ZwOpenFile( &hfile, GENERIC_ALL,&objectAttributes, &iostatus, FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_NONALERT);if (!NT_SUCCESS(ntStatus)){KdPrint(("The file is not exist!\n"));return 0;}//读取文件长度ntStatus = ZwQueryInformationFile(hfile,&iostatus,&fsi,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);//KdPrint(("The program want to read %d bytes\n",fsi.EndOfFile.QuadPart));//为读取的文件分配缓冲区pBuffer = (PUCHAR)ExAllocatePool(PagedPool,(LONG)fsi.EndOfFile.QuadPart);//读取文件ZwReadFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,(LONG)fsi.EndOfFile.QuadPart,NULL,NULL);//KdPrint(("The program really read %d bytes\n",iostatus.Information));//释放缓冲区//ExFreePool(pBuffer);*pFileBuffer = pBuffer;//关闭文件句柄ZwClose(hfile);return (ULONG)fsi.EndOfFile.QuadPart;
}// 内存数据写入文件
VOID MemoryToFile(PVOID pMemBuffer, ULONG ulSize, LPCWSTR lpszFile)
{OBJECT_ATTRIBUTES objectAttributes;IO_STATUS_BLOCK iostatus;HANDLE hfile;UNICODE_STRING logFileUnicodeString;NTSTATUS ntStatus;//初始化UNICODE_STRING字符串RtlInitUnicodeString( &logFileUnicodeString, lpszFile);//初始化objectAttributesInitializeObjectAttributes(&objectAttributes,&logFileUnicodeString,OBJ_CASE_INSENSITIVE,//对大小写敏感 NULL, NULL );//创建文件ntStatus = ZwCreateFile( &hfile, GENERIC_WRITE,&objectAttributes, &iostatus, NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE,FILE_OPEN_IF,//即使存在该文件,也创建 FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 );ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pMemBuffer,ulSize,NULL,NULL);KdPrint(("The program really wrote %d bytes\n",iostatus.Information));//关闭文件句柄ZwClose(hfile);}

(70)内核重载 xp sp3 x86 单核相关推荐

  1. Windows XP SP3细节官方详解

    Windows XP SP3预计本周即将正式发布.上周末,微软在官方网站上放出了名为"Overview of Windows XP Service Pack 3"的细节预览白皮书, ...

  2. xp sp3安装.Net 4.0提示严重错误,0x80070643,解决办法2017版

    客户电脑上要装金税开票软件,需要.net 4.0.30319.1,电脑环境是xp sp3,已经安装了.net 2, .net 3.5sp1,安装.net 4.0的时候提示错误0x80070643 因为 ...

  3. Windows驱动开发学习笔记(七)—— 多核同步内核重载

    Windows驱动开发学习笔记(七)-- 多核同步 基础知识 并发与同步 分析 InterlockedIncrement 原子操作相关API 内核文件 多核同步 临界区 示例一:错误的临界区 示例二: ...

  4. 微软推出Windows XP SP3中文版

    网易科技讯 4月29日消息,在昨日推出Windows XP Service Pack 3英文版后,微软Windows Update网站今日又推出了其中文版的下载. Windows XP SP3包括了自 ...

  5. 关于Windows XP SP3 的 FAQ

    根据 Microsoft 的消息,将在 2008 年第二季度发布的"Windows XP Service Pack 3"将是 Windows XP 的最后一个服务包了.并且 Win ...

  6. Microsoft Windows XP SP3安装测试手记

    作为一名Microsoft TechNet Observer,我近期收到了ITProCity方面关于Windows vista Service Pack 3和Windows XP Service Pa ...

  7. 一个XP SP3调用0地址蓝屏BUG

    0x00 蓝屏的堆栈 在XP SP3上跑POC之后,一段时间之后会出现蓝屏,蓝屏的堆栈如下,可以看出是ACKData里面CALL了一个0指针导致的蓝屏 0x01 蓝屏原因 1 ETW(Event Tr ...

  8. 关于Windows XP SP2 x86上不支持的两个C++11

    这个年代了还有人用Windows XP SP2 x86,我也是醉了... 这个bug估计很少有人遇到吧. std::mutex和std::thread不支持在Windows XP SP2 x86上运行 ...

  9. 官方原版Windows XP SP3(VOL)中文简体版ISO下载

    今天,向各位朋友推荐今年五月,由MSDN官方集成的XP With SP3专业VOL版.    文 件:Windows XP Professional with Service Pack 3 (x86) ...

最新文章

  1. 我花了三个小时写了一道题的六千字题解....(POJ 2888 Magic Bracelet)
  2. vs怎么编译php文件,vscode怎么初始编译
  3. 攻防世界-web-unfinish-从0到1的解题历程writeup
  4. Metro UI 菜单(Winform)
  5. Linux5观察doc目录并截屏,linux截屏命令
  6. 响应式布局之网站头部导航
  7. 轩辕实验室 |自动驾驶系统安全隐患分析
  8. 东芝Toshiba DP-2210 打印机驱动
  9. 第08章 Tableau在线服务器
  10. 企鹅龙(DRBL)无盘启动+再生龙(clonezilla)网络备份与还原系统
  11. 红尘梦落,卧醉千年,当所有的繁华散尽
  12. 专家访谈:Flex技术对web开发的影响
  13. 学习算法第一天:算法初步
  14. 李炎恢-在线商城第三季总结
  15. pixhawk(PX4)的一些论坛网站(包括中文版的PX4用户手册和PX4开发手册)
  16. html网页全选效果,为什么我用js写的全选/反选/全不选页面,没有效果?
  17. 原生Servlet的编写
  18. CodeForces_29B
  19. opencv opencv contrib
  20. 北京内推 | 清华大学周伯文老师课题组招聘助理教授/博士后/工程师/访问学生...

热门文章

  1. python socket发送组播数据_Python socket 如何实现广播单播切换
  2. 线上redis一般安在linux_redis的zset有多牛?请把耳朵递过来
  3. android的文件操作,Android文件操作概要1.ppt
  4. 成功解决ValueError: DataFrame.dtypes for data must be int, float or bool.Did not expect the data types
  5. TF之DNN:TF利用简单7个神经元的三层全连接神经网络【2-3-2】实现降低损失到0.000以下
  6. Dataset之Boston:Boston波士顿房价数据集的简介、下载、使用方法之详细攻略
  7. ML之DT(树模型):DT(树模型算法)算法的简介、代码定义、案例应用之详细攻略
  8. 微信小程序背景图虚化
  9. Apache部署网页-Ubuntu16.04
  10. 数据结构实验之链表一:顺序建立链表(SDUT 2116)