本人研究这些东西没有人一起讨论 不支持研究的方向对不对 如果有误还请指出 我的联系方式:
[email protected]
加载驱动 返回0xC0000428
IDA搜索立即数0xC0000428
地址 Function 指令
---- -------- ----
.text:00000001400EE0F0 MiResolveTransitionFault mov eax, 0C0000428h
.text:00000001400EE10F MiResolveTransitionFault mov eax, 0C0000428h
.text:00000001400EE3E3 MiResolveProtoPteFault mov eax, 0C0000428h
PAGE:00000001402E89E4 SeValidateImageHeader mov eax, 0C0000428h
PAGE:00000001403A5168 SeValidateImageData mov eax, 0C0000428h
PAGE:00000001404F6F37 PipCallDriverAddDeviceQueryRoutine cmp eax, 0C0000428h
PAGE:00000001404F6F8D PipCallDriverAddDeviceQueryRoutine cmp ebx, 0C0000428h
PAGE:00000001404F716F PipCallDriverAddDeviceQueryRoutine cmp ebx, 0C0000428h
发现有这么几个地方
看SeValidateImageHeader
[sourcecode language="c"]
int __fastcall SeValidateImageHeader(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5)
{
PVOID v5; // rax@2
int result; // eax@2
if ( g_CiEnabled )
{
if ( g_CiCallbacks )
result = g_CiCallbacks(a1, a2, a3, a4);//我们可以去看看它干了什么 这个 其实就是CiValidateImageHeader
else
result = 0xC0000428;//这个情况是因为是安全模式
}
else
{
v5 = ExAllocatePoolWithTag(PagedPool, 1ui64, 0x68506553u);
*(_QWORD *)a5 = v5;
result = v5 == 0i64 ? 0xC0000017 : 0;
}
return result;
}
[/sourcecode]
很明显一个全局变量在影响这个判断 g_CiEnabled
看看那个地方在操作g_CiEnabled 发现是SepInitializeCodeIntegrity
[sourcecode language="c"]
__int64 SepInitializeCodeIntegrity()
{
signed __int64 v0; // rbx@1
signed int v1; // edi@2
__int64 v2; // rax@2
bool v3; // zf@6
v0 = 0i64;
if ( InitIsWinPEMode )
{
g_CiEnabled = 0;//如果是安全模式就为0
}
else
{
g_CiEnabled = 1;
v1 = 6;
g_CiCallbacks = 0i64;
qword_1402256A8 = 0i64;
qword_1402256B0 = 0i64;
v2 = *(_QWORD *)&KeLoaderBlock_0;
if ( *(_QWORD *)&KeLoaderBlock_0 )
{
if ( *(_QWORD *)(*(_QWORD *)&KeLoaderBlock_0 + 152i64) )
{
if ( SepIsOptionPresent(*(_QWORD *)(*(_QWORD *)&KeLoaderBlock_0 + 152i64), "DISABLE_INTEGRITY_CHECKS") )
v1 = 0;
v3 = SepIsOptionPresent(*(_QWORD *)(*(_QWORD *)&KeLoaderBlock_0 + 152i64), "TESTSIGNING") == 0;
v2 = *(_QWORD *)&KeLoaderBlock_0;
if ( !v3 )
v1 |= 8u;
}
if ( v2 )
v0 = v2 + 48;
}
LODWORD(v0) = CiInitialize_0((unsigned int)v1, v0, &g_CiCallbacks);
}
return (unsigned int)v0;
}
[/sourcecode]
这跟我们研究下面没有太大的关系 因为如果在这里path已经迟了 这个函数在系统启动的时候就运行了 当然如果要静态过DSE的话就在这里path
根据SeValidateImageHeader的反汇编可以看到 只需要对g_CiEnabled就行置0即可
在看看SeValidateImageData
[sourcecode language="c"]
int SeValidateImageData()
{
int result; // eax@1
result = 0;
if ( g_CiEnabled )
{
if ( qword_1402256A8 )
result = qword_1402256A8();
else
result = 0xC0000428;
}
return result;
}
[/sourcecode]
这里也做了判断
这个函数其实没多大的作用qword_1402256A8其实就是CiValidateImageData的地址指针可在在windbg中查看 这个函数在ci.dll中
其它出现mov xxx,0xC0000428我在windbg双机调试中没有出现(加载驱动的时候没有断下)
还有一种方法不对g_CiEnabled处理 下面就调用了
result = g_CiCallbacks(a1, a2, a3, a4);
这个就是CiValidateImageHeader 我们去看看
[sourcecode language="c"]
__int64 __fastcall CiValidateImageHeader(__int64 a1, __int64 a2, unsigned int a3, unsigned int a4, PVOID *a5)
{
signed int v5; // ebp@1
unsigned int v6; // er12@1
__int64 v7; // r14@1
unsigned int v8; // ebx@1
__int64 v9; // r13@1
bool v10; // zf@1
int v11; // er15@1
unsigned int v12; // edi@1
int v13; // eax@2
int v14; // eax@4
__int64 v16; // r9@29
__int64 v17; // r8@29
__int64 v18; // rdx@29
__int64 v19; // rcx@29
int v20; // eax@30
signed int v21; // eax@43
__int64 v22; // rdx@46
int v23; // er11@55
__int64 v24; // rdx@65
__int64 v25; // rdx@76
PVOID v26; // rax@82
__int16 v27; // [sp+40h] [bp-98h]@1
__int16 v28; // [sp+42h] [bp-96h]@1
PVOID P; // [sp+48h] [bp-90h]@1
unsigned int v30; // [sp+50h] [bp-88h]@1
unsigned int v31; // [sp+54h] [bp-84h]@2
int v32; // [sp+58h] [bp-80h]@1
char Dst; // [sp+5Ch] [bp-7Ch]@1
v5 = 0;
v6 = a3;
v7 = a1;
LOBYTE(v8) = a4;
v9 = a2;
v30 = a4;
v32 = 0;
memset(&Dst, 0, 0x14ui64);
v10 = *a5 == 0i64;
v27 = 0;
v28 = 0;
P = 0i64;
v11 = v10;
v12 = CiInitializePhase2();
if ( (v12 & 0x80000000) == 0 )
{
v13 = CipFixImageType(v9, &v31, &v30);
v8 = v30;
v12 = v13;
if ( v13 >= 0 )
{
if ( v30 & 2 )
{
LABEL_4:
v14 = 1;
goto LABEL_12;
}
if ( *a5 && v30 & 5 )
{
v14 = 0;
}
else
{
if ( v30 & 4 || g_CiOptions & 4 && _bittest(&v8, 0x1Fu) )
goto LABEL_4;
v14 = v30 & 1;
}
LABEL_12:
v12 = 0;
if ( !v14 )
goto LABEL_81;
if ( v30 & 5 )
{
if ( v31 > v6 )
{
v12 = 0xC0000023;
LABEL_16:
if ( *a5 && v11 )
{
ExFreePoolWithTag(*a5, 0);
*a5 = 0i64;
}
goto LABEL_19;
}
v6 = v31;
}
v16 = v30;
v17 = v6;
v18 = v9;
v19 = v7;
if ( !(v30 & 5) )
{
v20 = CipValidatePageHash(v7, v9, v6);
if ( v20 >= 0 || v8 & 2 )
goto LABEL_34;
v16 = v8;
v17 = v6;
v18 = v9;
v19 = v7;
}
v20 = CipValidateFileHash(v19, v18, v17, v16);
LABEL_34:
v12 = CipCallPeauth((unsigned int)v20);
if ( (v12 & 0x80000000) == 0
|| g_CiOptions & 4 && _bittest(&v8, 0x1Fu)
|| g_CiOptions & 2 && v8 & 1
|| v8 & 4
|| v8 & 2 )
{
v5 = 0;
}
else
{
v5 = 0;
if ( v8 & 1 )
{
v21 = P ? 0 : CipQueryFileName(v7, &v27);
if ( v21 >= 0 )
{
v22 = (__int64)CiRevokedDriverLoaded;
if ( v12 != 0xC0000603 )
v22 = (__int64)CiUnsignedDriverLoaded;
CiLogFileEvent(&v27, v22);
CiAudit(&v27, 5038i64);
}
}
v12 = 0;
}
goto LABEL_52;
}
}
LABEL_52:
if ( v12 == 0xC0000428 || v12 == 0xC0000603 )
{
if ( P )
v23 = 0;
else
v23 = CipQueryFileName(v7, &v27);
if ( !(v8 & 2)
&& !(v8 & 4)
&& !(g_CiOptions & 0x10)
&& (_BYTE)KdDebuggerEnabled == 1
&& !(_BYTE)KdDebuggerNotPresent )
{
if ( v23 >= 0 && !(unsigned __int8)PsIsCurrentThreadPrefetching() )
{
if ( v12 == 0xC0000603 )
{
v24 = (__int64)CiRevokedDriverLoadedInDebugger;
}
else
{
v24 = (__int64)CiImagePageHashNotFoundDebuggerAttached;
if ( v8 & 1 )
v24 = (__int64)CiImageFileHashNotFoundDebuggerAttached;
}
CiLogFileEvent(&v27, v24);
CiAudit(&v27, (v8 & 5) != 0 ? 5038 : 6281);
}
if ( !(unsigned __int8)PsIsCurrentThreadPrefetching() && g_CiOptions & 1 )
{
DbgPrint("Code Integrity violation: %d\n", 446i64);
__debugbreak();
}
v12 = 0;
goto LABEL_81;
}
if ( v23 >= 0 && !(unsigned __int8)PsIsCurrentThreadPrefetching() )
{
if ( v12 == 0xC0000603 )
{
v25 = (__int64)CiRevokedDriverNotLoaded;
}
else
{
v25 = (__int64)CiImagePageHashNotFound;
if ( v8 & 5 )
v25 = (__int64)CiImageFileHashNotFound;
}
CiLogFileEvent(&v27, v25);
CiAudit(&v27, (v8 & 5) != 0 ? 5038 : 6281);
}
}
if ( (signed int)v12 < v5 )
goto LABEL_16;
LABEL_81:
if ( !*a5 )
{
v12 = 0;
v26 = ExAllocatePoolWithTag(PagedPool, 0x70ui64, 0x63734943u);
*a5 = v26;
if ( v26 )
{
memset(v26, 0, 0x70ui64);
*(_DWORD *)*a5 = 0;
*((_DWORD *)*a5 + 1) = 0;
*((_DWORD *)*a5 + 2) = 0;
*((_DWORD *)*a5 + 3) = 0;
*((_DWORD *)*a5 + 20) = 32772;
*((_DWORD *)*a5 + 22) = 0;
}
else
{
v12 = 0xC0000017;
}
}
LABEL_19:
if ( P )
ExFreePoolWithTag(P, 0);
MincryptFreePolicyInfo(&v32);
if ( (v12 & 0x80000000) != 0
&& v12 != 0xC0000023
&& !(unsigned __int8)PsIsCurrentThreadPrefetching()
&& v12 == 0xC0000428
&& g_CiOptions & 1 )
{
DbgPrint("Code Integrity violation: %d\n", 518i64);
__debugbreak();
}
return v12;
}
[/sourcecode]
这里还是直接找立即数吧 看看ci.dll是怎么 返回0xC0000428的
地址 Function 指令
---- -------- ----
PAGE:000007FF404CA15B CiInitializePhase2 cmp dword ptr [rdi+20h], 0C0000428h
PAGE:000007FF404CA350 CipInitialize cmp r12d, 0C0000428h
PAGE:000007FF404CA3F4 CipInitialize mov edi, 0C0000428h
PAGE:000007FF404CAEED CiValidateImageHeader cmp edi, 0C0000428h
PAGE:000007FF404CB063 CiValidateImageHeader cmp edi, 0C0000428h
PAGE:000007FF404CB560 CiValidateImageData mov ebx, 0C0000428h
PAGE:000007FF404CB826 CipCallPeauth mov eax, 0C0000428h
PAGE:000007FF404CB958 CipFindFileHash mov ebx, 0C0000428h
......
找了半天 CiValidateImageHeader 决定加载驱动的代码是
v20 = CipValidateFileHash(v19, v18, v17, v16);
[sourcecode language="c"]
LABEL_34:
v12 = CipCallPeauth((unsigned int)v20);
if ( (v12 & 0x80000000) == 0
|| g_CiOptions & 4 && _bittest(&v8, 0x1Fu)
|| g_CiOptions & 2 && v8 & 1
|| v8 & 4
|| v8 & 2 )
{
v5 = 0;
}
else //必须要else
{
v5 = 0;
if ( v8 & 1 )//如果是驱动
{
v21 = P ? 0 : CipQueryFileName(v7, &v27);
if ( v21 >= 0 )
{
v22 = (__int64)CiRevokedDriverLoaded;
if ( v12 != 0xC0000603 )
v22 = (__int64)CiUnsignedDriverLoaded;
CiLogFileEvent(&v27, v22);
CiAudit(&v27, 5038i64);
}
}
v12 = 0;
}
goto LABEL_52;
}
[/sourcecode]
g_CiOptions 默认是4 | 2 = 6 如果是6这就成立了 所以必须不为6 为0即可
另外一种解释
内核驱动初始化时调用SepInitializeCodeIntegrity
如果不是安全模式就走下面
注意下面这个v1 它决定了是否关闭DSE或测试模式
[sourcecode language="c"]
__int64 SepInitializeCodeIntegrity()
{
__int64 v0; // rbx@1
signed int v1; // edi@2
__int64 v2; // rax@2
bool v3; // zf@6
v0 = 0i64;
if ( InitIsWinPEMode )
{
g_CiEnabled = 0;
}
else
{
g_CiEnabled = 1;
v1 = 6;
g_CiCallbacks = 0i64;
qword_1402256A8 = 0i64;
qword_1402256B0 = 0i64;
v2 = *(_QWORD *)&KeLoaderBlock_0;
if ( *(_QWORD *)&KeLoaderBlock_0 )
{
if ( *(_QWORD *)(*(_QWORD *)&KeLoaderBlock_0 + 152i64) )
{
if ( (unsigned int)SepIsOptionPresent(
*(const char **)(*(_QWORD *)&KeLoaderBlock_0 + 152i64),
"DISABLE_INTEGRITY_CHECKS") )
v1 = 0;
v3 = (unsigned int)SepIsOptionPresent(*(const char **)(*(_QWORD *)&KeLoaderBlock_0 + 152i64), "TESTSIGNING") == 0;
v2 = *(_QWORD *)&KeLoaderBlock_0;
if ( !v3 )
v1 |= 8u;
}
if ( v2 )
v0 = v2 + 48;
}
LODWORD(v0) = CiInitialize_0((unsigned int)v1, v0, (__int64)&g_CiCallbacks);
}
return (unsigned int)v0;
}
[/sourcecode]
看CiInitialize_0 sub函数
[sourcecode language="c"]
int __fastcall CiInitialize_0(__int64 a1, __int64 a2, __int64 a3)
{
return CiInitialize(a1, a2, a3);
}
[/sourcecode]
看CiInitialize 注意第一个参数a1
.idata:00000001401AD370 ; Imports from CI.dll
.idata:00000001401AD370 ;
.idata:00000001401AD370 extrn __imp_CiInitialize:qword
去初始化ci.dll中的CiInitialize去看看 还是注意a1参数
[sourcecode language="c"]
__int64 __fastcall CipInitialize(int a1, __int64 a2, __int64 a3)
{
__int64 v3; // rbp@1
__int64 v4; // rsi@1
__int64 v5; // rax@1
PVOID *v6; // rbx@1
unsigned int v7; // edi@1
__int64 v8; // rbx@2
int v9; // er12@3
int v10; // er14@3
PVOID v11; // rax@6
__int64 v12; // r13@6
__int64 v13; // rax@7
__int64 v14; // rdx@13
__int64 v15; // rax@13
PVOID v16; // rcx@14
__int64 v18; // [sp+60h] [bp+18h]@1
v18 = a3;
v3 = a3;
v4 = a2;
g_CiOptions = a1;//给了g_CiOptions
LODWORD(v5) = PsGetCurrentProcess();
//............
// ............
//大量代码
return v7;
}
[/sourcecode]
来看看加载驱动是会调用哪些函数
.text:00000001400EE0F0 MiResolveTransitionFault mov eax, 0C0000428h
.text:00000001400EE10F MiResolveTransitionFault mov eax, 0C0000428h
.text:00000001400EE3E3 MiResolveProtoPteFault mov eax, 0C0000428h
PAGE:00000001402E89E4 SeValidateImageHeader mov eax, 0C0000428h
PAGE:00000001403A5168 SeValidateImageData mov eax, 0C0000428h
PAGE:00000001404F6F37 PipCallDriverAddDeviceQueryRoutine cmp eax, 0C0000428h
PAGE:00000001404F6F8D PipCallDriverAddDeviceQueryRoutine cmp ebx, 0C0000428h
PAGE:00000001404F716F PipCallDriverAddDeviceQueryRoutine cmp ebx, 0C0000428h
去看看SeValidateImageHeader
[sourcecode language="c"]
int __fastcall SeValidateImageHeader(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5)
{
PVOID v5; // rax@2
int result; // eax@2
if ( g_CiEnabled )//第一个可以patch点
{
if ( g_CiCallbacks )
result = g_CiCallbacks(a1, a2, a3, a4);这里调用了CiValidateImageHeader
else
result = 0xC0000428;
}
else
{
v5 = ExAllocatePoolWithTag(PagedPool, 1ui64, 0x68506553u);
*(_QWORD *)a5 = v5;
result = v5 == 0i64 ? 0xC0000017 : 0;
}
return result;
}
[/sourcecode]
去看看CiValidateImageHeader 这个应该不是这么执行的 我会在研究研究的
[sourcecode language="c"]
__int64 __fastcall CiValidateImageHeader(__int64 a1, __int64 a2, unsigned int a3, unsigned int a4, PVOID *a5)
{
signed int v5; // ebp@1
unsigned int v6; // er12@1
__int64 v7; // r14@1
int v8; // ebx@1
__int64 v9; // r13@1
bool v10; // zf@1
int v11; // er15@1
unsigned int v12; // edi@1
int v13; // eax@2
int v14; // eax@4
unsigned int v16; // eax@30
signed int v17; // eax@43
__int64 v18; // rdx@46
int v19; // er11@55
__int64 v20; // rdx@65
__int64 v21; // rdx@76
PVOID v22; // rax@82
__int16 v23; // [sp+40h] [bp-98h]@1
__int16 v24; // [sp+42h] [bp-96h]@1
PVOID P; // [sp+48h] [bp-90h]@1
int v26; // [sp+50h] [bp-88h]@1
unsigned int v27; // [sp+54h] [bp-84h]@2
int v28; // [sp+58h] [bp-80h]@1
char Dst; // [sp+5Ch] [bp-7Ch]@1
char v30; // [sp+70h] [bp-68h]@30
v5 = 0;
v6 = a3;
v7 = a1;
LOBYTE(v8) = a4;
v9 = a2;
v26 = a4;
v28 = 0;
memset(&Dst, 0, 0x14ui64);
v10 = *a5 == 0i64;
v23 = 0;
v24 = 0;
P = 0i64;
v11 = v10;
v12 = CiInitializePhase2();
if ( (v12 & 0x80000000) != 0 )
goto LABEL_52;
v13 = CipFixImageType(v9, &v27, &v26);
v8 = v26;
v12 = v13;
if ( v13 < 0 )
goto LABEL_52;
if ( !(v26 & 2) )
{
if ( *a5 && v26 & 5 )
{
v14 = 0;//这里为什么?
goto LABEL_12;
}
if ( !(v26 & 4) && (!(g_CiOptions & 4) || !_bittest((const unsigned int *)&v8, 0x1Fu)) )
{
v14 = v26 & 1; // //默认 为 4 | 2 = 6 成立 我们这里要不成立 才执行到这个地方
goto LABEL_12;
}
}
v14 = 1;
LABEL_12:
v12 = 0;
if ( !v14 )
goto LABEL_81; // //直接加载驱动
.....
}
[/sourcecode]
后面的再说
参考资料:
http://blog.csdn.net/whf727/article/details/6330510 windows x64 vista以上系统代码完整性校验分析
//[sourcecode language="c"]
__int64 CiInitializePhase2()
{
int v5; // esi@6
signed int v6; // ebx@9
__int64 v7; // rcx@22
__int64 v8; // rax@22
PVOID v9; // rdi@23
struct _KTIMER *v10; // rax@30
struct _KTIMER *v11; // rbp@30
char v12; // al@34
signed __int64 v13; // rbx@39
__int16 v14; // [sp+20h] [bp-18h]@11
__int16 v15; // [sp+22h] [bp-16h]@11
__int64 v16; // [sp+28h] [bp-10h]@11
if ( g_EtwEventHandle )
return 0i64;
__asm { lock bts cs:g_CiInitLock, 0 }
if ( _CF )
ExfAcquirePushLockExclusive(&g_CiInitLock);
if ( !g_EtwEventHandle )
{
v5 = CipCheckConfigOptions();
if ( v5 >= 0 )
{
v5 = EtwRegister(CodeIntegrityEventProviderId, 0i64, 0i64, &g_EtwEventHandle);
if ( v5 >= 0 )
{
v6 = 2;
if ( g_CiOptions & 8 )
v6 = 6;
v14 = 90;
v15 = 92;
v16 = (__int64)L"\\SystemRoot\\System32\\CodeIntegrity\\driver.stl";
if ( MinCrypKCallbacks && CipMinCrypK_CloseFile )
{
g_MincrypkCallbacks = (const struct _MINCRYPTK_CALLBACKS *const )&MinCrypKCallbacks;
ExInitializeResourceLite(&g_CatalogListLock);
v5 = I_LoadRevocationList(&v14, (unsigned int)v6, &g_RevocationList);
}
else
{
v5 = 0xC000000D;
}
if ( v5 >= 0 )
{
PESetInitialState();
while ( 1 )
{
v9 = g_BootDriverList; // //在初始化的时候赋值 发现初始化函数第一个参数为为SepInitializeCodeIntegrity(内核初始化函数)对g_ciEn判断 后面就是一个调用ci 初始化函数的sub函数 sub函数跳到这个函数来
// 初始化函数的第一个参数决定了是否可以关闭DSE 默认为6 (如果是双机调试的话是不走条路的)我们现在说的是正常系统 如果为0则关闭DSE
// 如果为8 则为测试模式
if ( g_BootDriverList == &g_BootDriverList )
break;
if ( *((_DWORD *)g_BootDriverList + 8) == 0xC0000428 )
{
CiLogFileEvent((__int64)((char *)g_BootDriverList + 16), (__int64)CiImageFileHashNotFound);// 没有找到签名 或无效的签名
CiAudit((__int64)((char *)v9 + 16), 0x13AE);
}
else if ( *((_DWORD *)g_BootDriverList + 8) >= 0 && *((_BYTE *)g_BootDriverList + 36) & 1 )
{
CiLogFileEvent((__int64)((char *)g_BootDriverList + 16), (__int64)CiNoEmbeddedSignatureDriverLoaded);// 这个地方出错说明内核调试器的问题 资料:https://technet.microsoft.com/en-us/library/dd363944(WS.10).aspx
}
v7 = *(_QWORD *)v9;
v8 = *((_QWORD *)v9 + 1);
*(_QWORD *)v8 = *(_QWORD *)v9;
*(_QWORD *)(v7 + 8) = v8;
ExFreePoolWithTag(v9, 0);
}
if ( (_DWORD)InitSafeBootMode
|| !g_BootCacheDelay
|| !(g_CiOptions & 0x10) && (_BYTE)KdDebuggerEnabled == 1 && !(_BYTE)KdDebuggerNotPresent
|| g_CiOptions & 8 )
goto LABEL_34;
v10 = (struct _KTIMER *)ExAllocatePoolWithTag(0, 0xA0ui64, 0x63734943u);
v11 = v10;
if ( v10 )
{
v13 = -600000000i64 * (unsigned int)g_BootCacheDelay;
KeInitializeTimer(v10);
KeInitializeDpc((PRKDPC)&v11[1], CipPostBootTimerRoutine, v11);
*(_QWORD *)&v11[2].Header.Type = 0i64;
v11[2].Header.WaitListHead.Blink = (struct _LIST_ENTRY *)CipPostBootWorker;
v11[2].DueTime.QuadPart = (ULONGLONG)v11;
KeSetTimer(v11, (LARGE_INTEGER)v13, (PKDPC)&v11[1]);
goto LABEL_34;
}
v5 = 0xC0000017;
}
}
}
MinCrypK_Cleanup();
if ( g_EtwEventHandle )
{
EtwUnregister();
g_EtwEventHandle = 0i64;
}
goto LABEL_34;
}
v5 = 0;
LABEL_34:
v12 = _InterlockedExchangeAdd8(&g_CiInitLock, 0xFFFFFFFFFFFFFFFFui64);
if ( v12 & 2 )
{
if ( !(v12 & 4) )
ExfTryToWakePushLock(&g_CiInitLock);
}
return (unsigned int)v5;
}
[/sourcecode]