同志们好哇,好久不见,我再更新一些干货给你们,至于为什么要研究这个?肯定是自己做DLP产品,自己的产品能优化就要偷学一下别人的思路,我自己目前是二种思路,一种是内核层的管控(minifilter,附加过滤设备,KMDF)这种管控,我们想一想尽量能用应用层解决还是通过应用层进行解决,我们今天主要是讲一下应用层进行USB管控的思路。
这还用问吗,之前我也想通过驱动层,直接禁用设备之类的,可惜哇,怪我太菜了,各种驱动写完了,GITHUB上找了一堆代码都不行,妈的生气,看看市面上有什么USB的管控软件,没想到哇,还真就是找到了一个可以用的软件,也没有用什么驱动,直接打开我们的IDA分析一下。
我们如何找到分析的要点,我们首先就先了解一下,WINDOWS 设备相关操作的API,链接我也贴上来了微软链接,我们首先通过SetupDiGetClassDevsW这个函数来寻找一下调用,看看人家软件是怎么操作的,直接抄袭之就可以了,
如图所示,就是函数的大概直接流程 获取设备的信息,由于是USB存储设备的管控,我们主要就是获取DISK信息, 然后枚举我们的设备信息,CM_Get_Device_IDW函数来获取USB存储的父对象,在通过CM_Get_DevNode_Status函数来获取USB存储设备的状态,如果状态是被禁用,就不进行下面的处理,
最后通过这SetupDiSetClassInstallParamsW,SetupDiCallClassInstaller,来进行设备的禁用,可是我不太理解,它为什么用0X12这个DIF_ALLOWINSTALL,没有进行动态的分析,不太理解它设置了什么状态,因此我采用的是网上通用的禁用或者启动设备,链接在此
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/
/
ListDevice.cpp : 此文件包含
"main"
函数。程序执行将在此处开始并结束。
/
/
int
enum_usb_device_info()
{
int
i
=
0
;
int
res
=
0
;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData
=
{ sizeof(DeviceInfoData) };
/
/
get device
class
information handle
hDevInfo
=
SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE,
0
,
0
, DIGCF_PRESENT );
if
(hDevInfo
=
=
INVALID_HANDLE_VALUE)
{
res
=
GetLastError();
return
res;
}
/
/
enumerute device information
DWORD required_size
=
0
;
for
(i
=
0
; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i
+
+
)
{
DWORD DataT;
char friendly_name[
2046
]
=
{
0
};
DWORD buffersize
=
2046
;
DWORD req_bufsize
=
0
;
char DeviceBuf[
4096
]
=
{
0
};
char DeviceParent[
4096
]
=
{
0
};
auto res
=
CM_Get_Device_IDA(DeviceInfoData.DevInst, DeviceBuf,
4096
,
0
);
if
(!res)
{
DEVNODE pdnDevInst
=
0
;
CM_Get_Parent(&pdnDevInst, DeviceInfoData.DevInst,
0
);
CM_Get_Device_IDA(pdnDevInst, DeviceParent,
4096
,
0
);
if
(strstr(DeviceParent,
"USB"
)!
=
nullptr)
{
ULONG pulStatus
=
0
;
ULONG pulProblemNumber
=
0
;
res
=
CM_Get_DevNode_Status(&pulStatus, &pulProblemNumber, pdnDevInst,
0
);
if
(!res)
{
SP_PROPCHANGE_PARAMS propChange
=
{ sizeof(SP_CLASSINSTALL_HEADER) };
propChange.ClassInstallHeader.InstallFunction
=
DIF_PROPERTYCHANGE;
propChange.Scope
=
DICS_FLAG_GLOBAL;
propChange.StateChange
=
DICS_DISABLE;
res
=
SetupDiSetClassInstallParams
(
hDevInfo,
&DeviceInfoData,
(SP_CLASSINSTALL_HEADER
*
)&propChange,
sizeof(propChange)
);
SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData);
}
}
}
/
/
get device description information
if
(!SetupDiGetDeviceRegistryPropertyA(hDevInfo, &DeviceInfoData, SPDRP_SERVICE, &DataT, (LPBYTE)friendly_name, buffersize, &req_bufsize))
{
res
=
GetLastError();
continue
;
}
char temp[
512
]
=
{
0
};
sprintf_s(temp,
512
,
"USB device %d: %s"
, i, friendly_name);
puts(temp);
}
return
0
;
}
int
main()
{
enum_usb_device_info();
std::cout <<
"Hello World!\n"
;
}