Fixed bug that made script-engine segfault, explained in the porting status, so you can type commands now
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled

This commit is contained in:
Max Raulea 2026-07-24 22:28:44 +02:00
parent 1a9a62a916
commit bdc7a150cb
2 changed files with 79 additions and 5 deletions

View file

@ -78,6 +78,29 @@ find_package(Threads REQUIRED)
#target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone Threads::Threads ${CMAKE_DL_LIBS})
target_link_libraries(libhyperdbg Zycore Zydis script-engine Threads::Threads ${CMAKE_DL_LIBS})
#
# Each library must define its own HYPERDBG_* macro so that the IMPORT_EXPORT_*
# annotations in include/SDK/imports/user/ resolve to the "export" form
# (visibility("default")) while it is being built, and to the "import" form in
# every other translation unit. This mirrors what the Windows .vcxproj files do
# with __declspec(dllexport)/dllimport.
#
target_compile_definitions(script-engine PRIVATE HYPERDBG_SCRIPT_ENGINE)
target_compile_definitions(libhyperdbg PRIVATE HYPERDBG_LIBHYPERDBG)
#
# The annotations above only mean something if the default visibility is hidden;
# otherwise every symbol is exported anyway and visibility("default") is a no-op.
# Hiding by default matches the Windows model (private unless dllexport-ed) and
# keeps each library's internal globals private, so same-named module-private
# globals in different libraries are no longer merged by the dynamic linker.
#
set_target_properties(script-engine libhyperdbg PROPERTIES
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
)
add_subdirectory(hyperdbg-cli)
target_link_libraries(hyperdbg-cli libhyperdbg)

View file

@ -616,15 +616,66 @@ helper code reached only through those entry points, so it does not exist in the
Linux TU. `pt.cpp` is still left 100% untouched. CMake `if(UNIX)` now does the
usual REMOVE_ITEM + APPEND pair.
**Result: `hyperdbg-cli` links and runs on Linux for the first time.** The binary
starts, prints its banner and reaches the `HyperDbg>` prompt, and `.exit` exits
cleanly (0). The port is out of the compile/link phase and into the runtime phase.
**Result: `hyperdbg-cli` links and runs on Linux for the first time.** With the
symbol-visibility fix below also in place, the binary starts, reaches the
`HyperDbg>` prompt and executes host-side commands correctly — verified with
`.help`, `.help !monitor`, `.formats 0x1337` (full hex/decimal/octal/binary/char/
time/float/double output) and `? 5 * 8` (script engine) — then exits cleanly on
`.exit`. The port is out of the compile/link phase and into the runtime phase.
Run it with:
```bash
LD_LIBRARY_PATH=$PWD/libhyperdbg:$PWD/script-engine ./hyperdbg-cli/hyperdbg-cli
```
- [ ] Port `pt.cpp` for real — see the process-control entry in the TODO ledger.
---
### Symbol visibility: honour the existing IMPORT_EXPORT_* model — DONE (2026-07-24)
## TODO ledger — revisit before Linux is functional
Build-system change in the top-level `CMakeLists.txt`, two parts:
```cmake
target_compile_definitions(script-engine PRIVATE HYPERDBG_SCRIPT_ENGINE)
target_compile_definitions(libhyperdbg PRIVATE HYPERDBG_LIBHYPERDBG)
set_target_properties(script-engine libhyperdbg PROPERTIES
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON)
```
**Why.** `include/SDK/imports/user/HyperDbg*Imports.h` already carries a Linux
branch for each library's export macro — `IMPORT_EXPORT_LIBHYPERDBG` and friends
expand to `__attribute__((visibility("default")))` when the library's own
`HYPERDBG_*` macro is defined, and to nothing otherwise, mirroring the
`__declspec(dllexport)`/`dllimport` pair used on Windows. 77 symbols are annotated
for libhyperdbg and 29 for script-engine. Neither half was active on Linux: the
`HYPERDBG_*` defines were never set by CMake, and `visibility("default")` is a
no-op unless the compiler's baseline visibility is `hidden` (it can only raise a
symbol above the baseline, and the baseline was already default). So the whole
export model existed in the headers but did nothing, and every symbol in both
libraries was exported.
That matters because ELF merges same-named exported symbols across shared objects,
whereas a Windows DLL's non-exported globals are private to it. Three globals were
defined independently in both libraries and were being silently collapsed into one
object at load time:
| Symbol | libhyperdbg | script-engine |
|--------|-------------|---------------|
| `g_MessageHandler` | `header/globals/globals.h:460` | `code/globals.c:24` |
| `g_HwdbgInstanceInfo` | ” | ” |
| `g_HwdbgInstanceInfoIsValid` | ” | ” |
Turning both halves on restores the Windows semantics (private unless explicitly
exported). Exported data symbols drop to **0** in both libraries; total exports go
from everything to 264 (libhyperdbg) and 25 (script-engine). The link stays clean
**0 undefined references** — so nothing was relying on an unannotated symbol
crossing a library boundary. No source file was touched.
⚠️ `VISIBILITY_INLINES_HIDDEN` is included to match the usual CMake pairing; if a
future change takes the address of an inline member across a library boundary and
compares it, that flag is the first thing to re-check.
Grouped by subsystem. These are the shortcuts taken to reach compilation.