文章目录
- 反调试
- 反沙箱
- 时间对抗
- 环境检测
- 反虚拟机
- 黑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.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, 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(); // 获取系统默认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 | 中文(台湾) |