----------------------------------------------------- // ============================================================================ // x64DBG WINDOWS/WINE PLUGIN HOOK MODULE: PRODUCTION IMPLEMENTATION // ============================================================================ #include #include #define PLUG_SDKVERSION 5 typedef size_t CBTYPE; struct PLUG_INITSTRUCT { int pluginHandle; int sdkVersion; int pluginVersion; char pluginName[256]; }; int pluginHandle; HANDLE hPipe = INVALID_HANDLE_VALUE; struct __attribute__((packed)) WineIpcPayload { unsigned __int64 rip; unsigned int eflags; unsigned int buffer_len; unsigned char bytes[15]; }; void AttemptPipeConnection() { // Wine intercepts Windows named pipe routing and maps them // straight to Unix sockets automatically hPipe = CreateFileA( "\\\\.\\pipe\\stave_bridge_ipc", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); } extern "C" __declspec(dllexport) bool pluginit(PLUG_INITSTRUCT* initStruct) { initStruct->pluginVersion = 7; initStruct->sdkVersion = PLUG_SDKVERSION; strcpy(initStruct->pluginName, "WarlockStaveWineBridgeMaster"); pluginHandle = initStruct->pluginHandle; AttemptPipeConnection(); return true; } extern "C" __declspec(dllexport) void plugstop() { if (hPipe != INVALID_HANDLE_VALUE) { CloseHandle(hPipe); hPipe = INVALID_HANDLE_VALUE; } } // Triggered automatically by the x64dbg engine core on every // user breakpoint step execution event extern "C" __declspec(dllexport) void CBSTEPPED(CBTYPE cbType, void* info) { if (hPipe == INVALID_HANDLE_VALUE) { AttemptPipeConnection(); if (hPipe == INVALID_HANDLE_VALUE) return; } CONTEXT context; context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; HANDLE currentThread = GetCurrentThread(); if (GetThreadContext(currentThread, &context)) { WineIpcPayload payload; payload.rip = context.Rip; payload.eflags = context.EFlags; payload.buffer_len = 15; memset(payload.bytes, 0, 15); SIZE_T bytesRead = 0; ReadProcessMemory( GetCurrentProcess(), (LPCVOID)context.Rip, payload.bytes, 15, &bytesRead ); if (bytesRead > 0) { payload.buffer_len = (unsigned int)bytesRead; DWORD bytesWritten; WriteFile(hPipe, &payload, sizeof(payload), &bytesWritten, NULL); } } } 10B. Ghidra Java JNI Bridge (WarlockStaveBridge.java)