文章目录
- 反调试
- 反沙箱
- 时间对抗
- 环境检测
- 反虚拟机
- 黑DLL父进程检测
- 傀儡进程
- 后记
反调试
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, PLARGE_INTEGER DelayInterval);
BOOL check()
{// 加载 ntdll.dllHMODULE 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, PLARGE_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, PLARGE_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, PLARGE_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, PLARGE_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, PLARGE_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(); // 获取系统默认IDswitch (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);}//申请内存设置属性为rwxPVOID 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 | 中文(台湾) |