【文章标题】: E书工厂 电子书 染毒后的修复原理和工具源码
【文章作者】: 啊CR/FTSTT
【作者主页】: Viper.68ab.com
【下载地址】: 自己搜索下载
--------------------------------------------------------------------------------
【详细过程】
  原理:
  
  E书工厂的电子书就是一个带有附加数据的程序文件,程序本身加有aspack的壳。
  
  中毒&杀毒会改变什么呢?
  
  1.文件实际长度,PE病毒要写入自己的代码通常是在文件末尾增加一段数据,杀软并没有完全清除这些数据造成文件的长度和原始文件不同,导致运行错误,电子书无法浏览。
  
  2.校验和,E书工厂 的电子书的校验和是空的,杀软或病毒自作聪明 的填充这个位置,程序引用此值时产生错误,找不到正确的书籍数据,电子书无法浏览。
  
  3.最后区段大小&总大小,这是相关联的一对,病毒加了代码需要再获得虚拟地址所以它修改程序的最后区段大小,自然也修改了总大小(也许是杀软干的,呵呵),程序引用此值时产生错误,找不到正确的书籍数据,电子书无法浏览。
  
  4.最后区段属性,这个是修改3的后遗症。应该不影响阅读的(未测)。
  
  5.OEP,病毒要执行自然要有切入点,通常是OEP,他如果改了这个杀软没有正确恢复,电子书自然不能正常运行了。
  
  
  修复方案
  
  1.根据电子书的特征串 “ADAEBOOK”判断结尾,去除垃圾数据
  
  2.清空校验和
  
  3.aspack加壳的最后区段的相关值是固定的,直接恢复
  
  4.同3
  
  5.杀软目前做的比较好,暂不考虑。
  
  
  恢复方法
  
  二十一世纪还要手工恢复吗?
  
  不!
  
  
  以下为Masm 的源程序,功能是自动完成修复,支持E书工厂的 1.4和1.5两个版本
  
  
  部分代码有注释希望大家能看懂,附件为编译好的程序。
  
  
  
  
 

引用:
 ;电子书修复工具 For E书工厂(EbookWorkShop) 1.4/1.5
  ;版本0.3
  ;源码开放,欢迎修改
  
  ;啊Cr/FTSTT
  
  
  ;感谢 陈余,老鬼,SKMS/FTSTT,bwin/FTSTT ,你
  .586
  .model flat,stdcall
  option casemap:none
  
     include windows.inc
     include user32.inc
     include kernel32.inc
     include windows.inc
     
     includelib user32.lib
     includelib kernel32.lib
  
  
  WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
  
  
  .data
     Number  DD 0        ;参数数量
     Curren  DD 0        ;当前的参数序号
     FileSign  DD 0      ;文件系统标志
     NeedFix  DD 0      ;文件是否需要修复
     FileDateBegin DD 0      ;数据开始
     FileSize DD 0      ;数据大小
     hehe  db 'FTSTT',0    
     FixedSign db '.已修复.exe',0    ;修复文件标志
     noteCaption db '提示',0
     noteText db '本程序使用命令行操作!  可以将需修复的电子书文件拖拽到本程序图标开始修复.  支持多文件同时拖拽,程序会自动识别同时修复.',0
     Version  DD 0      ;1.4 Or 1.5
  
  
  .data?
      FileName  db  4096 dup (?)
      hInstance HINSTANCE ?
      CommandLine LPSTR ?
  
  .code
  include    _Cmdline.asm  ;这个文件来自罗云彬的例子
  ; ---------------------------------------------------------------------------
  
  
  start:
    invoke GetModuleHandle, NULL
    mov    hInstance,eax
    
    
    ;----------------获得目标文件------------------------
    
    
    invoke  _argc    ;调用获得参数子程序
    
      mov Number,eax  ;保存参数数量
      cmp  eax,1    ;判断是否有参数
      je  Note
      mov  eax,1
  Cycle0:  invoke  _argv,eax,addr FileName,sizeof FileName
    
    mov  Curren,eax
    
    
    ;----------------读取文件内容------------------------
    
    
    lea eax,FileName  ;参数装入eax
    INVOKE CreateFile, eax ,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
          mov FileSign,eax
          INVOKE GetFileSize, EAX, NULL
          mov FileSize,eax
          cmp eax,180*1024  ;检查文件是否大于180k
          jl Cycle
          INVOKE VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
          mov FileDateBegin,eax
          INVOKE _lread, FileSign,eax,FileSize
          
    
    ;----------------修复文件内容------------------------
    
    
    mov  eax,FileDateBegin
    mov  esi,FileSize
    add  eax,esi
    mov  edi,eax
  AAAA:  dec  eax    
    dec  esi
    je  Cycle    ;文件不支持则跳走
    cmp  dword ptr [eax],45414441h
    jnz  AAAA
    cmp  dword ptr [eax+4],4B4F4F42h
    jnz  AAAA
    cmp     dword ptr [eax+8], 0
    jnz  AAAA
    cmp     dword ptr [eax+0Bh], 0
    jnz  AAAA
  
    add   eax,0Fh
    cmp  eax,edi
    je  AAAB
    mov  NeedFix,1  ;设置需要修复标志位
  AAAB:  mov  edi,FileDateBegin
    sub  eax,edi
    mov  FileSize,eax
    
    
    ;文件大小处理完毕,继续处理校验和
    
    
    mov  eax,FileDateBegin
    cmp  dword ptr [eax+158h], 0
    je  V14
    mov  dword ptr [eax+158h], 0    ;校验和清零
    mov  NeedFix,1      ;设置需要修复标志位
  
    
    ;校验和处理结束,继续处理最后区段大小
    
    ;判断版本(开始谢的时候都不一样,最后调试的时候很多都一样了(浪费了大量的调试时间),懒得改了*_*)
    
  
  V14:  cmp  dword ptr [eax+128h], 0A9001h  ;根据Ep判断版本[1.4]
    jne  V15
    mov  Version,14
    jmp  AAAC
  V15:  cmp  dword ptr [eax+128h], 0C7001h  ;根据Ep判断版本[1.5]
    jne  Cycle
    mov  Version,15      ;其实ep也应该是一个需要修复的项目,但还没遇到这类情况,暂且用着
    
    
    ;虚拟大小
    
  AAAC:  cmp  Version,14
    jne  AAAC15
    
    cmp  dword ptr [eax+368h], 1000h  ;aspack最后一个区段虚拟大小应该多大?
    je  AAAD
    mov  esi,dword ptr [eax+368h]
    sub  esi,1000      ;保存最后区段大小变化(没用到)
    mov  dword ptr [eax+368h], 1000h  ;aspack最后一个区段虚拟大小应该1000h
    mov  NeedFix,1      ;设置需要修复标志位
    jmp  AAAD
    
  AAAC15:  
    cmp  dword ptr [eax+368h], 1000h  ;aspack最后一个区段虚拟大小应该多大?
    je  AAAD
    mov  esi,dword ptr [eax+368h]
    sub  esi,1000      ;保存最后区段大小变化(没用到)
    mov  dword ptr [eax+368h], 1000h  ;aspack最后一个区段虚拟大小应该1000h
    mov  NeedFix,1  
    
    
    ;实际大小
  AAAD:  cmp  Version,14
    jne  AAAD15
    
    cmp  dword ptr [eax+370h], 0    ;aspack最后一个区段实际大小应该多大?
    je  AAAE
    mov  dword ptr [eax+370h], 0    ;aspack最后一个区段实际大小应该0
    mov  NeedFix,1      ;设置需要修复标志位
    jmp  AAAE
    
  AAAD15:  
    cmp  dword ptr [eax+370h], 0    ;aspack最后一个区段实际大小应该多大?
    je  AAAE
    mov  dword ptr [eax+370h], 0    ;aspack最后一个区段实际大小应该0
    mov  NeedFix,1      ;设置需要修复标志位
    
    
    ;特征值
    
  AAAE:  cmp  Version,14
    jne  AAAE15
    
    cmp  dword ptr [eax+384h], 0C0000040h  ;aspack最后一个区段读写标志应该是?
    je  AAAF
    mov  dword ptr [eax+384h], 0C0000040h  ;
  
    mov  NeedFix,1        ;设置需要修复标志位
    jmp  AAAF
  AAAE15:  
    cmp  dword ptr [eax+384h], 0C0000040h  ;aspack最后一个区段读写标志应该是?
    je  AAAF
    mov  dword ptr [eax+384h], 0C0000040h  ;
    mov  NeedFix,1        ;设置需要修复标志位
  
    
    ;区段大小结束,继续处理总大小
    
    
  AAAF:  cmp  Version,14
    jne  AAAF15
    
    cmp  dword ptr [eax+150h],0AC000h
    je  Write0
    mov  dword ptr [eax+150h],0AC000h
    mov  NeedFix,1        ;设置需要修复标志位
    jmp  Write0
    
  AAAF15:  
    cmp  dword ptr [eax+150h],0CA000h
    je  Write0
    mov  dword ptr [eax+150h],0CA000h
    mov  NeedFix,1        ;设置需要修复标志位
    
    
    ;其他问题陆续填补,凑合用着先:-)
    
    ;----------------文件内容修复完毕--------------------
    
    ;输出修复后的文件
      
  Write0:  cmp  NeedFix,1
    jne  Cycle
    
    invoke  _argv,Curren,addr FileName,sizeof FileName
    
    lea  eax,FileName
  
    INVOKE lstrcat,eax,addr FixedSign
  
    INVOKE _lcreat,addr FileName,0
    
    mov  esi,eax
    INVOKE  _lwrite,eax,FileDateBegin,FileSize
    
    INVOKE  _lclose,esi
    
  
    
    
  Cycle:    ;循环  
    
    mov  eax,Curren
    cmp  eax,Number
    je  Exit
    inc  eax
    mov  Curren,eax
    mov  NeedFix,0
    jmp  Cycle0
    
  Note:  invoke  MessageBox,NULL,offset noteText,offset noteCaption,MB_OK
  Exit:   invoke  ExitProcess,eax
    end  start
  
  
  
--------------------------------------------------------------------------------

                                                       2007年08月06日 1:17:50