Skip to content

Instantly share code, notes, and snippets.

@hasherezade
Last active August 21, 2022 02:20
Show Gist options
  • Save hasherezade/66210ce376084fdae85e1f20512db00d to your computer and use it in GitHub Desktop.
Save hasherezade/66210ce376084fdae85e1f20512db00d to your computer and use it in GitHub Desktop.
RtlPcToFileHeader - decompiled from Win10 64bit
PVOID __stdcall RtlPcToFileHeader(PVOID PcValue, PVOID *BaseOfImage)
{
PVOID result; // rax
FUNCTION_TABLE_DATA func_tbl_data; // [rsp+20h] [rbp-28h] BYREF
if ( (unsigned __int64)PcValue < g_FuncTbl.ImageBase
|| (unsigned __int64)PcValue >= g_FuncTbl.ImageBase + g_FuncTbl.ImageSize )
{
RtlpxLookupFunctionTable((unsigned __int64)PcValue, &func_tbl_data);
}
else
{
*(_OWORD *)&func_tbl_data.TableAddress = *(_OWORD *)&g_FuncTbl.TableAddress;
}
result = (PVOID)func_tbl_data.ImageBase;
*BaseOfImage = (PVOID)func_tbl_data.ImageBase;
return result;
}
__int64 __fastcall RtlpxLookupFunctionTable(unsigned __int64 a1, FUNCTION_TABLE_DATA *func_tbl_data)
{
bool v3; // zf
__int64 TableAddress; // rbp
__int64 v6; // r13
unsigned __int64 v7; // rdi
int v8; // r9d
int v9; // ebx
int v10; // eax
unsigned __int64 v11; // r8
FUNCTION_TABLE_DATA *v12; // rdx
signed __int64 v13; // rax
unsigned __int64 ImageBaseViaQueryVirtualMemory; // rax
__int64 v16; // rbx
__int64 v17; // rcx
signed __int64 v18; // rbx
signed __int64 v19; // rtt
signed __int64 v20; // rcx
__int64 v21; // rdx
signed __int64 v22; // rdx
signed __int64 v23; // rtt
char v24; // cl
char *v25; // rdx
signed __int64 v26; // rax
int j; // ecx
unsigned __int64 v28; // r8
unsigned __int64 v29; // r9
unsigned __int64 v30; // rcx
unsigned __int64 v31; // rax
_QWORD *v32; // rcx
__int64 i; // rdx
unsigned __int64 v34; // [rsp+30h] [rbp-68h] BYREF
unsigned __int64 *v35; // [rsp+38h] [rbp-60h]
__int64 v36; // [rsp+40h] [rbp-58h]
HANDLE UniqueThread; // [rsp+48h] [rbp-50h]
int v38; // [rsp+50h] [rbp-48h]
int v39[17]; // [rsp+54h] [rbp-44h] BYREF
int v40; // [rsp+A8h] [rbp+10h] BYREF
__int64 v41; // [rsp+B0h] [rbp+18h] BYREF
v3 = LdrInitState == 3;
TableAddress = 0i64;
func_tbl_data->ImageBase = 0i64;
func_tbl_data->ImageSize = 0;
if ( v3 )
{
v6 = -1i64;
v40 = 0;
v7 = _InterlockedCompareExchange64(&LdrpInvertedFunctionTableSRWLock, 17i64, 0i64);
if ( !v7 )
{
LABEL_3:
if ( KiUserInvertedFunctionTable != 1 )
{
v8 = 1;
v9 = KiUserInvertedFunctionTable - 1;
while ( v9 >= v8 )
{
v10 = (v9 + v8) >> 1;
v11 = *((_QWORD *)&g_FuncTbl + 3 * v10 + 1);
v12 = (FUNCTION_TABLE_DATA *)((char *)&g_FuncTbl + 24 * v10);
if ( a1 < v11 )
{
if ( !v10 )
break;
v9 = v10 - 1;
}
else
{
if ( a1 < v11 + v12->ImageSize )
{
*func_tbl_data = *v12;
TableAddress = func_tbl_data->TableAddress;
break;
}
v8 = v10 + 1;
}
}
}
v13 = _InterlockedCompareExchange64(&LdrpInvertedFunctionTableSRWLock, 0i64, 17i64);
if ( v13 != 17 )
{
if ( (v13 & 1) == 0 )
RtlRaiseStatus(0xC0000264i64);
if ( (v13 & 2) != 0 )
{
LABEL_38:
if ( (v13 & 8) != 0 )
{
v32 = (_QWORD *)(v13 & 0xFFFFFFFFFFFFFFF0ui64);
for ( i = *(_QWORD *)((v13 & 0xFFFFFFFFFFFFFFF0ui64) + 8); !i; i = v32[1] )
v32 = (_QWORD *)*v32;
if ( _InterlockedExchangeAdd((volatile signed __int32 *)(i + 32), 0xFFFFFFFF) > 1 )
goto LABEL_14;
v6 = -9i64;
}
do
{
v20 = v13 & 6;
if ( v20 == 2 )
v21 = v6 + 4;
else
v21 = v6;
v22 = v13 + v21;
v23 = v13;
v13 = _InterlockedCompareExchange64(&LdrpInvertedFunctionTableSRWLock, v22, v13);
}
while ( v23 != v13 );
if ( v20 == 2 )
RtlpWakeSRWLock(&LdrpInvertedFunctionTableSRWLock, v22, 0i64);
goto LABEL_14;
}
while ( 1 )
{
v18 = 0i64;
if ( (v13 & 0xFFFFFFFFFFFFFFF0ui64) != 16 )
v18 = v13 - 16;
v19 = v13;
v13 = _InterlockedCompareExchange64(&LdrpInvertedFunctionTableSRWLock, v18, v13);
if ( v19 == v13 )
break;
if ( (v13 & 2) != 0 )
goto LABEL_38;
}
}
LABEL_14:
if ( TableAddress || !byte_18017F50C && SLOBYTE(NtCurrentPeb()->CrossProcessFlags) >= 0 )
return TableAddress;
goto query_virtual_memory;
}
while ( 1 )
{
v16 = (v7 >> 1) & 1;
if ( (v7 & 1) != 0 && (v16 || (v7 & 0xFFFFFFFFFFFFFFF0ui64) == 0) )
{
if ( (unsigned __int8)RtlpWaitCouldDeadlock() )
ZwTerminateProcess(-1i64, 0xC000004Bi64);
UniqueThread = NtCurrentTeb()->ClientId.UniqueThread;
v24 = 0;
v39[0] = 2;
v36 = 0i64;
if ( v16 )
{
v35 = 0i64;
v38 = -1;
v34 = v7 & 0xFFFFFFFFFFFFFFF0ui64;
v25 = (char *)((unsigned __int64)&v34 | v7 & 8 | 7);
if ( (v7 & 4) == 0 )
v24 = 1;
}
else
{
v38 = -2;
v35 = &v34;
v25 = (char *)&v34 + 3;
}
v26 = _InterlockedCompareExchange64(&LdrpInvertedFunctionTableSRWLock, (signed __int64)v25, v7);
v3 = v7 == v26;
v7 = v26;
if ( !v3 )
goto LABEL_49;
if ( v24 )
RtlpOptimizeSRWLockList(&LdrpInvertedFunctionTableSRWLock);
if ( MEMORY[0x7FFE036A] > 1u ) // 7FFE0000 -> KUSER_SHARED_DATA
{
if ( MEMORY[0x7FFE0297] )
{
v28 = __rdtsc();
v29 = v28 + (unsigned int)dword_180168FC4;
while ( 1 )
{
__asm { monitorx rax, rcx, rdx }
if ( (v39[0] & 2) == 0 )
break;
v30 = v28;
v31 = __rdtsc();
v28 = v31;
if ( v31 <= v30 || v31 >= v29 )
break;
__asm { mwaitx rax, rcx, rbx }
}
}
else
{
for ( j = 0; (v39[0] & 2) != 0 && j != dword_180168FC4 / (unsigned int)MEMORY[0x7FFE02D6]; ++j )
_mm_pause();
}
}
if ( _interlockedbittestandreset(v39, 1u) )
{
do
NtWaitForAlertByThreadId(&LdrpInvertedFunctionTableSRWLock, 0i64);
while ( (v39[0] & 4) == 0 );
}
}
else
{
v17 = v7 | 1;
if ( !v16 )
v17 += 16i64;
if ( v7 == _InterlockedCompareExchange64(&LdrpInvertedFunctionTableSRWLock, v17, v7) )
goto LABEL_3;
LABEL_49:
RtlBackoff(&v40);
_m_prefetchw(&LdrpInvertedFunctionTableSRWLock);
v7 = LdrpInvertedFunctionTableSRWLock;
}
}
}
query_virtual_memory:
ImageBaseViaQueryVirtualMemory = RtlpGetImageBaseViaQueryVirtualMemory(a1, &func_tbl_data->ImageSize);
func_tbl_data->ImageBase = ImageBaseViaQueryVirtualMemory;
if ( ImageBaseViaQueryVirtualMemory )
{
if ( (int)RtlpImageDirectoryEntryToDataEx(ImageBaseViaQueryVirtualMemory, 1, 3u, &func_tbl_data->Size, &v41) < 0 )
TableAddress = 0i64;
else
TableAddress = v41;
if ( !TableAddress )
func_tbl_data->Size = 0;
func_tbl_data->TableAddress = TableAddress;
}
return TableAddress;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment