I'm working on a tool to monitor RDTSC instruction being called by arbitrary program on Windows through ISR hook by a Windows kernel. Everything is working fine on Windows 7 64-bit however, it seems that it is not straight forward to implement the same ISR hook on Windows 10 64-bit.
The driver was tested on Windows 10 64-bit 19H1 (build 18362) with single CPU, to eliminate potential race condition due to synchronization issues, with the following debugging steps taken:
- The software breakpoint at
hookInterruptwill be hit
kd> u .
HookIDTx64!hookInterrupt+0x1b [F:\ProjectDDK\HookIDTx64.git\HookIDTx64.c @ 307]:
fffff801`0583902b cc int 3
fffff801`0583902c 0f014c2448 sidt tbyte ptr [rsp+48h]
fffff801`05839031 488b44244a mov rax,qword ptr [rsp+4Ah]
fffff801`05839036 4889442430 mov qword ptr [rsp+30h],rax
fffff801`0583903b fa cli
fffff801`0583903c e81fffffff call HookIDTx64!KeRaiseIrqlToDpcLevel (fffff801`05838f60)
fffff801`05839041 88442420 mov byte ptr [rsp+20h],al
fffff801`05839045 0f20c0 mov rax,cr0
- Type
guand it will return to the caller. We will inspect the IDT to confirm the "divide by zero" interrupt is properly replaced with our hook handler
kd> gu
HookIDTx64!DriverEntry+0xb1:
fffff801`05838ef1 ebae jmp HookIDTx64!DriverEntry+0x61 (fffff801`05838ea1)
kd> !idt 0
Dumping IDT: fffff80108e5b000
00: fffff80105831000 HookIDTx64!hookDVStub_
- Now we set the breakpoint at HookIDTx64!hookDVStub_ and continue the execution:
kd> ba e1 HookIDTx64!hookDVStub_
kd> g
- The driver should be loaded successfully as indicated in the screenshot HookIDTx64.sys loaded successfully
- Use the following dummy program to explicity trigger the "divide by zero" interrupt:
#include <stdio.h>
void main() {
int i = 0;
int res = 1000000 / i;
printf("Should print this if the exception is handled by our IDT hook!\n");
return;
}
- Upon executing the dummy program from step 5, we should be able to hit the breakpoint set in step 3:
Breakpoint 0 hit
HookIDTx64!hookDVStub_:
fffff801`05831000 0fa0 push fs
kd> ba e1 fffff801`05831028
kd> g
Breakpoint 1 hit
HookIDTx64!hookDVStub_+0x28:
fffff801`05831028 ffd0 call rax // <== (1)
kd> pr
[hookDivideErrorImpl] Caller RIP: 0x7ff675201012
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff8010583102a rsp=fffff80108e5f148 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=fffff80108e5ef48 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di ng nz ac pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000092
HookIDTx64!hookDVStub_+0x2a:
fffff801`0583102a 4883c408 add rsp,8
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff8010583102e rsp=fffff80108e5f150 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=fffff80108e5ef48 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di ng nz ac po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010096
HookIDTx64!hookDVStub_+0x2e:
fffff801`0583102e 3c00 cmp al,0
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831030 rsp=fffff80108e5f150 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=fffff80108e5ef48 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x30:
fffff801`05831030 741c je HookIDTx64!hookDVStub_+0x4e (fffff801`0583104e) [br=0]
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831032 rsp=fffff80108e5f150 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=fffff80108e5ef48 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x32:
fffff801`05831032 415f pop r15
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831034 rsp=fffff80108e5f158 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=fffff80108e5ef48 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x34:
fffff801`05831034 415e pop r14
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831036 rsp=fffff80108e5f160 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=fffff80108e5ef48 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x36:
fffff801`05831036 415d pop r13
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831038 rsp=fffff80108e5f168 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=fffff80108e5ef48 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x38:
fffff801`05831038 415c pop r12
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff8010583103a rsp=fffff80108e5f170 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=fffff80108e5ef48 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x3a:
fffff801`0583103a 415b pop r11
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff8010583103c rsp=fffff80108e5f178 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x3c:
fffff801`0583103c 415a pop r10
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff8010583103e rsp=fffff80108e5f180 rbp=0000000000000000
r8=ffffffffffffffff r9=fffff80108e5e858 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x3e:
fffff801`0583103e 4159 pop r9
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831040 rsp=fffff80108e5f188 rbp=0000000000000000
r8=ffffffffffffffff r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x40:
fffff801`05831040 4158 pop r8
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831042 rsp=fffff80108e5f190 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x42:
fffff801`05831042 5f pop rdi
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831043 rsp=fffff80108e5f198 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x43:
fffff801`05831043 5e pop rsi
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831044 rsp=fffff80108e5f1a0 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x44:
fffff801`05831044 5d pop rbp
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831045 rsp=fffff80108e5f1a8 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x45:
fffff801`05831045 5a pop rdx
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=00007ff675201016
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831046 rsp=fffff80108e5f1b0 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x46:
fffff801`05831046 59 pop rcx
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=0000000000000001
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831047 rsp=fffff80108e5f1b8 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x47:
fffff801`05831047 5b pop rbx
kd> p
rax=fffff80108e5f101 rbx=00000251adce79d0 rcx=0000000000000001
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831048 rsp=fffff80108e5f1c0 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x48:
fffff801`05831048 58 pop rax
kd> p
rax=00000000000f4240 rbx=00000251adce79d0 rcx=0000000000000001
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff80105831049 rsp=fffff80108e5f1c8 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x49:
fffff801`05831049 9d popfq
kd> p
rax=00000000000f4240 rbx=00000251adce79d0 rcx=0000000000000001
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff8010583104a rsp=fffff80108e5f1d0 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000002
HookIDTx64!hookDVStub_+0x4a:
fffff801`0583104a 0fa1 pop fs
kd> p
rax=00000000000f4240 rbx=00000251adce79d0 rcx=0000000000000001
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=fffff8010583104c rsp=fffff80108e5f1d8 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010002
HookIDTx64!hookDVStub_+0x4c:
fffff801`0583104c 48cf iretq
kd> .reload
Connected to Windows 10 18362 x64 target at (Wed Dec 27 22:06:34.923 2023 (UTC + 8:00)), ptr64 TRUE
Loading Kernel Symbols
...............................................................
................................................................
............................
Loading User Symbols
.....
Loading unloaded module list
.........
*** WARNING: Unable to verify checksum for DivideByZero.exe
************* Symbol Loading Error Summary **************
Module name Error
DivideByZero The system cannot find the file specified
You can troubleshoot most symbol related issues by turning on symbol loading diagnostics (!sym noisy) and repeating the command that caused symbols to be loaded.
You should also verify that your symbol search path (.sympath) is correct.
kd> dps rsp l5
fffff801`08e5f1d8 00007ff6`75201016 DivideByZero+0x1016 // <=== (2)
fffff801`08e5f1e0 00000000`00000033
fffff801`08e5f1e8 00000000`00010202
fffff801`08e5f1f0 000000fc`0beffa20
fffff801`08e5f1f8 00000000`0000002b
kd> u 00007ff6`75201016
DivideByZero+0x1016:
00007ff6`75201016 89442424 mov dword ptr [rsp+24h],eax
00007ff6`7520101a 488d0ddfff0100 lea rcx,[DivideByZero+0x21000 (00007ff6`75221000)]
00007ff6`75201021 e86a000000 call DivideByZero+0x1090 (00007ff6`75201090)
00007ff6`75201026 33c0 xor eax,eax
00007ff6`75201028 4883c438 add rsp,38h
00007ff6`7520102c c3 ret
00007ff6`7520102d cc int 3
00007ff6`7520102e cc int 3
kd> p
rax=00000000000f4240 rbx=00000251adce79d0 rcx=0000000000000001
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=00007ff675201016 rsp=000000fc0beffa20 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
DivideByZero+0x1016:
0033:00007ff6`75201016 89442424 mov dword ptr [rsp+24h],eax ss:002b:000000fc`0beffa44=00000000
kd> p
rax=00000000000f4240 rbx=00000251adce79d0 rcx=0000000000000001
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=00007ff67520101a rsp=000000fc0beffa20 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
DivideByZero+0x101a:
0033:00007ff6`7520101a 488d0ddfff0100 lea rcx,[DivideByZero+0x21000 (00007ff6`75221000)]
kd> p
rax=00000000000f4240 rbx=00000251adce79d0 rcx=00007ff675221000
rdx=0000000000000000 rsi=0000000000000000 rdi=00000251adceb940
rip=00007ff675201021 rsp=000000fc0beffa20 rbp=0000000000000000
r8=00000251adceb940 r9=0000000000000001 r10=0000000000000000
r11=000000fc0beff9f0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
DivideByZero+0x1021:
0033:00007ff6`75201021 e86a000000 call DivideByZero+0x1090 (00007ff6`75201090)
kd> p
rax=000000000000003f rbx=00000251adce79d0 rcx=00000000ffffffff
rdx=0000000000000001 rsi=0000000000000000 rdi=00000251adceb940
rip=00007ff675201026 rsp=000000fc0beffa20 rbp=0000000000000000
r8=00007ff675222070 r9=00000251adcef69f r10=0000000000000000
r11=000000fc0beff880 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
DivideByZero+0x1026:
0033:00007ff6`75201026 33c0 xor eax,eax
kd> p
rax=0000000000000000 rbx=00000251adce79d0 rcx=00000000ffffffff
rdx=0000000000000001 rsi=0000000000000000 rdi=00000251adceb940
rip=00007ff675201028 rsp=000000fc0beffa20 rbp=0000000000000000
r8=00007ff675222070 r9=00000251adcef69f r10=0000000000000000
r11=000000fc0beff880 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
DivideByZero+0x1028:
0033:00007ff6`75201028 4883c438 add rsp,38h
As indicated in (1), our hook implementation of the "divide by zero" HookIDTx64!hookDivideErrorImpl is executed successfully and the corresponding debug message is returned and rax is returned with value 4 which indicates the size of the byte code for the idiv opcode.
We step into the code until it reaches iretq. We inspect the stack and observe the return address at (2) which indicates our dummy program. We continue the execution and notice the expected message output in the program console as indicated in the screenshot.
- Now, we remove all the breakpoints and try to execute our dummy program again. The VM will be crashed immediately. I checked the VBOX's log and does not seem to be helpul. Anyway, I also attach the VBOX's log in case it would be helpful https://gist.github.com/x9090/90d7e70af10b71ec9df72587e93d71e2
The full source code of the driver with VS2019 solution can be found here https://github.com/x9090/HookIDTx64/
So, here are the things that I would like to clarify:
- Does anyone with experience on Windows ISR hook notice any issues on the hook stub code? I believe the issue is within the hook stub code.
- Any explanations on why the ISR hook would work only when the breakpoint is set at the entrypoint of the hook stub code? The weird thing is, the hook stub code and the hook implementation will work properly only when the breakpoint is set at the entrypoint of the hook stub code and when I step into the code.
P/S: I totally understand hooking ISR on Windows is strongly not recommended and Windows PG does not like it too. Anyway, I would appreciate if anyone with experience on Windows ISR hook could shed some lights on how to implement a proper hook stub code as we will deal with Windows PG later on using the known bypass techniques.