-
-
[原创]TX管家驱动--TSKsp
-
发表于:
2010-11-20 02:10
13400
-
TSKsp应该算是TX管家的主要驱动了(貌似最新版本又出了一个文件加密功能,将近200K的一个驱动,没仔细看,从里面的某个字符串"TrueCrypt“基本能猜个大概了)。
下面来看TSKsp的实现。
1.Shadow SSDT Hook
首先是一个PsSetCreateProcessNotifyRoutine,设置一个进程创建回调函数。
在回调函数中,当发现Winlogon.exe进程启动时,就初始化一些与Shadow SSDT有关的信息,/*由于一些没有GUI的进程不能访问Shadow SSDT表*/(此处错误,具体看3楼),这里就使用KeStackAttachProcess附加到Winlogon.exe,以访问Shadow SSDT表。要得到的信息无外乎这些:Shadow SSDT表基址,相应服务函数的服务号。
表基址:这里就是从KeAddSystemServiceTable函数里面找,代码可搜到。
服务号:这里是驱动自己建立了一个表,然后根据不同系统版本,获得相应服务号,这个表如下。
typedef struct _SHADOW_INDEX
{
ULONG Index_NtUserFindWindowEx,
ULONG Index_NtUserBuildHwndList,
ULONG Index_NtUserQueryWindow,
ULONG Index_NtUserGetForegroundWindow,
ULONG Index_NtUserSetParent,
ULONG Index_NtUserSetWindowLong,
ULONG Index_NtUserMoveWindow,
ULONG Index_NtUserSetWindowPos,
ULONG Index_NtUserSetWindowPlacement,
ULONG Index_NtUserShowWindow,
ULONG Index_NtUserShowWindowAsync,
ULONG Index_NtUserSendInput
}SHADOW_INDEX,*PSHADOW_INDEX;
SHADOW_INDEX ShadowIndex[9];
这里为什么是9,因为驱动里面获得版本号如下:
enum VERSION
{
Win2000 = 1,
WinXP = 2,
Win2003 = 3,
Vista = 4,
Win7 = 7,
Win7SP1 = 8
};
ShadowIndex[0]
.data:0001F590 dd 0
.data:0001F594 dd 0
.data:0001F598 dd 0
.data:0001F59C dd 0
.data:0001F5A0 dd 0
.data:0001F5A4 dd 0
.data:0001F5A8 dd 0
.data:0001F5AC dd 0
.data:0001F5B0 dd 0
.data:0001F5B4 dd 0
.data:0001F5B8 dd 0
.data:0001F5BC dd 0
ShadowIndex[Win2000]
.data:0001F5C0 dd 170h
.data:0001F5C4 dd 12Eh
.data:0001F5C8 dd 1D2h
.data:0001F5CC dd 189h
.data:0001F5D0 dd 1FEh
.data:0001F5D4 dd 20Dh
.data:0001F5D8 dd 1C1h
.data:0001F5DC dd 20Fh
.data:0001F5E0 dd 20Eh
.data:0001F5E4 dd 218h
.data:0001F5E8 dd 219h
.data:0001F5EC dd 1E1h
ShadowIndex[WinXP]
.data:0001F5F0 dd 17Ah
.data:0001F5F4 dd 138h
.data:0001F5F8 dd 1E3h
.data:0001F5FC dd 194h
.data:0001F600 dd 211h
.data:0001F604 dd 220h
.data:0001F608 dd 1D1h
.data:0001F60C dd 222h
.data:0001F610 dd 221h
.data:0001F614 dd 22Bh
.data:0001F618 dd 22Ch
.data:0001F61C dd 1F6h
ShadowIndex[Win2003]
.data:0001F620 dd 179h
.data:0001F624 dd 137h
.data:0001F628 dd 1E1h
.data:0001F62C dd 193h
.data:0001F630 dd 20Eh
.data:0001F634 dd 21Ch
.data:0001F638 dd 1D0h
.data:0001F63C dd 21Eh
.data:0001F640 dd 21Dh
.data:0001F644 dd 227h
.data:0001F648 dd 228h
.data:0001F64C dd 1F4h
ShadowIndex[Vista]
.data:0001F650 dd 187h
.data:0001F654 dd 142h
.data:0001F658 dd 1F8h
.data:0001F65C dd 1A2h
.data:0001F660 dd 226h
.data:0001F664 dd 236h
.data:0001F668 dd 1E4h
.data:0001F66C dd 238h
.data:0001F670 dd 237h
.data:0001F674 dd 243h
.data:0001F678 dd 244h
.data:0001F67C dd 20Dh
ShadowIndex[Vista]
.data:0001F680 dd 187h
.data:0001F684 dd 142h
.data:0001F688 dd 1F8h
.data:0001F68C dd 1A2h
.data:0001F690 dd 226h
.data:0001F694 dd 236h
.data:0001F698 dd 1E4h
.data:0001F69C dd 238h
.data:0001F6A0 dd 237h
.data:0001F6A4 dd 243h
.data:0001F6A8 dd 244h
.data:0001F6AC dd 20Dh
ShadowIndex[Vista]
.data:0001F6B0 dd 187h
.data:0001F6B4 dd 142h
.data:0001F6B8 dd 1F8h
.data:0001F6BC dd 1A2h
.data:0001F6C0 dd 226h
.data:0001F6C4 dd 236h
.data:0001F6C8 dd 1E4h
.data:0001F6CC dd 238h
.data:0001F6D0 dd 237h
.data:0001F6D4 dd 243h
.data:0001F6D8 dd 244h
.data:0001F6DC dd 20Dh
ShadowIndex[Win7]
.data:0001F6E0 dd 18Ch
.data:0001F6E4 dd 143h
.data:0001F6E8 dd 203h
.data:0001F6EC dd 1A7h
.data:0001F6F0 dd 230h
.data:0001F6F4 dd 242h
.data:0001F6F8 dd 1EFh
.data:0001F6FC dd 244h
.data:0001F700 dd 243h
.data:0001F704 dd 24Fh
.data:0001F708 dd 250h
.data:0001F70C dd 218h
ShadowIndex[Win7SP1]
.data:0001F710 dd 18Ch
.data:0001F714 dd 143h
.data:0001F718 dd 203h
.data:0001F71C dd 1A7h
.data:0001F720 dd 230h
.data:0001F724 dd 242h
.data:0001F728 dd 1EFh
.data:0001F72C dd 244h
.data:0001F730 dd 243h
.data:0001F734 dd 24Fh
.data:0001F738 dd 250h
.data:0001F73C dd 218h
版本号里面没有5,6这两个索引,本来应该定义成VistaSP1和VistaSP2,但由于它们的这些服务号都相同,因此就都定义成了Vista = 4。
这些信息又是以何种方式存储的,定义的结构如下:
typedef struct _SHADOW_FUNCTION_INFO
{
char *FunctionName;
PVOID MyFunction;
ULONG FunctionIndex;
LONG isRealFunctionValid;
LONG GotOriginalFunctionInTable;
PVOID OriginalFunctionInTable;
PVOID RealFunction;
}SHADOW_FUNCTION_INFO,*PSHADOW_FUNCTION_INFO;
需要解释一下其中几个成员的意义:
MyFunction,就是进行Hook替换的函数;
FunctionIndex,服务号;
RealFunction,这个函数是从win32k.sys文件里读出来的真实函数地址,也就是使用ZwCreateSection,ZwMapViewOfSection,然后定位到Shadow SSDT表,,从文件读取表中的地址;
isRealFunctionValid,判断上面获取到的RealFunction是否在win32k的映像范围中;
OriginalFunctionInTable,当进行Shadow SSDT Hook时,这个地址是从表中取出的值,这个函数又可能也被其他驱动Hook过,所以这个值可能是其他驱动中的某个函数地址;
GotOriginalFunctionInTable,判断是否已经从Shadow SSDT表中取得OriginalFunctionInTable。
这样构成SHADOW_FUNCTION_INFO ShadowFunction[12];每一项与SHADOW_INDEX对应。
有一个需要注意的地方,在Hook函数(就是MyFunction)中,会判断OriginalFunctionInTable是否有效,然后才进行调用,因为可能前一个进行Hook的驱动可能已经卸载,这个函数地址不再有效了,这时就调用RealFunction。
2. SSDT Hook
进行SSDT Hook要获取的信息也和上面差不多,不过这里获取服务号的方法有两种:
(1)得到NT内核映像的基址,然后从搜索导出表中的相应函数名的地址,这里都是搜的Zw*函数的地址,因此 函数地址+1 的地方就是服务号。
(2)根据不同版本的系统建立一张表,从表中获取服务号。
基本结构和上面的Shadow一样。
typedef struct _INDEX
{
ULONG Index_ZwCreateKey,
ULONG Index_ZwTerminateProcess,
ULONG Index_ZwSetInformationFile,
ULONG Index_ZwWriteFile,
ULONG Index_ZwSetValueKey,
ULONG Index_ZwWriteVirtualMemory,
ULONG Index_ZwCreateFile,
ULONG Index_ZwOpenProcess,
ULONG Index_ZwDeleteKey,
ULONG Index_ZwDeleteValueKey,
ULONG Index_ZwRequestWaitReplyPort,
ULONG Index_ZwQueryValueKey,
ULONG Index_ZwEnumerateValueKey,
ULONG Index_ZwCreateThread,
ULONG Index_ZwDuplicateObject,
ULONG Index_ZwLoadDriver
}INDEX,*PINDEX;
INDEX ShadowIndex[16];
Index[0]
.data:0001F0F0 dd 0
.data:0001F0F4 dd 0
.data:0001F0F8 dd 0
.data:0001F0FC dd 0
.data:0001F100 dd 0
.data:0001F104 dd 0
.data:0001F108 dd 0
.data:0001F10C dd 0
.data:0001F110 dd 0
.data:0001F114 dd 0
.data:0001F118 dd 0
.data:0001F11C dd 0
.data:0001F120 dd 0
.data:0001F124 dd 0
.data:0001F128 dd 0
.data:0001F12C dd 0
Index[Win2000]
.data:0001F130 dd 23h
.data:0001F134 dd 0E0h
.data:0001F138 dd 0C2h
.data:0001F13C dd 0EDh
.data:0001F140 dd 0D7h
.data:0001F144 dd 0F0h
.data:0001F148 dd 20h
.data:0001F14C dd 6Ah
.data:0001F150 dd 35h
.data:0001F154 dd 37h
.data:0001F158 dd 0B0h
.data:0001F15C dd 9Bh
.data:0001F160 dd 3Dh
.data:0001F164 dd 2Eh
.data:0001F168 dd 3Ah
.data:0001F16C dd 55h
Index[WinXP]
.data:0001F170 dd 29h
.data:0001F174 dd 101h
.data:0001F178 dd 0E0h
.data:0001F17C dd 112h
.data:0001F180 dd 0F7h
.data:0001F184 dd 115h
.data:0001F188 dd 25h
.data:0001F18C dd 7Ah
.data:0001F190 dd 3Fh
.data:0001F194 dd 41h
.data:0001F198 dd 0C8h
.data:0001F19C dd 0B1h
.data:0001F1A0 dd 49h
.data:0001F1A4 dd 35h
.data:0001F1A8 dd 44h
.data:0001F1AC dd 61h
Index[Win2003]
.data:0001F1B0 dd 2Bh
.data:0001F1B4 dd 10Ah
.data:0001F1B8 dd 0E9h
.data:0001F1BC dd 11Ch
.data:0001F1C0 dd 100h
.data:0001F1C4 dd 11Fh
.data:0001F1C8 dd 27h
.data:0001F1CC dd 80h
.data:0001F1D0 dd 42h
.data:0001F1D4 dd 44h
.data:0001F1D8 dd 0D0h
.data:0001F1DC dd 0B9h
.data:0001F1E0 dd 4Dh
.data:0001F1E4 dd 37h
.data:0001F1E8 dd 47h
.data:0001F1EC dd 65h
Index[Vista]
.data:0001F1F0 dd 40h
.data:0001F1F4 dd 152h
.data:0001F1F8 dd 131h
.data:0001F1FC dd 167h
.data:0001F200 dd 148h
.data:0001F204 dd 16Ah
.data:0001F208 dd 3Ch
.data:0001F20C dd 0C2h
.data:0001F210 dd 7Bh
.data:0001F214 dd 7Eh
.data:0001F218 dd 113h
.data:0001F21C dd 0FCh
.data:0001F220 dd 88h
.data:0001F224 dd 4Eh
.data:0001F228 dd 81h
.data:0001F22C dd 0A5h
Index[Vista]
.data:0001F230 dd 40h
.data:0001F234 dd 14Eh
.data:0001F238 dd 12Dh
.data:0001F23C dd 163h
.data:0001F240 dd 144h
.data:0001F244 dd 166h
.data:0001F248 dd 3Ch
.data:0001F24C dd 0C2h
.data:0001F250 dd 7Bh
.data:0001F254 dd 7Eh
.data:0001F258 dd 114h
.data:0001F25C dd 0FCh
.data:0001F260 dd 88h
.data:0001F264 dd 4Eh
.data:0001F268 dd 81h
.data:0001F26C dd 0A5h
Index[Vista]
.data:0001F270 dd 40h
.data:0001F274 dd 14Eh
.data:0001F278 dd 12Dh
.data:0001F27C dd 163h
.data:0001F280 dd 144h
.data:0001F284 dd 166h
.data:0001F288 dd 3Ch
.data:0001F28C dd 0C2h
.data:0001F290 dd 7Bh
.data:0001F294 dd 7Eh
.data:0001F298 dd 114h
.data:0001F29C dd 0FCh
.data:0001F2A0 dd 88h
.data:0001F2A4 dd 4Eh
.data:0001F2A8 dd 81h
.data:0001F2AC dd 0A5h
Index[Win7]
.data:0001F2B0 dd 47h
.data:0001F2B4 dd 174h
.data:0001F2B8 dd 14Bh
.data:0001F2BC dd 18Eh
.data:0001F2C0 dd 168h
.data:0001F2C4 dd 191h
.data:0001F2C8 dd 43h
.data:0001F2CC dd 0BEh
.data:0001F2D0 dd 7Bh
.data:0001F2D4 dd 7Eh
.data:0001F2D8 dd 12Bh
.data:0001F2DC dd 10Ah
.data:0001F2E0 dd 77h
.data:0001F2E4 dd 57h
.data:0001F2E8 dd 6Fh
.data:0001F2EC dd 9Bh
Index[Win7SP1]
.data:0001F2F0 dd 46h
.data:0001F2F4 dd 172h
.data:0001F2F8 dd 149h
.data:0001F2FC dd 18Ch
.data:0001F300 dd 166h
.data:0001F304 dd 18Fh
.data:0001F308 dd 42h
.data:0001F30C dd 0BEh
.data:0001F310 dd 67h
.data:0001F314 dd 6Ah
.data:0001F318 dd 12Bh
.data:0001F31C dd 10Ah
.data:0001F320 dd 77h
.data:0001F324 dd 57h
.data:0001F328 dd 6Fh
.data:0001F32C dd 9Bh
typedef struct _FUNCTION_INFO
{
char *FunctionName;
PVOID MyFunction;
ULONG FunctionIndex;
LONG isRealFunctionValid;
LONG GotOriginalFunctionInTable;
PVOID OriginalFunctionInTable;
PVOID RealFunction;
}FUNCTION_INFO,*PFUNCTION_INFO;
这些结构都和上面是一样的。
此外,还单独对KeUserModeCallback进行了Inline Hook。
3.奇怪的Shadow SSDT Hook 恢复
程序中使用PsSetLoadImageNotifyRoutine设置一个映像加载回调函数,在回调函数中判断,如果是TesSafe.sys加载,首先得到如下信息:
typedef struct _SHADOW_FUNCTION
{
ULONG ArrayIndex;
char* FunctionName;
ULONG ShadowIndex;
ULONG OriginalFunctionInTable;
LONG GotOriginalFunctionInTable;
}SHADOW_FUNCTION,*PSHADOW_FUNCTION;
SHADOW_FUNCTION ShadowFunction[6];
ArrayIndex代表这个结构在数组中的索引,便于下面的两组服务号中取得相应的值。
NtUserGetDC
NtUserGetDCEx
NtUserBuildHwndList
NtUserFindWindowEx
NtUserGetForegroundWindow
NtUserWindowFromPoint
.data:0001F908 ; int dword_1F908[]
.data:0001F908 dd 19Fh
.data:0001F90C dd 1A0h
.data:0001F910 dd 142h
.data:0001F914 dd 187h
.data:0001F918 dd 1A2h
.data:0001F91C dd 269h
.data:0001F920 ; int dword_1F920[]
.data:0001F920 dd 1A4h
.data:0001F924 dd 1A5h
.data:0001F928 dd 143h
.data:0001F92C dd 18Ch
.data:0001F930 dd 1A7h
.data:0001F934 dd 275h
这两组服务号分别对应Vista和Win7。
之后,开启一个系统线程,每隔一段时间将SHADOW_FUNCTION.OriginalFunctionInTable恢复到Shadow SSDT表中。很明显,就是要将TesSafe.sys将要Hook的这几个函数恢复,但是我没明白为什么要这么做,难道是跟Vista和Win7有关系?因为这两组服务号只针对这两个系统版本,也就是说只恢复这两个系统版本下的这些Shadow Hook。
另外,还有一个系统线程一直恢复与TX管家相关的注册表键值。
idb不在自己电脑上,就不发了。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课