本帖最后由 爱飞的猫 于 2024-5-30 11:13 编辑
试着改了下,将 MajorSubsystemVersion 的值(文件偏移 0x140 )降低到 6 后是会进入正常加载流程。
估计是 Win 10 的兼容层会检查额外的值,这个应该需要逆向 PE 文件加载流程了,不清楚怎么操作了。
试着跟了下 ntdll 的加载过程,LdrpProcessMappedModule 的这个分支,初始化 SecurityCookie 失败。
if ( (a2 & 0x800000) == 0
&& ((*(_BYTE *)(a1 + 104) & 4) != 0 || a3 && (unsigned int)LdrpIsExecutableRelocatedImage(v3))
&& (*(_DWORD *)(a1 + 104) & 0x2000) == 0
&& a3 )
{
v14 = 0i64;
v10 = LdrpGenRandom();
inited = LdrInitSecurityCookie(v3, *(_DWORD *)(a1 + 64), 0, v10 ^ (unsigned int)dword_18019B3A8, (__int64)&v14);
if ( v3 == 0x180000000i64
|| !*(_QWORD *)(a1 + 56)
|| (*(_WORD *)(v13 + 72) != 6 || *(_WORD *)(v13 + 74) < 3u) && *(_WORD *)(v13 + 72) < 7u
|| inited )
{
Config = LdrpCfgProcessLoadConfig(a1, v13, v14);
if ( Config < 0 )
return (unsigned int)Config;
goto LABEL_18;
}
return 0xC000007B; // 此处失败
}
跟进去看,发现是在校验 Data Directory 的第 0x0A 项,该值不能为 0。
LdrInitSecurityCookie
LdrpFetchAddressOfSecurityCookie
LdrImageDirectoryEntryToLoadConfig(p_dos_hdr)
RtlpImageDirectoryEntryToDataEx(pDosHeader, 1, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &v5, (__int64 *)&v6)
if (nt_hdr->OptionalHeader.DataDirectory[idx].VirtualAddress) { ... }
void **__fastcall LdrImageDirectoryEntryToLoadConfig(PIMAGE_DOS_HEADER pDosHeader)
{
NTSTATUS status; // eax
void **pEntryToConfig; // rdx
unsigned int v5; // [rsp+40h] [rbp+8h] BYREF
void **v6; // [rsp+48h] [rbp+10h] BYREF
PIMAGE_NT_HEADERS hdr; // [rsp+50h] [rbp+18h] BYREF
RtlImageNtHeaderEx(1i64, pDosHeader, 0i64, &hdr);
if ( !pDosHeader )
return 0i64;
status = RtlpImageDirectoryEntryToDataEx(pDosHeader, 1, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &v5, (__int64 *)&v6);
pEntryToConfig = v6;
if ( status < 0 )
pEntryToConfig = 0i64;
if ( pEntryToConfig && v5 && v5 == *(_DWORD *)pEntryToConfig && hdr->FileHeader.Machine == 0x8664 )
return pEntryToConfig;
else
return 0i64;
}
__int64 __fastcall RtlpImageDirectoryEntryToDataEx(
PIMAGE_DOS_HEADER a1,
char a2,
unsigned __int16 a3,
unsigned int *a4,
__int64 *a5)
{
// 省略片段
if ( nt_hdr->OptionalHeader.Magic == 0x20B && (unsigned int)idx < nt_hdr->OptionalHeader.NumberOfRvaAndSizes )
{
VirtualAddress = nt_hdr->OptionalHeader.DataDirectory[idx].VirtualAddress;
if ( (_DWORD)VirtualAddress ) // 此处失败,因为该值被置 0
{
Size = nt_hdr->OptionalHeader.DataDirectory[idx].Size;
LABEL_10:
*a4 = Size;
if ( v7 || (unsigned int)VirtualAddress < v12->OptionalHeader.SizeOfHeaders )
{
*a5 = v10 + VirtualAddress;
}
else
{
v15 = RtlAddressInSectionTable(v12, v10, (unsigned int)VirtualAddress);
*a5 = v15;
return v15 == 0 ? 0xC000000D : 0;
}
return v6;
}
return 0xC0000002;
}
// 省略片段
}
|