In Visual C/C++ 之中运行你的 .NET Executable Assembly(Use Microsoft .NET CLR Framework) != Mono Jit

53 篇文章 2 订阅
#include <string>
#include <cstring>
#include <iostream>
#include <metahost.h>
#include <Windows.h>

#include "rc4.h"
#include "resource.h"

// --confusion = C:\Users\yxg\Desktop\tun2socks\tun2socks\bin\Debug\publish\public\lib35.exe
// --confusion = C:\Users\yxg\Desktop\tun2socks\tun2socks\bin\Debug\publish\public\lib40.exe

#pragma comment(lib, "MSCorEE.lib")

// Import mscorlib.tlb (Microsoft Common Language Runtime Class Library).
#import "mscorlib.tlb" raw_interfaces_only				\
    high_property_prefixes("_get","_put","_putref")		\
    rename("ReportEvent", "InteropServices_ReportEvent")
using namespace mscorlib;
#pragma endregion

class FunctionHook
{
public:
    unsigned char           a[5];
    unsigned char           b[5];
    void*                   c;
    CRITICAL_SECTION        cs;

public:
    inline FunctionHook() : c(0), cs{}
    {
        InitializeCriticalSection(&cs);
    }
    inline ~FunctionHook()
    {
        DeleteCriticalSection(&cs);
    }

public:
    inline void             Enter()
    {
        EnterCriticalSection(&cs);
    }
    inline void             Exit()
    {
        LeaveCriticalSection(&cs);
    }

public:
    inline bool             Protect(void* p)
    {
        DWORD dw;
        return VirtualProtect(p, 5, PAGE_EXECUTE_READWRITE, &dw) ? 1 : 0;
    }
    inline void             Install(void* sources, void* destination)
    {
        Protect(sources);
        memcpy(a, sources, 5);
        b[0] = 0xE9;
        *(char**)&b[1] = (char*)((char*)destination - ((char*)sources + 5));
        c = sources;
        Resume();
    }
    inline void             Suspend()
    {
        memcpy(c, a, 5);
    }
    inline void             Resume()
    {
        memcpy(c, b, 5);
    }
};

static std::string g_szAppDomainPath;
static FunctionHook g_fSetConsoleTitleW;

static std::string 
W2A(DWORD codepage, const WCHAR* s, int len)
{
    if (s == NULL || (len != -1 && len <= 0))
    {
        return NULL;
    }
    if (len == -1)
    {
        len = WideCharToMultiByte(codepage, 0, s, -1, NULL, 0, 0, 0);
    }
    if (len <= 0)
    {
        return NULL;
    }
    std::string result = "";
    CHAR* contents = (CHAR*)malloc(len);
    if (contents)
    {
        WideCharToMultiByte(codepage, 0, s, -1, contents, len, 0, 0);
        result = contents;
        free(contents);
    }
    return result;
}

static std::string 
carg(const char* name, int argc, const char* argv[])
{
    if (argc <= 1)
        return "";
    for (int i = 1; i < argc; i++) {
        char* p = (char*)strstr(argv[i], name);
        if (!p)
            continue;
        p = strchr(p, '=');
        if (!p)
            continue;
        return 1 + p;
    }
    return "";
}

static HGLOBAL
GetResourceHandle(DWORD dwResourceId, DWORD& rdwResourceSize)
{
    rdwResourceSize = 0;

    HINSTANCE hModule = GetModuleHandleA(NULL);
    // "ZIP" 是自定义资源类型,可以自己决定
    HRSRC hSrc = FindResourceA(hModule, MAKEINTRESOURCEA(dwResourceId), "tun2socks");
    if (hSrc == NULL)
    {
        return false;
    }

    HGLOBAL hGlobalResource = LoadResource(hModule, hSrc);
    if (hGlobalResource == NULL)
    {
        return false;
    }

    rdwResourceSize = SizeofResource(hModule, hSrc);
    return hGlobalResource;
}

static void 
ConfusionAssemblyStream(const void* resourceData, int resourceSize)
{
    unsigned char key[8];
    key[0] = 'a';
    key[1] = 'a';
    key[2] = '1';
    key[3] = '2';
    key[4] = '3';
    key[5] = 'o';
    key[6] = '!';
    key[7] = '!';
    rc4_crypt(key, 8, (unsigned char*)resourceData, resourceSize, 0, 0);
}

static int
DecodeResourceAssembly(const void* pResourceData, DWORD dwResourceSize)
{
    ConfusionAssemblyStream(pResourceData, (int)dwResourceSize);
    return 0;
}

static int 
ConfusionAssemblyFile(const char* pResourceFile)
{
    int error = 0;
    HANDLE hFile = CreateFileA(
        pResourceFile,   //文件名
        GENERIC_READ | GENERIC_WRITE, //对文件进行读写操作
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,  //打开已存在文件
        FILE_ATTRIBUTE_NORMAL,
        0);
    if (NULL == hFile || INVALID_HANDLE_VALUE == hFile)
    {
        error = -1;
        return error;
    }

    HANDLE hFileMapping = NULL;
    void* pFileView = NULL;
    do
    {
        DWORD dwLow;
        DWORD dwHigh;
        dwLow = GetFileSize(hFile, &dwHigh);
        if (0 == dwLow)
        {
            error = -2;
            break;
        }

        hFileMapping = CreateFileMapping(
            hFile,
            NULL,
            PAGE_READWRITE,  //对映射文件进行读写
            dwHigh,
            dwLow,   //这两个参数共64位,所以支持的最大文件长度为16EB
            NULL);
        if (NULL == hFile || INVALID_HANDLE_VALUE == hFile)
        {
            hFileMapping = NULL;
            error = -3;
            break;
        }

        pFileView = MapViewOfFile(
            hFileMapping,
            FILE_MAP_READ | FILE_MAP_WRITE,
            0,
            0,
            0);
        if (NULL == pFileView)
        {
            error = -4;
            break;
        }

        ConfusionAssemblyStream(pFileView, (int)dwLow);
    } while (0, 0);
    if (pFileView)
    {
        UnmapViewOfFile(pFileView);
    }
    if (hFileMapping)
    {
        CloseHandle(hFileMapping);
    }
    if (hFile)
    {
        CloseHandle(hFile);
    }
    return error;
}

static std::wstring
ExtractResource(DWORD dwResourceId)
{
    DWORD RAW_ASSEMBLY_LENGTH = 0;
    HGLOBAL hGlobalResource = GetResourceHandle(dwResourceId, RAW_ASSEMBLY_LENGTH);

    const void* pResourceData = ::LockResource(hGlobalResource);
    if (!pResourceData)
    {
        FreeResource(hGlobalResource);
        return L"";
    }

    WCHAR wzSystemTempPath[MAX_PATH];
    DWORD dwPathSize = GetTempPathW(MAX_PATH, wzSystemTempPath);
    if (dwPathSize > MAX_PATH || (dwPathSize == 0))
    {
        UnlockResource(pResourceData);
        FreeResource(hGlobalResource);
        return L"";
    }

    WCHAR wzRandomTempFileName[MAX_PATH];
    GetTempFileNameW(wzSystemTempPath, NULL, 0, wzRandomTempFileName);

    HANDLE hFile = CreateFileW(wzRandomTempFileName,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, 
        NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        wzRandomTempFileName[0] = L'\x0';
    }
    else
    {
        void* pszLib = malloc(RAW_ASSEMBLY_LENGTH);
        memcpy(pszLib, pResourceData, RAW_ASSEMBLY_LENGTH);
        DecodeResourceAssembly(pszLib, RAW_ASSEMBLY_LENGTH);

        DWORD dwNumberOfBytesWritten;
        if (!WriteFile(hFile, pszLib, RAW_ASSEMBLY_LENGTH, &dwNumberOfBytesWritten, NULL) ||
            dwNumberOfBytesWritten != RAW_ASSEMBLY_LENGTH)
        {
            wzRandomTempFileName[0] = L'\x0';
        }

        free(pszLib);
        CloseHandle(hFile);
    }

    UnlockResource(pResourceData);
    FreeResource(hGlobalResource);

    return wzRandomTempFileName;
}

static int
ExecuteEntryPoint(LPCWSTR pwzVersion, DWORD dwResourceId)
{
    ICLRMetaHost* pMetaHost = NULL;
    HRESULT hr;

    /* Get ICLRMetaHost instance */

    hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (VOID**)&pMetaHost);
    if (FAILED(hr))
    {
        OutputDebugStringA("[!] CLRCreateInstance(...) failed\n");
        return -1;
    }

    OutputDebugStringA("[+] CLRCreateInstance(...) succeeded\n");
    ICLRRuntimeInfo* pRuntimeInfo = NULL;

    /* Get ICLRRuntimeInfo instance */

    hr = pMetaHost->GetRuntime(pwzVersion, IID_ICLRRuntimeInfo, (VOID**)&pRuntimeInfo);
    if (FAILED(hr))
    {
        pMetaHost->Release();
        OutputDebugStringA("[!] pMetaHost->GetRuntime(...) failed\n");
        return -1;
    }

    OutputDebugStringA("[+] pMetaHost->GetRuntime(...) succeeded\n");
    BOOL bLoadable;

    /* Check if the specified runtime can be loaded */

    hr = pRuntimeInfo->IsLoadable(&bLoadable);
    if (FAILED(hr) || !bLoadable)
    {
        pRuntimeInfo->Release();
        pMetaHost->Release();
        OutputDebugStringA("[!] pRuntimeInfo->IsLoadable(...) failed\n");
        return -1;
    }

    OutputDebugStringA("[+] pRuntimeInfo->IsLoadable(...) succeeded\n");
    ICorRuntimeHost* pRuntimeHost = NULL;

    /* Get ICorRuntimeHost instance */

    hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (VOID**)&pRuntimeHost);
    if (FAILED(hr))
    {
        pRuntimeInfo->Release();
        pMetaHost->Release();
        OutputDebugStringA("[!] pRuntimeInfo->GetInterface(...) failed\n");
        return -1;
    }

    OutputDebugStringA("[+] pRuntimeInfo->GetInterface(...) succeeded\n");

    /* Start the CLR */
    hr = pRuntimeHost->Start();
    if (FAILED(hr))
    {
        pRuntimeHost->Release();
        pRuntimeInfo->Release();
        pMetaHost->Release();
        OutputDebugStringA("[!] pRuntimeHost->Start() failed\n");
        return -1;
    }

    OutputDebugStringA("[+] pRuntimeHost->Start() succeeded\n");

    IUnknownPtr pAppDomainThunk = NULL;
    hr = pRuntimeHost->GetDefaultDomain(&pAppDomainThunk);
    if (FAILED(hr))
    {
        pRuntimeHost->Release();
        pRuntimeInfo->Release();
        pMetaHost->Release();
        OutputDebugStringA("[!] pRuntimeHost->GetDefaultDomain(...) failed\n");
        return -1;
    }

    OutputDebugStringA("[+] pRuntimeHost->GetDefaultDomain(...) succeeded\n");

    _AppDomainPtr pDefaultAppDomain = NULL;
    /* Equivalent of System.AppDomain.CurrentDomain in C# */

    hr = pAppDomainThunk->QueryInterface(__uuidof(_AppDomain), (VOID**)&pDefaultAppDomain);
    if (FAILED(hr))
    {
        pAppDomainThunk->Release();
        pRuntimeHost->Release();
        pRuntimeInfo->Release();
        pMetaHost->Release();
        OutputDebugStringA("[!] pAppDomainThunk->QueryInterface(...) failed\n");
        return -1;
    }

    OutputDebugStringA("[+] pAppDomainThunk->QueryInterface(...) succeeded\n");

    std::wstring wzAppDomainPathW = ExtractResource(dwResourceId);
    if (!wzAppDomainPathW.empty())
    {
        g_szAppDomainPath = W2A(CP_ACP, wzAppDomainPathW.data(), -1);
    }
    BSTR wzAssemblyFileName = SysAllocString(wzAppDomainPathW.data());

    long lRetVal = 0;
    hr = pDefaultAppDomain->ExecuteAssembly_2(wzAssemblyFileName, &lRetVal);

    pDefaultAppDomain->Release();
    pAppDomainThunk->Release();
    pRuntimeHost->Release();
    pRuntimeInfo->Release();
    pMetaHost->Release();
    if (wzAssemblyFileName)
    {
        SysFreeString(wzAssemblyFileName);
    }
    return 0;
}

static std::string 
ReplaceAllText(const std::string& s, const std::string& oldValue, const std::string& newValue)
{
    std::string r = s;
    std::string::size_type pos = 0;
    while ((pos = r.find(oldValue)) != std::string::npos)   //替换所有指定子串
    {
        r.replace(pos, oldValue.length(), newValue);
    }
    return r;
}

static BOOL WINAPI
__SetConsoleTitleW(LPCWSTR lpConsoleTitle)
{
    if (!lpConsoleTitle)
    {
        lpConsoleTitle = L"";
    }
    std::string szConsoleTitle = W2A(CP_ACP, lpConsoleTitle, -1);
    do
    {
        std::string szConsoleTemp = ReplaceAllText(szConsoleTitle, "/", "\\");
        if (0 != _strnicmp(szConsoleTemp.data(), "file:\\\\\\", 9))
        {
            if (0 == _stricmp(szConsoleTemp.data() + 8, g_szAppDomainPath.data()))
            {
                break;
            }
        }
        SetConsoleTitleA(szConsoleTitle.data());
    } while (0, 0);
    return TRUE;
}

static void 
Initialize(void)
{
    g_fSetConsoleTitleW.Install(SetConsoleTitleW, __SetConsoleTitleW);
}

static bool
ProcessInsideCommands(int argc, const char* argv[])
{
    std::string confusion = carg("--confusion", argc, argv);
    if (confusion.empty())
    {
        return false;
    }
    printf("confusion=%d\n", ConfusionAssemblyFile(confusion.data()));
    getchar();
    return true;
}

int main(int argc, const char* argv[])
{
    Initialize();
    if (ProcessInsideCommands(argc, argv))
    {
        return 0;
    }
    int rc = ExecuteEntryPoint(L"v4.0.30319", IDR_TUN2SOCKS2);
    if (0 != rc)
    {
        rc = ExecuteEntryPoint(L"v2.0.50727", IDR_TUN2SOCKS1);
    }
    return rc;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Visual Studio Code(VSCode)中配置C/C++开发环境,你需要安装必要的插件和设置合适的编译器工具链。以下是详细的步骤: 1. **安装C/C++插件**: - 安装`C/C++ Development Tools`插件,可以在VSCode的扩展商店中搜索并安装 "ms-vscode.cpptools"。 2. **配置C/C++ Extension**: - 打开VSCode,点击左下角的扩展图标(齿轮),找到已安装的"C/C++ Development Tools",确保其处于启用状态。 - 在扩展详情页面,点击"Configure",这将打开一个新的窗口。 3. **设置系统路径**: - 在`settings.json`文件中(或者使用`Ctrl + ,`快捷键打开),添加`"path"`字段,指定C编译器(如gcc或cl.exe)的路径。例如: ``` { "C_Cpp.intelliSenseEngine": "gcc-x64", "C_Cpp.default.compilerPath": "/usr/bin/g++" } ``` 将路径替换为你实际的编译器路径。 4. **设置编译配置**: - 在`tasks.json`文件中配置构建任务,定义构建命令和参数。比如,对于Linux上的GCC,可能像这样: ``` { "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "g++", "args": ["your_source.cpp", "-o", "your_executable"], "problemMatcher": ["$gcc"] } ] } ``` 根据你的项目需求修改源文件和目标文件名。 5. **设置调试配置**: - 如果你需要调试代码,还需要创建一个`launch.json`文件,配置启动程序的参数和断点行为。 6. **验证配置**: - 使用`C/C++: Compile Task`命令尝试编译一个简单的C/C++程序,如果能成功,说明配置基本正确。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值