原以为是杀毒软件冲突 仔细分析发现...
正在撰写中... 稍等...
2017-12-20 22:15更新:
起因
下班回来闲着 然后就开个虚拟机玩玩... 想调戏avast来着...
就切换浏览网页的功夫 神奇的一幕发生了 蓝屏...
和普通用户不一样 我的内心是兴奋的...
终于.......有好东西玩了..
遂开机 耐心等待那么1分钟左右 便会蓝屏 那么一开始安装怎么没蓝屏呢 也折腾了最起码半小时以上 难道是后台更新了吗...
怀疑
会不会是avast搞的鬼? 不过马上被我否定了 因为仔细一想安装完avast之后还重启好多次 都没此问题
动手
再次重启挂上windbg 蓝屏后执行k
命令:
# Child-SP RetAddr Call Site
00 ffffbd01`58866df8 fffff803`b3c86f22 nt!DbgBreakPointWithStatus
01 ffffbd01`58866e00 fffff803`b3c867d2 nt!KiBugCheckDebugBreak+0x12
02 ffffbd01`58866e60 fffff803`b3bf60d7 nt!KeBugCheck2+0x922
03 ffffbd01`58867570 fffff803`b3c4d9de nt!KeBugCheckEx+0x107
04 ffffbd01`588675b0 fffff803`b3af9149 nt!MiCheckFatalAccessViolation+0xbcae2
05 ffffbd01`588675f0 fffff803`b3af7f6b nt!MiResolvePageTablePage+0x349
06 ffffbd01`588676c0 fffff803`b3bff872 nt!MmAccessFault+0x2eb
07 ffffbd01`588678b0 fffff807`7912c66a nt!KiPageFault+0x132
08 ffffbd01`58867a40 fffff807`79130358 sysdiag+0x1c66a
09 ffffbd01`58867b00 fffff807`7913c76d sysdiag+0x20358
0a ffffbd01`58867b30 fffff803`b35d2370 sysdiag+0x2c76d
0b ffffbd01`58867b60 fffff803`b3b43a37 hrwfpdrv+0x2370
0c ffffbd01`58867c10 fffff803`b3bfb456 nt!PspSystemThreadStartup+0x47
0d ffffbd01`58867c60 00000000`00000000 nt!KiStartSystemThread+0x16
很明显可以看出在地址:08 ffffbd0158867a40 fffff807
79130358 sysdiag+0x1c66a
来我们看下此地址处汇编上下文:
fffff806`ecafc654 488b03 mov rax,qword ptr [rbx]
fffff806`ecafc657 488b7e10 mov rdi,qword ptr [rsi+10h]
fffff806`ecafc65b 4c896c2478 mov qword ptr [rsp+78h],r13
fffff806`ecafc660 4c896c2470 mov qword ptr [rsp+70h],r13
fffff806`ecafc665 4c896c2468 mov qword ptr [rsp+68h],r13
fffff806`ecafc66a 48898734020000 mov qword ptr [rdi+234h],rax 此处引发蓝屏
fffff806`ecafc671 488b4308 mov rax,qword ptr [rbx+8]
fffff806`ecafc675 4889873c020000 mov qword ptr [rdi+23Ch],rax
fffff806`ecafc67c 418bc5 mov eax,r13d
fffff806`ecafc67f 394630 cmp dword ptr [rsi+30h],eax
fffff806`ecafc682 4c896c2460 mov qword ptr [rsp+60h],r13
fffff806`ecafc687 4c896c2458 mov qword ptr [rsp+58h],r13
执行r
:
kd> r
rax=0000000000000000 rbx=0000000000000003 rcx=0000000000000003
rdx=000000000000008a rsi=0000000000000000 rdi=0000000000000000
rip=fffff801fd5f3a40 rsp=ffff858084272df8 rbp=ffff858084272f60
r8=fffff801fc472180 r9=0000000000000000 r10=ffff858084272bf0
r11=0000000000000000 r12=000000000000001a r13=0000000000004477
r14=0000000000000065 r15=0000000000000003
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000286
很明显 是由于rdi引起的内存写入错误...
在习惯性的执行下!analyze -v
:
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
MEMORY_MANAGEMENT (1a)
# Any other values for parameter 1 must be individually examined.
Arguments:
Arg1: 0000000000004477, A driver tried to write to an unallocated address in the
user space of the system process. Parameter 2 contains the
address of the attempted write.
Arg2: 0000000001d37bbe
Arg3: 0000000000000000
Arg4: 0000000000000000
Debugging Details:
------------------
DUMP_CLASS: 1
DUMP_QUALIFIER: 0
BUILD_VERSION_STRING: 15063.0.amd64fre.rs2_release.170317-1834
DUMP_TYPE: 0
BUGCHECK_P1: 4477
BUGCHECK_P2: 1d37bbe
BUGCHECK_P3: 0
BUGCHECK_P4: 0
BUGCHECK_STR: 0x1a_4477
CPU_COUNT: 1
CPU_MHZ: c78
CPU_VENDOR: GenuineIntel
CPU_FAMILY: 6
CPU_MODEL: 5e
CPU_STEPPING: 3
CPU_MICROCODE: 6,5e,3,0 (F,M,S,R) SIG: BA'00000000 (cache) BA'00000000 (init)
DEFAULT_BUCKET_ID: WIN8_DRIVER_FAULT
PROCESS_NAME: System
CURRENT_IRQL: 2
ANALYSIS_SESSION_HOST: DESKTOP-E00AFJN
ANALYSIS_SESSION_TIME: 12-20-2017 20:03:48.0329
ANALYSIS_VERSION: 10.0.15063.468 amd64fre
TRAP_FRAME: ffffbd01588678b0 -- (.trap 0xffffbd01588678b0)
.trap 0xffffbd01588678b0
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=ffffab09bacaa010 rbx=0000000000000000 rcx=fffff8077916a950
rdx=fffff8077916a950 rsi=0000000000000000 rdi=0000000000000000
rip=fffff8077912c66a rsp=ffffbd0158867a40 rbp=ffffab09b7aa8760
r8=0000000000000000 r9=0000000000000000 r10=fffff8077916a950
r11=ffffab09baeb41b0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei ng nz na po nc
sysdiag+0x1c66a:
fffff807`7912c66a 48898734020000 mov qword ptr [rdi+234h],rax ds:00000000`00000234=????????????????
.trap
Resetting default scope
LAST_CONTROL_TRANSFER: from fffff803b3c86f22 to fffff803b3bfba40
STACK_TEXT:
ffffbd01`58866df8 fffff803`b3c86f22 : 00000000`00004477 00000000`0000001a ffffbd01`58866f60 fffff803`b3b39c60 : nt!DbgBreakPointWithStatus
ffffbd01`58866e00 fffff803`b3c867d2 : 00000000`00000003 ffffbd01`58866f60 fffff803`b3d38160 00000000`0000001a : nt!KiBugCheckDebugBreak+0x12
ffffbd01`58866e60 fffff803`b3bf60d7 : fffff803`b2a04800 ffff30c7`b6a48474 00000000`00000000 ffffab09`b97cf140 : nt!KeBugCheck2+0x922
ffffbd01`58867570 fffff803`b3c4d9de : 00000000`0000001a 00000000`00004477 00000000`01d37bbe 00000000`00000000 : nt!KeBugCheckEx+0x107
ffffbd01`588675b0 fffff803`b3af9149 : ffffbd01`58867828 00000000`7dbd6d47 00000000`406f0088 fffff803`b3ad89fa : nt!MiCheckFatalAccessViolation+0xbcae2
ffffbd01`588675f0 fffff803`b3af7f6b : 00000000`00000002 00000000`01d37bbe ffffbd01`58867820 ffffab09`00000000 : nt!MiResolvePageTablePage+0x349
ffffbd01`588676c0 fffff803`b3bff872 : ffffab09`b8eb51a0 00000000`00000000 00000000`00000000 fffff807`7916bba8 : nt!MmAccessFault+0x2eb
ffffbd01`588678b0 fffff807`7912c66a : ffffab09`baeb41b0 ffffab09`b7aa8760 ffffab09`b7aa8740 00000000`000004e0 : nt!KiPageFault+0x132
ffffbd01`58867a40 fffff807`79130358 : 00000000`000004e0 00000000`00000000 ffffab09`b7aa8740 00000000`000002f8 : sysdiag+0x1c66a
ffffbd01`58867b00 fffff807`7913c76d : 00000000`00000000 fffff803`b35d2650 fffff803`b35d2270 00000000`00000000 : sysdiag+0x20358
ffffbd01`58867b30 fffff803`b35d2370 : ffffab09`b8ec4b38 00000000`00000000 00000000`00000000 00000000`00000000 : sysdiag+0x2c76d
ffffbd01`58867b60 fffff803`b3b43a37 : ffffab09`b97cf040 ffffffff`ff676980 00000000`00000080 fffff803`b35d2270 : hrwfpdrv+0x2370
ffffbd01`58867c10 fffff803`b3bfb456 : fffff803`b2a01180 ffffab09`b97cf040 fffff803`b3b439f0 00000000`00000000 : nt!PspSystemThreadStartup+0x47
ffffbd01`58867c60 00000000`00000000 : ffffbd01`58868000 ffffbd01`58862000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x16
STACK_COMMAND: kb
THREAD_SHA1_HASH_MOD_FUNC: 3a895aaebe25ee46d02cb1b232797cb8387156d4
THREAD_SHA1_HASH_MOD_FUNC_OFFSET: dbd867a4abfaba47564457c4326e181b32526e2a
THREAD_SHA1_HASH_MOD: f88e80decddedfd714964ecc72240a246955dd39
FOLLOWUP_IP:
sysdiag+1c66a
fffff807`7912c66a 48898734020000 mov qword ptr [rdi+234h],rax
FAULT_INSTR_CODE: 34878948
SYMBOL_STACK_INDEX: 8
SYMBOL_NAME: sysdiag+1c66a
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: sysdiag
IMAGE_NAME: sysdiag.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 5a0c0ca0
BUCKET_ID_FUNC_OFFSET: 1c66a
FAILURE_BUCKET_ID: 0x1a_4477_sysdiag!unknown_function
BUCKET_ID: 0x1a_4477_sysdiag!unknown_function
PRIMARY_PROBLEM_CLASS: 0x1a_4477_sysdiag!unknown_function
TARGET_TIME: 2017-12-20T12:01:35.000Z
OSBUILD: 15063
OSSERVICEPACK: 0
SERVICEPACK_NUMBER: 0
OS_REVISION: 0
SUITE_MASK: 272
PRODUCT_TYPE: 1
OSPLATFORM_TYPE: x64
OSNAME: Windows 10
OSEDITION: Windows 10 WinNt TerminalServer SingleUserTS
OS_LOCALE:
USER_LCID: 0
OSBUILD_TIMESTAMP: 2017-03-18 12:40:44
BUILDDATESTAMP_STR: 170317-1834
BUILDLAB_STR: rs2_release
BUILDOSVER_STR: 10.0.15063.0.amd64fre.rs2_release.170317-1834
ANALYSIS_SESSION_ELAPSED_TIME: 11e3
ANALYSIS_SOURCE: KM
FAILURE_ID_HASH_STRING: km:0x1a_4477_sysdiag!unknown_function
FAILURE_ID_HASH: {5c06afd1-a6da-3115-f347-42a303cc8ca5}
Followup: MachineOwner
---------
ida
最帅的楼主:来 谁还没有ida 7.0的给我发邮件
..... .. .. .. .
甲:我我我我 大佬 我啊
乙:看这里 看这里……*){擦“”》|><
丙:大佬 7.0我有了 ida更新了 你看...
戊:嘿嘿嘿...
...
...
开玩笑的 拒绝盗版 支持正版 从你做起....
- 来 重启windows 对 重启 按照分析来看 我们需要
hrwfpdrv
、sysdiag
这俩个驱动 考验手速的时候到了...
sysdiag
ida
打开sysdiag.sys
再键盘g+000000014001C66A
:
rdi是rsi的儿子 rsi是rcx的儿子
或者说
rcx生下了rsi rsi生下了rdi
看不懂?没关系 看动图 看鼠标箭头:
然后接下来分析其它几个函数 很简单 给个伪代码算了你看行不行:
sysdiag.sys:
sub_14002C760(rcx){
sub_140020340(rcx){
sub_14001C5C0(rcx){
//rdi + 0x234 (rdi == 0)
mov [rdi+234h], rax
}
}
}
很明显 能发现谁是罪魁祸首了...
断断续续的在写 再稍等... 洗个澡先...
2017-12-20 23:27更新:
hrwfpdrv
ida打开hrwfpdrv.sys
再键盘g+000000014000236D
:
rcx是rbx的儿子 rbx是rdx的儿子 rdx是rcx的儿子 rcx是qword_140008000的儿子
....
咱还是看动图吧:
很明显我们要看这个 qword_140008000 发现其来自:
NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
struc_FT *v2; // rbx
PDRIVER_OBJECT v3; // rsi
NTSTATUS result; // eax
NTSTATUS v5; // edi
PVOID v6; // rax
UNICODE_STRING DestinationString; // [rsp+40h] [rbp-18h]
PDEVICE_OBJECT DeviceObject; // [rsp+70h] [rbp+18h]
v2 = 0i64;
v3 = DriverObject;
ExInitializeNPagedLookasideList(&ListHead, 0i64, 0i64, 0, 0x76Cui64, 0, 0);
RtlInitUnicodeString(&DestinationString, L"\\Device\\HR_WFP_BASE_DRV");
result = IoCreateDevice(v3, 0xF0u, &DestinationString, 0x12u, 0, 0, &DeviceObject);
v5 = result;
if ( result >= 0 )
{
qword_140008008 = (PDRIVER_EXTENSION)DeviceObject->DeviceExtension;
LODWORD(qword_140008008->DriverObject) = 1;
HIDWORD(qword_140008008->DriverObject) = 305419896;
LODWORD(qword_140008008->AddDevice) = 0;
*(_QWORD *)&qword_140008008[5].Count = sub_140005650;
qword_140008008[5].AddDevice = (PDRIVER_ADD_DEVICE)sub_140005710;
v3->MajorFunction[0] = (PDRIVER_DISPATCH)&sub_140001FD0;
v3->MajorFunction[2] = (PDRIVER_DISPATCH)&sub_140001FD0;
v6 = ExAllocatePoolWithTag(0, 0x118ui64, 0);
if ( v6 )
{
v2 = (struc_FT *)sub_140002140((__int64)v6);
qword_140008000 = v2; //看这里
}
else
{
qword_140008000 = 0i64;
}
sub_1400053A0(v2->field_0, (__int64)v3, (__int64)DeviceObject);
result = v5;
}
return result;
}
结合上下文(注意动图) 我们可以得出 qword140008000 是个结构体 大小0x118
然后里面 居然初始化为0 为0... 我没有发现其它有给赋值的地方... 所以这就是引起蓝屏的原因了
我们回到000000014000236D
处:
.text:0000000140002360
.text:0000000140002360 loc_140002360:
.text:0000000140002360 mov rax, cs:qword_140008008
.text:0000000140002367 xor edx, edx
.text:0000000140002369 mov rcx, [rbx+8]
.text:000000014000236D call qword ptr [rax+48h]
.text:0000000140002370 test eax, eax
.text:0000000140002372 jz short loc_1400
发现call sub_14002C760
来自call qword ptr [rax+48h]
即qword_140008008 + 0x48
而我们可以在上面的DriverEntry
找到它 发现它是来自IoCreateDevice
按名字创建设备 具体啥用我也不大清楚 虽然没事看了源码和msdn看到过N次 但自己没用过啊 而且工作中都没有驱动... 没关系 我认识汇编啊 我可以凭感觉啊...
我们来分析一波...
它既然在偏移0x48 可以打call 那么qword_140008008 + 0x48
必定有个地方写入 最有可的地方在sysdiag.sys
那么我们切换到sysdiag.sys
现在做什么 ?
我们可以发现DriverEntry
中有字符串 \\Device\\HR_WFP_BASE_DRV
搜索之 发现
.rdata:000000014003FA88 text "UTF-16LE", '\Device\HR_WFP_BASE_DRV',0
切到引用函数sub_1400324B0
作为一个资深大佬 你懂我的意思吧:
void __fastcall sub_1400324B0(PVOID StartContext)
{
UNICODE_STRING DestinationString; // [rsp+20h] [rbp-18h]
PFILE_OBJECT FileObject; // [rsp+48h] [rbp+10h]
PDEVICE_OBJECT DeviceObject; // [rsp+50h] [rbp+18h]
LARGE_INTEGER Interval; // [rsp+58h] [rbp+20h]
Interval.QuadPart = -30000000i64;
RtlInitUnicodeString(&DestinationString, L"\\Device\\HR_WFP_BASE_DRV");
while ( IoGetDeviceObjectPointer(&DestinationString, 0x1F01FFu, &FileObject, &DeviceObject) < 0 )
KeDelayExecutionThread(0, 0, &Interval);
ObfDereferenceObject(FileObject);
sub_14002D5F0((__int64)DeviceObject->DeviceExtension);
PsTerminateSystemThread(0);
}
循环接收对象指针
我们又可以看到sub_14002D5F0((__int64)DeviceObject->DeviceExtension);
使用了设备扩展指针
点击进去 你懂我的意思吧:
__int64 __fastcall sub_14002D5F0(__int64 a1)
{
__int64 result; // rax
if ( a1 )
{
qword_14005DBC8 = a1;
if ( *(_DWORD *)(a1 + 4) == 305419896 )
{
*(_QWORD *)(a1 + 16) = sub_14002DCA0;
*(_QWORD *)(qword_14005DBC8 + 24) = sub_14002DB60;
*(_QWORD *)(qword_14005DBC8 + 32) = sub_14002DDE0;
*(_QWORD *)(qword_14005DBC8 + 40) = sub_14002E030;
*(_QWORD *)(qword_14005DBC8 + 48) = sub_14002DF30;
*(_QWORD *)(qword_14005DBC8 + 56) = sub_14002E120;
*(_QWORD *)(qword_14005DBC8 + 64) = sub_14002D460;
*(_QWORD *)(qword_14005DBC8 + 72) = sub_14002C760; // 这里 看这里
*(_QWORD *)(qword_14005DBC8 + 80) = &sub_14002D1D0;
*(_QWORD *)(qword_14005DBC8 + 88) = &sub_14002CF80;
*(_QWORD *)(qword_14005DBC8 + 96) = &sub_14002CE00;
*(_QWORD *)(qword_14005DBC8 + 104) = sub_14002D2E0;
*(_QWORD *)(qword_14005DBC8 + 112) = sub_14002D2F0;
*(_QWORD *)(qword_14005DBC8 + 120) = &sub_14002CC60;
*(_QWORD *)(qword_14005DBC8 + 128) = sub_14002C740;
*(_QWORD *)(qword_14005DBC8 + 136) = sub_14002D820;
*(_QWORD *)(qword_14005DBC8 + 144) = sub_14002D490;
*(_QWORD *)(qword_14005DBC8 + 152) = sub_14002D480;
*(_QWORD *)(qword_14005DBC8 + 160) = sub_14002D470;
*(_QWORD *)(qword_14005DBC8 + 168) = sub_14002D9C0;
*(_QWORD *)(qword_14005DBC8 + 176) = sub_14002D9E0;
*(_QWORD *)(qword_14005DBC8 + 184) = sub_14002D9D0;
*(_QWORD *)(qword_14005DBC8 + 192) = sub_14002DA20;
*(_QWORD *)(qword_14005DBC8 + 200) = sub_14002DA10;
*(_QWORD *)(qword_14005DBC8 + 224) = sub_1400211A0;
*(_QWORD *)(qword_14005DBC8 + 232) = sub_140021220;
result = qword_14005DBC8;
*(_DWORD *)(qword_14005DBC8 + 8) = 1;
dword_14005DBC0 = 1;
}
}
return result;
}
结束
那么这俩个驱动之间的工作流程是:
分析才一个小时左右 写帖子前后断断续续三四个小时...
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!