new email and some changes

This commit is contained in:
Max Raulea 2026-07-22 11:05:07 +02:00
parent 6f7bc287fe
commit 1abac35edc
17 changed files with 210 additions and 25 deletions

View file

@ -75,7 +75,7 @@ add_subdirectory(script-engine)
link_directories(libraries/zydis/user libraries/keystone/release-lib)
add_subdirectory(libhyperdbg)
find_package(Threads REQUIRED)
target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone Threads::Threads)
target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone Threads::Threads ${CMAKE_DL_LIBS})
add_subdirectory(hyperdbg-cli)
target_link_libraries(hyperdbg-cli libhyperdbg)

View file

@ -50,6 +50,10 @@
// POSIX sleep primitives (usleep) backing the Win32 Sleep() shim below
# include <unistd.h>
// DECIMAL_DIG and the FLT/DBL limits (ISO C99 <float.h>); MSVC exposes these
// transitively through its CRT/pch, glibc needs the explicit include
# include <float.h>
// Windows string/char types
typedef char TCHAR;
typedef char * LPTSTR;

View file

@ -1,6 +1,6 @@
/**
* @file nt-list.h
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief Cross-platform NT-style intrusive doubly-linked list helpers + CONTAINING_RECORD
* @details The shared debugger code uses the NT LIST_ENTRY API (InitializeListHead,
* InsertHeadList, RemoveEntryList, CONTAINING_RECORD, ...). On Windows these

View file

@ -1,6 +1,6 @@
/**
* @file platform-ioctl.c
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief User mode cross-platform implementation of the local kernel-driver IOCTL transport
* @details See platform-ioctl.h. The Windows branch forwards directly to Win32
* DeviceIoControl / CreateFileA. The Linux branch is currently stubbed and is

View file

@ -1,6 +1,6 @@
/**
* @file platform-lib-calls.c
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief User mode Cross platform APIs for platofrm dependend library calls
* @details
* @version 0.19
@ -21,6 +21,7 @@
# include <string.h>
# include <strings.h>
# include <signal.h>
# include <dlfcn.h>
#endif // defined(__linux__)
/**
@ -643,6 +644,46 @@ PlatformOpenFileForWriting(const WCHAR * Path)
#endif
}
/**
* @brief Platform independent wrapper to open a file for writing with
* OPEN_ALWAYS semantics (open existing without truncating, else create),
* taking a narrow (char*) path
*
* @details Unlike PlatformOpenFileForWriting (wide path, CREATE_ALWAYS/truncate)
* this keeps any existing file content. The Linux handle is a FILE* so
* it works with PlatformWriteFile / PlatformCloseFile.
*
* @param Path narrow path of the file to open or create
* @return HANDLE to the opened file, or INVALID_HANDLE_VALUE on failure
*/
HANDLE
PlatformOpenFileForWritingNarrow(const CHAR * Path)
{
#if defined(_WIN32)
return CreateFileA(Path, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
#elif defined(__linux__)
//
// NOT YET TESTED!!
// "r+b" opens an existing file at offset 0 without truncating (matching
// OPEN_ALWAYS on an existing file); if it does not exist, create it with
// "w+b". Return the FILE* as the HANDLE (PlatformWriteFile/PlatformCloseFile
// treat the Linux handle as a FILE*).
//
FILE * File = fopen(Path, "r+b");
if (File == NULL)
{
File = fopen(Path, "w+b");
}
if (File == NULL)
{
return INVALID_HANDLE_VALUE;
}
return (HANDLE)File;
#else
# error "Unsupported platform"
#endif
}
/**
* @brief Platform independent wrapper to write a buffer to an open file
*
@ -990,3 +1031,65 @@ PlatformGetExitCodeProcess(HANDLE Process, LPDWORD ExitCode)
# error "Unsupported platform"
#endif
}
/**
* @brief Platform independent wrapper for LoadLibrary
*
* @param ModulePath narrow path of the shared module to load
* @return HMODULE handle to the loaded module, or NULL on failure
*/
HMODULE
PlatformLoadLibrary(const CHAR * ModulePath)
{
#if defined(_WIN32)
return LoadLibraryA(ModulePath);
#elif defined(__linux__)
// NOT YET TESTED!!
return (HMODULE)dlopen(ModulePath, RTLD_NOW | RTLD_LOCAL);
#else
# error "Unsupported platform"
#endif
}
/**
* @brief Platform independent wrapper for GetProcAddress
*
* @param Module module handle returned by PlatformLoadLibrary
* @param ProcName name of the exported symbol to resolve
* @return PVOID address of the symbol, or NULL if not found
*/
PVOID
PlatformGetProcAddress(HMODULE Module, const CHAR * ProcName)
{
#if defined(_WIN32)
return (PVOID)GetProcAddress(Module, ProcName);
#elif defined(__linux__)
// NOT YET TESTED!!
return dlsym((void *)Module, ProcName);
#else
# error "Unsupported platform"
#endif
}
/**
* @brief Platform independent wrapper for FreeLibrary
*
* @param Module module handle returned by PlatformLoadLibrary
* @return BOOL non-zero on success, zero on failure
*/
BOOL
PlatformFreeLibrary(HMODULE Module)
{
#if defined(_WIN32)
return FreeLibrary(Module);
#elif defined(__linux__)
//
// NOT YET TESTED!!
// dlclose returns 0 on success (opposite of FreeLibrary), so invert it to
// preserve the "non-zero == success" contract.
//
return (BOOL)(dlclose((void *)Module) == 0);
#else
# error "Unsupported platform"
#endif
}

View file

@ -1,6 +1,6 @@
/**
* @file platform-serial.c
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief User mode cross-platform implementation of the kernel-debugger serial transport
* @details See platform-serial.h. The Windows branch wraps the Win32 serial primitives
* (CreateFile / Comm* / overlapped ReadFile/WriteFile) and owns the per-direction

View file

@ -1,6 +1,6 @@
/**
* @file platform-signal.c
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief User mode cross-platform implementation of the console-control handler
* @details See platform-signal.h. The Windows branch forwards to SetConsoleCtrlHandler.
* The Linux branch blocks the handled signals and dispatches them from a

View file

@ -1,6 +1,6 @@
/**
* @file platform-ioctl.h
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief User mode cross-platform interface for the local kernel-driver IOCTL transport
* @details Distinct from the serial transport (platform-serial), which talks to a remote
* debuggee. This interface is the LOCAL control channel: the userspace library

View file

@ -1,6 +1,6 @@
/**
* @file platform-lib-calls.h
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief User mode Cross platform APIs for platofrm dependend library calls
* @details
* @version 0.19
@ -157,6 +157,16 @@ PlatformWriteConsole(const VOID * Buffer, DWORD NumberOfBytes);
HANDLE
PlatformOpenFileForWriting(const WCHAR * Path);
//
// Narrow (char*) variant with OPEN_ALWAYS semantics (open existing, else
// create; no truncate), as opposed to the wide PlatformOpenFileForWriting above
// which truncates (CREATE_ALWAYS). Used by the event-forwarding file sink, whose
// path is already a narrow std::string, so it sidesteps the wide-char issue and
// works on Linux.
//
HANDLE
PlatformOpenFileForWritingNarrow(const CHAR * Path);
BOOLEAN
PlatformWriteFile(HANDLE FileHandle, const VOID * Buffer, DWORD NumberOfBytes);
@ -228,3 +238,20 @@ PlatformResumeThread(HANDLE Thread);
BOOL
PlatformGetExitCodeProcess(HANDLE Process, LPDWORD ExitCode);
//
// DYNAMIC LIBRARY LOADING
//
// Thin wrappers over LoadLibrary/GetProcAddress/FreeLibrary, used by the
// event-forwarding "module" sink (loads a plugin exporting
// hyperdbg_event_forwarding). Windows = the Win32 calls; Linux = dlopen/dlsym/
// dlclose (exact 1:1 semantic map).
//
HMODULE
PlatformLoadLibrary(const CHAR * ModulePath);
PVOID
PlatformGetProcAddress(HMODULE Module, const CHAR * ProcName);
BOOL
PlatformFreeLibrary(HMODULE Module);

View file

@ -1,6 +1,6 @@
/**
* @file platform-serial.h
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief User mode cross-platform interface for the kernel-debugger serial transport
* @details The kernel-debugging *protocol* in kd.cpp is platform independent; only
* the byte transport underneath it (serial COM port / named pipe) is OS

View file

@ -1,6 +1,6 @@
/**
* @file platform-signal.h
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief User mode cross-platform interface for the console-control (CTRL+C / CTRL+BREAK) handler
* @details HyperDbg installs a single handler (BreakController) that pauses the
* debuggee when the user hits CTRL+C / CTRL+BREAK. The handler body is

View file

@ -193,6 +193,8 @@ if(UNIX)
list(APPEND SourceFiles "code/debugger/user-level/pe-parser-linux.cpp")
list(REMOVE_ITEM SourceFiles "code/debugger/driver-loader/install.cpp")
list(APPEND SourceFiles "code/debugger/driver-loader/install-linux.cpp")
list(REMOVE_ITEM SourceFiles "code/debugger/communication/namedpipe.cpp")
list(APPEND SourceFiles "code/debugger/communication/namedpipe-linux.cpp")
endif()
add_library(libhyperdbg SHARED ${SourceFiles})

View file

@ -142,7 +142,7 @@ ForwardingCloseOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor)
//
// Close the handle
//
CloseHandle(SourceDescriptor->Handle);
PlatformCloseFile(SourceDescriptor->Handle);
//
// Return the status
@ -183,7 +183,7 @@ ForwardingCloseOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor)
//
// Free the library
//
FreeLibrary(SourceDescriptor->Module);
PlatformFreeLibrary(SourceDescriptor->Module);
//
// Return the status
@ -226,7 +226,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
//
// Create a new file
//
HANDLE FileHandle = CreateFileA(Description.c_str(), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE FileHandle = PlatformOpenFileForWritingNarrow(Description.c_str());
//
// The handle might be INVALID_HANDLE_VALUE which will be
@ -236,7 +236,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
}
else if (SourceType == EVENT_FORWARDING_MODULE)
{
HMODULE ModuleHandle = LoadLibraryA(Description.c_str());
HMODULE ModuleHandle = PlatformLoadLibrary(Description.c_str());
if (ModuleHandle == NULL)
{
@ -244,7 +244,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
return INVALID_HANDLE_VALUE;
}
hyperdbg_event_forwarding_t hyperdbg_event_forwarding = (hyperdbg_event_forwarding_t)GetProcAddress(ModuleHandle, "hyperdbg_event_forwarding");
hyperdbg_event_forwarding_t hyperdbg_event_forwarding = (hyperdbg_event_forwarding_t)PlatformGetProcAddress(ModuleHandle, "hyperdbg_event_forwarding");
if (hyperdbg_event_forwarding == NULL)
{
@ -503,11 +503,9 @@ ForwardingWriteToFile(HANDLE FileHandle, CHAR * Message, UINT32 MessageLength)
DWORD BytesWritten = 0;
BOOL ErrorFlag = FALSE;
ErrorFlag = WriteFile(FileHandle, // open file handle
Message, // start of data to write
MessageLength, // number of bytes to write
&BytesWritten, // number of bytes that were written
NULL); // no overlapped structure
ErrorFlag = PlatformWriteFile(FileHandle, // open file handle
Message, // start of data to write
MessageLength); // number of bytes to write
return TRUE;

View file

@ -1,6 +1,6 @@
/**
* @file install-linux.cpp
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief Linux stub implementations of the driver-loader (install.cpp)
* @details The Windows implementation (install.cpp) loads/unloads the HyperDbg
* kernel-mode driver (the .sys file that contains the actual debugging

View file

@ -1,6 +1,6 @@
/**
* @file symbol-linux.cpp
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief Linux stub implementations of the symbol subsystem
* @details The Windows implementation uses DbgHelp + PDB files (symbol-parser/).
* Linux uses ELF/DWARF which requires a separate implementation.

View file

@ -1,6 +1,6 @@
/**
* @file pe-parser-linux.cpp
* @author Max Raulea (max.raulea@gmail.com)
* @author Max Raulea (max.raulea@hyperdbg.org)
* @brief Linux stub implementations of the PE (Portable Executable) parser
* @details The Windows implementation (pe-parser.cpp) parses the full PE image
* format and depends on the complete set of Windows IMAGE_* headers,

View file

@ -77,9 +77,11 @@ Shared, OS-neutral headers:
| `.../script-engine/symbol-linux.cpp` | `symbol.cpp` (DbgHelp + PDB) | All `Symbol*` functions. Only `SymbolConvertNameOrExprToAddress` does real work: parses a plain hex/decimal literal so numeric addresses work. | Real ELF/DWARF symbol parser (libdw / libelf / libbfd). |
| `.../user-level/pe-parser-linux.cpp` | `pe-parser.cpp` (Windows PE format) | The 3 public fns: `PeShowSectionInformationAndDump`, `PeIsPE32BitOr64Bit` (→ FALSE), `PeGetSyscallNumber` (→ 0). | Recreate the Windows `IMAGE_*` headers for Linux, then port `pe-parser.cpp`. Only needed for Windows-target debugging on Linux. |
| `.../driver-loader/install-linux.cpp` | `install.cpp` (SCM driver loader) | The 2 Linux-visible public fns: `ManageDriver` (→ FALSE) and `SetupPathForFileName` (→ FALSE). The 4 `SC_HANDLE` helpers (`InstallDriver`/`RemoveDriver`/`StartDriver`/`StopDriver`) are guarded out of `install.h` on Linux (never referenced there). | `ManageDriver`: load/unload a future HyperDbg Linux kernel module via `finit_module`/`delete_module` (needs CAP_SYS_MODULE). `SetupPathForFileName`: `readlink("/proc/self/exe")` + strip + append + `access()` (generic "find a file beside my binary"; also used by hwdbg). |
| `.../communication/namedpipe-linux.cpp` | `namedpipe.cpp` (Win32 named-pipe IPC) | All 10 public `NamedPipeServer*`/`NamedPipeClient*` fns. `Create*``INVALID_HANDLE_VALUE` (print); send/read → 0/FALSE; close → no-op (quiet, unreachable once Create fails). The two internal `*Example()` demos are not in the Linux TU. | Back with a filesystem FIFO (`mkfifo`) or, better for framed bidirectional messages, an `AF_UNIX` socket derived from the `\\.\pipe\NAME` string; overlapped/event I/O collapses to blocking `read`/`write`. |
All three self-guard with `#ifdef __linux__` and print
`"... is not supported on Linux yet"` at runtime.
All four self-guard with `#ifdef __linux__` and print
`"... is not supported on Linux yet"` at runtime (named-pipe: only in the
`Create*` entry points, to avoid per-loop spam).
---
@ -320,6 +322,55 @@ over serial/namedpipe). Two mechanical fixes:
Matches the CTRL_*/PROCESS_*/ERROR_* constant blocks already there. Actual Linux
serial I/O is still the platform-serial termios TODO.
### formats.cpp DECIMAL_DIG — DONE (2026-07-22)
`meta-commands/formats.cpp:94` uses `DECIMAL_DIG` (the ISO C99 `<float.h>` macro,
widest-float round-trip digit count) in a `.formats` output format string. MSVC
exposes it transitively via its CRT/pch; glibc needs the explicit include.
**Pure addition:** `#include <float.h>` in the `Environment.h` Linux block
(next to `<wchar.h>`/`<unistd.h>`). Standard header, cross-platform-safe.
### forwarding.cpp output-event forwarding — DONE (2026-07-22)
`communication/forwarding.cpp` is the debug-output forwarding subsystem (sinks:
file / TCP / named-pipe / loadable module). Bucket-2, multi-category. User chose
**new Platform\* wrappers** for both non-trivial subsystems (not guards).
- **Clean swap:** `WriteFile``PlatformWriteFile` (exact match; the original
assigns the result then unconditionally `return TRUE`, so the error-check below
was already dead code — `BytesWritten` out-param dropped, still referenced by
that dead code so no unused-var). `CloseHandle` (FILE source)→`PlatformCloseFile`
(fclose on Linux — matches the FILE\* the new open returns).
- **File sink** (`CreateFileA`, narrow path + `OPEN_ALWAYS`): existing
`PlatformOpenFileForWriting` did NOT fit (it is wide + `CREATE_ALWAYS`/truncate),
so **pure addition** `PlatformOpenFileForWritingNarrow(const CHAR *)` — Windows
`CreateFileA(...OPEN_ALWAYS...)`; Linux `fopen("r+b")` then `fopen("w+b")`
(open-existing-no-truncate, else create) returning the `FILE*` as the HANDLE.
Named `...Narrow` (user preference) to flag the char-width difference vs the
wide variant. Because the path is already a narrow `std::string`, this sink
actually works on Linux — no wide-char blocker.
- **Module/plugin sink** (`LoadLibraryA`/`GetProcAddress`/`FreeLibrary`): **pure
additions** `PlatformLoadLibrary`/`PlatformGetProcAddress`/`PlatformFreeLibrary`
in platform-lib-calls — Windows real; Linux `dlopen(RTLD_NOW|RTLD_LOCAL)`/
`dlsym`/`dlclose` (dlclose return inverted to keep "non-zero == success").
`PlatformGetProcAddress` returns `PVOID` (no `FARPROC` on Linux); caller casts.
- **Build:** added `#include <dlfcn.h>` to the platform-lib-calls Linux includes;
added `${CMAKE_DL_LIBS}` to the `libhyperdbg` link (top-level CMakeLists) — the
portable dl link (empty where dl is in libc). Only libhyperdbg compiles
platform-lib-calls.c on Linux, so no other target needed it.
- ⚠️ All four new Linux branches marked `NOT YET TESTED!!` in source.
### namedpipe.cpp — DONE via namedpipe-linux.cpp + CMake swap (2026-07-22)
`communication/namedpipe.cpp` is a whole Windows-only TU (Win32 named-pipe IPC:
server `CreateNamedPipe`/`ConnectNamedPipe`, client `CreateFileA` on `\\.\pipe\`
+ overlapped `ReadFile`/`WriteFile` via `g_OverlappedIoStructureFor*Debugger`).
Followed pattern-2 (like symbol/pe-parser/install): new `namedpipe-linux.cpp`
`#ifdef __linux__` stubs of the 10 public `NamedPipe{Server,Client}*` fns;
`namedpipe.cpp` left 100% untouched; CMake `if(UNIX)` REMOVE_ITEM + APPEND swap.
6 callers link the stubs transparently (forwarding/kd/debug/export/tests/test).
See the Linux-replacement-files table above for the FIFO/AF_UNIX TODO.
---
## TODO ledger — revisit before Linux is functional