多数恶意代码以Windows平台为目标,并且与操作系统进行紧密交互。对基本Windoows编程概念的深刻理解会帮助你识别出恶意代码在主机上的感染迹象,跟踪恶意代码的执行(因为它们可能使用操作系统来执行代码而不是用一个跳转或调用指令),并最终分析出恶意代码的目的。
Windows API
Windows API是一个广泛的功能集合,管理着恶意代码与微软程序库之间的交互方式。Windows API使用特定术语,名字,已经约定。
类型和匈牙利表达法
多数Windows API使用它自己的 名字,来表示C语言类型。Windows总体上使用匈牙利表达法,作为API函数标识符,这个表达式 使用一个前缀命名模式
windows API中的常见类型
句柄(HANDLE)
句柄是在操作系统中被打开或被创建的项。你对句柄做的唯一的事情,就是保存它,并在后续函数调用中使用它来引用同一对象。
例:CreateWindowEx函数是一个句柄的简单例子。他返回一个HWND,这是一个窗口句柄。任何时候当你想要对那个窗口做些什么,比如调用DestroyWindows函数是,你就需要使用这个窗口。
文件系统函数
恶意代码与系统交互的一个最常用的方式就是创建或修改文件,而且独特文件名或修改为既有的文件名是明显的基于主机的感染现象。
CreateFile
这个函数被用来创建和打开文件。它可以打开已经存在的文件,管道,流,以及I/O设备。还能创建新的文件。
函数结构体
ReadFile和WriteFile
这两个函数用来对文件进行读写
ReadFile函数结构体
WriteFile函数结构体
CreateFileMapping和MapViewofFile
文件映射经常被恶意代码作者使用,因为它们允许讲一个文件加载到内存中,以便更加容易地进行操作。CreateFileMapping函数负责从磁盘上加载一个文件到内存。MapViewofFile函数则返回一个指向映射的基地址指针,它可以被用来访问内存中的文件。
CreateFileMapping函数结构体
MapViewofFile函数结构体
特殊文件
Windows系统中有一些特殊文件类型,它们的访问方式与普通文件不太一样。恶意程序经常使用特殊文件。比如:一下特殊文件比普通文件更隐蔽,因为它们在列出目录时不会显示出来,某些特殊文件可以提取对系统硬件和内部数据更强的访问能力。
Windows注册表
Windows注册表被用来保存操作系统与程序配置信息,比如设置和选项,和文件系统一样,它是基于主机的感染迹象的很好来源,并且能够揭示出关于恶意代码功能的有用信息。Windows的早期版本使用.ini文件来保存配置信息。注册表被引入后,作为一个层次逐步提升。现在几乎所有的Windows配置信息都保存在注册表中,包括网络驱动,启动项,用户账户,以及其他信息。
恶意代码经常使用注册表来完成持久驻留或者存储配置数据。恶意代码添加项到注册表中,这使它在计算机引导时能够自动运行。
你需要知道几个重要的注册表术语
根键: 注册表被划分为称为根键的5个顶层节。有时,术语HKEY和储巢也被使用。每一个跟键有一个特定的目的。
子键: 一个子键就像一个文件夹中的子文件夹
键: 一个键是一个注册表中的文件夹,它可以包含额外的文件夹或键值。跟健和子键都是键。
值项: 一个值项是一个配对的名字和值。
值或数据: 值或数据是存储在注册表项中的数据。
注册表根键
注册表被划分成下面5个键:
最常用的根键是HKLM和HKCU。
注册表编辑器(Regedit)
注册表编辑器(Regedit)是windows内建的用来查看和编辑注册表的工具。
自启动程序
向run子健中写入项,是一个普定设置程序自启动的方法,尽管不是一个隐蔽的技术,它任然经常被恶意代码用来自启动自身程序。(Autoruns工具可以使用)
常用注册表函数
|
|
网络API
伯克利兼容套接字
在Windows的网络选项中,恶意代码最普遍使用的是伯克利兼容套接字,在UNIX也是一样的。伯克利兼容套接字的网络功能在Windows系统中是由Winsock库实现的,主要在ws32_32.dll中,在所有库函数中,socket,connect,bind,listen,accept,send和recv函数最常用的
跟踪恶意代码的运行
动态链接库(DLL)
DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件
恶意代码作者使用DLL的三种方式:
保存恶意代码
有时候将恶意代码保存到一个DLL文件比exe文件更加有利。它可以附加到其他进程
通过使用Windows DLL
可以通过windows调用dll的程序
通过使用第三方的DLL
因为是动态链接,所以可以使用第三方的DLL
DLL的结构
dll的文件结构几乎和exe文件一模一样,只有一个单一的标志指示这是dll。DLL经常有更多的导出函数,并且导入函数较少。
进程
恶意代码可以通过创建一个新的进程或修改一个已存在的进程,来执行恶意代码。
创建一个新的进程需要用到这个函数CreateProcess,下面是代码范例:
线程
进程是执行代码的容器,线程才是Windows操作系统真正要执行的内容。
创建一个新的线程CreateThread
使用互斥量(mutex)的进程间协作
互斥量是全局对象,用于协调多个进程和线程。主要用于控制共享资源的访问,并且经常被恶意代码使用(因为它们经常使用硬编码)。因为如果一个互斥量被两个不使用其它方式通讯的进程使用时,它的名字必须是互斥一致的。
一个互斥量可以通过CreateMutex函数进行创建,而进程可以通过OpenMutex调用来获取另一个进程中互斥量的句柄。线程通过一个对WaitForSingleObject的调用,获取对互斥量的访问,当一个线程完成对互斥量的使用后,需要使用ReleaseMutex
内核与用户模式
Windows使用两种处理器特权级别:内核模式与用户模式。
依据处理器上执行的代码的类型,处理器在两个模式之间切换。应用程序在用户模式下执行。核心操作系统组件在内核模式下执行。多个驱动程序在内核模式下执行,但某些驱动程序在用户模式下执行。
用户模式:不能直接访问硬件,应用程序的虚拟地址空间除了为专用空间以外。还会受到限制。在用户模式下执行的处理器无法訪问为该操作系统保留的虚拟地址。限制用户模式应用程序的虚拟地址空间可防止应用程序更改而且可能损坏关键的操作系统数据。
内核模式: 内核模式下执行的全部代码都共享单个虚拟地址空间。这表示内核模式驱动程序未从其它驱动程序和操作系统自身独立开来。
原生态API
原生态API是用来和Windows进行交互的底层API,他们很少被非恶意软件使用,但是在恶意代码作者之间却很受欢迎。调用原生API函数可以绕过普通Windows API。
当调用Windows API中的一个函数时,这个函数通常不会直接执行请求的动作,因为大多数重要的数据结构都会被保存在内核中。这时用户程序被给予对用户API(如:DLL)的访问,这些DLL会调用ntdll.dll,这是一个特殊的DLL程序,它管理用户空间与内核的 交互。然后处理器却换到内核模式,并执行内核中的一个函数。这里ntdll函数像内核中的函数一样,使用API和结构体,这些函数组成了原生API。应用程序不建议调用原生API,但是操作系统中没有任何东西来阻止它们这样做。所有直接调用原生API对恶意代码作者来说很有吸引力,因为原生态API允许它们做一些采用别的方式不可能做到的事情,同时有时候很隐蔽(比如:一些反病毒软件是监控一个进程使用的系统调用,这里就可以躲避啦)。
lab
这个程序如何完成持久化驻留,来确保在计算机被重启后它能继续运行
发现两个函数:
其中一个是StartServiceCtrlDispatcherA——>在2000/XP等基于NT 的操作系统中,有一个服务管理器,它管理的后台进程被称为 service。在任务管理器中,并且随系统启动而最先运行,随系统关闭而最后停止。
为什么程序会使用一个互斥量
用于控制共享资源的访问
可以用来检测这个程序的基于主机特征是什么?
使用Malservice与HGL345的互斥量,发现恶意域名:http://www.malwareanalysisbook.com
检测这个恶意代码基于网络特征是什么?
发现恶意域名:http://www.malwareanalysisbook.com。并且调用InternetOpenUrlA网络函数
这个程序的目的是什么
开机自启动,并且访问域名http://www.malwareanalysisbook,同时有WriteFile函数,可以写文件
这个程序什么时候完成执行
关机即结束
API实战
MessageBox
MessageBox指的是显示一个模态对话框
函数定义
使用
GetWindowText
Windows API宏,在WinUser.h中根据是否已定义Unicode被分别定义为GetWindowTextW和GetWindowTextA。该函数将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内。如果指定的窗口是一个控件,则拷贝控件的文本。
函数定义