恶意代码分析常见Windows函数
accept
用来监听入站网络连接,这个函数预示着程序会在一个套接字上监听入站网络连接。
AdjustTokenPrivileges
用来启用或禁用特定的访问权限。执行进程注入的恶意代码会经常调用这个函数 ,来取得额外的权限。
AttachThreadInput
将一个线程处理的输入附加到另一个线程上,使得第二个线程接收到输入事件。如键盘和鼠标事件。击键记录器和其他间谍软件会使用这个函数。
bind
用来将一个本地地址关联到套接字上,以监听入站网络连接。
BitBlt
用来将图形数据从一个设备复制到另一设备。间谍软件有时会使用这个函数来捕获屏幕。这个函数也经常被编译器作为共享库代码而添加。
CallNextHookEx
在由SetWindowsHookEx函数设置了挂钩事件的代码中使用。CallNextHookEx函数会调用链上的下一个挂钩函数。分析调用CallNextHookEx的函数可以确定出SetWindowsHookEx设置挂钩的用意。
CertOpenSystemStore
用来访问在本地系统中的证书。
CheckRemoteDebuggerPresent
检查一个特定进程(包括你自己的)是否被调试。这个函数通常在一种反调试技术中被使用。
CoCreateInstance
创建一个COM对象。COM对象提供了非常多样化的功能。类标识(CLSID)会告知你哪个文件包含着实现COM对象的代码。
connect
用来连接一个远程套接字。恶意代码经常使用底层功能函数来连接一个命令控制服务器。
ConnectNamedPipe
用来为进程间通信创建一个服务端管道,等待一个客户端管道来连接。后门程序和反向shell经常使用ConnectNamedPipe函数,来简单地连接到一个命令控制服务器。
ControlService
用来启动、停止、修改或发送一个信号到运行服务。如果恶意代码使用了它自己的恶意服务,需要分析实现服务的代码,来确定出调用的用意。
CreateFile
创建一个新文件,或是仅仅打开一个已有文件。
CreateFileMapping
创建一个映射到文件的句柄,将文件装载到内存,并使得它可以通过内存地址进行访问。启动器、装载器和注入器会使用这个函数来读取和修改PE文件。
CreateMutex
创建一个互斥对象,可以被恶意代码用来确保在给定时刻只有一个实例在系统上运行。恶意代码经常使用固定名字为互斥对象命名,这样它们就可以成为一个很好的主机特征,来检测系统是否感染了这个恶意代码。
CreateProcess
创建并启动一个新进程。如果恶意代码创建了一个新进程,需要同时分析这个新进程。
CreateRemoteThread
用来在一个远程进程(也就是与调用进程不同的进程)中启动一个线程。启动器和隐蔽性恶意代码通常使用这个函数,将代码注入到其他进程中执行。
CreateService
创建一个可以在启动时刻运行的服务。恶意代码使用CreateService函数来持久化、 隐藏,或是启动内核驱动。
CreateToolhelp32Snapshot
用来创建一个进程、堆空间、线程和模块的快照。恶意代码经常使用这个函数,在多个进程或线程之间传播感染。
CryptAcquireContext
这经常是恶意代码用来初始化使用Windows加密库的第一个函数。还有很多其他函数是和加密相关的,绝大多数的函数名都以Crypt开头。
DeviceIoControl
从用户空间向设备驱动发送一 个控制消息。 DeviceIoControl在驱动级的恶意代码中是非常普遍使用的,因为它是一种最简单和灵话的方式,在用户空间和内核空间之间传递信息。
DllCanUnloadNow
预示着程序实现了一个COM服务的导出函数。
DllGetClassObject
预示着程序实现了一个COM服务的导出函数。
DllInstall
预示着程序实现了一个COM服务的导出函数。
DllRegisterServer
预示着程序实现了一个COM服务的导出函数。
DllUnregisterServer
预示着程序实现了一个COM服务的导出函数。
EnableExecuteProtectionSupport
一个未经文档化的API函数, 用来修改宿主上的数据执行保护(DEP)设置,使得系统更容易被攻击。
EnumProcesses
用来在系统上枚举运行进程的函数,恶意代码经常枚举进程来找到一个可以注入的进程。
EnumProcessModules
用来枚举给定进程的已装载模块(可执行文件和DLL程序),恶意代码在进行注入时经常枚举模块。
FindFirstFile/FindNextFile
用来搜索文件目录和枚举文件系统的函数。
FindResource
用来在可执行文件和装载DLL程序中寻找资源的函数。恶意代码有时会使用资源,来存储字符串、配置信息或者其他恶意文件。如果你看到使用了这个函数,需要进一步检查恶意代码PE头中的.rsrc节。
FindWindow
在桌面上搜索打开窗口的函数。有时这个函数会在反调试技术中使用,来搜索OllyDbg工具的窗口。
FtpPutFile
一个高层次上的函数,用来向一个远程FTP服务器上传文件。
GetAdaptersInfo
用来获取系统上网络适配器的相关信息。后门程序有时会调用GetAdaptersInfo函数,来取得关于受感染主机的摘要信息。在某些情况下,这个函数也会被使用来取得主机的MAC地址,在对抗虚拟机技术中用来检则VMware等虚拟机。
GetAsyncKeyState
用来确定一个特定键是否被输入。恶意代码有时会使用这个函数来实现一个击键记录器。
GetDC
返回一个窗口或是整个屏幕的设备上下文句柄。间谍软件经常使用这个函数来抓取桌面截屏。
GetForegroundWindow
返回桌面目前正在处于前端的窗口句柄。击键记录器件普遍使用这个函数,来确定用户正在往哪个窗口输入。
gethostbyname
在向一个远程主机发起IP连接之前,用来对一个特定域名执行一次DNS查询。作为命令控制服务器的域名通常可以用来创建很好的网络检测特征码。
gethostname
获取计算机的主机名。后门程序经常使用gethostname函数来获取受害主机的摘要信息。
GetKeyState
被击键记录器使用, 来获取键盘上一个特定键的状态。
GetModuleFilename
返回目前进程装载某个模块的文件名。恶意代码可以使用这个函数,在目前运行进程中修改或者复制文件。
GetModuleHandle
用来获取已装载模块句柄的函数, 恶意代码可以使用GetModuleHandle在一个装载模块中定位和修改代码,或者搜索一个合适位置来注入代码。
GetProcAddress
获取装载到内存中一个DLL程序的函数地址。用来从其他DLL程序中导入函数,以补充在PE文件头部中导入的函数。
GetStartupInfo
获取一个包含当前进程如何自动运行配置信息的结构,比如标准句柄指向哪些位置。
GetSystemDefaultLangId
返回系统默认语言设置的函数。这可以用来定制显示与文件名,作为对感染主机摘要信息的获取,这个函数也会被一些由“爱国主义”所驱动的恶意代码使用,从而对一些特定区域的系统进行感染。
GetTempPath
返回临时文件路径, 如果看到一个恶意代码调用了这个函数,需要检查它是否在临时文件路径中读取或写入了一些文件。
GetThreadContext
返回一个给定线程的上下文结构。线程上下文结构中存储了所有线程信息,比如寄存器值和目前状态。
GetTickCount
返回从启动后到当前时间的微秒数。 这个函数有时在反调试技术中被使用来获取时间信息。GetTickCount也经常由编译器添加并包含在许多可执行程序中,因此简单地在导入函数列表中看到这个函数,只能提供少量的线索信息。
GetVersionEx
返回目前正在运行的Windows操作系统版本信息。这可以被用来获取受害主机的摘要信息,或是在不同Windows版本中选择未经文档化结构的一些偏移地址。
GetWindowsDirectory
返回Windows目录的文件系统路径(通常是C:\Windows),恶意代码经常使用这个函数来确定将其他恶意程序安装到哪个目录。
inet_ addr
将一个IP地址字符串,如127.0.0.1,进行转换,使其能够在如connect等函数中使用,这些字符中有时也可以用作基于网络的特征码。
InternetOpen
初始化WinINet中的一些高层次互联网访问函数,比如InternetOpenUrl和InternetReadFile。搜索InternetOpen函数是找到互联网访问功能初始位置的一个好方法。 InternetOpen函数的一个参数是User-Agent,有时也可以作为基于网络的特征码。
InternetOpenUrl
使用FTP、HTTP或HTTPS协议连接来打开一个特定的URL,如果URL固定, 则可以作为基于网络的特征码。
InternetReadFlle
从之前打开的URL中读取数据。
InternetWriteF1le
写数据到之前打开的个URL。
IsDebuggerPresent
检查当前进程是否被调试,经常在反调试技术中使用。这个函數经常由编译器添加并包含在许多可执行程序中,因此简单地在导入函数列表中看到这个函数,只能提供少量的线索信息。
IsNTAdmin
检查一个用户是否拥有管理员权限。
IsWoW64Process
由一个32位进程使用,来确定它是否运行在64位操作系统上。
LdrLoadDll
装载一个DLL程序到进程中的底层函数,功能就像是LoadLibrary函数,而LoadLibrary函数是普通程序使用的。在导入函数表中如果发现LdrLoadDll函数,就预示着这个程序尝试更加隐蔽。
LoadLibrary
装载一个DLL.程序到进程中,而这个程序在程序启动时还没有被装载。几乎每个Win32程序都会导入这个函数。
LoadResource
从PE文件中装载资源进入到内存中。恶意代码有时会使用资源来存储字符串、配置信息,或者其他恶意文件。
LsaEnumerateLogonSessions
枚举当前系统上的登录会话,往往是一个登录凭证窃取器使用的部分功能。
MapViewOfFile
映射一个文件到内存, 将文件内容变得通过内存地址可访问。启动器、装载器和注入器使用这个函数来读取和修改PE文件。通过使用MapViewOfFile函数,恶意代码可以避免使用WriteFile来修改文件内容。
MapVirtualKey
将一个虚拟键值代码转换成字符值,经常被击键记录器恶意代码所使用。
MmGetSystemRoutineAddress
与GetProcAddress类似,但是这个函数是内核代码使用的。这个函数从另外一个模块中获取函数的地址,但仅仅可以用来获得ntoskrnl.exe和hal.dll的函数地址。
Module32First /Module32Next
用来枚举装载到进程中的模块,注入器通常使用这个函数来确定注入代码的位置。
NetScheduleJobAdd
提交一个计划安排,来让一个程序在某个特定日期时间运行。恶意代码可以使用NetScheduleJobAdd函数来运行一个其他程序,作为一位恶意代码分析师,需要定位与分析会在未来某个时间运行的程序。
NetShareEnum
用来枚举网络共享的函数。
NtQueryDirectoryFile
返回一个目录中文件的信息。内核套件普遍会挂钩这个函数,来隐藏文件。
NtQueryInformationProcess
返回关于一个特定进程的不同信息。 这个函数通常在反调试技术中被使用,因为它可以返回与CheckRemoteDebuggerPresent函数同样的信息。
NtSetInformationProcess
可以用来改变一个程序的权限级别,或者来绕过数据执行保护(DEP)。
OleInitialize
用来初始化COM库。使用COM对象的程序必须在调用任何其他COM功能之前,调用这个函数。
OpenMutex
打开一个双向互斥对象的句柄,可以被恶意代码用来确保在任意给定时间在系统上只能一个运行实例。恶意代码通常使用固定名字来为互斥对象命名,因此可以用作很好的主机特征。
OpenProcess
打开系统上运行其他进程的句柄。这个句柄可以被用来向其他进程内存中读写数据,或是注入代码到其他进程中。
OpenSCManager
打开一个到服务控制管理器的句柄。任何想要安装、修改或是控制一个服务的程序,都必须要调用这个函数,才能使用其他服务操纵函数。
OutputDebugString
输由字符串到一个附加的调试器上,这可以被使用在反调试技术上。
PeekNamedPipe
用来从一个命名管道中复制数据,而无须从管道中移除数据。这个函数在反向shell中很常用。
Process32First/Process32Next
在调用CreateToolhelp32Snapshot之后,使用这些函数来开始枚举进程。恶意代码通常枚举进程,来找到一个可以注入的进程。
QueryPerformanceCounter
用来获取基于硬件的性能计数器的值,这个函数有时会在反调试技术中用来获取时间信息,这个函數经常由编译器添加并包含在许多可执行程序中,因此简单地在导入函数列表中看到这个函数,只能提供少量的线索信息。
QueueUserAPC
用来在其他线程执行代码,恶意代码有时会使用这个函数注入代码到其他进程。
ReadProcessMemory
用来从远程进程读取内存。
recv
从一个远程主机获取数据。恶意代码经常使用这个函数来从远程的命令控制服务器获取数据。
RegisterHotKey
用来注册 一个热键,当用户任意时刻输入一个特定键值组合(比如Ctrl+Alt+J)时,注册热键句柄将会被通知,无论当用户输入键值组合时哪个窗口是活跃的。这个函数通常被间谍软件使用,使其在键值组合输入前对用户保持隐藏。
RegOpenKey
打开一个注册表键值的句柄,来进行读写。修改注册表键值通常是软件在主机上进行持久化保存的一种方法。注册表也包含了完整的操作系统和应用程序配置信息。
ResumeThread
继续之前挂起的线程。ResumeThread函数在几种注入技术中都会被使用
RtlCreateRegistryKey
在内核模式代码中用于创建一个注册表键值。
RtlWriteRegistryValue
在内核模式代码中用于向注册表写一个键值。
SamIConnect
连接安全账户管理器 (SAM),以调用其他用来访问登录凭证信息的函数。口令哈希窃取程序会访问SAM数据库,来获取用户登录口令的哈希列表。
SamIGetPrivateData
从安全账户管理器 (SAM)数据库中查询某个特定用户的私密信息。口令哈希窃取程序会访问SAM数据库,来获取用户登录口令的哈希列表。
SamQueryInformationUse
从安全账户管理器(SAM)数据库中查询某个特定用户的口令密文。口令哈希窃取程序会访问SAM数据库,来获取用户登录口令的哈希列表。
send
发送数据到远程主机。恶意代码经常会使用这个函数来发送数据到运程的命令控制服务器。
SetFileTime
修改一个文件的创建、访问或者最后修改时间。恶意代码经常使用这个函数来隐藏恶意行为。
SetThreadContext
用来修改给定线程的上下文。一些注入技术会使用这个函数。
SetWindowsHookEx
设置一个挂钩函数,使其在某个特定事件触发时被调用。这个函数普遍被击键记录器和间谍软件使用,这个函数也提供了一种轻易的方法,将一个DLL程序装载入系统的所有GUI进程中。这个函数有时也会被编译器添加。
SfcTerminateWatcherThread
用来禁用Windows文件保护并修改被保护的文件。SfcFileException函数也可以在这种场景中被使用。
ShellExecute
用来执行另一个程序。如果恶意代码创建了一个新进程,还需要分析这个新进程。
StartServiceCtrlDispatcher
由服务使用来连接到服务管理控制器进程的主线程。任何以服务方式运行的进程必须在启动后30秒内调用这个函数。在恶意代码中找到这个函数,可以知道它的功能应该以服务方式运行。
SuspendThread
挂起一个线程,使得它停止运行。恶意代码有时会挂起一个线程,通过代码注入技术来修改它。
system
由一些C语言运行库提供的用来运行其他程序的函数。在Windows操作系统上,这一函数是CreateProcess的封装。
Thread32First /Thread32Next
用来轮询一个进程的所有线程。注入器会使用这些函数来找出可供注入的合适线程。
Toolhelp32ReadProcessMemory
用来读取远程进程的内存。
URLDownloadToFile
一个高层次的函数调用,来从一个Web服务器下载文件并存储到硬盘上。这一函数在下载器中是非常普遍的,因为它以一个函数调用便实现了下载器的所有功能。
VirtualAllocEx
一个内存分配的例程,支持在远程进程中分配内存。恶意代码有时会在进程注入中使用VirtualAllocEx函数。
VirtualProtectEx
修改一个内存区域的保护机制。恶意代码可能会使用这个函数来将一块只读的内存节修改为可执行代码。
WideCharToMultiByte
用来将一个Unicode类型字符串转化为一个ASCII类型字符串。
WinExec
用来执行其他程序。如果恶意代码创建了一个新的进程,那么你需要进一步分析这个新进程。
WlxLoggedOnSAS (和其他Wlx* 系函数)
作为身份认证模块DLL程序必须导出的函数。导出许多Wlx* 系函数的恶意代码可能在进行图形化标识与认证模块(GINA)的劫持。
Wow64DisableWow64FsRedirection
禁用32位文件在64位操作系统中装载后发生的文件重定向机制,如果一个32位应用程序在调用这个函数后向C:\Windows\System32写数据,那么它将会直接写到真正的C:\Wndows\System32,而不是被重定向至C:\Windows\SysWOW64。
WriteProcessMemory
用来向远程进程写数据的函数。恶意代码在进程注入中也会用到WriteProcessMemory函数。
WSAStartup
用来初始化底层级别的网络功能,搜索WSAStartup函数调用位子,经常是定位网络相关功能最简单的方法。
Kernel32.dll
这是一个很常见的DLL,它包含核心系统功能,如访问和操作内存、文件和硬件,等等。
Advapi32.dll
这个DLL提供了对核心Windows组件的访问,比如服务管理器和注册表。
User32.dll
这个DLL中包含了所有用户界面组件,如按钮、滚动条以及控制和响应用户操作的组件。
Gdi32.dll
这个DLL中包含了图形显示和操作的函数。
Ntdll.dll
这个DLL是Windows内核的接口。可执行文件通常不直接导入这个函数,而是由Kernel32.dll间接导入,如果一个可执行文件导入了这个文件,这意味着作者企图使用那些不是正常提供给Windows程序使用的函数。一些如隐藏功能和操作进程等任务会使用这个接口。
Wsock32.dll和Ws2_32.dll
这两个是联网DLL,访何其中任一个DLL的程序非常可能连接网络,或是执行网络相关的任务。
Wininet.dll
这个DLL包含了更高层次的网络函数,实现了如FTP、 HTTP和NTP等协议。
来源:《恶意代码分析实战》附录