Last active
April 25, 2020 21:17
-
-
Save Egor-Skriptunoff/fc40fb206f5df6b8027e71a39f5ccfb5 to your computer and use it in GitHub Desktop.
LuaJIT script to receive a message sent with OutputDebugMessage() from LGS/GHUB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- This LuaJIT script receives first OutputDebugMessage() from LGS/GHUB, prints the message to stdout and exits | |
-- Waiting is limited to 2 seconds | |
local timeout_msec = 2000 -- set 2^32-1 for infinite waiting | |
local ffi = require"ffi" | |
local psapi = ffi.load"psapi" | |
ffi.cdef[[ | |
uint32_t EnumProcesses(uint32_t *, uint32_t, uint32_t *); | |
void ** OpenProcess(uint32_t, uint32_t, uint32_t); | |
uint32_t CloseHandle(void **); | |
uint32_t GetModuleBaseNameA(void **, void **, void *, uint32_t); | |
uint32_t DebugActiveProcess(uint32_t); | |
uint32_t DebugActiveProcessStop(uint32_t); | |
uint32_t DebugSetProcessKillOnExit(uint32_t); | |
typedef struct { | |
uint32_t dwDebugEventCode; | |
uint32_t dwProcessId; | |
uint32_t dwThreadId; | |
union { | |
struct { | |
void ** hFile; | |
void ** hProcess; | |
} CreateProcessInfo; | |
struct { | |
void * lpDebugStringData; | |
uint16_t fUnicode; | |
uint16_t nDebugStringLength; | |
} DebugString; | |
} u; | |
} *LPDEBUG_EVENT; | |
uint32_t WaitForDebugEvent(LPDEBUG_EVENT, uint32_t); | |
uint32_t ContinueDebugEvent(uint32_t, uint32_t, uint32_t); | |
uint32_t ReadProcessMemory(void **, void *, void *, size_t, size_t *); | |
]] | |
local DWORDS = ffi.typeof"uint32_t[?]" | |
local block64K = DWORDS(16384) | |
local DebugEvent = ffi.cast("LPDEBUG_EVENT", block64K) | |
local block20 = DWORDS(5) | |
local PID | |
if psapi.EnumProcesses(block64K, ffi.sizeof(block64K), block20) ~= 0 then | |
for j = 0, block20[0]/4 - 1 do | |
local next_PID = block64K[j] | |
local ProcessHandle = ffi.C.OpenProcess(0x0410, 0, next_PID) -- PROCESS_VM_READ | PROCESS_QUERY_INFORMATION | |
if ProcessHandle ~= nil then | |
local name_len = psapi.GetModuleBaseNameA(ProcessHandle, nil, block20, ffi.sizeof(block20)) | |
ffi.C.CloseHandle(ProcessHandle) | |
local ProcessName = ffi.string(block20, name_len) | |
if ProcessName == "LCore.exe" or ProcessName == "lghub_agent.exe" then | |
PID = next_PID | |
break | |
end | |
end | |
end | |
end | |
if PID and ffi.C.DebugActiveProcess(PID) ~= 0 then | |
ffi.C.DebugSetProcessKillOnExit(0) | |
local ProcessHandle | |
repeat | |
local exit = ffi.C.WaitForDebugEvent(DebugEvent, timeout_msec) == 0 | |
if not exit then | |
local ThreadId = DebugEvent.dwThreadId | |
local info = DebugEvent.u.CreateProcessInfo | |
local DebugEventCode = DebugEvent.dwDebugEventCode | |
if DebugEventCode == 3 then -- CREATE_PROCESS_DEBUG_EVENT | |
ProcessHandle = info.hProcess | |
ffi.C.CloseHandle(info.hFile) | |
elseif DebugEventCode == 6 then -- LOAD_DLL_DEBUG_EVENT | |
ffi.C.CloseHandle(info.hFile) | |
elseif DebugEventCode == 8 then -- OUTPUT_DEBUG_STRING_EVENT | |
exit = true | |
info = DebugEvent.u.DebugString | |
local len = info.nDebugStringLength | |
if len ~= 0 and info.fUnicode == 0 | |
and ffi.C.ReadProcessMemory(ProcessHandle, info.lpDebugStringData, block64K, len, nil) ~= 0 | |
then | |
local str = ffi.string(block64K, len - 1) | |
print(str) | |
end | |
end | |
ffi.C.ContinueDebugEvent(PID, ThreadId, 0x10002) -- DBG_CONTINUE | |
end | |
until exit | |
ffi.C.DebugActiveProcessStop(PID) | |
ffi.C.CloseHandle(ProcessHandle) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment