我们这里以腾讯的TSSysKit.sys驱动举例。金山的对应的驱动是kisapi.sys 。360对应的是bapidrv.sys
1 逆向相关的注册表底层操作相关的函数
(驱动的大小) 1 s -d b21c4000 L2b000 nt!cmpcallbackcount; 2 s -d b21c4000 L2b000 nt!CmDeleteKey; 3 s -d b21c4000 L2b000 nt!CmDeleteValueKey; 4 s -d b21c4000 L2b000 nt!CmEnumerateKey; 5 s -d b21c4000 L2b000 nt!CmEnumerateValueKey; 6 s -d b21c4000 L2b000 nt!CmQueryValueKey; 7 s -d b21c4000 L2b000 nt!CmSetValueKey (驱动加载的基地址) 9 kd> s -d b21c4000 L2b000 nt!cmpcallbackcount; 10 b21e7520 8067d000 80635556 80632514 8063213a ..g.VUc..%c.:!c. 11 kd> s -d b21c4000 L2b000 nt!CmDeleteKey; 12 b21e7524 80635556 80632514 8063213a 00000000 VUc..%c.:!c..... 13 b21e75a4 80635556 e1bed7f0 8063213a 00000000 VUc.....:!c..... 14 b21e75cc 80635556 825da2d0 00000000 000000bc VUc...]......... 15 kd> s -d b21c4000 L2b000 nt!CmDeleteValueKey; 16 b21e75c0 80631f60 80633aac 00000000 80635556 `.c..:c.....VUc. 17 kd> s -d b21c4000 L2b000 nt!CmEnumerateKey; 18 b21e752c 8063213a 00000000 00000000 00000000 :!c............. 19 b21e75ac 8063213a 00000000 80638392 8001003b :!c.......c.;... 20 kd> s -d b21c4000 L2b000 nt!CmEnumerateValueKey; 21 b21e75e0 80632212 00000001 805ea292 0000020c ."c.......^..... 22 kd> s -d b21c4000 L2b000 nt!CmQueryValueKey; 23 b21e7528 80632514 8063213a 00000000 00000000 .%c.:!c......... 24 b21e75bc 80632514 80631f60 80633aac 00000000 .%c.`.c..:c..... 25 kd> s -d b21c4000 L2b000 nt!CmSetValueKey 26 b21e75c4 80633aac 00000000 80635556 825da2d0 .:c.....VUc...].或者使用这样的命令更简洁s -d driver_module_name L2b000 nt!cmpcallbackcount;比如说这样的。s -d bapidrv L2b000 nt!cmpcallbackcount;
当然我们也可以把一些相关的nt函数放进去比方说这样的。
s -d bapidrv L2b000 nt!NtDeleteKey; s -d bapidrv L2b000 nt!NtDeleteValueKey; s -d bapidrv L2b000 nt!NtEnumerateKey; s -d bapidrv L2b000 nt!NtEnumerateValueKey; s -d bapidrv L2b000 nt!NtQueryValueKey; s -d bapidrv L2b000 nt!NtSetValueKey; s -d bapidrv L2b000 nt!NtCreateKey; s -d bapidrv L2b000 nt!NtOpenKey
1 kd> s -d bapidrv L2b000 nt!NtDeleteKey; 2 b179f500 80624c16 80624de6 00000000 00000001 .Lb..Mb......... 3 kd> s -d bapidrv L2b000 nt!NtDeleteValueKey; 4 b179f504 80624de6 00000000 00000001 00000000 .Mb............. 5 kd> s -d bapidrv L2b000 nt!NtEnumerateKey; 6 b179f4f8 80624fc6 80625230 80624c16 80624de6 .Ob.0Rb..Lb..Mb. 7 kd> s -d bapidrv L2b000 nt!NtEnumerateValueKey; 8 b179f4fc 80625230 80624c16 80624de6 00000000 0Rb..Lb..Mb..... 9 kd> s -d bapidrv L2b000 nt!NtQueryValueKey; 10 b179f4f4 806229be 80624fc6 80625230 80624c16 .)b..Ob.0Rb..Lb. 11 kd> s -d bapidrv L2b000 nt!NtSetValueKey 12 b179f4f0 80622d0c 806229be 80624fc6 80625230 .-b..)b..Ob.0Rb. 13 kd> s -d bapidrv L2b000 nt!NtCreateKey; 14 b179f4e8 80624786 80625b58 80622d0c 806229be .Gb.X[b..-b..)b. 15 kd> s -d bapidrv L2b000 nt!NtOpenKey 16 b179f4ec 80625b58 80622d0c 806229be 80624fc6 X[b..-b..)b..Ob.
得到了一些dword之后我们就完全可以通过IDA进行栈回溯定位相关的IOCTL_CODE了。变得特别简单了。
我们比较容易的就得到了下面的对应关系 以及相应的对应的ioctl_code
1 1 BRegCloseKey 2 2 BRegCreateKey BRegCreateKeyEx BRegCreateKeyW BRegCreateKeyExW ---?ObOpenObjectByName---?ObReferenceObjectByHandle---?TempHandle = (HANDLE)LongToHandle(KeyBody->Type); 3 3 BregDeleteKey BregDeleteKeyEx BregDeleteKeyW BregDeleteKeyExW 4 ---? CmDeleteKey 5 4 BRegDeleteValue BRegDeleteValueW (0X889928a4) 6 ---?CmDeleteValueKey 7 5 BRegEnumKey BRegEnumKeyEx BRegEnumKeyW BRegEnumKeyExW 8 ---?CmEnumerateKey 9 6 BRegEnumValue BRegEnumValueW 10 ---?CmEnumerateValueKey 11 7 BRegOpenKey BRegOpenKeyEx BRegOpenKeyW BRegOpenKeyExW (0x8899288c) 12 ---? ObOpenObjectByName---?ObReferenceObjectByHandle---? TempHandle = (HANDLE)LongToHandle(KeyBody->Type); 13 8 BRegQueryValueEx BRegQueryValueExW (0x88992890) 14 ---? CmQueryValueKey 15 9 BRegSetValueEx BRegSetValueExW 16 ---? CmSetValueKey
我们可以使用windbg的条件断点命令来验证我们逆向得到的ioctl_code对不对
1 bp nt!NtDeviceIoControlFile+0x5 ".if (poi(@ebp+0x1c)=0x8899288c) {} .else {gc}" 2 bp nt!NtDeviceIoControlFile+0x5 ".if (poi(@ebp+0x1c)=0x88992890) {} .else {gc}" 3 bp nt!NtDeviceIoControlFile+0x5 ".if (poi(@ebp+0x1c)=0x889928a4) {} .else {gc}" 4 bp nt!NtDeviceIoControlFile+0x5 ".if (poi(@ebp+0x1c)=0x88992888) {} .else {gc}" 5 bp nt!NtDeviceIoControlFile+0x5 ".if (poi(@ebp+0x1c)=0x88992894) {} .else {gc}"
比方说我们逆向得到了 管家的删除注册表的ctl_code。 我们直接用管家删除一个文件 ,用上面的条件断点命令就可以验证我们逆向的对不对了。
我们同时可以使用下面的简单的条件断点的命令观察完整的底层注册表操纵接口栈回溯
bp /t @$thread nt!CmDeleteValueKey bp /t @$proc nt!CmDeleteValueKey
时间: 2024-09-30 14:33:39