Informative Information for the Uninformed | ||||||||||||||
|
||||||||||||||
Next: Misleading Symbol Names
Up: Notable Protection Mechanisms
Previous: Obfuscation of System Integrity
Contents
Disruption of Debug Register-Based BreakpointsPatchGuard version 2 attempts to protect itself from breakpoints that are set using the hardware debug registers. These breakpoints operate by setting up to four designated memory locations that are of interest. Each memory location can be configured to cause a debug exception when it is read, written, or executed. Because breakpoints of this flavor are not visible to PatchGuard's code integrity checks (unlike conventional breakpoints, these breakpoints do not involve int 3 (0xcc) opcodes being substituted for target instructions), debug register-based breakpoints (sometimes known as ``memory breakpoints'' or ``hardware breakpoints'') pose a threat to PatchGuard. PatchGuard attempts to counter this threat by disabling all such debug register-based breakpoints as a first step after the system integrity checking routine has been decrypted in-memory:
; ; Here, the second stage decryption sequence is ; set to run to decrypt the system integrity ; check routine. We step over the second stage ; decryption and examine the integrity check ; routine in its plaintext state... ; fffffadf`f6edc043 8b4a4c mov ecx,dword ptr [rdx+4Ch] fffffadf`f6edc046 483144ca48 xor qword ptr [rdx+rcx*8+48h],rax fffffadf`f6edc04b 48d3c8 ror rax,cl fffffadf`f6edc04e e2f6 loop fffffadf`f6edc046 fffffadf`f6edc050 8b8288010000 mov eax,dword ptr [rdx+188h] fffffadf`f6edc056 4803c2 add rax,rdx fffffadf`f6edc059 ffe0 jmp rax fffffadf`f6edc05b 90 nop ; ; We set a breakpoint on the 'jmp rax' instruction ; above. This instruction is what transfers control ; to the system integrity check routine. ; 0: kd> ba e1 fffffadf`f6edc059 0: kd> g Breakpoint 2 hit fffffadf`f6edc059 ffe0 jmp rax ; ; rax now points to the decrypted system ; integrity check routine in-memory. The ; first call it makes is to a routine whose ; purpose is to disable all debug register-based ; breakpoints by clearing the debug control ; register (dr7). Doing so effectively turns ; off all of the debug register breakpoints. ; 0: kd> u @rax fffffadf`f6edd8de 4883ec78 sub rsp,78h fffffadf`f6edd8e2 48895c2470 mov qword ptr [rsp+70h],rbx fffffadf`f6edd8e7 48896c2468 mov qword ptr [rsp+68h],rbp fffffadf`f6edd8ec 4889742460 mov qword ptr [rsp+60h],rsi fffffadf`f6edd8f1 48897c2458 mov qword ptr [rsp+58h],rdi fffffadf`f6edd8f6 4c89642450 mov qword ptr [rsp+50h],r12 fffffadf`f6edd8fb 488bda mov rbx,rdx fffffadf`f6edd8fe 4c896c2448 mov qword ptr [rsp+48h],r13 0: kd> u fffffadf`f6edd903 e8863a0000 call fffffadf`f6ee138e ; ; The routine simply writes all zeros to dr7. ; 0: kd> u fffffadf`f6ee138e fffffadf`f6ee138e 33c0 xor eax,eax fffffadf`f6ee1390 0f23f8 mov dr7,rax fffffadf`f6ee1393 c3 ret
|