- Status
- Offline
- Joined
- Mar 3, 2026
- Messages
- 247
- Reaction score
- 7
Anyone else looking into this specific module?
Had to dump this manually again to see how the restrictions messenger actually handles things. Found this build (v.1.17.18-11) floating around and decided to break down the logic behind the restrictions messenger. You can bypass it relatively easily by hooking WTSSendMessageW, WaitForSingleObject, or CreateProcessAsUserW.
Whitelisted Hashes:
I've seen similar patterns in other kernel-mode protection suites, but the session handling here is pretty straightforward. If you're messing with this, make sure your token manipulation is solid before calling CreateProcessAsUserW to avoid getting flagged by the behavioral heuristics.
Tech-wise:
Has anyone tested this on an active session yet? Curious if they've updated the whitelist check in the latest patches or if these hashes are still valid for the messenger bypass. Drop your findings below if you've poked at the restrictions logic.
Had to dump this manually again to see how the restrictions messenger actually handles things. Found this build (v.1.17.18-11) floating around and decided to break down the logic behind the restrictions messenger. You can bypass it relatively easily by hooking WTSSendMessageW, WaitForSingleObject, or CreateProcessAsUserW.
Code:
__int64 __fastcall sub_D7BA0(unsigned __int64 a1, unsigned __int64 a2, __int64 a3)
{
HANDLE v4; // rax
void *v5; // rbx
DWORD CurrentProcessId; // eax
HMODULE LibraryW; // rdi
FARPROC ProcAddress; // rbx
FARPROC v9; // rax
void (*v10)(void); // rsi
HANDLE CurrentProcess; // rax
__int64 v12; // r8
DWORD active; // eax
__int128 *v14; // rcx
__int64 v15; // rbx
__int128 *v16; // r9
__m128 *p_Parameter; // rcx
__m128 *v18; // r8
WCHAR LibFileName[8]; // [rsp+60h] [rbp-A0h] BYREF
__m128 v21; // [rsp+70h] [rbp-90h]
CHAR ProcName[16]; // [rsp+80h] [rbp-80h] BYREF
__m128 v23; // [rsp+90h] [rbp-70h]
CHAR v24[16]; // [rsp+A0h] [rbp-60h] BYREF
__m128 v25; // [rsp+B0h] [rbp-50h]
__m128 Parameter; // [rsp+C0h] [rbp-40h] BYREF
__m128 v27; // [rsp+D0h] [rbp-30h]
_BYTE ProcessInformation[32]; // [rsp+E0h] [rbp-20h] BYREF
HANDLE hToken; // [rsp+100h] [rbp+0h] BYREF
void *TokenHandle; // [rsp+108h] [rbp+8h] BYREF
LPVOID lpEnvironment; // [rsp+110h] [rbp+10h] BYREF
DWORD pSessionId; // [rsp+118h] [rbp+18h] BYREF
__int128 v33; // [rsp+120h] [rbp+20h] BYREF
__m128i si128; // [rsp+130h] [rbp+30h]
struct _STARTUPINFOW StartupInfo; // [rsp+140h] [rbp+40h] BYREF
hToken = 0LL;
lpEnvironment = 0LL;
v33 = 0LL;
si128 = _mm_load_si128((const __m128i *)&xmmword_4EAC20);
LOWORD(v33) = 0;
Parameter.m128_u64[0] = a1;
Parameter.m128_u64[1] = a2;
v27.m128_u64[0] = 30LL;
v27.m128_i32[2] = 0;
v4 = CreateThread(0LL, 0LL, (LPTHREAD_START_ROUTINE)StartAddress, &Parameter, 0, 0LL);// WTSSendMessageW
v5 = v4;
if ( v4 )
{
WaitForSingleObject(v4, 0x7918u);
CloseHandle(v5);
if ( v27.m128_i32[2] )
{
if ( v27.m128_i32[1] == 1 )
{
if ( a3 )
{
pSessionId = 0;
CurrentProcessId = GetCurrentProcessId();
ProcessIdToSessionId(CurrentProcessId, &pSessionId);
*(_QWORD *)ProcessInformation = 0x3CBF9C9FFF72D2DLL;
*(_QWORD *)&ProcessInformation[8] = 0x6A1932D85C1EE862LL;
*(_QWORD *)&ProcessInformation[16] = 0xDE2087BD6B2BC7FLL;
*(_QWORD *)&ProcessInformation[24] = 0x69CFA552E40CE5D4LL;
Parameter.m128_u64[0] = 0x3B9F9ACFF842D78LL;
Parameter.m128_u64[1] = 0x6A3732AE5C70E807LL;
v27.m128_u64[0] = 0xDE20817D6DEBC1BLL;
v27.m128_u64[1] = 0x69CFA552E40CE5D4LL;
*(__m128 *)LibFileName = _mm_xor_ps(Parameter, *(__m128 *)ProcessInformation);
v21 = _mm_xor_ps(v27, *(__m128 *)&ProcessInformation[16]);
LibraryW = LoadLibraryW(LibFileName);
if ( LibraryW )
{
*(_QWORD *)ProcessInformation = 0x3CBF9C9FFF72D2DLL;
*(_QWORD *)&ProcessInformation[8] = 0x6A1932D85C1EE862LL;
*(_QWORD *)&ProcessInformation[16] = 0xDE2087BD6B2BC7FLL;
*(_QWORD *)&ProcessInformation[24] = 0x69CFA552E40CE5D4LL;
Parameter.m128_u64[0] = 0x6D8E9CBD9E925F6ELL;
Parameter.m128_u64[1] = 0x47C5FB6336C8114LL;
v27.m128_u64[0] = 0xDE26318B9DEFE0BLL;
v27.m128_u64[1] = 0x69CFA552E40CE5D4LL;
*(__m128 *)ProcName = _mm_xor_ps(Parameter, *(__m128 *)ProcessInformation);
v23 = _mm_xor_ps(v27, *(__m128 *)&ProcessInformation[16]);
ProcAddress = GetProcAddress(LibraryW, ProcName);
*(_QWORD *)ProcessInformation = 0x3CBF9C9FFF72D2DLL;
*(_QWORD *)&ProcessInformation[8] = 0x6A1932D85C1EE862LL;
*(_QWORD *)&ProcessInformation[16] = 0xDE2087BD6B2BC7FLL;
*(_QWORD *)&ProcessInformation[24] = 0x69CFA552E40CE5D4LL;
Parameter.m128_u64[0] = 0x46B296BB8B844869LL;
Parameter.m128_u64[1] = 0xF745CB72E779E0CLL;
v27.m128_u64[0] = 0xD896B14BAF0C811LL;
v27.m128_u64[1] = 0x69CFA552E40CE5D4LL;
*(__m128 *)v24 = _mm_xor_ps(Parameter, *(__m128 *)ProcessInformation);
v25 = _mm_xor_ps(v27, *(__m128 *)&ProcessInformation[16]);
v9 = GetProcAddress(LibraryW, v24);
v10 = (void (*)(void))v9;
if ( ProcAddress && v9 )
{
if ( pSessionId )
goto LABEL_32;
TokenHandle = 0LL;
CurrentProcess = GetCurrentProcess();
if ( OpenProcessToken(CurrentProcess, 0xF01FFu, &TokenHandle) )
{
*(_QWORD *)ProcessInformation = 0x3CBF9C9FFF72D2DLL;
*(_QWORD *)&ProcessInformation[8] = 0x6A1932D85C1EE862LL;
*(_QWORD *)&ProcessInformation[16] = 0xDE2087BD6B2BC7FLL;
*(_QWORD *)&ProcessInformation[24] = 0x69CFA552E40CE5D4LL;
Parameter.m128_u64[0] = 0x3A8F99DFF922D7ELL;
Parameter.m128_u64[1] = 0x6A7032AA5C4EE800LL;
v27.m128_u64[0] = 0xD870817D6DBBC09LL;
v27.m128_u64[1] = 0x69CFA552E469E5B3LL;
Parameter = _mm_xor_ps(Parameter, *(__m128 *)ProcessInformation);
v27 = _mm_xor_ps(v27, *(__m128 *)&ProcessInformation[16]);
LOBYTE(v12) = 1;
sub_F8AA0(TokenHandle, &Parameter, v12);
CloseHandle(TokenHandle);
}
active = WTSGetActiveConsoleSessionId();
if ( (unsigned int)QueryUserToken(active, &hToken) )
{
LABEL_32:
if ( ((unsigned int (__fastcall *)(LPVOID *, HANDLE, __int64))ProcAddress)(&lpEnvironment, hToken, 1LL)
&& (unsigned __int8)sub_D7740(hToken, &v33) )
{
v14 = &v33;
if ( si128.m128i_i64[1] > 7uLL )
v14 = (__int128 *)v33;
v15 = (int)sub_E21B0(v14, a3);
Parameter = 0LL;
v27 = (__m128)_mm_load_si128((const __m128i *)&xmmword_4EAC20);
Parameter.m128_i16[0] = 0;
sub_CD860(&Parameter, v15 + 1);
v16 = &v33;
if ( si128.m128i_i64[1] > 7uLL )
LODWORD(v16) = v33;
p_Parameter = &Parameter;
if ( v27.m128_u64[1] > 7 )
LODWORD(p_Parameter) = Parameter.m128_i32[0];
sub_E2140((_DWORD)p_Parameter, v15 + 1, si128.m128i_i32[0], (_DWORD)v16, a3);
memset(&StartupInfo.cb + 1, 0, 100);
StartupInfo.cb = 104;
memset(ProcessInformation, 0, 24);
v18 = &Parameter;
if ( v27.m128_u64[1] > 7 )
v18 = (__m128 *)Parameter.m128_u64[0];
if ( CreateProcessAsUserW(
hToken,
0LL,
(LPWSTR)v18,
0LL,
0LL,
0,
0x420u,
lpEnvironment,
0LL,
&StartupInfo,
(LPPROCESS_INFORMATION)ProcessInformation) )
{
CloseHandle(*(HANDLE *)ProcessInformation);
CloseHandle(*(HANDLE *)&ProcessInformation[8]);
}
VGC_WStr_Destroy(&Parameter);
}
}
}
if ( lpEnvironment )
v10();
FreeLibrary(LibraryW);
if ( hToken )
CloseHandle(hToken);
}
}
}
}
}
return VGC_WStr_Destroy(&v33);
}
Whitelisted Hashes:
Code:
"6b3b4992ac7003797b25510e2142e68cde4c762b","83fa0fb4bfb2eafcb60b2213a521f9cb66368e27","0027bb9f956056b469b1dfd7cebd23c53b8f6f79","97b52574e15ef740531fca85e1cae85b5a2a81da","672499b0d7c7681aa42cebf22eb4368813d7d4b3","5a3ab2cac8775a050d8dd38d56cf28871a95db8d","92e520459e7f93d8d91ec5d78d0fe1bdefdb0e06","38c7b3846244f87b702fad14a7f54fe5a29ad34e","824bdcff868a17043ccd8909299650b5ad5c9dee","d686c8d1c7bc340ccaabf2a23b7fb74ce9fe178b","7f530281c5ba86b81ae4230dab1617cb55260d9e","13516890a00a9b004ef8b2e9a9901504b8c84dae","f45c326eb377ab9667e0d0d3ec72c4417dbb2286","48b2f27c3468a11a693a115a510c96c32468c734","c521025c55687c1f29b1f3a3c69b3d152ce84981","2bbb5e521ca92fd885873b76af07d58053e39067","e1b50088ed92b60a1400cd60c2afae9808ea15b3","fbfef415104e20b86d86c051653d5ed61e003943","0ef4679521b05f40eba025ef063d8061b49c93e8","92de6eafef2a0fad235b69f1f1a00d8c50a121d1","e9a35d72ad9c0f35c77912d454915d5f76356c41","91180ed89976d16353404ac982a422a707f2ae37","42c3957e46997d88b257315be61c1c9c7cda5bf1","1f15ac2ba806275afa35ab9373bacd5f5f8533d2","234e3ed163f6d1f9b93368d83112d4340ceafe2f","dd7195ffa375b3e2b6d32bfae755f474641f049a","3f64c98f22da277a07cab248c44c56eedb796a81","3d824f6aa75611478e56f4f56d0a6f6db8cb1c9b","e4e3f6bbad17b41a42687b3d75ade4a10b0870ec","ddb988b23c7516d2accfcd1796aceb2de705fbe1","660e47d00af463cdb615026565f06d9edb896fee","1b199e0dc32b76eca078f2878f1880f8ef330799","6c8be217856ca0378fb0e0a62c24a62771fce049","4568aff6010b4eabde4e141e7eebc4b53deb7ba0","3d26b0dc519e04999118f4a02ea8acd5f1db8feb","4f58be64ebff5be3132122612cbd3983cf7d05f7","341af85b4fe8b55c6f9875abd76dfea3a0e1f29d","8b9c5f448f8c08f3162638ce455a3a52ba6d9ee7","07d0249357b792bd35cdc0d23a2b2fa2b1fdbd4b","e3ce7157dc3334a1d95f2aad137d9ca66160b71c","73ccf556516c5e8a450f4d9b44b004dfad57d7b1","953fb3d50404336d9e3b220fd15f770e90a369a0","06395febb61b01844e23f42eec0a01b3bd4f65a8","944bb7170090377d57b65aa3aedb4068f474184e","2c33d4573e21c7d18de1d3f337bacd7c4e58fe87","e88efd65b405e1821c6e427500d78b57fe9ef20b","b74c93f07fa1bfe70950f0f71f5fbcb7cfd2bb98","026123af200ca87911e62b46a578afcf7479d6c4","f948a4c5e01a74b17d0f966615834ba76dc1badc","c2342aadac5b6dc6c9d2ff2e6ba5af0c40ed329c","73569b302c7811efdaa387b24d7bf4ad28e6d687","def9de1a7310f464ddd6b770e34de0205d650b45","200055b8a095a51e7d1604865d32f458ff72d540","098ad48e3787adbcda57c4e39a45ac8a6ca35359","964c42a4b15f0456d21673129a30fb9e78f219cb","a44b02c5c4750258566f0709b2ec8063802d5037","0811c39fd76395ed47646310bf5ecf57a0ac8ce4"
I've seen similar patterns in other kernel-mode protection suites, but the session handling here is pretty straightforward. If you're messing with this, make sure your token manipulation is solid before calling CreateProcessAsUserW to avoid getting flagged by the behavioral heuristics.
Tech-wise:
- Hooking Targets: WTSSendMessageW, WaitForSingleObject, CreateProcessAsUserW.
- Session Handling: Uses WTSGetActiveConsoleSessionId to verify token state.
- Obfuscation: Standard string XORing with mm_xor_ps.
Has anyone tested this on an active session yet? Curious if they've updated the whitelist check in the latest patches or if these hashes are still valid for the messenger bypass. Drop your findings below if you've poked at the restrictions logic.