简单的沙箱反调试
前言
很多杀软都有自己的后端云沙箱,这些沙箱能够模拟出软件执行所需的运行环境,通过进程hook技术来对软件执行过程中的行为进行分析,判断其是否有敏感的操作行为,或者更高级的检测手法是,将获取到的程序的API调用序列以及其他的一些行为特征输入到智能分析引擎中(基于机器学习org)进行检测。所以,如果我们的木马没有做好反调试,很容易就被沙箱检测出来。
最简单的反调试的措施就是检测父进程。一般来说,我们手动点击执行的程序的父进程都是explorer。如果一个程序的父进程不是explorer,那么我们就可以认为他是由沙箱启动的。那么我们就直接exit退出,这样,杀软就无法继续对我们进行行为分析了。
explorer.exe是Windows程序管理器或者文件资源管理器,它用于管理Windows图形壳,包括桌面和文件管理,删除该程序会导致Windows图形界面无法使用。
头文件
1 #include <iostream> 2 #include <windows.h> 3 #include <tlhelp32.h> 4 #include <tchar.h>
核心代码
通过Loadlibrary 和 GetProcAddress 来获取 CreateToolhelp32Snapshot函数的地址 获取一个快照,找到当前的父进程,当然这个函数也可以直接用
HMODULE hModule = LoadLibrary(_T("Kernel32.dll")); FARPROC Address = GetProcAddress(hModule, "CreateToolhelp32Snapshot");
镶嵌一点汇编语言进行传参
_asm{ push 0 push 2 call Address mov hkz, eax }
记得传参是从右往左传参 所以CreateToolhelp32Snapshot的第一个参数是 2
第二个参数是 0 传入0的话就是默认的当前进程
然后遍历并返回,找到当前程序的父进程
pe.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hkz, &pe)) { do { if (pe.th32ProcessID == pid) { ParentProcessID = pe.th32ParentProcessID; break; } }while (Process32Next(hkz, &pe)); } return ParentProcessID;
然后找到explorer.exe的Pid
1 DWORD get_explorer_processid() { 2 DWORD explorer_id = -1; 3 PROCESSENTRY32 pe; 4 HANDLE hkz; 5 HMODULE hModule = LoadLibrary(_T("Kernel32.dll")); 6 7 if (hModule == NULL) { 8 OutputDebugString(_T("Loaddll error")); 9 return(-1); 10 } 11 FARPROC Address = GetProcAddress(hModule, "CreateToolhelp32Snapshot"); 12 13 if (Address == NULL) { 14 OutputDebugString(_T("GetProc error")); 15 return(-1); 16 } 17 18 _asm { 19 push 0 20 push 2 21 call Address 22 mov hkz, eax 23 } 24 25 pe.dwSize = sizeof(PROCESSENTRY32); 26 27 if (Process32First(hkz, &pe)) { 28 do { 29 if (_wcsicmp(pe.szExeFile, L"explorer.exe") == 0) 30 { 31 explorer_id = pe.th32ProcessID; 32 break; 33 } 34 } while (Process32Next(hkz, &pe)); 35 } 36 return explorer_id; 37 }
将我们进程的父进程的pid和explorer.exe 的pid进行比较,相同则运行,不同就直接退出了,我这里是个MessageBox
void domain() { DWORD explorer_id = get_explorer_processid(); DWORD parent_id = get_parent_processid(GetCurrentProcessId()); if (explorer_id == parent_id) { MessageBox(NULL, L"Fine", L"OK", NULL); } else { exit(1); } }
验证
正常启动
我们假设通过x32debug调试,相当于另一个进程打开了我们保护的进程,可以看到直接结束了