报名参加了一下2024的游戏安全竞赛,今天初赛结束,总体来说赛题质量还是非常高的。
解题附件下载
<!--more-->
略
先工具分析一下,发现加了 VM,动调发现对很多工具有检测,部分改名可以直接绕过,但是 CE 怎么改都会被检测,所以先上微步基本分析一下行为:
https://s.threatbook.com/report/file/1bc2f607b5e4707a70a32bb78ac72c9b895f00413ba4bd21229f6103757ca19f
注意到了有注入行为,一般会通过 WriteProcessMemory
这个 API 进行,于是编写 DLL 去hook看看情况。
这一块没什么进展,但是突然发现这个进程对其它进程有些操作
这不就是 token1 嘛,但是发现底下没有这个文件,尝试创建这个文件,发现直接就有内容写进去了,用命令可以打印出来。
于是 token1 就出来了,很神奇。 token1: 757F4749AEBB1891EF5AC2A9B5439CEA
。
对于token2,一直尝试做一些 API 的 hook 想看看它干了啥,这里我做了 MmCopyMemory 的 hook。
结果直接没有调用过。后面还同样的方法 hook 了其它的 API,诸如 KeStackAttachProcess 的,同样没有调用,于是陷入沉思,既然它没有把 token 写到 r3 那大概率在 r0 层。
同时在一次巧合中(开了 DbgView 的 verbose),发现 token 直接打印出来了。
那么 token2 就出来了 token2: 8b3f14a24d64f3e697957c252e3a5686
所以 flag 就是 flag{757F4749AEBB1891EF5AC2A9B5439CEA-8b3f14a24d64f3e697957c252e3a5686}
首先看看内核层的输出吧,因为它本来就可以输出,直接调用的 DbgPrintEx 函数,只不过某个 Level 无法正常被接受罢了,尝试 hook 一下,看看 Level
持续输出了 call DbgPrintEx(0000000000000000,0000000000000005,FFFFF1001067EB90)
Level=5几乎不能输出任何内容了,因此尝试hook替换让它可以输出,但是这里 Hook 还是太麻烦了,于是我选择打下断点之后栈回溯一下看看情况
可以发现关键 call 之前,有对 edx 赋值为 5,那么直接修改这个指令,把 hook 解掉看看能否输出。
这里我选择手动改一下,一共发现了三个位置,特征都是差不多的,都把 mov edx,5
改成 mov edx,0
。
发现改完之后 token 成功输出了。
但是这里应该是驱动加载时候分配的内存写入的 shellcode,如果能知道地址,那么能去改掉这些指令,但是地址是我通过栈回溯找到的,如果没有hook掉系统 API,那么我根本不太可能去获取到shellcode的地址。于是想到它既然是不停地在打印的,必然创建了一个内核线程,那么我先遍历一下内核线程。
在中间我判断了一下地址是否为 0xFFFF
开头来判断是否为内核线程,然后打印出来之后,搜索通过栈回溯得到的 shellcode 的前几位。
很幸运地只能找到一个,多次实验之后发现它shellcode是不会变的(至少头几个字节),那么就可以匹配特征码去判断 shellcode 的地址。
并且可以手动计算一下 shellcode StartAddress 和 对应要修改的指令的偏移。
启动地址:0xFFFFBB0EDB013DB0
修改地址1:0xffffbb0edb013e01
修改地址2:0xffffbb0edb013e64
修改地址3:0xffffbb0edb013ed4
分别是 shellcode+0x51+1
,shellcode+0xb4+1
,shellcode+0x124+1
的位置。(+1是因为要改的操作数在指令的偏移处)
先编写一个遍历内核线程的程序,然后去特判它的特征码,来确定shellcode位置,最后再写入三个指令即可。
该文件编译产物为 XSafe2.sys,运行题目之后加载这个驱动可以让 token2 输出。
通过下图可以看到,驱动加载后搜索到了 shellcode 的地址,并通过修改内存让 token成功输出了,但是自己做的时候发现是有概率的,有时候可能搜不到这个线程,从截图可以看出反复加载了4次才成功找到 shellcode,但是注入成功之后也成功输出了 token2。
token1 的话可以采用新建 C:\2024GameSafeRace.token1
文件的方式让它将 token1 打印出来,究其原因没有成功输出出来是因为创建文件的时候没有让它在文件不存在时创建。
后面发现写文件的进程好像是 TaskMgr,并且 token1 是可以独立运行的,所以可以把虚拟机的测试模式关了,后面只需要分析这个三环程序即可。
用调试器附加,虽然外挂程序检测了调试器,但是通过改名可以绕过,断在创建文件的API上 CreateFileA
栈回溯一下发现创建是失败的(返回-1)。
要让它成功输出让它创建成功即可,同时观察栈我注意到了有个参数3,而参数通过查阅 CreateFileA 的参数说明可知
这也就解释了为什么创建一个文件能够成功写入,尝试把它修改成 1。
发现成功返回了,所以目的非常明确了,让它传的第五个参数改成1即可成功输出到文件中,而刚好注意到上面的一条指令有直接 mov xxx,3 的,把它改成1试试。
文件即使不存在也会创建并输出成功。
那么这里说一个可行的思路:同样注入一个 dll 给它,然后去遍历线程找到 shellcode 入口,计算偏移改掉这个指令,让 token3 成功输出。
先手动操作一遍:
此时可以发现线程入口是 0000019B070AAB48,要修改的指令地址为 0000019B070A4D6D
在 StartRoutine - 0x5ddb 的位置上,而且它的地址很明显,只要在堆上就符合条件,但是为了保险还是取一定长度的特征码去比较。
那么据此写一个针对 Taskmgr 的注入器(二进制文件为 Xinject.exe):
然后根据以上分析结果写一个改变这个代码的 DLL(二进制文件为 XHack.dll):
运行 hack.exe 之后,运行 Xinject.exe 即可达到如下效果:
注入结束之后可以看到马上创建了文件。
第二题就完整地实现了。
附件说明:
其实还是 hook 这个地方,改它的写入文件名即可,这里我又注意到
往下顺着看,它把RAX写到了 RBP+0x20 的位置,但是最后又对它写了第五个参数,因此基本可以认为这个指令是无用的,尝试去进程分配一块内存,在这个地方将 RCX 的值赋值给它即可达成任意位置的写入。
这个指令位置在 StartRoutine - 0x5ddb - 0x67 处。
用下面的代码编译出 XHack.dll
(运行时需要改名为这个,用第二题的注入器,附件中的文件名为 XHack3.dll)
先分配一个内存,写入地址,再构造 mov rcx,xxx
指令,最后替换到指定位置即可。
内容也非常完美没有被改变
4,5如上所示,源代码均在本文中提供,在打包的可执行文件中:
总共的附件说明:
三天没打满,中间一天抽空去拿了个ACM省赛。
然后第二天又接到调剂复试通知赶路去了。
不过最后好在还是赶着最后完成了赛题 233。
https://www.ctyun.cn/zhishi/p-233867
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
#include<Psapi.h>
typedef
BOOL
(*Func)(
HANDLE
hProcess,
LPVOID
lpBaseAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize,
SIZE_T
* lpNumberOfBytesWritten
);
Func OriginFunc = NULL;
BYTE
HookCode[] = {
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xE0
};
BYTE
OriginCode[0x50];
SIZE_T
HookLen =
sizeof
(HookCode);
DWORD
saved=0;
WCHAR
FILENAME[MAX_PATH];
BOOL
HackWriteProcessMemory(
HANDLE
hProcess,
LPVOID
lpBaseAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize,
SIZE_T
* lpNumberOfBytesWritten
) {
VirtualProtect(OriginFunc, HookLen, PAGE_EXECUTE_READWRITE, &saved);
memcpy
(OriginFunc, OriginCode,HookLen);
printf
(
"Call WriteProcessMemory(%p,%p,%p,%d,%p)"
,hProcess,lpBaseAddress,lpBuffer,nSize,lpNumberOfBytesWritten);
GetModuleFileNameEx(hProcess, NULL, FILENAME, MAX_PATH);
wprintf(L
"ProcessName=%s\n"
, FILENAME);
BOOL
ret=OriginFunc(hProcess, lpBaseAddress, lpBuffer, nSize,lpNumberOfBytesWritten);
memcpy
(OriginFunc, HookCode, HookLen);
VirtualProtect(OriginFunc, HookLen, saved, &saved);
return
ret;
}
void
hack() {
OriginFunc = WriteProcessMemory;
VirtualProtect(OriginFunc, HookLen, PAGE_EXECUTE_READWRITE, &saved);
memcpy
(OriginCode, OriginFunc,HookLen);
*(
__int64
*)(HookCode + 2) = (
__int64
)HackWriteProcessMemory;
memcpy
(OriginFunc, HookCode, HookLen);
VirtualProtect(OriginFunc, HookLen, saved, &saved);
printf
(
"Hook done\n"
);
}
BOOL
APIENTRY DllMain(
HMODULE
hModule,
DWORD
ul_reason_for_call,
LPVOID
lpReserved
)
{
switch
(ul_reason_for_call)
{
case
DLL_PROCESS_ATTACH: {
AllocConsole();
freopen
(
"CONOUT$"
,
"w"
, stdout);
hack();
}
case
DLL_THREAD_ATTACH:
case
DLL_THREAD_DETACH:
case
DLL_PROCESS_DETACH:
break
;
}
return
TRUE;
}
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
#include<Psapi.h>
typedef
BOOL
(*Func)(
HANDLE
hProcess,
LPVOID
lpBaseAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize,
SIZE_T
* lpNumberOfBytesWritten
);
Func OriginFunc = NULL;
BYTE
HookCode[] = {
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xE0
};
BYTE
OriginCode[0x50];
SIZE_T
HookLen =
sizeof
(HookCode);
DWORD
saved=0;
WCHAR
FILENAME[MAX_PATH];
BOOL
HackWriteProcessMemory(
HANDLE
hProcess,
LPVOID
lpBaseAddress,
LPCVOID
lpBuffer,
SIZE_T
nSize,
SIZE_T
* lpNumberOfBytesWritten
) {
VirtualProtect(OriginFunc, HookLen, PAGE_EXECUTE_READWRITE, &saved);
memcpy
(OriginFunc, OriginCode,HookLen);
printf
(
"Call WriteProcessMemory(%p,%p,%p,%d,%p)"
,hProcess,lpBaseAddress,lpBuffer,nSize,lpNumberOfBytesWritten);
GetModuleFileNameEx(hProcess, NULL, FILENAME, MAX_PATH);
wprintf(L
"ProcessName=%s\n"
, FILENAME);
BOOL
ret=OriginFunc(hProcess, lpBaseAddress, lpBuffer, nSize,lpNumberOfBytesWritten);
memcpy
(OriginFunc, HookCode, HookLen);
VirtualProtect(OriginFunc, HookLen, saved, &saved);
return
ret;
}
void
hack() {
OriginFunc = WriteProcessMemory;
VirtualProtect(OriginFunc, HookLen, PAGE_EXECUTE_READWRITE, &saved);
memcpy
(OriginCode, OriginFunc,HookLen);
*(
__int64
*)(HookCode + 2) = (
__int64
)HackWriteProcessMemory;
memcpy
(OriginFunc, HookCode, HookLen);
VirtualProtect(OriginFunc, HookLen, saved, &saved);
printf
(
"Hook done\n"
);
}
BOOL
APIENTRY DllMain(
HMODULE
hModule,
DWORD
ul_reason_for_call,
LPVOID
lpReserved
)
{
switch
(ul_reason_for_call)
{
case
DLL_PROCESS_ATTACH: {
AllocConsole();
freopen
(
"CONOUT$"
,
"w"
, stdout);
hack();
}
case
DLL_THREAD_ATTACH:
case
DLL_THREAD_DETACH:
case
DLL_PROCESS_DETACH:
break
;
}
return
TRUE;
}
#include <ntifs.h>
#include <ntdef.h>
#include <ntstatus.h>
#include <ntddk.h>
#define MAX_BACKTRACE_DEPTH 20
#define SYMBOL L"\\??\\xia0ji2333"
#define kprintf(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, ##__VA_ARGS__)
UINT64
BaseAddr=NULL, DLLSize=0;
NTSTATUS CreateDevice(PDEVICE_OBJECT driver) {
NTSTATUS status;
UNICODE_STRING MyDriver;
PDEVICE_OBJECT device = NULL;
RtlInitUnicodeString(&MyDriver, L
"\\DEVICE\\xia0ji233"
);
status = IoCreateDevice(
driver,
sizeof
(driver->DeviceExtension),
&MyDriver,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&device
);
if
(status == STATUS_SUCCESS) {
UNICODE_STRING Sym;
RtlInitUnicodeString(&Sym, SYMBOL);
status = IoCreateSymbolicLink(&Sym, &MyDriver);
if
(status == STATUS_SUCCESS) {
kprintf((
"Line %d:xia0ji233: symbol linked success\n"
), __LINE__);
}
else
{
kprintf((
"Line %d:xia0ji233: symbol linked failed status=%x\n"
), __LINE__, status);
}
}
else
{
kprintf((
"Line %d:xia0ji233: create device fail status=%x\n"
), __LINE__, status);
}
}
void
DeleteDevice(PDRIVER_OBJECT pDriver) {
kprintf((
"Line %d:xia0ji233: start delete device\n"
), __LINE__);
if
(pDriver->DeviceObject) {
UNICODE_STRING Sym;
RtlInitUnicodeString(&Sym, SYMBOL);
kprintf((
"Line %d:xia0ji233: Delete Symbol\n"
), __LINE__);
IoDeleteSymbolicLink(&Sym);
kprintf((
"Line %d:xia0ji233: Delete Device\n"
), __LINE__);
IoDeleteDevice(pDriver->DeviceObject);
}
kprintf((
"Line %d:xia0ji233: end delete device\n"
), __LINE__);
}
char
newcode[] = {
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xE0
};
char
oldcode[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,
};
char
*target;
KIRQL WPOFFx64()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64
cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
return
irql;
}
void
WPONx64(KIRQL irql)
{
UINT64
cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
NTSTATUS Unhook() {
KIRQL irql = WPOFFx64();
for
(
int
i = 0; i <
sizeof
(newcode); i++) {
target[i] = oldcode[i];
}
WPONx64(irql);
return
STATUS_SUCCESS;
}
NTSTATUS Hook() {
KIRQL irql = WPOFFx64();
for
(
int
i = 0; i <
sizeof
(newcode); i++) {
target[i] = newcode[i];
}
WPONx64(irql);
return
STATUS_SUCCESS;
}
typedef
NTSTATUS(*Copy)(
PVOID
, MM_COPY_ADDRESS,
SIZE_T
,
ULONG
,
SIZE_T
*);
PDRIVER_OBJECT g_Object = NULL;
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;
USHORT
LoadCount;
USHORT
TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID
SectionPointer;
ULONG
CheckSum;
};
};
union
{
struct
{
ULONG
TimeDateStamp;
};
struct
{
PVOID
LoadedImports;
};
};
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
VOID
bianliqudongmokuai(PUNICODE_STRING name,
UINT64
* pBaseAddr,
UINT64
* pSize)
{
LDR_DATA_TABLE_ENTRY *TE, *Tmp;
TE = (LDR_DATA_TABLE_ENTRY*)g_Object->DriverSection;
PLIST_ENTRY LinkList;
;
int
i = 0;
LinkList = TE->InLoadOrderLinks.Flink;
while
(LinkList != &TE->InLoadOrderLinks)
{
Tmp = (LDR_DATA_TABLE_ENTRY*)LinkList;
if
(RtlCompareUnicodeString(&Tmp->BaseDllName, name, FALSE))
{
}
else
{
kprintf((
"Found Module!\n"
));
*pBaseAddr = (
UINT64
)(Tmp->DllBase);
*pSize = (
UINT64
)(Tmp->SizeOfImage);
}
LinkList = LinkList->Flink;
i++;
}
}
NTSTATUS
myMmCopyMemory(
_In_
PVOID
TargetAddress,
_In_ MM_COPY_ADDRESS SourceAddress,
_In_
SIZE_T
NumberOfBytes,
_In_
ULONG
Flags,
_Out_
PSIZE_T
NumberOfBytesTransferred
) {
if
(!BaseAddr) {
UNICODE_STRING name;
RtlInitUnicodeString(&name, L
"ace.sys"
);
bianliqudongmokuai(&name,&BaseAddr,&DLLSize);
if
(!BaseAddr) {
goto
end;
}
}
PVOID
backtrace[MAX_BACKTRACE_DEPTH];
USHORT
capturedFrames = RtlCaptureStackBackTrace(0, MAX_BACKTRACE_DEPTH, backtrace, NULL);
UINT64
addr = BaseAddr;
UINT64
size = DLLSize;
int
flag = 0;
for
(
USHORT
i = 0; i < capturedFrames; i++)
{
if
(backtrace[i] >= addr && backtrace[i] <= addr + size) {
flag = 1;
}
}
if
(flag) {
kprintf((
"xia0ji233: calls MmCopyMemory(%p,%p,%d,%p,%p)\n"
), TargetAddress, SourceAddress, NumberOfBytes, Flags, NumberOfBytesTransferred);
kprintf((
"Here is data: "
));
for
(
INT64
i = 0; i < NumberOfBytes; i++) {
kprintf((
"%02x "
), *((unsigned
char
*)SourceAddress.VirtualAddress + i));
}
kprintf((
"\n"
));
}
end:
Unhook();
Copy func = (Copy)target;
NTSTATUS s = func(TargetAddress, SourceAddress, NumberOfBytes, Flags, NumberOfBytesTransferred);
Hook();
return
s;
}
void
DriverUnload(PDRIVER_OBJECT pDriver) {
kprintf((
"Line %d:xia0ji233: start unload\n"
), __LINE__);
Unhook();
DeleteDevice(pDriver);
}
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath
) {
DriverObject->DriverUnload = DriverUnload;
CreateDevice(DriverObject);
kprintf((
"Line %d:xia0ji233: RegistryPath = %S\n"
), __LINE__, RegistryPath->Buffer);
target = MmCopyMemory;
kprintf((
"Line %d:xia0ji233: MmCopyMemory=%p\n"
), __LINE__, target);
g_Object = DriverObject;
if
(target) {
for
(
int
i = 0; i <
sizeof
(oldcode); i++) {
oldcode[i] = target[i];
}
*(
UINT64
*)(newcode + 2) = myMmCopyMemory;
Hook();
}
else
{
kprintf((
"xia0ji233:hahaha"
));
}
return
0;
}
#include <ntifs.h>
#include <ntdef.h>
#include <ntstatus.h>
#include <ntddk.h>
#define MAX_BACKTRACE_DEPTH 20
#define SYMBOL L"\\??\\xia0ji2333"
#define kprintf(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, ##__VA_ARGS__)
UINT64
BaseAddr=NULL, DLLSize=0;
NTSTATUS CreateDevice(PDEVICE_OBJECT driver) {
NTSTATUS status;
UNICODE_STRING MyDriver;
PDEVICE_OBJECT device = NULL;
RtlInitUnicodeString(&MyDriver, L
"\\DEVICE\\xia0ji233"
);
status = IoCreateDevice(
driver,
sizeof
(driver->DeviceExtension),
&MyDriver,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&device
);
if
(status == STATUS_SUCCESS) {
UNICODE_STRING Sym;
RtlInitUnicodeString(&Sym, SYMBOL);
status = IoCreateSymbolicLink(&Sym, &MyDriver);
if
(status == STATUS_SUCCESS) {
kprintf((
"Line %d:xia0ji233: symbol linked success\n"
), __LINE__);
}
else
{
kprintf((
"Line %d:xia0ji233: symbol linked failed status=%x\n"
), __LINE__, status);
}
}
else
{
kprintf((
"Line %d:xia0ji233: create device fail status=%x\n"
), __LINE__, status);
}
}
void
DeleteDevice(PDRIVER_OBJECT pDriver) {
kprintf((
"Line %d:xia0ji233: start delete device\n"
), __LINE__);
if
(pDriver->DeviceObject) {
UNICODE_STRING Sym;
RtlInitUnicodeString(&Sym, SYMBOL);
kprintf((
"Line %d:xia0ji233: Delete Symbol\n"
), __LINE__);
IoDeleteSymbolicLink(&Sym);
kprintf((
"Line %d:xia0ji233: Delete Device\n"
), __LINE__);
IoDeleteDevice(pDriver->DeviceObject);
}
kprintf((
"Line %d:xia0ji233: end delete device\n"
), __LINE__);
}
char
newcode[] = {
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xE0
};
char
oldcode[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,
};
char
*target;
KIRQL WPOFFx64()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64
cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
return
irql;
}
void
WPONx64(KIRQL irql)
{
UINT64
cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
NTSTATUS Unhook() {
KIRQL irql = WPOFFx64();
for
(
int
i = 0; i <
sizeof
(newcode); i++) {
target[i] = oldcode[i];
}
WPONx64(irql);
return
STATUS_SUCCESS;
}
NTSTATUS Hook() {
KIRQL irql = WPOFFx64();
for
(
int
i = 0; i <
sizeof
(newcode); i++) {
target[i] = newcode[i];
}
WPONx64(irql);
return
STATUS_SUCCESS;
}
typedef
NTSTATUS(*Copy)(
PVOID
, MM_COPY_ADDRESS,
SIZE_T
,
ULONG
,
SIZE_T
*);
PDRIVER_OBJECT g_Object = NULL;
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;
USHORT
LoadCount;
USHORT
TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID
SectionPointer;
ULONG
CheckSum;
};
};
union
{
struct
{
ULONG
TimeDateStamp;
};
struct
{
PVOID
LoadedImports;
};
};
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
VOID
bianliqudongmokuai(PUNICODE_STRING name,
UINT64
* pBaseAddr,
UINT64
* pSize)
{
LDR_DATA_TABLE_ENTRY *TE, *Tmp;
TE = (LDR_DATA_TABLE_ENTRY*)g_Object->DriverSection;
PLIST_ENTRY LinkList;
;
int
i = 0;
LinkList = TE->InLoadOrderLinks.Flink;
while
(LinkList != &TE->InLoadOrderLinks)
{
Tmp = (LDR_DATA_TABLE_ENTRY*)LinkList;
if
(RtlCompareUnicodeString(&Tmp->BaseDllName, name, FALSE))
{
}
else
{
kprintf((
"Found Module!\n"
));
*pBaseAddr = (
UINT64
)(Tmp->DllBase);
*pSize = (
UINT64
)(Tmp->SizeOfImage);
}
LinkList = LinkList->Flink;
i++;
}
}
NTSTATUS
myMmCopyMemory(
_In_
PVOID
TargetAddress,
_In_ MM_COPY_ADDRESS SourceAddress,
_In_
SIZE_T
NumberOfBytes,
_In_
ULONG
Flags,
_Out_
PSIZE_T
NumberOfBytesTransferred
) {
if
(!BaseAddr) {
UNICODE_STRING name;
RtlInitUnicodeString(&name, L
"ace.sys"
);
bianliqudongmokuai(&name,&BaseAddr,&DLLSize);
if
(!BaseAddr) {
goto
end;
}
}
PVOID
backtrace[MAX_BACKTRACE_DEPTH];
USHORT
capturedFrames = RtlCaptureStackBackTrace(0, MAX_BACKTRACE_DEPTH, backtrace, NULL);
UINT64
addr = BaseAddr;
UINT64
size = DLLSize;
int
flag = 0;
for
(
USHORT
i = 0; i < capturedFrames; i++)
{
if
(backtrace[i] >= addr && backtrace[i] <= addr + size) {
flag = 1;
}
}
if
(flag) {
kprintf((
"xia0ji233: calls MmCopyMemory(%p,%p,%d,%p,%p)\n"
), TargetAddress, SourceAddress, NumberOfBytes, Flags, NumberOfBytesTransferred);
kprintf((
"Here is data: "
));
for
(
INT64
i = 0; i < NumberOfBytes; i++) {
kprintf((
"%02x "
), *((unsigned
char
*)SourceAddress.VirtualAddress + i));
}
kprintf((
"\n"
));
}
end:
Unhook();
Copy func = (Copy)target;
NTSTATUS s = func(TargetAddress, SourceAddress, NumberOfBytes, Flags, NumberOfBytesTransferred);
Hook();
return
s;
}
void
DriverUnload(PDRIVER_OBJECT pDriver) {
kprintf((
"Line %d:xia0ji233: start unload\n"
), __LINE__);
Unhook();
DeleteDevice(pDriver);
}
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath
) {
DriverObject->DriverUnload = DriverUnload;
CreateDevice(DriverObject);
kprintf((
"Line %d:xia0ji233: RegistryPath = %S\n"
), __LINE__, RegistryPath->Buffer);
target = MmCopyMemory;
kprintf((
"Line %d:xia0ji233: MmCopyMemory=%p\n"
), __LINE__, target);
g_Object = DriverObject;
if
(target) {
for
(
int
i = 0; i <
sizeof
(oldcode); i++) {
oldcode[i] = target[i];
}
*(
UINT64
*)(newcode + 2) = myMmCopyMemory;
Hook();
}
else
{
kprintf((
"xia0ji233:hahaha"
));
}
return
0;
}
#include <ntifs.h>
#include <ntdef.h>
#include <ntstatus.h>
#include <ntddk.h>
#define MAX_BACKTRACE_DEPTH 20
#define SYMBOL L"\\??\\xia0ji2333"
#define kprintf(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, ##__VA_ARGS__)
UINT64
BaseAddr=NULL, DLLSize=0;
void
DeleteDevice(PDRIVER_OBJECT pDriver) {
kprintf((
"Line %d:xia0ji233: start delete device\n"
), __LINE__);
if
(pDriver->DeviceObject) {
UNICODE_STRING Sym;
RtlInitUnicodeString(&Sym, SYMBOL);
kprintf((
"Line %d:xia0ji233: Delete Symbol\n"
), __LINE__);
IoDeleteSymbolicLink(&Sym);
kprintf((
"Line %d:xia0ji233: Delete Device\n"
), __LINE__);
IoDeleteDevice(pDriver->DeviceObject);
}
kprintf((
"Line %d:xia0ji233: end delete device\n"
), __LINE__);
}
char
newcode[] = {
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xE0
};
char
oldcode[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,
};
char
*target;
KIRQL WPOFFx64()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64
cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
return
irql;
}
void
WPONx64(KIRQL irql)
{
UINT64
cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
NTSTATUS Unhook() {
KIRQL irql = WPOFFx64();
for
(
int
i = 0; i <
sizeof
(newcode); i++) {
target[i] = oldcode[i];
}
WPONx64(irql);
return
STATUS_SUCCESS;
}
NTSTATUS Hook() {
KIRQL irql = WPOFFx64();
for
(
int
i = 0; i <
sizeof
(newcode); i++) {
target[i] = newcode[i];
}
WPONx64(irql);
return
STATUS_SUCCESS;
}
PDRIVER_OBJECT g_Object = NULL;
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;
USHORT
LoadCount;
USHORT
TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID
SectionPointer;
ULONG
CheckSum;
};
};
union
{
struct
{
ULONG
TimeDateStamp;
};
struct
{
PVOID
LoadedImports;
};
};
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
VOID
bianliqudongmokuai(PUNICODE_STRING name,
UINT64
* pBaseAddr,
UINT64
* pSize)
{
LDR_DATA_TABLE_ENTRY *TE, *Tmp;
TE = (LDR_DATA_TABLE_ENTRY*)g_Object->DriverSection;
PLIST_ENTRY LinkList;
;
int
i = 0;
LinkList = TE->InLoadOrderLinks.Flink;
while
(LinkList != &TE->InLoadOrderLinks)
{
Tmp = (LDR_DATA_TABLE_ENTRY*)LinkList;
if
(RtlCompareUnicodeString(&Tmp->BaseDllName, name, FALSE))
{
}
else
{
kprintf((
"Found Module!\n"
));
*pBaseAddr = (
UINT64
)(Tmp->DllBase);
*pSize = (
UINT64
)(Tmp->SizeOfImage);
}
LinkList = LinkList->Flink;
i++;
}
}
typedef
ULONG
(*FuncPtr) (
ULONG
ComponentId,
ULONG
Level,
PCSTR
Format, ...);
ULONG
myDbgPrintEx(
ULONG
ComponentId,
ULONG
Level,
PCSTR
Format, ... ) {
Unhook();
FuncPtr func = (FuncPtr)target;
kprintf((
"call DbgPrintEx(%p,%p,%p)"
), ComponentId, Level, Format);
DbgBreakPoint();
NTSTATUS s = func(ComponentId,Level,Format);
Hook();
return
s;
}
void
DriverUnload(PDRIVER_OBJECT pDriver) {
kprintf((
"Line %d:xia0ji233: start unload\n"
), __LINE__);
Unhook();
DeleteDevice(pDriver);
}
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath
) {
DriverObject->DriverUnload = DriverUnload;
kprintf((
"Line %d:xia0ji233: RegistryPath = %S\n"
), __LINE__, RegistryPath->Buffer);
target = DbgPrintEx;
kprintf((
"Line %d:xia0ji233: DbgPrintEx=%p\n"
), __LINE__, target);
g_Object = DriverObject;
if
(target) {
for
(
int
i = 0; i <
sizeof
(oldcode); i++) {
oldcode[i] = target[i];
}
*(
UINT64
*)(newcode + 2) = myDbgPrintEx;
Hook();
}
else
{
kprintf((
"xia0ji233:hahaha"
));
}
return
0;
}
#include <ntifs.h>
#include <ntdef.h>
#include <ntstatus.h>
#include <ntddk.h>
#define MAX_BACKTRACE_DEPTH 20
#define SYMBOL L"\\??\\xia0ji2333"
#define kprintf(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, ##__VA_ARGS__)
UINT64
BaseAddr=NULL, DLLSize=0;
void
DeleteDevice(PDRIVER_OBJECT pDriver) {
kprintf((
"Line %d:xia0ji233: start delete device\n"
), __LINE__);
if
(pDriver->DeviceObject) {
UNICODE_STRING Sym;
RtlInitUnicodeString(&Sym, SYMBOL);
kprintf((
"Line %d:xia0ji233: Delete Symbol\n"
), __LINE__);
IoDeleteSymbolicLink(&Sym);
kprintf((
"Line %d:xia0ji233: Delete Device\n"
), __LINE__);
IoDeleteDevice(pDriver->DeviceObject);
}
kprintf((
"Line %d:xia0ji233: end delete device\n"
), __LINE__);
}
char
newcode[] = {
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xE0
};
char
oldcode[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,
};
char
*target;
KIRQL WPOFFx64()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64
cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
return
irql;
}
void
WPONx64(KIRQL irql)
{
UINT64
cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
NTSTATUS Unhook() {
KIRQL irql = WPOFFx64();
for
(
int
i = 0; i <
sizeof
(newcode); i++) {
target[i] = oldcode[i];
}
WPONx64(irql);
return
STATUS_SUCCESS;
}
NTSTATUS Hook() {
KIRQL irql = WPOFFx64();
for
(
int
i = 0; i <
sizeof
(newcode); i++) {
target[i] = newcode[i];
}
WPONx64(irql);
return
STATUS_SUCCESS;
}
PDRIVER_OBJECT g_Object = NULL;
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;
USHORT
LoadCount;
USHORT
TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID
SectionPointer;
ULONG
CheckSum;
};
};
union
{
struct
{
ULONG
TimeDateStamp;
};
struct
{
PVOID
LoadedImports;
};
};
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
VOID
bianliqudongmokuai(PUNICODE_STRING name,
UINT64
* pBaseAddr,
UINT64
* pSize)
{
LDR_DATA_TABLE_ENTRY *TE, *Tmp;
TE = (LDR_DATA_TABLE_ENTRY*)g_Object->DriverSection;
PLIST_ENTRY LinkList;
;
int
i = 0;
LinkList = TE->InLoadOrderLinks.Flink;
while
(LinkList != &TE->InLoadOrderLinks)
{
Tmp = (LDR_DATA_TABLE_ENTRY*)LinkList;
if
(RtlCompareUnicodeString(&Tmp->BaseDllName, name, FALSE))
{
}
else
{
kprintf((
"Found Module!\n"
));
*pBaseAddr = (
UINT64
)(Tmp->DllBase);
*pSize = (
UINT64
)(Tmp->SizeOfImage);
}
LinkList = LinkList->Flink;
i++;
}
}
typedef
ULONG
(*FuncPtr) (
ULONG
ComponentId,
ULONG
Level,
PCSTR
Format, ...);
ULONG
myDbgPrintEx(
ULONG
ComponentId,
ULONG
Level,
PCSTR
Format, ... ) {
Unhook();
FuncPtr func = (FuncPtr)target;
kprintf((
"call DbgPrintEx(%p,%p,%p)"
), ComponentId, Level, Format);
DbgBreakPoint();
NTSTATUS s = func(ComponentId,Level,Format);
Hook();
return
s;
}
void
DriverUnload(PDRIVER_OBJECT pDriver) {
kprintf((
"Line %d:xia0ji233: start unload\n"
), __LINE__);
Unhook();
DeleteDevice(pDriver);
}
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath
) {
DriverObject->DriverUnload = DriverUnload;
kprintf((
"Line %d:xia0ji233: RegistryPath = %S\n"
), __LINE__, RegistryPath->Buffer);
target = DbgPrintEx;
kprintf((
"Line %d:xia0ji233: DbgPrintEx=%p\n"
), __LINE__, target);
g_Object = DriverObject;
if
(target) {
for
(
int
i = 0; i <
sizeof
(oldcode); i++) {
oldcode[i] = target[i];
}
*(
UINT64
*)(newcode + 2) = myDbgPrintEx;
Hook();
}
else
{
kprintf((
"xia0ji233:hahaha"
));
}
return
0;
}
#include <ntddk.h>
#define kprintf(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, ##__VA_ARGS__)
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
VOID
UnloadDriver(PDRIVER_OBJECT DriverObject);
NTSTATUS EnumerateKernelThreads();
typedef
NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
ULONG
,
PVOID
,
ULONG
,
PULONG
);
typedef
struct
_SYSTEM_PROCESS_INFORMATION {
ULONG
NextEntryOffset;
ULONG
NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
ULONG
BasePriority;
HANDLE
ProcessId;
HANDLE
InheritedFromProcessId;
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef
struct
_SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG
WaitTime;
PVOID
StartAddress;
CLIENT_ID ClientId;
ULONG
Priority;
LONG
BasePriority;
ULONG
ContextSwitchCount;
LONG
State;
LONG
WaitReason;
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
typedef
enum
_SYSTEM_INFORMATION_CLASS {
SystemProcessInformation = 5
} SYSTEM_INFORMATION_CLASS;
#define SystemModuleInformation 11
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
UNREFERENCED_PARAMETER(RegistryPath);
DriverObject->DriverUnload = UnloadDriver;
kprintf((
"Driver Loaded\n"
));
return
EnumerateKernelThreads();
}
VOID
UnloadDriver(PDRIVER_OBJECT DriverObject) {
UNREFERENCED_PARAMETER(DriverObject);
kprintf((
"Driver Unloaded\n"
));
}
NTSTATUS EnumerateKernelThreads() {
UNICODE_STRING routineName;
RtlInitUnicodeString(&routineName, L
"ZwQuerySystemInformation"
);
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress(&routineName);
if
(!ZwQuerySystemInformation) {
return
STATUS_UNSUCCESSFUL;
}
ULONG
returnLength = 0;
ZwQuerySystemInformation(SystemProcessInformation, NULL, 0, &returnLength);
PVOID
buffer = ExAllocatePool(NonPagedPool, returnLength);
if
(!buffer) {
return
STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS status = ZwQuerySystemInformation(SystemProcessInformation, buffer, returnLength, &returnLength);
if
(!NT_SUCCESS(status)) {
ExFreePool(buffer);
return
status;
}
PSYSTEM_PROCESS_INFORMATION current = (PSYSTEM_PROCESS_INFORMATION)buffer;
while
(TRUE) {
PSYSTEM_THREAD_INFORMATION threadInfo = (PSYSTEM_THREAD_INFORMATION)(current + 1);
for
(
ULONG
i = 0; i < current->NumberOfThreads; i++) {
if
(((
UINT64
)(threadInfo->StartAddress) & 0xFFFF000000000000) == 0xFFFF000000000000) {
kprintf((
"Thread StartAddress: %p\n"
), threadInfo->StartAddress);
}
threadInfo++;
}
if
(current->NextEntryOffset == 0)
break
;
current = (PSYSTEM_PROCESS_INFORMATION)((
PUCHAR
)current + current->NextEntryOffset);
}
ExFreePool(buffer);
return
STATUS_SUCCESS;
}
#include <ntddk.h>
#define kprintf(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, ##__VA_ARGS__)
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
VOID
UnloadDriver(PDRIVER_OBJECT DriverObject);
NTSTATUS EnumerateKernelThreads();
typedef
NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
ULONG
,
PVOID
,
ULONG
,
PULONG
);
typedef
struct
_SYSTEM_PROCESS_INFORMATION {
ULONG
NextEntryOffset;
ULONG
NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2024-4-15 10:05
被xi@0ji233编辑
,原因: