Debug Control support in x64 versions of ms windows Before you get lost in this spartan plaintext - you can download the patch to enable the feature in win 7 / windows server 2008 R2 here: http://fdbg.x86asm.net/add_debugctl_support_ws2008R2_w7.UEFI.BIOS.ver048.zip unpack and run the patch.exe file (not the *.bat file, the bat is used only to compile the final patch.exe) the patch adds a new boot entry and makes it the default, after reboot you will run with patched kernel (debug control enabled, driver signing disabled, patchguard disabled) - the untouched kernel still stays as a boot menu so you can revert back anytime using bcdedit.exe by erasing this patched kernel boot choice and making the original boot menu the default to use the feature download fdbg here: http://fdbg.x86asm.net/fdbg0024.zip after loading executable go to the menu: Control -> Toggle DebugCtlMSR.LBR Control -> Toggle DebugCtlMSR.BTF (after that you should see that value of DR7 changed - look into DR window) I try to clarify how to use this feature under x64 versions of ms windows. To understand the principle at CPU level please refer to CPU manuals. http://developer.amd.com/documentation/guides/Pages/default.aspx 24593_APM_v2.pdf, chapter 13: Debug and Performance Resources http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3b-part-2-manual.pdf chapter 17: Debugging, ... Support for last branch recording and single step on branching instructions was implemented in windows server 2003 SP1 x64 (the same kernel is also in windows XP x64). Because enabling this feature requires turning on some bits in MSR, somebody clever had an idea to use available bits in DR7 as shadows. DR7 is saved in ThreadContext so the feature may be enabled/disabled per every thread. This code fragment from windows server 2003 SP1 x64 explains everything: nt!KiSaveDebugRegisterState: fffff800`0102ee00 654c8b0c2518000000 mov r9,qword ptr gs:[18h] fffff800`0102ee09 0f21c0 mov rax,dr0 fffff800`0102ee0c 0f21ca mov rdx,dr1 fffff800`0102ee0f 48894558 mov qword ptr [rbp+58h],rax fffff800`0102ee13 48895560 mov qword ptr [rbp+60h],rdx fffff800`0102ee17 0f21d0 mov rax,dr2 fffff800`0102ee1a 0f21da mov rdx,dr3 fffff800`0102ee1d 48894568 mov qword ptr [rbp+68h],rax fffff800`0102ee21 48895570 mov qword ptr [rbp+70h],rdx fffff800`0102ee25 0f21f0 mov rax,dr6 fffff800`0102ee28 0f21fa mov rdx,dr7 fffff800`0102ee2b 48894578 mov qword ptr [rbp+78h],rax fffff800`0102ee2f 48899580000000 mov qword ptr [rbp+80h],rdx fffff800`0102ee36 33c0 xor eax,eax fffff800`0102ee38 0f23f8 mov dr7,rax fffff800`0102ee3b 65803c25bd07000001 cmp byte ptr gs:[7BDh],1 fffff800`0102ee44 755f jne nt!KiSaveDebugRegisterState+0xa5 (fffff800`0102eea5) fffff800`0102ee46 66f7c20003 test dx,300h fffff800`0102ee4b 7458 je nt!KiSaveDebugRegisterState+0xa5 (fffff800`0102eea5) fffff800`0102ee4d b9db010000 mov ecx,1DBh fffff800`0102ee52 0f32 rdmsr fffff800`0102ee54 898598000000 mov dword ptr [rbp+98h],eax fffff800`0102ee5a 89959c000000 mov dword ptr [rbp+9Ch],edx fffff800`0102ee60 b9dc010000 mov ecx,1DCh fffff800`0102ee65 0f32 rdmsr fffff800`0102ee67 898590000000 mov dword ptr [rbp+90h],eax fffff800`0102ee6d 899594000000 mov dword ptr [rbp+94h],edx fffff800`0102ee73 b9dd010000 mov ecx,1DDh fffff800`0102ee78 0f32 rdmsr fffff800`0102ee7a 8985a8000000 mov dword ptr [rbp+0A8h],eax fffff800`0102ee80 8995ac000000 mov dword ptr [rbp+0ACh],edx fffff800`0102ee86 b9de010000 mov ecx,1DEh fffff800`0102ee8b 0f32 rdmsr fffff800`0102ee8d 8985a0000000 mov dword ptr [rbp+0A0h],eax fffff800`0102ee93 8995a4000000 mov dword ptr [rbp+0A4h],edx fffff800`0102ee99 b9d9010000 mov ecx,1D9h fffff800`0102ee9e 0f32 rdmsr fffff800`0102eea0 83e0fc and eax,0FFFFFFFCh fffff800`0102eea3 0f30 wrmsr fffff800`0102eea5 6641f781080200005503 test word ptr [r9+208h],355h fffff800`0102eeaf 746c je nt!KiSaveDebugRegisterState+0x11d (fffff800`0102ef1d) fffff800`0102eeb1 498b81e0010000 mov rax,qword ptr [r9+1E0h] fffff800`0102eeb8 498b91e8010000 mov rdx,qword ptr [r9+1E8h] fffff800`0102eebf 0f23c0 mov dr0,rax fffff800`0102eec2 0f23ca mov dr1,rdx fffff800`0102eec5 498b81f0010000 mov rax,qword ptr [r9+1F0h] fffff800`0102eecc 498b91f8010000 mov rdx,qword ptr [r9+1F8h] fffff800`0102eed3 0f23d0 mov dr2,rax fffff800`0102eed6 0f23da mov dr3,rdx fffff800`0102eed9 498b9108020000 mov rdx,qword ptr [r9+208h] fffff800`0102eee0 33c0 xor eax,eax fffff800`0102eee2 0f23f0 mov dr6,rax fffff800`0102eee5 0f23fa mov dr7,rdx fffff800`0102eee8 65803c25bd07000001 cmp byte ptr gs:[7BDh],1 fffff800`0102eef1 752a jne nt!KiSaveDebugRegisterState+0x11d (fffff800`0102ef1d) fffff800`0102eef3 66f7c20002 test dx,200h fffff800`0102eef8 7403 je nt!KiSaveDebugRegisterState+0xfd (fffff800`0102eefd) fffff800`0102eefa 83c802 or eax,2 fffff800`0102eefd 66f7c20001 test dx,100h fffff800`0102ef02 7403 je nt!KiSaveDebugRegisterState+0x107 (fffff800`0102ef07) fffff800`0102ef04 83c801 or eax,1 fffff800`0102ef07 85c0 test eax,eax fffff800`0102ef09 7412 je nt!KiSaveDebugRegisterState+0x11d (fffff800`0102ef1d) fffff800`0102ef0b 448bc0 mov r8d,eax fffff800`0102ef0e b9d9010000 mov ecx,1D9h fffff800`0102ef13 0f32 rdmsr fffff800`0102ef15 83e0fc and eax,0FFFFFFFCh fffff800`0102ef18 410bc0 or eax,r8d fffff800`0102ef1b 0f30 wrmsr fffff800`0102ef1d c3 ret nt!KiRestoreDebugRegisterState+0x1b: fffff800`0102edab 0f23d0 mov dr2,rax fffff800`0102edae 0f23da mov dr3,rdx fffff800`0102edb1 488b9580000000 mov rdx,qword ptr [rbp+80h] fffff800`0102edb8 33c0 xor eax,eax fffff800`0102edba 0f23f0 mov dr6,rax fffff800`0102edbd 0f23fa mov dr7,rdx fffff800`0102edc0 65803c25bd07000001 cmp byte ptr gs:[7BDh],1 fffff800`0102edc9 752a jne nt!KiRestoreDebugRegisterState+0x65 (fffff800`0102edf5) fffff800`0102edcb 66f7c20002 test dx,200h fffff800`0102edd0 7403 je nt!KiRestoreDebugRegisterState+0x45 (fffff800`0102edd5) fffff800`0102edd2 83c802 or eax,2 fffff800`0102edd5 66f7c20001 test dx,100h fffff800`0102edda 7403 je nt!KiRestoreDebugRegisterState+0x4f (fffff800`0102eddf) fffff800`0102eddc 83c801 or eax,1 fffff800`0102eddf 85c0 test eax,eax fffff800`0102ede1 7412 je nt!KiRestoreDebugRegisterState+0x65 (fffff800`0102edf5) fffff800`0102ede3 448bc0 mov r8d,eax fffff800`0102ede6 b9d9010000 mov ecx,1D9h fffff800`0102edeb 0f32 rdmsr fffff800`0102eded 83e0fc and eax,0FFFFFFFCh fffff800`0102edf0 410bc0 or eax,r8d fffff800`0102edf3 0f30 wrmsr fffff800`0102edf5 c3 ret The cmp byte ptr gs:[7BDh],1 instruction checks whether CPU_vendor is AuthenticAMD (later OS versions use CPU_vendor 2 for GenuineIntel and 3 for CentaurHauls) The DebugCtl MSR 1D9h is read/written (and also LastBranchFrom/LastBranchTo, LastExceptionFrom/LastExceptionTo) only when any of bits 9., 8. is set (see e.g. the instruction test dx,300h). To enable DebugCtl.LBR (last branch recording, bit 0. of MSR 1D9h) it is necessary to set DR7.LE (bit 8.), to enable DebugCtl.BTR (single step on branches, bit 1. of MSR 1D9h) it is necessary to set DR7.GE (bit 9.) The LastBranchFrom/LastBranchTo, LastExceptionFrom/LastExceptionTo are copied between trap frame and ThreadContext offsets 4B0h (LastBranchTo), 4B8h (LastBranchFrom), 4C0h (LastExceptionTo), 4C8h (LastExceptionFrom) if you have ntddk.h file it looks like: ntddk.h typedef struct DECLSPEC_ALIGN(16) _CONTEXT { ... ULONG64 DebugControl; ULONG64 LastBranchToRip; ULONG64 LastBranchFromRip; ULONG64 LastExceptionToRip; ULONG64 LastExceptionFromRip; } CONTEXT, *PCONTEXT; The DebugCtl at AMD64 architecture stayed the same til today so you can use this feature at all AMD64 CPUs at all x64 versions of ms windows. Intel introduced x64 architecture later than AMD64 so Debug Control support for Intel x64 CPUs was introduced in windows server 2008 R2 x64 (the same kernel as in windows 7 x64). Intel extended the Debug Control feature further and newer Intel CPUs have more LastBranchFrom/LastBranchTo MSRs (upto 16 pairs). MS windows saves only the most important pair where MSR_LASTBRANCH_TOS is pointing (MSR 1C9h). The KiSaveDebugRegisterState, KiRestoreDebugRegisterState changed a lot to support not only AMD64 but also Intel CPUs (Intel have more possible MSRs for LastBranch). Now these 2 procedures don't check for cpu vendor (1=AMD, 2=Intel), but they check one bit whether DebugCtl feature is present. KiSaveDebugRegisterState .text:0000000140080AF0 sub_140080AF0 proc near .text:0000000140080AF0 mov r9, gs:18h .text:0000000140080AF9 mov rax, dr0 .text:0000000140080AFC mov rdx, dr1 .text:0000000140080AFF mov [rbp+58h], rax .text:0000000140080B03 mov [rbp+60h], rdx .text:0000000140080B07 mov rax, dr2 .text:0000000140080B0A mov rdx, dr3 .text:0000000140080B0D mov [rbp+68h], rax .text:0000000140080B11 mov [rbp+70h], rdx .text:0000000140080B15 mov rax, dr6 .text:0000000140080B18 mov rdx, dr7 .text:0000000140080B1B mov [rbp+78h], rax .text:0000000140080B1F mov [rbp+80h], rdx .text:0000000140080B26 xor eax, eax .text:0000000140080B28 mov dr7, rax .text:0000000140080B2B test byte ptr gs:4D4Ah, 2 .text:0000000140080B34 jz short loc_140080BB3 .text:0000000140080B36 test dx, 300h .text:0000000140080B3B jz short loc_140080BB3 .text:0000000140080B3D mov r8d, cs:dword_1402B16B4 .text:0000000140080B44 or r8d, r8d .text:0000000140080B47 jz short loc_140080B51 .text:0000000140080B49 mov ecx, r8d .text:0000000140080B4C rdmsr .text:0000000140080B4E mov r8d, eax .text:0000000140080B51 .text:0000000140080B51 loc_140080B51: ; CODE XREF: sub_140080AF0+57 .text:0000000140080B51 mov ecx, cs:dword_1402B12A8 .text:0000000140080B57 add ecx, r8d .text:0000000140080B5A rdmsr .text:0000000140080B5C mov [rbp+98h], eax .text:0000000140080B62 mov ecx, cs:dword_1402B1350 .text:0000000140080B68 mov [rbp+9Ch], edx .text:0000000140080B6E add ecx, r8d .text:0000000140080B71 rdmsr .text:0000000140080B73 mov [rbp+90h], eax .text:0000000140080B79 mov [rbp+94h], edx .text:0000000140080B7F mov ecx, cs:dword_1402B147C .text:0000000140080B85 rdmsr .text:0000000140080B87 mov [rbp+0A8h], eax .text:0000000140080B8D mov [rbp+0ACh], edx .text:0000000140080B93 mov ecx, cs:dword_1402B1478 .text:0000000140080B99 rdmsr .text:0000000140080B9B mov [rbp+0A0h], eax .text:0000000140080BA1 mov [rbp+0A4h], edx .text:0000000140080BA7 mov ecx, 1D9h .text:0000000140080BAC rdmsr .text:0000000140080BAE and eax, 0FFFFFFFCh .text:0000000140080BB1 wrmsr .text:0000000140080BB3 .text:0000000140080BB3 loc_140080BB3: ; CODE XREF: sub_140080AF0+44 .text:0000000140080BB3 ; sub_140080AF0+4B .text:0000000140080BB3 test word ptr [r9+208h], 355h .text:0000000140080BBD jz short locret_140080C2B .text:0000000140080BBF mov rax, [r9+1E0h] .text:0000000140080BC6 mov rdx, [r9+1E8h] .text:0000000140080BCD mov dr0, rax .text:0000000140080BD0 mov dr1, rdx .text:0000000140080BD3 mov rax, [r9+1F0h] .text:0000000140080BDA mov rdx, [r9+1F8h] .text:0000000140080BE1 mov dr2, rax .text:0000000140080BE4 mov dr3, rdx .text:0000000140080BE7 mov rdx, [r9+208h] .text:0000000140080BEE xor eax, eax .text:0000000140080BF0 mov dr6, rax .text:0000000140080BF3 mov dr7, rdx .text:0000000140080BF6 test byte ptr gs:4D4Ah, 2 .text:0000000140080BFF jz short locret_140080C2B .text:0000000140080C01 test dx, 200h .text:0000000140080C06 jz short loc_140080C0B .text:0000000140080C08 or eax, 2 .text:0000000140080C0B .text:0000000140080C0B loc_140080C0B: ; CODE XREF: sub_140080AF0+116 .text:0000000140080C0B test dx, 100h .text:0000000140080C10 jz short loc_140080C15 .text:0000000140080C12 or eax, 1 .text:0000000140080C15 .text:0000000140080C15 loc_140080C15: ; CODE XREF: sub_140080AF0+120 .text:0000000140080C15 test eax, eax .text:0000000140080C17 jz short locret_140080C2B .text:0000000140080C19 mov r8d, eax .text:0000000140080C1C mov ecx, 1D9h .text:0000000140080C21 rdmsr .text:0000000140080C23 and eax, 0FFFFFFFCh .text:0000000140080C26 or eax, r8d .text:0000000140080C29 wrmsr .text:0000000140080C2B .text:0000000140080C2B locret_140080C2B: ; CODE XREF: sub_140080AF0+CD .text:0000000140080C2B ; sub_140080AF0+10F ... .text:0000000140080C2B retn 0 .text:0000000140080C2B sub_140080AF0 endp KiRestoreDebugRegisterState .text:0000000140080A80 sub_140080A80 proc near .text:0000000140080A80 xor edx, edx .text:0000000140080A82 mov dr7, rdx .text:0000000140080A85 mov rax, [rbp+58h] .text:0000000140080A89 mov rdx, [rbp+60h] .text:0000000140080A8D mov dr0, rax .text:0000000140080A90 mov dr1, rdx .text:0000000140080A93 mov rax, [rbp+68h] .text:0000000140080A97 mov rdx, [rbp+70h] .text:0000000140080A9B mov dr2, rax .text:0000000140080A9E mov dr3, rdx .text:0000000140080AA1 mov rdx, [rbp+80h] .text:0000000140080AA8 xor eax, eax .text:0000000140080AAA mov dr6, rax .text:0000000140080AAD mov dr7, rdx .text:0000000140080AB0 test byte ptr gs:4D4Ah, 2 .text:0000000140080AB9 jz short locret_140080AE5 .text:0000000140080ABB test dx, 200h .text:0000000140080AC0 jz short loc_140080AC5 .text:0000000140080AC2 or eax, 2 .text:0000000140080AC5 .text:0000000140080AC5 loc_140080AC5: ; CODE XREF: sub_140080A80+40 .text:0000000140080AC5 test dx, 100h .text:0000000140080ACA jz short loc_140080ACF .text:0000000140080ACC or eax, 1 .text:0000000140080ACF .text:0000000140080ACF loc_140080ACF: ; CODE XREF: sub_140080A80+4A .text:0000000140080ACF test eax, eax .text:0000000140080AD1 jz short locret_140080AE5 .text:0000000140080AD3 mov r8d, eax .text:0000000140080AD6 mov ecx, 1D9h .text:0000000140080ADB rdmsr .text:0000000140080ADD and eax, 0FFFFFFFCh .text:0000000140080AE0 or eax, r8d .text:0000000140080AE3 wrmsr .text:0000000140080AE5 .text:0000000140080AE5 locret_140080AE5: ; CODE XREF: sub_140080A80+39 .text:0000000140080AE5 ; sub_140080A80+51 .text:0000000140080AE5 retn 0 .text:0000000140080AE5 sub_140080A80 endp The check whether DebugCtl feature is present is done by test byte ptr gs:4D4Ah, 2 where is the origin of the bit 1 of byte gs:4D4Ah ??? using SimNow 4.6.2 (http://developer.amd.com/cpu/simnow/Pages/default.aspx) and iso image of ws2008R2x64SP1 (7601.17514.101119-1850_x64fre_server_eval_en-us-GRMSXEVAL_EN_DVD.iso) vp_bd_phase1.bsd, the iso image mounted as DVD to boot these commands (intercepting writing into MSR_GS_BASE C0000101h, determining the value in the MSR, intercepting writing 4D4Ah bytes after the value in MSR) br c0000101 g r edx edx=fffff800 r eax eax=0d43dd00 d fffff8000d43dd00 bm FFFFF8000D442A4A,l w g u rip 0010:FFFFF8000D503AB1 898BC84B0000 mov [rbx+00004bc8h],ecx r rbx rbx=FFFFF8000D43DE80 r ecx ecx=203B7DFE 0010:FFFFF8000D503AAA 8B8C24A0000000 mov ecx,[rsp+000000a0h] ; rsp = FFFFF8000DC07ED0 0010:FFFFF8000D503AB1 898BC84B0000 mov [rbx+00004bc8h],ecx ; ecx = 203B7DFE, rbx = FFFFF8000D43DE80 0010:FFFFF8000D503AB7 488B9C24B0000000 mov rbx,[rsp+000000b0h] 0010:FFFFF8000D503ABF 4883C460 add rsp,60h 0010:FFFFF8000D503AC3 415F pop r15 0010:FFFFF8000D503AC5 415E pop r14 0010:FFFFF8000D503AC7 415D pop r13 0010:FFFFF8000D503AC9 415C pop r12 0010:FFFFF8000D503ACB 5F pop rdi 0010:FFFFF8000D503ACC 5E pop rsi 0010:FFFFF8000D503ACD 5D pop rbp 0010:FFFFF8000D503ACE C3 retnq so the bit 1 of gs:4D4Ah is bit 11h of ECX at 0010:FFFFF8000D503AB1 now IDA analysis of ntoskrnl.exe, hexadecimal search for bytes 898BC84B0000 and scrolling up to find the begin of the whole procedure (which has the name KiSetFeatureBits - obtaining the name requires symbols) KiSetFeatureBits: PAGELK:00000001402B8410 sub_1402B8410 proc near ; CODE XREF: sub_1402C8050+2A7 PAGELK:00000001402B8410 PAGELK:00000001402B8410 var_78 = qword ptr -78h PAGELK:00000001402B8410 var_68 = dword ptr -68h PAGELK:00000001402B8410 var_64 = byte ptr -64h PAGELK:00000001402B8410 var_60 = dword ptr -60h PAGELK:00000001402B8410 var_5C = dword ptr -5Ch PAGELK:00000001402B8410 var_58 = byte ptr -58h PAGELK:00000001402B8410 var_54 = dword ptr -54h PAGELK:00000001402B8410 var_50 = dword ptr -50h PAGELK:00000001402B8410 BugCheckParameter1= qword ptr -4Ch PAGELK:00000001402B8410 var_3C = dword ptr -3Ch PAGELK:00000001402B8410 arg_0 = dword ptr 8 PAGELK:00000001402B8410 arg_8 = dword ptr 10h PAGELK:00000001402B8410 arg_10 = qword ptr 18h PAGELK:00000001402B8410 PAGELK:00000001402B8410 mov [rsp+arg_10], rbx PAGELK:00000001402B8415 push rbp PAGELK:00000001402B8416 push rsi PAGELK:00000001402B8417 push rdi PAGELK:00000001402B8418 push r12 PAGELK:00000001402B841A push r13 PAGELK:00000001402B841C push r14 PAGELK:00000001402B841E push r15 PAGELK:00000001402B8420 sub rsp, 60h PAGELK:00000001402B8424 mov rbx, rcx PAGELK:00000001402B8427 lea r8, [rsp+98h+var_68] PAGELK:00000001402B842C xor edx, edx PAGELK:00000001402B842E xor ecx, ecx PAGELK:00000001402B8430 call KiCpuId PAGELK:00000001402B8435 mov eax, [rsp+98h+var_5C] PAGELK:00000001402B8439 mov r12d, [rsp+98h+var_60] PAGELK:00000001402B843E lea rcx, [rsp+98h+var_64] PAGELK:00000001402B8443 mov [rsp+98h+var_60], eax PAGELK:00000001402B8447 mov [rsp+98h+var_5C], r12d PAGELK:00000001402B844C mov rax, [rcx] PAGELK:00000001402B844F xor r13d, r13d PAGELK:00000001402B8452 lea rdx, aAuthenticamd ; "AuthenticAMD" PAGELK:00000001402B8459 mov [rbx+4BB8h], rax PAGELK:00000001402B8460 mov eax, [rcx+8] PAGELK:00000001402B8463 lea edi, [r13+0Ch] PAGELK:00000001402B8467 lea rcx, [rsp+98h+var_64] ; char * PAGELK:00000001402B846C mov r8, rdi ; size_t PAGELK:00000001402B846F mov [rbx+4BC4h], r13b PAGELK:00000001402B8476 mov [rbx+4BC0h], eax PAGELK:00000001402B847C call strncmp PAGELK:00000001402B8481 lea r15d, [r13+1] PAGELK:00000001402B8485 cmp eax, r13d PAGELK:00000001402B8488 jnz short loc_1402B8493 PAGELK:00000001402B848A mov [rbx+63Dh], r15b PAGELK:00000001402B8491 jmp short loc_1402B84D9 PAGELK:00000001402B8493 ; --------------------------------------------------------------------------- PAGELK:00000001402B8493 PAGELK:00000001402B8493 loc_1402B8493: ; CODE XREF: sub_1402B8410+78 PAGELK:00000001402B8493 lea rdx, aGenuineintel ; "GenuineIntel" PAGELK:00000001402B849A lea rcx, [rsp+98h+var_64] ; char * PAGELK:00000001402B849F mov r8, rdi ; size_t PAGELK:00000001402B84A2 call strncmp PAGELK:00000001402B84A7 cmp eax, r13d PAGELK:00000001402B84AA jnz short loc_1402B84B5 PAGELK:00000001402B84AC mov byte ptr [rbx+63Dh], 2 PAGELK:00000001402B84B3 jmp short loc_1402B84D9 PAGELK:00000001402B84B5 ; --------------------------------------------------------------------------- PAGELK:00000001402B84B5 PAGELK:00000001402B84B5 loc_1402B84B5: ; CODE XREF: sub_1402B8410+9A PAGELK:00000001402B84B5 lea rdx, aCentaurhauls ; "CentaurHauls" PAGELK:00000001402B84BC lea rcx, [rsp+98h+var_64] ; char * PAGELK:00000001402B84C1 mov r8, rdi ; size_t PAGELK:00000001402B84C4 call strncmp PAGELK:00000001402B84C9 cmp eax, r13d PAGELK:00000001402B84CC jnz loc_1402B8AE8 PAGELK:00000001402B84D2 mov byte ptr [rbx+63Dh], 3 PAGELK:00000001402B84D9 PAGELK:00000001402B84D9 loc_1402B84D9: ; CODE XREF: sub_1402B8410+81 PAGELK:00000001402B84D9 ; sub_1402B8410+A3 PAGELK:00000001402B84D9 lea r8, [rsp+98h+var_68] PAGELK:00000001402B84DE xor edx, edx PAGELK:00000001402B84E0 mov ecx, r15d PAGELK:00000001402B84E3 call KiCpuId PAGELK:00000001402B84E8 mov ebp, [rsp+98h+var_68] PAGELK:00000001402B84EC mov r8d, 0Fh PAGELK:00000001402B84F2 mov edi, ebp PAGELK:00000001402B84F4 mov edx, 0F0h PAGELK:00000001402B84F9 shr edi, 8 PAGELK:00000001402B84FC mov esi, edi PAGELK:00000001402B84FE and esi, r8d PAGELK:00000001402B8501 cmp esi, r8d PAGELK:00000001402B8504 jnz short loc_1402B8522 PAGELK:00000001402B8506 and edi, 0F00h PAGELK:00000001402B850C mov eax, ebp PAGELK:00000001402B850E shr eax, 14h PAGELK:00000001402B8511 movzx esi, al PAGELK:00000001402B8514 mov eax, ebp PAGELK:00000001402B8516 and eax, edx PAGELK:00000001402B8518 add esi, r8d PAGELK:00000001402B851B or edi, eax PAGELK:00000001402B851D shr edi, 4 PAGELK:00000001402B8520 jmp short loc_1402B852A PAGELK:00000001402B8522 ; --------------------------------------------------------------------------- PAGELK:00000001402B8522 PAGELK:00000001402B8522 loc_1402B8522: ; CODE XREF: sub_1402B8410+F4 PAGELK:00000001402B8522 mov edi, ebp PAGELK:00000001402B8524 shr edi, 4 PAGELK:00000001402B8527 and edi, r8d PAGELK:00000001402B852A PAGELK:00000001402B852A loc_1402B852A: ; CODE XREF: sub_1402B8410+110 PAGELK:00000001402B852A mov cl, [rbx+63Dh] PAGELK:00000001402B8530 cmp cl, 2 PAGELK:00000001402B8533 jnz short loc_1402B8543 PAGELK:00000001402B8535 cmp esi, 6 PAGELK:00000001402B8538 jnz short loc_1402B8543 PAGELK:00000001402B853A mov eax, ebp PAGELK:00000001402B853C shr eax, 0Ch PAGELK:00000001402B853F and eax, edx PAGELK:00000001402B8541 or edi, eax PAGELK:00000001402B8543 PAGELK:00000001402B8543 loc_1402B8543: ; CODE XREF: sub_1402B8410+123 PAGELK:00000001402B8543 ; sub_1402B8410+128 PAGELK:00000001402B8543 and ebp, r8d PAGELK:00000001402B8546 movzx eax, di PAGELK:00000001402B8549 mov [rbx+5F1h], r15b PAGELK:00000001402B8550 shl ax, 8 PAGELK:00000001402B8554 mov [rbx+5F0h], sil PAGELK:00000001402B855B mov r14b, r13b PAGELK:00000001402B855E or ax, bp PAGELK:00000001402B8561 mov [rbx+5F2h], ax PAGELK:00000001402B8568 cmp cl, 2 PAGELK:00000001402B856B jnz loc_1402B861D PAGELK:00000001402B8571 cmp esi, r8d PAGELK:00000001402B8574 jnb short loc_1402B8584 PAGELK:00000001402B8576 cmp esi, 6 PAGELK:00000001402B8579 jnz loc_1402B8653 PAGELK:00000001402B857F cmp edi, 0Dh PAGELK:00000001402B8582 jbe short loc_1402B85A9 PAGELK:00000001402B8584 PAGELK:00000001402B8584 loc_1402B8584: ; CODE XREF: sub_1402B8410+164 PAGELK:00000001402B8584 mov ecx, 1A0h PAGELK:00000001402B8589 rdmsr PAGELK:00000001402B858B shl rdx, 20h PAGELK:00000001402B858F or rax, rdx PAGELK:00000001402B8592 btr rax, 16h PAGELK:00000001402B8597 mov rdx, rax PAGELK:00000001402B859A shr rdx, 20h PAGELK:00000001402B859E wrmsr PAGELK:00000001402B85A0 cmp esi, 6 PAGELK:00000001402B85A3 jnz loc_1402B8653 PAGELK:00000001402B85A9 PAGELK:00000001402B85A9 loc_1402B85A9: ; CODE XREF: sub_1402B8410+172 PAGELK:00000001402B85A9 cmp edi, r8d PAGELK:00000001402B85AC jz short loc_1402B85C1 PAGELK:00000001402B85AE cmp edi, 16h PAGELK:00000001402B85B1 jz short loc_1402B85C1 PAGELK:00000001402B85B3 cmp edi, 17h PAGELK:00000001402B85B6 jz short loc_1402B85C1 PAGELK:00000001402B85B8 cmp edi, 1Ah PAGELK:00000001402B85BB jnz loc_1402B8653 PAGELK:00000001402B85C1 PAGELK:00000001402B85C1 loc_1402B85C1: ; CODE XREF: sub_1402B8410+19C PAGELK:00000001402B85C1 ; sub_1402B8410+1A1 ... PAGELK:00000001402B85C1 mov r14b, r15b PAGELK:00000001402B85C4 cmp [rbx+24h], r13d PAGELK:00000001402B85C8 jnz loc_1402B8653 PAGELK:00000001402B85CE mov cs:dword_1402B16B4, 1C9h PAGELK:00000001402B85D8 mov cs:dword_1402B147C, 1DDh PAGELK:00000001402B85E2 mov cs:dword_1402B1478, 1DEh PAGELK:00000001402B85EC cmp edi, 1Ah PAGELK:00000001402B85EF jz short loc_1402B8607 PAGELK:00000001402B85F1 mov cs:dword_1402B12A8, 40h PAGELK:00000001402B85FB mov cs:dword_1402B1350, 60h PAGELK:00000001402B8605 jmp short loc_1402B8653 PAGELK:00000001402B8607 ; --------------------------------------------------------------------------- PAGELK:00000001402B8607 PAGELK:00000001402B8607 loc_1402B8607: ; CODE XREF: sub_1402B8410+1DF PAGELK:00000001402B8607 mov cs:dword_1402B12A8, 680h PAGELK:00000001402B8611 mov cs:dword_1402B1350, 6C0h PAGELK:00000001402B861B jmp short loc_1402B8653 PAGELK:00000001402B861D ; --------------------------------------------------------------------------- PAGELK:00000001402B861D PAGELK:00000001402B861D loc_1402B861D: ; CODE XREF: sub_1402B8410+15B PAGELK:00000001402B861D cmp cl, r15b PAGELK:00000001402B8620 jnz short loc_1402B8653 PAGELK:00000001402B8622 mov r14b, r15b PAGELK:00000001402B8625 cmp [rbx+24h], r13d PAGELK:00000001402B8629 jnz short loc_1402B8653 PAGELK:00000001402B862B mov cs:dword_1402B12A8, 1DBh PAGELK:00000001402B8635 mov cs:dword_1402B1350, 1DCh PAGELK:00000001402B863F mov cs:dword_1402B147C, 1DDh PAGELK:00000001402B8649 mov cs:dword_1402B1478, 1DEh PAGELK:00000001402B8653 PAGELK:00000001402B8653 loc_1402B8653: ; CODE XREF: sub_1402B8410+169 PAGELK:00000001402B8653 ; sub_1402B8410+193 ... PAGELK:00000001402B8653 lea r8, [rsp+98h+var_68] PAGELK:00000001402B8658 xor edx, edx PAGELK:00000001402B865A xor ecx, ecx PAGELK:00000001402B865C call KiCpuId PAGELK:00000001402B8661 cmp byte ptr [rbx+63Dh], 2 PAGELK:00000001402B8668 mov r13d, [rsp+98h+var_68] PAGELK:00000001402B866D jnz short loc_1402B86AB PAGELK:00000001402B866F xor eax, eax PAGELK:00000001402B8671 mov r15d, 8Bh PAGELK:00000001402B8677 mov rdx, rax PAGELK:00000001402B867A mov ecx, r15d PAGELK:00000001402B867D shr rdx, 20h PAGELK:00000001402B8681 wrmsr PAGELK:00000001402B8683 lea r8, [rsp+98h+var_68] PAGELK:00000001402B8688 lea ecx, [rax+1] PAGELK:00000001402B868B xor edx, edx PAGELK:00000001402B868D call KiCpuId PAGELK:00000001402B8692 mov ecx, r15d PAGELK:00000001402B8695 rdmsr PAGELK:00000001402B8697 shl rdx, 20h PAGELK:00000001402B869B mov r15d, 1 PAGELK:00000001402B86A1 or rax, rdx PAGELK:00000001402B86A4 mov [rbx+4BD0h], rax PAGELK:00000001402B86AB PAGELK:00000001402B86AB loc_1402B86AB: ; CODE XREF: sub_1402B8410+25D PAGELK:00000001402B86AB cmp [rbx+63Dh], r15b PAGELK:00000001402B86B2 jnz short loc_1402B86CA PAGELK:00000001402B86B4 cmp esi, 0Fh PAGELK:00000001402B86B7 ja short loc_1402B86CA PAGELK:00000001402B86B9 cmp edi, 5 PAGELK:00000001402B86BC ja short loc_1402B86CA PAGELK:00000001402B86BE cmp ebp, 8 PAGELK:00000001402B86C1 ja short loc_1402B86CA PAGELK:00000001402B86C3 or cs:byte_1402B105F, r15b PAGELK:00000001402B86CA PAGELK:00000001402B86CA loc_1402B86CA: ; CODE XREF: sub_1402B8410+2A2 PAGELK:00000001402B86CA ; sub_1402B8410+2A7 ... PAGELK:00000001402B86CA lea r8, [rsp+98h+var_58] PAGELK:00000001402B86CF xor edx, edx PAGELK:00000001402B86D1 mov ecx, r15d PAGELK:00000001402B86D4 call KiCpuId PAGELK:00000001402B86D9 lea r8, [rsp+98h+BugCheckParameter1+4] PAGELK:00000001402B86DE xor edx, edx PAGELK:00000001402B86E0 mov ecx, 80000000h PAGELK:00000001402B86E5 call KiCpuId PAGELK:00000001402B86EA mov ebp, dword ptr [rsp+98h+BugCheckParameter1+4] PAGELK:00000001402B86EE lea r8, [rsp+98h+BugCheckParameter1+4] PAGELK:00000001402B86F3 xor edx, edx PAGELK:00000001402B86F5 mov ecx, 80000001h PAGELK:00000001402B86FA mov [rsp+98h+arg_8], ebp PAGELK:00000001402B8701 call KiCpuId PAGELK:00000001402B8706 mov edx, dword ptr [rsp+98h+BugCheckParameter1+4] PAGELK:00000001402B870A mov rcx, rbx PAGELK:00000001402B870D call sub_1402B77A0 PAGELK:00000001402B8712 mov r9d, [rsp+98h+var_54] PAGELK:00000001402B8717 mov r8d, dword ptr [rsp+98h+BugCheckParameter1] PAGELK:00000001402B871C mov ecx, 789F3FDh PAGELK:00000001402B8721 mov eax, r9d PAGELK:00000001402B8724 shr eax, 18h PAGELK:00000001402B8727 mov [rbx+650h], eax PAGELK:00000001402B872D mov eax, r9d PAGELK:00000001402B8730 shr eax, 5 PAGELK:00000001402B8733 and eax, 7F8h PAGELK:00000001402B8738 mov [rbx+644h], eax PAGELK:00000001402B873E mov eax, r8d PAGELK:00000001402B8741 and eax, ecx PAGELK:00000001402B8743 cmp eax, ecx PAGELK:00000001402B8745 jnz loc_1402B8ACF PAGELK:00000001402B874B mov eax, [rsp+98h+var_3C] PAGELK:00000001402B874F bt eax, 0Bh PAGELK:00000001402B8753 jnb loc_1402B8ACF PAGELK:00000001402B8759 bt r8d, 15h PAGELK:00000001402B875E mov edi, 13DFEh PAGELK:00000001402B8763 mov ecx, 13FFEh PAGELK:00000001402B8768 cmovb edi, ecx PAGELK:00000001402B876B mov [rsp+98h+arg_0], edi PAGELK:00000001402B8772 test byte ptr [rsp+98h+var_50], r15b PAGELK:00000001402B8777 jz short loc_1402B8784 PAGELK:00000001402B8779 bts edi, 13h PAGELK:00000001402B877D mov [rsp+98h+arg_0], edi PAGELK:00000001402B8784 PAGELK:00000001402B8784 loc_1402B8784: ; CODE XREF: sub_1402B8410+367 PAGELK:00000001402B8784 bt [rsp+98h+var_50], 0Dh PAGELK:00000001402B878A jnb short loc_1402B8797 PAGELK:00000001402B878C bts edi, 14h PAGELK:00000001402B8790 mov [rsp+98h+arg_0], edi PAGELK:00000001402B8797 PAGELK:00000001402B8797 loc_1402B8797: ; CODE XREF: sub_1402B8410+37A PAGELK:00000001402B8797 bt eax, 1Fh PAGELK:00000001402B879B jnb short loc_1402B87A8 PAGELK:00000001402B879D bts edi, 0Eh PAGELK:00000001402B87A1 mov [rsp+98h+arg_0], edi PAGELK:00000001402B87A8 PAGELK:00000001402B87A8 loc_1402B87A8: ; CODE XREF: sub_1402B8410+38B PAGELK:00000001402B87A8 xor esi, esi PAGELK:00000001402B87AA cmp [rbx+24h], esi PAGELK:00000001402B87AD jz short loc_1402B87B9 PAGELK:00000001402B87AF bt cs:dword_1402B1044, 1Dh PAGELK:00000001402B87B7 jnb short loc_1402B87CA PAGELK:00000001402B87B9 PAGELK:00000001402B87B9 loc_1402B87B9: ; CODE XREF: sub_1402B8410+39D PAGELK:00000001402B87B9 bt eax, 14h PAGELK:00000001402B87BD jnb short loc_1402B87CA PAGELK:00000001402B87BF bts edi, 1Dh PAGELK:00000001402B87C3 mov [rsp+98h+arg_0], edi PAGELK:00000001402B87CA PAGELK:00000001402B87CA loc_1402B87CA: ; CODE XREF: sub_1402B8410+3A7 PAGELK:00000001402B87CA ; sub_1402B8410+3AD PAGELK:00000001402B87CA bt eax, 19h PAGELK:00000001402B87CE jnb short loc_1402B87EC PAGELK:00000001402B87D0 mov ecx, 0C0000080h PAGELK:00000001402B87D5 rdmsr PAGELK:00000001402B87D7 shl rdx, 20h PAGELK:00000001402B87DB or rax, rdx PAGELK:00000001402B87DE bts rax, 0Eh PAGELK:00000001402B87E3 mov rdx, rax PAGELK:00000001402B87E6 shr rdx, 20h PAGELK:00000001402B87EA wrmsr PAGELK:00000001402B87EC PAGELK:00000001402B87EC loc_1402B87EC: ; CODE XREF: sub_1402B8410+3BE PAGELK:00000001402B87EC mov al, [rbx+63Dh] PAGELK:00000001402B87F2 mov [rbx+63Eh], r15b PAGELK:00000001402B87F9 mov [rbx+63Fh], r15b PAGELK:00000001402B8800 cmp al, 2 PAGELK:00000001402B8802 jnz loc_1402B8918 PAGELK:00000001402B8808 bts edi, 18h PAGELK:00000001402B880C mov [rsp+98h+arg_0], edi PAGELK:00000001402B8813 cmp r13d, 0Bh PAGELK:00000001402B8817 jb loc_1402B88B1 PAGELK:00000001402B881D xor edx, edx PAGELK:00000001402B881F lea r8, [rsp+98h+var_68] PAGELK:00000001402B8824 lea ecx, [rdx+0Bh] PAGELK:00000001402B8827 call KiCpuId PAGELK:00000001402B882C cmp dword ptr [rsp+98h+var_64], esi PAGELK:00000001402B8830 jz short loc_1402B88A7 PAGELK:00000001402B8832 mov eax, [rsp+98h+var_5C] PAGELK:00000001402B8836 xor ebp, ebp PAGELK:00000001402B8838 mov [rbx+650h], eax PAGELK:00000001402B883E PAGELK:00000001402B883E loc_1402B883E: ; CODE XREF: sub_1402B8410+479 PAGELK:00000001402B883E lea r8, [rsp+98h+var_68] PAGELK:00000001402B8843 mov edx, esi PAGELK:00000001402B8845 mov ecx, 0Bh PAGELK:00000001402B884A call KiCpuId PAGELK:00000001402B884F mov eax, [rsp+98h+var_60] PAGELK:00000001402B8853 add esi, r15d PAGELK:00000001402B8856 shr eax, 8 PAGELK:00000001402B8859 sub eax, r15d PAGELK:00000001402B885C jz short loc_1402B8872 PAGELK:00000001402B885E cmp eax, r15d PAGELK:00000001402B8861 jnz short loc_1402B8884 PAGELK:00000001402B8863 mov ecx, [rsp+98h+var_68] PAGELK:00000001402B8867 mov r12d, r15d PAGELK:00000001402B886A and ecx, 0Fh PAGELK:00000001402B886D shl r12d, cl PAGELK:00000001402B8870 jmp short loc_1402B8884 PAGELK:00000001402B8872 ; --------------------------------------------------------------------------- PAGELK:00000001402B8872 PAGELK:00000001402B8872 loc_1402B8872: ; CODE XREF: sub_1402B8410+44C PAGELK:00000001402B8872 mov ecx, [rsp+98h+var_68] PAGELK:00000001402B8876 mov edx, r15d PAGELK:00000001402B8879 and ecx, 0Fh PAGELK:00000001402B887C shl dl, cl PAGELK:00000001402B887E mov [rbx+63Fh], dl PAGELK:00000001402B8884 PAGELK:00000001402B8884 loc_1402B8884: ; CODE XREF: sub_1402B8410+451 PAGELK:00000001402B8884 ; sub_1402B8410+460 PAGELK:00000001402B8884 cmp word ptr [rsp+98h+var_64], bp PAGELK:00000001402B8889 jnz short loc_1402B883E PAGELK:00000001402B888B movzx ecx, byte ptr [rbx+63Fh] PAGELK:00000001402B8892 mov ebp, [rsp+98h+arg_8] PAGELK:00000001402B8899 xor edx, edx PAGELK:00000001402B889B mov eax, r12d PAGELK:00000001402B889E div ecx PAGELK:00000001402B88A0 xor esi, esi PAGELK:00000001402B88A2 jmp loc_1402B8953 PAGELK:00000001402B88A7 ; --------------------------------------------------------------------------- PAGELK:00000001402B88A7 PAGELK:00000001402B88A7 loc_1402B88A7: ; CODE XREF: sub_1402B8410+420 PAGELK:00000001402B88A7 mov r8d, dword ptr [rsp+98h+BugCheckParameter1] PAGELK:00000001402B88AC mov r9d, [rsp+98h+var_54] PAGELK:00000001402B88B1 PAGELK:00000001402B88B1 loc_1402B88B1: ; CODE XREF: sub_1402B8410+407 PAGELK:00000001402B88B1 mov ecx, 4 PAGELK:00000001402B88B6 cmp r13d, ecx PAGELK:00000001402B88B9 jb short loc_1402B88EA PAGELK:00000001402B88BB lea r8, [rsp+98h+var_68] PAGELK:00000001402B88C0 xor edx, edx PAGELK:00000001402B88C2 call KiCpuId PAGELK:00000001402B88C7 mov eax, [rsp+98h+var_68] PAGELK:00000001402B88CB mov r8d, dword ptr [rsp+98h+BugCheckParameter1] PAGELK:00000001402B88D0 mov r9d, [rsp+98h+var_54] PAGELK:00000001402B88D5 shr eax, 1Ah PAGELK:00000001402B88D8 lea eax, [rax+rax+1] PAGELK:00000001402B88DC bsr ecx, eax PAGELK:00000001402B88DF mov eax, r15d PAGELK:00000001402B88E2 shl al, cl PAGELK:00000001402B88E4 mov [rbx+63Eh], al PAGELK:00000001402B88EA PAGELK:00000001402B88EA loc_1402B88EA: ; CODE XREF: sub_1402B8410+4A9 PAGELK:00000001402B88EA bt r8d, 1Ch PAGELK:00000001402B88EF jnb short loc_1402B8959 PAGELK:00000001402B88F1 shr r9d, 10h PAGELK:00000001402B88F5 xor edx, edx PAGELK:00000001402B88F7 movzx eax, r9b PAGELK:00000001402B88FB lea eax, [rax+rax-1] PAGELK:00000001402B88FF bsr ecx, eax PAGELK:00000001402B8902 mov eax, r15d PAGELK:00000001402B8905 shl eax, cl PAGELK:00000001402B8907 movzx ecx, byte ptr [rbx+63Eh] PAGELK:00000001402B890E div ecx PAGELK:00000001402B8910 mov [rbx+63Fh], al PAGELK:00000001402B8916 jmp short loc_1402B8959 PAGELK:00000001402B8918 ; --------------------------------------------------------------------------- PAGELK:00000001402B8918 PAGELK:00000001402B8918 loc_1402B8918: ; CODE XREF: sub_1402B8410+3F2 PAGELK:00000001402B8918 cmp al, r15b PAGELK:00000001402B891B jnz short loc_1402B8959 PAGELK:00000001402B891D cmp ebp, 80000008h PAGELK:00000001402B8923 jb short loc_1402B8959 PAGELK:00000001402B8925 lea r8, [rsp+98h+var_68] PAGELK:00000001402B892A xor edx, edx PAGELK:00000001402B892C mov ecx, 80000008h PAGELK:00000001402B8931 call KiCpuId PAGELK:00000001402B8936 mov ecx, [rsp+98h+var_60] PAGELK:00000001402B893A shr ecx, 0Ch PAGELK:00000001402B893D and ecx, 0Fh PAGELK:00000001402B8940 jnz short loc_1402B894E PAGELK:00000001402B8942 movzx eax, byte ptr [rsp+98h+var_60] PAGELK:00000001402B8947 lea eax, [rax+rax+1] PAGELK:00000001402B894B bsr ecx, eax PAGELK:00000001402B894E PAGELK:00000001402B894E loc_1402B894E: ; CODE XREF: sub_1402B8410+530 PAGELK:00000001402B894E mov eax, r15d PAGELK:00000001402B8951 shl al, cl PAGELK:00000001402B8953 PAGELK:00000001402B8953 loc_1402B8953: ; CODE XREF: sub_1402B8410+492 PAGELK:00000001402B8953 mov [rbx+63Eh], al PAGELK:00000001402B8959 PAGELK:00000001402B8959 loc_1402B8959: ; CODE XREF: sub_1402B8410+4DF PAGELK:00000001402B8959 ; sub_1402B8410+506 ... PAGELK:00000001402B8959 cmp [rbx+63Dh], r15b PAGELK:00000001402B8960 jnz short loc_1402B896D PAGELK:00000001402B8962 bts edi, 15h PAGELK:00000001402B8966 mov [rsp+98h+arg_0], edi PAGELK:00000001402B896D PAGELK:00000001402B896D loc_1402B896D: ; CODE XREF: sub_1402B8410+550 PAGELK:00000001402B896D movzx r8d, byte ptr [rbx+63Fh] PAGELK:00000001402B8975 movzx ecx, byte ptr [rbx+63Eh] PAGELK:00000001402B897C mov edx, cs:dword_1402B106C PAGELK:00000001402B8982 imul ecx, r8d PAGELK:00000001402B8986 movzx eax, dl PAGELK:00000001402B8989 cmp ecx, eax PAGELK:00000001402B898B jle short loc_1402B89AA PAGELK:00000001402B898D cmp r8d, edx PAGELK:00000001402B8990 jbe short loc_1402B8998 PAGELK:00000001402B8992 mov [rbx+63Fh], dl PAGELK:00000001402B8998 PAGELK:00000001402B8998 loc_1402B8998: ; CODE XREF: sub_1402B8410+580 PAGELK:00000001402B8998 movzx r8d, byte ptr [rbx+63Fh] PAGELK:00000001402B89A0 cdq PAGELK:00000001402B89A1 idiv r8d PAGELK:00000001402B89A4 mov [rbx+63Eh], al PAGELK:00000001402B89AA PAGELK:00000001402B89AA loc_1402B89AA: ; CODE XREF: sub_1402B8410+57B PAGELK:00000001402B89AA mov [rbx+654h], r8d PAGELK:00000001402B89B1 cmp [rbx+24h], esi PAGELK:00000001402B89B4 jnz short loc_1402B89BC PAGELK:00000001402B89B6 lea eax, [r8-1] PAGELK:00000001402B89BA jmp short loc_1402B89D0 PAGELK:00000001402B89BC ; --------------------------------------------------------------------------- PAGELK:00000001402B89BC PAGELK:00000001402B89BC loc_1402B89BC: ; CODE XREF: sub_1402B8410+5A4 PAGELK:00000001402B89BC call HalIsHyperThreadingEnabled PAGELK:00000001402B89C1 cmp al, sil PAGELK:00000001402B89C4 jz short loc_1402B89DA PAGELK:00000001402B89C6 movzx eax, byte ptr [rbx+63Fh] PAGELK:00000001402B89CD sub eax, r15d PAGELK:00000001402B89D0 PAGELK:00000001402B89D0 loc_1402B89D0: ; CODE XREF: sub_1402B8410+5AA PAGELK:00000001402B89D0 not eax PAGELK:00000001402B89D2 mov [rbx+640h], eax PAGELK:00000001402B89D8 jmp short loc_1402B89F6 PAGELK:00000001402B89DA ; --------------------------------------------------------------------------- PAGELK:00000001402B89DA PAGELK:00000001402B89DA loc_1402B89DA: ; CODE XREF: sub_1402B8410+5B4 PAGELK:00000001402B89DA movzx edx, byte ptr [rbx+63Fh] PAGELK:00000001402B89E1 movzx eax, byte ptr [rbx+63Eh] PAGELK:00000001402B89E8 imul edx, eax PAGELK:00000001402B89EB sub edx, r15d PAGELK:00000001402B89EE not edx PAGELK:00000001402B89F0 mov [rbx+640h], edx PAGELK:00000001402B89F6 PAGELK:00000001402B89F6 loc_1402B89F6: ; CODE XREF: sub_1402B8410+5C8 PAGELK:00000001402B89F6 mov al, [rbx+63Dh] PAGELK:00000001402B89FC mov r12b, 2 PAGELK:00000001402B89FF cmp al, r12b PAGELK:00000001402B8A02 jnz short loc_1402B8A0C PAGELK:00000001402B8A04 cmp ebp, 80000008h PAGELK:00000001402B8A0A jnb short loc_1402B8A19 PAGELK:00000001402B8A0C PAGELK:00000001402B8A0C loc_1402B8A0C: ; CODE XREF: sub_1402B8410+5F2 PAGELK:00000001402B8A0C cmp al, r15b PAGELK:00000001402B8A0F jnz short loc_1402B8A3A PAGELK:00000001402B8A11 cmp ebp, 80000008h PAGELK:00000001402B8A17 jb short loc_1402B8A36 PAGELK:00000001402B8A19 PAGELK:00000001402B8A19 loc_1402B8A19: ; CODE XREF: sub_1402B8410+5FA PAGELK:00000001402B8A19 lea r8, [rsp+98h+var_68] PAGELK:00000001402B8A1E xor edx, edx PAGELK:00000001402B8A20 mov ecx, 80000008h PAGELK:00000001402B8A25 call KiCpuId PAGELK:00000001402B8A2A mov cl, byte ptr [rsp+98h+var_68] PAGELK:00000001402B8A2E PAGELK:00000001402B8A2E loc_1402B8A2E: ; CODE XREF: sub_1402B8410+628 PAGELK:00000001402B8A2E mov cs:byte_1401ECFEE, cl PAGELK:00000001402B8A34 jmp short loc_1402B8A40 PAGELK:00000001402B8A36 ; --------------------------------------------------------------------------- PAGELK:00000001402B8A36 PAGELK:00000001402B8A36 loc_1402B8A36: ; CODE XREF: sub_1402B8410+607 PAGELK:00000001402B8A36 mov cl, 28h PAGELK:00000001402B8A38 jmp short loc_1402B8A2E PAGELK:00000001402B8A3A ; --------------------------------------------------------------------------- PAGELK:00000001402B8A3A PAGELK:00000001402B8A3A loc_1402B8A3A: ; CODE XREF: sub_1402B8410+5FF PAGELK:00000001402B8A3A mov cl, cs:byte_1401ECFEE PAGELK:00000001402B8A40 PAGELK:00000001402B8A40 loc_1402B8A40: ; CODE XREF: sub_1402B8410+624 PAGELK:00000001402B8A40 mov rax, r15 PAGELK:00000001402B8A43 shl rax, cl PAGELK:00000001402B8A46 sub rax, r15 PAGELK:00000001402B8A49 and rax, 0FFFFFFFFFFFFF000h PAGELK:00000001402B8A4F mov cs:qword_1401F0F08, rax PAGELK:00000001402B8A56 mov cs:qword_1401F0F10, rax PAGELK:00000001402B8A5D cmp [rbx+63Dh], r12b PAGELK:00000001402B8A64 jnz short loc_1402B8A8D PAGELK:00000001402B8A66 cmp r13d, 6 PAGELK:00000001402B8A6A jb short loc_1402B8A8D PAGELK:00000001402B8A6C xor edx, edx PAGELK:00000001402B8A6E lea r8, [rsp+98h+var_68] PAGELK:00000001402B8A73 lea ecx, [rdx+6] PAGELK:00000001402B8A76 call KiCpuId PAGELK:00000001402B8A7B test byte ptr [rsp+98h+var_60], r12b PAGELK:00000001402B8A80 jz short loc_1402B8A8D PAGELK:00000001402B8A82 bts edi, 16h PAGELK:00000001402B8A86 mov [rsp+98h+arg_0], edi PAGELK:00000001402B8A8D PAGELK:00000001402B8A8D loc_1402B8A8D: ; CODE XREF: sub_1402B8410+654 PAGELK:00000001402B8A8D ; sub_1402B8410+65A ... PAGELK:00000001402B8A8D cmp r14b, sil PAGELK:00000001402B8A90 jz short loc_1402B8A9D PAGELK:00000001402B8A92 bts edi, 11h ; set bit indicating DebugCtl feature PAGELK:00000001402B8A96 mov [rsp+98h+arg_0], edi PAGELK:00000001402B8A9D PAGELK:00000001402B8A9D loc_1402B8A9D: ; CODE XREF: sub_1402B8410+680 PAGELK:00000001402B8A9D lea rcx, [rsp+98h+arg_0] PAGELK:00000001402B8AA5 call sub_140109A00 PAGELK:00000001402B8AAA mov ecx, [rsp+98h+arg_0] PAGELK:00000001402B8AB1 mov [rbx+4BC8h], ecx ; rbx = prcb = MSR_C0000101+180h PAGELK:00000001402B8AB7 mov rbx, [rsp+98h+arg_10] PAGELK:00000001402B8ABF add rsp, 60h PAGELK:00000001402B8AC3 pop r15 PAGELK:00000001402B8AC5 pop r14 PAGELK:00000001402B8AC7 pop r13 PAGELK:00000001402B8AC9 pop r12 PAGELK:00000001402B8ACB pop rdi PAGELK:00000001402B8ACC pop rsi PAGELK:00000001402B8ACD pop rbp PAGELK:00000001402B8ACE retn few lines ago it is seen bts edi, 11h \ mov [rsp+98h],edi \ ... \ mov ecx,[rsp+98h] \ mov [rbx+4BC8h],ecx the bit 11h of edi is set if r14b <> sil sil=0 because of xor esi,esi so r14b mustn't be 0 r14b is written by mov r14b,r15b r15=1 by lea r15d,[r13+1] becuase r13=0 (xor r13d,r13d) mov r14b,r15b occures only when esi=6 at this point: PAGELK:00000001402B8576 cmp esi, 6 PAGELK:00000001402B8579 jnz loc_1402B8653 by further analysis, the value means CPU family ID obtained by the CPUID with input eax=1 also the CPU must pass this check: PAGELK:00000001402B85A9 loc_1402B85A9: ; CODE XREF: sub_1402B8410+172 PAGELK:00000001402B85A9 cmp edi, r8d PAGELK:00000001402B85AC jz short loc_1402B85C1 PAGELK:00000001402B85AE cmp edi, 16h PAGELK:00000001402B85B1 jz short loc_1402B85C1 PAGELK:00000001402B85B3 cmp edi, 17h PAGELK:00000001402B85B6 jz short loc_1402B85C1 PAGELK:00000001402B85B8 cmp edi, 1Ah PAGELK:00000001402B85BB jnz loc_1402B8653 PAGELK:00000001402B85C1 value of r8d = 0Fh at the check by further analysis, the value means CPU model ID obtained by the CPUID with input eax=1 the returned EAX encodes family in bits 11.-8. and model in bits 7.-4. When family ID = 06h extended model ID (bits 19.-16.) must be AND-ed with model ID by a formula like (Extended_Model_ID << 4) + Model_ID So the DebugCtl feature at Intel is enabled for CPU family ID = 06h and model ID 0Fh, 16h, 17h, 1Ah. Looking into Intel CPU manuals: Family 06h Model 0Fh means: Intel Xeon Processor 3000, 3200, 5100, 5300, 7300 series, Intel Core 2 Quad processor 6000 series, Intel Core 2 Extreme 6000 series, Intel Core 2 Duo 4000, 5000, 6000, 7000 series processors, Intel Pentium dual-core processors LastBranchFrom are MSRs at 40h-43h, LastBranchTo at 60h-63h (4 pairs). The most frequent CPU is Core 2 Duo The family 06h model 16h is not documented in Intel manuals (maybe a CPU sample sent from Intel to Microsoft ?). But it is very important that it is implemented in ms windows kernel because I will use it to add DebugCtl support for feature CPUs not available at the time of creating kernel. Family 06h Model 17h means: Intel Xeon Processor 3100, 3300, 5200, 5400 series, Intel Core 2 Quad processors 8000, 9000 series Family 06h Model 1Ah means: Intel Core i7 Processor, Intel Xeon Processor 3400, 3500, 5500 series LastBranchFrom are MSRs at 68h-68Fh, LastBranchTo are 6C0h-6CFh (16 pairs). It is very important that MS implemented support for this model because newer Core i architecture uses the same MSRs and I will use this fact to enable DebugCtl feature for these newer Core i CPUs. (Pentium 4 architecture = Family 0Fh has also DebugCtl feature but is not supported in ms windows x64 kernel because doesn't support x64, the MSR_LastBranchTOS is completely different, etc.) Short conclusion: To use DebugControl feature, use AMD64 and any x64 version of ms windows. To use DebugControl feature, use Intel CPUs Family 06h and Model 0Fh (Core 2 family), Model 17h (Enhanced Core 2 family), Model 1Ah (Nehalem, the first Core i7 and Core i5 processors) and use Windows Server 2008 R2 x64 = windows 7 x64 or newer OS. To enable Single Step on Branches - set bit 9. of DR7 of the thread. To enable LastBranchFrom/LastBranchTo recording - set bit 8. of DR7 of the thread and obtain the branches from ThreadContext But what to do if you have newer Intel CPU than Family 06h Model 1Ah ? Sandy Bridge, Ivy Bridge, Haswell, newer CPU not available at the time of writing these words ? Buy an AMD64 ? Buy an older Intel CPU like Core 2 Duo ? That's also possible way. What else can be done? - creating patched copy of kernel which enables the feature - pretend that the new CPU is older type At the time of writing these my thoughts - for me there is not known method of patching windows server 2012 x64 / windows server 2012 R2 kernel (windows 8 x64 / windows 8.1 x64). The only one remaining working solution is pretending that the CPU is older type. ------------------------------------------- Patching the kernel in KiSetFeatureBits original: PAGELK:00000001402B85AE cmp edi, 16h PAGELK:00000001402B85B1 jz short loc_1402B85C1 will be patched in a way that EDI is compared with your model patched: PAGELK:00000001402B85AE cmp edi, your_model PAGELK:00000001402B85B1 jz short loc_1402B85C1 your_model value is obtained by a way like: xor eax,eax cpuid sub ebx,'Genu' sub edx,'ineI' sub ecx,'ntel' or ebx,edx or ebx,ecx jnz fail mov eax,1 cpuid ; eax bits ; 27-20 extended family ID ; 19-16 extended model ID ; 11-8 family ID ; 7-4 model ID ; now we need family 06h test eax,11111111b shl 20 jnz fail ; extended family ID is not 0 so then full family ID can't be 06h and ah,1111b cmp ah,06h ; family ID must be 06h jnz fail shr eax,4 ; shift bits 19-16 into bits 15-12, bits 7-4 into bits 3-0 and eax,1111000000001111b or al,ah ; AL = your_model = the value that is compared with EDI in KiSetFeatureBits instead of value 16h the second point where to patch is: original: cmp edi, 1Ah jz short loc_1402B8607 patched: cmp edi, 1Ah jnc short loc_1402B8607 ; because model 1Ah and Core i models above have MSRs680h/6C0h ------------------------------------------- Pretending that your new Core i CPU is family 06h model 1Ah This worked at me, but may lead into serious problems. Don't use it at PC where you hold valuable data. If you have a PC suitable for testing purposes, you may try it (it may be even harddiskless). It is necessary to tweak CPUID before OS boots. Hypervisor is perfect to do that. Remember that: Kernel may behave in an unexpected way (but in some situations the debug ctl feature may be more valuable for you than BSOD / silent malfunction). Any attempt to update CPU microcode after tampering CPUID (e.g. during OS boot) fails - update may be performed at firmware initialization well (before hypervisor starts), update just fails if an attempt is made after running hypervisor. You can't enable VMX/EPT features for virtual machines (VirtualBox, VMware) until the hypervisor is running (it is tiny - only to tweak CPUD - and without nested hypervisor support) - but it is possible to turn hypervisor off and then you may run VM's with all features and best performance - tiny hypervisor is necessary only during OS boot when executing KiSetFeatureBits. I wonder whether OS asks you to activate or not (it detects different CPU) - if you are afraid of activation, use trial version like me (server versions are available as free download from microsoft). You even don't need to install anything / you can try at PC without harddisk : just extract files from the iso image into USB flash disk formatted as FAT32, boot from the USB, press SHIFT + F10 which runs command prompt, then you can ran console apps as well GUI apps at some small resolution screen (copy them somewhere into the USB disk). You may also try this method at windows server 2008 R2 x64 = windows 7 x64 if you don't want to create and load patched copy of kernel (you may dislike that patchguard is off and driver signinig is disbled). Using hypervisor = no traces of kernel modifications (because they aren't). 2013-December-31, Feryno