Skip to content

Instantly share code, notes, and snippets.

@Egor-Skriptunoff
Last active April 25, 2020 21:17
Show Gist options
  • Select an option

  • Save Egor-Skriptunoff/fc40fb206f5df6b8027e71a39f5ccfb5 to your computer and use it in GitHub Desktop.

Select an option

Save Egor-Skriptunoff/fc40fb206f5df6b8027e71a39f5ccfb5 to your computer and use it in GitHub Desktop.

Revisions

  1. Egor-Skriptunoff revised this gist Apr 25, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion LGS_OutputDebugMessage_Receiver.lua
    Original file line number Diff line number Diff line change
    @@ -63,6 +63,7 @@ if PID and ffi.C.DebugActiveProcess(PID) ~= 0 then
    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
    @@ -81,7 +82,7 @@ if PID and ffi.C.DebugActiveProcess(PID) ~= 0 then
    print(str)
    end
    end
    ffi.C.ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x10002) -- DBG_CONTINUE
    ffi.C.ContinueDebugEvent(PID, ThreadId, 0x10002) -- DBG_CONTINUE
    end
    until exit
    ffi.C.DebugActiveProcessStop(PID)
  2. Egor-Skriptunoff created this gist Apr 24, 2020.
    89 changes: 89 additions & 0 deletions LGS_OutputDebugMessage_Receiver.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    -- 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 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(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x10002) -- DBG_CONTINUE
    end
    until exit
    ffi.C.DebugActiveProcessStop(PID)
    ffi.C.CloseHandle(ProcessHandle)
    end