2024年腾讯游戏安全技术大赛-PC方向初赛复现
2024腾讯游戏安全技术大赛-PC方向初赛
第一问
token1
hace.exe被VM了没法看,观察导入表发现导入了LoadLibraryA和GetProcAddress两个函数,大概率是加载了一个dll。
用一些云工具分析一下可以看出来exe应该是一个dll注入器,用远线程的方法把dll注入到了某个进程中。根据这一
特性,可以考虑HookWriteProcessMemory这个API来获取到lpBuffer这个参数,也就是DLL。
拿到三个文件,其中只有一个文件有PE头,这个就是DLL。
很伤心这个DLL也有一大坨混淆,在IDA中翻一下函数看看能不能找突破口。
发现有几个函数采用了下面的混淆方法
int sub_180001990()
{
size_t v0; // rbx
DWORD v1; // eax
__m128i Dst; // [rsp+20h] [rbp-48h] BYREF
__int64 v4; // [rsp+30h] [rbp-38h]
__int64 v5; // [rsp+38h] [rbp-30h]
__m128i Src; // [rsp+40h] [rbp-28h] BYREF
Dst.m128i_i64[0] = 0xE795A7603F90341FuLL;
Dst.m128i_i64[1] = 0xC65BF3E99CAA093CuLL;
Src.m128i_i64[0] = 0x89FAC00F53FE5D68uLL;
Src.m128i_i64[1] = 0xC65BF3E9F9D26C12uLL;
Src = _mm_xor_si128(_mm_load_si128(&Src), Dst);
v0 = -1LL;
do
++v0;
while ( Src.m128i_i8[v0] );
memmove(&unk_1800349A0, &Src, v0);
Dst.m128i_i64[0] = 0LL;
v4 = 0LL;
v5 = 15LL;
sub_180004770((void **)&Dst, &Src, v0);
v1 = sub_1800070A0(&Dst);
sub_1800063D0(&unk_1800349A0, v1);
return atexit(sub_180020C90);
}
解密出来的字符串是winlogon.exe,这个是Windows的登陆进程,可能DLL注入到了这里?
类似的函数还有五六个,解密出来一部分,根据字符串来看似乎是用于反调试的,包括CE、x64dbg、IDA等动调。
注意到这样一个函数:
void sub_180007C10()
{
HANDLE v1; // rcx
void *v2; // rdx
__int128 v3; // xmm0
__int128 v4; // xmm1
HANDLE FileA; // rbx
__int64 v8; // rcx
_BYTE *v9; // rdx
unsigned __int64 v10; // rdx
_QWORD *v11; // rcx
char Buffer; // [rsp+60h] [rbp+0h] BYREF
_RBP = (unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL;
while ( byte_180032C00 )
{
if ( !byte_180034961 && !byte_180034960 )
sub_1800041D0();
v1 = hProcess;
v2 = (void *)(qword_180034968 + 2766);
*(_BYTE *)_RBP = 15;
WriteProcessMemory(v1, v2, (LPCVOID)((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL), 1uLL, 0LL);
byte_180032C00 = 0;
*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x20) = 0xAA32D3B2B7C50388uLL;
*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x10) = 0xA0A195500DCC0E5CuLL;
*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x18) = 0x943E9588CFCF645DuLL;
v3 = *(_OWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x10);
*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x28) = 0xA727C0574231D098uLL;
v4 = *(_OWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x20);
*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x80) = 0xE795A7603F90341FuLL;
*(_OWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x60) = v3;
*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x88) = 0xC65BF3E99CAA093CuLL;
*(_OWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x70) = v4;
*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x90) = 0xCF59BCC699A060E9uLL;
*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x98) = 0xA727C0574231E1F6uLL;
__asm
{
vmovdqu ymm0, [rbp+0D0h+var_50]
vpxor ymm1, ymm0, [rbp+0D0h+var_70]
vmovdqa [rbp+0D0h+var_70], ymm1
vzeroupper
}
FileA = CreateFileA((LPCSTR)(_RBP + 96), 0x40000000u, 0, 0LL, 3u, 0x80u, 0LL);
if ( FileA != (HANDLE)-1LL )
{
((void (__fastcall *)(unsigned __int64))loc_180007A20)(_RBP + 48);
v8 = -1LL;
if ( *(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x48) < 0x10uLL )
{
do
++v8;
while ( *(_BYTE *)(_RBP + 48 + v8) );
v9 = (_BYTE *)(_RBP + 48);
}
else
{
v9 = *(_BYTE **)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x30);
do
++v8;
while ( v9[v8] );
}
WriteFile(FileA, v9, v8, (LPDWORD)(_RBP + 8), 0LL);
CloseHandle(FileA);
v10 = *(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x48);
if ( v10 >= 0x10 )
{
v11 = *(_QWORD **)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x30);
if ( v10 + 1 >= 0x1000 )
{
v11 = (_QWORD *)*(v11 - 1);
if ( (unsigned __int64)(*(_QWORD *)(((unsigned __int64)&Buffer & 0xFFFFFFFFFFFFFFE0uLL) + 0x30)
- (_QWORD)v11
- 8LL) > 0x1F )
invalid_parameter_noinfo_noreturn();
}
j_j_free(v11);
}
}
}
}
这个函数调用了一些敏感的API,创建了一个文件,想办法把这个文件给搞出来。
首先把字符串解密出来:
def decrypt_string(encrypted_data, keys):
decrypted_bytes = b''
for i in range(len(encrypted_data)):
result = encrypted_data[i] ^ keys[i]
decrypted_bytes += result.to_bytes(8, byteorder='little')
try:
text = decrypted_bytes.split(b'\x00')[0].decode('ascii')
return text
except:
return decrypted_bytes.decode('ascii', errors='replace')
part1_data = [0xA0A195500DCC0E5C, 0x943E9588CFCF645D]
part1_keys = [0xE795A7603F90341F, 0xC65BF3E99CAA093C]
part2_data = [0xAA32D3B2B7C50388, 0xA727C0574231D098]
part2_keys = [0xCF59BCC699A060E9, 0xA727C0574231E1F6]
part1 = decrypt_string(part1_data, part1_keys)
part2 = decrypt_string(part2_data, part2_keys)
print("前半部分:", part1)
print("后半部分:", part2)
print("完整路径:", part1 + part2)
输出:完整路径: C:\2024GameSafeRace.token1,但是在C盘下找不到这个文件,注意到这一行代码:
FileA = CreateFileA((LPCSTR)(_RBP + 96), 0x40000000u, 0, 0LL, 3u, 0x80u, 0LL);
根据微软的文档,还原一下这个函数的参数:
CreateFileA((LPCSTR)"C:\2024GameSafeRace.token1",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
其中比较关键的参数是OPEN_EXISTING,微软是这么描述的:

意思是就是文件不存在的话,CreateFileA失败,那么手动创建一个名为C:\2024GameSafeRace.token1的文件。

这样token1就拿到了757F4749AEBB1891EF5AC2A9B5439CEA
token2
3环分析完毕,token2大概率在0环了,把驱动加载上看看
在DbgView把Caputure Kernel、Verbose Kernel Output、Capture Events都开上,捕捉到调试信息:

拿到token2:8b3f14a24d64f3e697957c252e3a5686
第二问
token1
首先是输出token1,这个比较简单,前面已经分析过token1之所以没被输出,是因为[in] dwCreationDisposition这个参数被置为了OPEN_EXISTING,改成OPEN_ALWAYS即可,就是把3改成4。下面DLL中Patch的效果:

由于DLL是在exe中被直接注入的,所以得通过Hook WriteProcessMemory的方式来Patch DLL。
HookWriteProcessMemory(
_In_ HANDLE hProcess,
_In_ LPVOID lpBaseAddress,
_In_reads_bytes_(nSize) LPCVOID lpBuffer,
_In_ SIZE_T nSize,
_Out_opt_ SIZE_T* lpNumberOfBytesWritten
)
{
if (nSize > 0x440000 && *((PUCHAR)lpBuffer + 0x7171) == 0x3) {
*((PUCHAR)lpBuffer + 0x7171) = 4;
DebugLog("Hooked!");
}
return TrueWriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
}
之前的output中有三次调用WriteProcessMemory,所以得用nSize过滤出需要的Buffer,避免访问空指针。

成功输出token1
token2
关于token2,第一问的时候就注意到只有勾选了Enable Verbose Kernel Output时,token2才会被打印。也就是说token2的打印语句level设置的太低了,尝试Hook DbgPrintEx函数看看怎么回事:

Level只有5,看来果然是Level的问题导致了token2没被打印
想要打印token2,只需要将level改为0即可,但是题目要求不能更改系统模块代码,所以只能想办法patch ace.sys。这里有一点是值得注意的,ace.sys在被启动后提示:启动服务失败,ID31。题目告诉我们这是成功加载了,但实际上ace.sys在DriverEntry里应该是返回了STATUS_UNSUCCESSFUL实现了自卸载,应该是在启动的过程中开了一个线程来不断的打印token2。
这赛题的反黑工具真的很厉害,想打开Ark工具分析一下进程直接蓝屏了,调用栈也被清空看不到什么有用的信息。

在驱动程序中,一般使用PsCreateSystemThread来创建线程,阅读微软文档后知道,驱动程序创建的线程实在初始系统进程中的,即System进程

Hook PsCreateSystemThread打印[in] StartRoutine这个参数拿到线程的起始地址,再用Windbg查看这个地址的反汇编代码,看看是不是我们想要的东西。
这里我用常规的Hook框架一直蓝屏,只能隔离system进程用PTE Hook试试。隔离之后不蓝了挺好,输出了两个地址:

分别查看两个地址:
后面那个带符号的肯定不是我们需要的,前面那个很像,继续反汇编看看:
ffff918b`ca013db0 488bc4 mov rax,rsp
ffff918b`ca013db3 48895808 mov qword ptr [rax+8],rbx
ffff918b`ca013db7 48897818 mov qword ptr [rax+18h],rdi
ffff918b`ca013dbb 4c897020 mov qword ptr [rax+20h],r14
ffff918b`ca013dbf 55 push rbp
ffff918b`ca013dc0 488d68a1 lea rbp,[rax-5Fh]
ffff918b`ca013dc4 4881eca0000000 sub rsp,0A0h
ffff918b`ca013dcb 48bf4e93328b546b331e mov rdi,1E336B548B32934Eh
ffff918b`ca013dd5 49bed520794add1d6d4b mov r14,4B6D1DDD4A7920D5h
ffff918b`ca013ddf 0f57c0 xorps xmm0,xmm0
ffff918b`ca013de2 488d4d37 lea rcx,[rbp+37h]
ffff918b`ca013de6 0f114537 movups xmmword ptr [rbp+37h],xmm0
ffff918b`ca013dea e8d1030000 call ffff918b`ca0141c0
ffff918b`ca013def 48b8a14f122fb3276d4b mov rax,4B6D27B32F124FA1h
ffff918b`ca013df9 4c8d45e7 lea r8,[rbp-19h]
ffff918b`ca013dfd 4889456f mov qword ptr [rbp+6Fh],rax
ffff918b`ca013e01 ba05000000 mov edx,5
ffff918b`ca013e06 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013e0a 33c9 xor ecx,ecx
ffff918b`ca013e0c 488945e7 mov qword ptr [rbp-19h],rax
ffff918b`ca013e10 48897d6f mov qword ptr [rbp+6Fh],rdi
ffff918b`ca013e14 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013e18 488945ef mov qword ptr [rbp-11h],rax
ffff918b`ca013e1c 4c89756f mov qword ptr [rbp+6Fh],r14
ffff918b`ca013e20 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013e24 48894517 mov qword ptr [rbp+17h],rax
ffff918b`ca013e28 48897d6f mov qword ptr [rbp+6Fh],rdi
ffff918b`ca013e2c 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013e30 660f6f45e7 movdqa xmm0,xmmword ptr [rbp-19h]
ffff918b`ca013e35 4889451f mov qword ptr [rbp+1Fh],rax
ffff918b`ca013e39 660fef4517 pxor xmm0,xmmword ptr [rbp+17h]
ffff918b`ca013e3e 488b0543330000 mov rax,qword ptr [ffff918b`ca017188]
ffff918b`ca013e45 660f7f45e7 movdqa xmmword ptr [rbp-19h],xmm0
ffff918b`ca013e4a ff15c8210000 call qword ptr [ffff918b`ca016018]
ffff918b`ca013e50 33db xor ebx,ebx
ffff918b`ca013e52 48b8f0104b32dd1d6d4b mov rax,4B6D1DDD324B10F0h
ffff918b`ca013e5c 4c8d45f7 lea r8,[rbp-9]
ffff918b`ca013e60 4889456f mov qword ptr [rbp+6Fh],rax
ffff918b`ca013e64 ba05000000 mov edx,5
ffff918b`ca013e69 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013e6d 33c9 xor ecx,ecx
ffff918b`ca013e6f 488945f7 mov qword ptr [rbp-9],rax
ffff918b`ca013e73 48897d6f mov qword ptr [rbp+6Fh],rdi
ffff918b`ca013e77 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013e7b 488945ff mov qword ptr [rbp-1],rax
ffff918b`ca013e7f 4c89756f mov qword ptr [rbp+6Fh],r14
ffff918b`ca013e83 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013e87 48894527 mov qword ptr [rbp+27h],rax
ffff918b`ca013e8b 48897d6f mov qword ptr [rbp+6Fh],rdi
ffff918b`ca013e8f 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013e93 660f6f45f7 movdqa xmm0,xmmword ptr [rbp-9]
ffff918b`ca013e98 440fb64c1d37 movzx r9d,byte ptr [rbp+rbx+37h]
ffff918b`ca013e9e 4889452f mov qword ptr [rbp+2Fh],rax
ffff918b`ca013ea2 660fef4527 pxor xmm0,xmmword ptr [rbp+27h]
ffff918b`ca013ea7 488b05da320000 mov rax,qword ptr [ffff918b`ca017188]
ffff918b`ca013eae 660f7f45f7 movdqa xmmword ptr [rbp-9],xmm0
ffff918b`ca013eb3 ff155f210000 call qword ptr [ffff918b`ca016018]
ffff918b`ca013eb9 48ffc3 inc rbx
ffff918b`ca013ebc 4883fb10 cmp rbx,10h
ffff918b`ca013ec0 7c90 jl ffff918b`ca013e52
ffff918b`ca013ec2 48b8df20794add1d6d4b mov rax,4B6D1DDD4A7920DFh
ffff918b`ca013ecc 4c8d4507 lea r8,[rbp+7]
ffff918b`ca013ed0 4889456f mov qword ptr [rbp+6Fh],rax
ffff918b`ca013ed4 ba05000000 mov edx,5
ffff918b`ca013ed9 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013edd 33c9 xor ecx,ecx
ffff918b`ca013edf 48894507 mov qword ptr [rbp+7],rax
ffff918b`ca013ee3 48897d6f mov qword ptr [rbp+6Fh],rdi
ffff918b`ca013ee7 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013eeb 4889450f mov qword ptr [rbp+0Fh],rax
ffff918b`ca013eef 4c89756f mov qword ptr [rbp+6Fh],r14
ffff918b`ca013ef3 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013ef7 48894547 mov qword ptr [rbp+47h],rax
ffff918b`ca013efb 48897d6f mov qword ptr [rbp+6Fh],rdi
ffff918b`ca013eff 488b456f mov rax,qword ptr [rbp+6Fh]
ffff918b`ca013f03 660f6f4507 movdqa xmm0,xmmword ptr [rbp+7]
ffff918b`ca013f08 4889454f mov qword ptr [rbp+4Fh],rax
ffff918b`ca013f0c 660fef4547 pxor xmm0,xmmword ptr [rbp+47h]
ffff918b`ca013f11 488b0570320000 mov rax,qword ptr [ffff918b`ca017188]
ffff918b`ca013f18 660f7f4507 movdqa xmmword ptr [rbp+7],xmm0
ffff918b`ca013f1d ff15f5200000 call qword ptr [ffff918b`ca016018]
ffff918b`ca013f23 b9ce0a0000 mov ecx,0ACEh
ffff918b`ca013f28 e833e9ffff call ffff918b`ca012860
ffff918b`ca013f2d e9adfeffff jmp ffff918b`ca013ddf
ffff918b`ca013f32 cc int 3
ffff918b`ca013f33 cc int 3
ffff918b`ca013f34 4152 push r10
ffff918b`ca013f36 49ba2563296284038fe2 mov r10,0E28F038462296325h
ffff918b`ca013f40 9c pushfq
ffff918b`ca013f41 49f7da neg r10
ffff918b`ca013f44 e834180000 call ffff918b`ca01577d
ffff918b`ca013f49 7398 jae ffff918b`ca013ee3
ffff918b`ca013f4b cc int 3
ffff918b`ca013f4c 95 xchg eax,ebp
ffff918b`ca013f4d df1b fistp word ptr [rbx]
ffff918b`ca013f4f 30948f434add5a xor byte ptr [rdi+rcx*4+5ADD4A43h],dl
ffff918b`ca013f56 3e040a add al,0Ah
ffff918b`ca013f59 f363ed rep movsxd ebp,ebp
ffff918b`ca013f5c cf iretd
ffff918b`ca013f5d f0cf lock iretd
ffff918b`ca013f5f 05c53e2100 add eax,213EC5h
ffff918b`ca013f64 3ef5 cmc
ffff918b`ca013f66 4a751c jne ffff918b`ca013f85
ffff918b`ca013f69 b06a mov al,6Ah
ffff918b`ca013f6b 39250d62b076 cmp dword ptr [ffff918c`40b1a17e],esp
ffff918b`ca013f71 0d650d62b0 or eax,0B0620D65h
ffff918b`ca013f76 44e10b loope ffff918b`ca013f84
ffff918b`ca013f79 b5ee mov ch,0EEh
ffff918b`ca013f7b 11939fa9bfcf adc dword ptr [rbx-30405661h],edx
ffff918b`ca013f81 67ac lods byte ptr [esi]
ffff918b`ca013f83 5d pop rbp
ffff918b`ca013f84 76ff jbe ffff918b`ca013f85
ffff918b`ca013f86 ff ???
ffff918b`ca013f87 ff ???
ffff918b`ca013f88 ff ???
ffff918b`ca013f89 3d54e42db8 cmp eax,0B82DE454h
ffff918b`ca013f8e dd ???
ffff918b`ca013f8f ac lods byte ptr [rsi]
ffff918b`ca013f90 0895e617a01d or byte ptr [rbp+1DA017E6h],dl
ffff918b`ca013f96 c4e1e2595eba vmulss xmm3,xmm3,dword ptr [rsi-46h]
ffff918b`ca013f9c a13f2afab36a30020f mov eax,dword ptr [0F02306AB3FA2A3Fh]
ffff918b`ca013fa5 c0fe1e sar dh,1Eh
ffff918b`ca013fa8 d01f rcr byte ptr [rdi],1
ffff918b`ca013faa ef out dx,eax
ffff918b`ca013fab 2aea sub ch,dl
ffff918b`ca013fad 3a13 cmp dl,byte ptr [rbx]
ffff918b`ca013faf e8d7d7d66f call ffff918c`39d8178b
ffff918b`ca013fb4 5a pop rdx
ffff918b`ca013fb5 e449 in al,49h
ffff918b`ca013fb7 10c1 adc cl,al
ffff918b`ca013fb9 448a8ecaaa44ae mov r9b,byte ptr [rsi-51BB5536h]
ffff918b`ca013fc0 0e ???
ffff918b`ca013fc1 3d7433d5f1 cmp eax,0F1D53374h
ffff918b`ca013fc6 96 xchg eax,esi
ffff918b`ca013fc7 4edb28 fld tbyte ptr [rax]
ffff918b`ca013fca 16 ???
ffff918b`ca013fcb 00a78dc2ce7e add byte ptr [rdi+7ECEC28Dh],ah
ffff918b`ca013fd1 f8 clc
ffff918b`ca013fd2 f2331e xacquire xor ebx,dword ptr [rsi]
ffff918b`ca013fd5 51 push rcx
ffff918b`ca013fd6 765d jbe ffff918b`ca014035
ffff918b`ca013fd8 6404c3 add al,0C3h
ffff918b`ca013fdb f04c86a3a01fba35 lock xchg r12b,byte ptr [rbx+35BA1FA0h]
ffff918b`ca013fe3 df09 fisttp word ptr [rcx]
ffff918b`ca013fe5 2bbc73d33d9b5c sub edi,dword ptr [rbx+rsi*2+5C9B3DD3h]
ffff918b`ca013fec 6d ins dword ptr [rdi],dx
ffff918b`ca013fed 9f lahf
ffff918b`ca013fee d1cb ror ebx,1
ffff918b`ca013ff0 c5 ???
ffff918b`ca013ff1 51 push rcx
ffff918b`ca013ff2 417f48 jg ffff918b`ca01403d
ffff918b`ca013ff5 7eae jle ffff918b`ca013fa5
ffff918b`ca013ff7 69583893602e8f imul ebx,dword ptr [rax+38h],8F2E6093h
ffff918b`ca013ffe 3b2d552bb681 cmp ebp,dword ptr [ffff918b`4bb76b59]
ffff918b`ca014004 51 push rcx
ffff918b`ca014005 bd9d1ddf23 mov ebp,23DF1D9Dh
ffff918b`ca01400a 8145aa2a6867ab add dword ptr [rbp-56h],0AB67682Ah
ffff918b`ca014011 35d12a2a97 xor eax,972A2AD1h
ffff918b`ca014016 bb35d12a8e mov ebx,8E2AD135h
看汇编跟3环的字符串加密似乎是一样的,应该就是打印token2的地方,我们的目的就是Patch这个线程,将DbgPrintEx的Level从5改成0,就是Patch这三处:
ffff918b`ca013e01 ba05000000 mov edx,5
ffff918b`ca013e64 ba05000000 mov edx,5
ffff918b`ca013ed4 ba05000000 mov edx,5
StartRoutine是FFFF918BCA013DB0,根据Base算出三个偏移:
Offset1:0x52
Offset2:0xB5
Offset3:0x125
接下来想想怎么自动定位这个Base,我们既然已经Hook了PsCreateSystemThread,那么不妨从这里入手,通过特征过滤出目标线程。
typedef NTSTATUS(*fpPsCreateSystemThread) (
PHANDLE ThreadHandle,
ULONG DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PCLIENT_ID ClientId,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext);
fpPsCreateSystemThread g_oriPsCreateSystemThread = NULL;
ULONG64 Offset1 = 0x52, Offset2 = 0xB5, Offset3 = 0x125;
NTSTATUS myPsCreateSystemThread(
PHANDLE ThreadHandle,
ULONG DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PCLIENT_ID ClientId,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext
)
{
//reset_hook(recodeNum);
//DbgPrintEx(77, 0, "[myPsCreateSystemThread]%p\n", StartRoutine);
//NTSTATUS s = g_oriPsCreateSystemThread(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, ClientId, StartRoutine, StartContext);
//hook_by_addr((ULONG64)g_oriPsCreateSystemThread, (ULONG64)myPsCreateSystemThread, &recodeNum);
DbgPrintEx(77, 0, "[myPsCreateSystemThread]%p\n", StartRoutine);
if (*(PUCHAR)((ULONG64)StartRoutine + Offset1) == 0x5 && *(PUCHAR)((ULONG64)StartRoutine + Offset2) == 0x5 && *(PUCHAR)((ULONG64)StartRoutine + Offset3) == 0x5) {
DbgPrintEx(77, 0, "Patched");
*(PUCHAR)((ULONG64)StartRoutine + Offset1) = 0;
*(PUCHAR)((ULONG64)StartRoutine + Offset2) = 0;
*(PUCHAR)((ULONG64)StartRoutine + Offset3) = 0;
}
return g_oriPsCreateSystemThread(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, ClientId, StartRoutine, StartContext);
}
改变Level后,现在就可以在Windbg里看见token2的输出了

第三问
这一问又回到了3环,根据我们的分析在sub_180007C10这个函数里,通过异或加密的方式拿到了输出路径C:\2024GameSafeRace.token1,可以通过Patch密文和密钥的方式更改路径,即将密文改为自己的路径的ASCII码,密钥改为0就行。这里我采用另一种方法,直接Hook CreateFileA,更改第一个参数,重定向到目标路径
FileA = CreateFileA((LPCSTR)(_RBP + 96), 0x40000000u, 0, 0LL, 4u, 0x80u, 0LL);


浙公网安备 33010602011771号