Skip to content

shanewas/StructProbe

Repository files navigation

StructProbe — Struct Layout Inspector

A C++ / libclang utility that parses Windows-style SDK headers on Linux and reports struct sizes and field memory offsets.

Designed for working with Windows-style SDK headers (e.g., payment gateway SDKs, cryptographic libraries) without leaving a Linux development environment.

What it does

Input: A directory of Windows-style C/C++ headers (*.h files)
↓
Generate: AllHeaders.h — umbrella header including all matching files
↓
Parse: libclang AST traversal of the combined translation unit
↓
Find: All target structs (by default: names starting with SGNV)
↓
Generate: AutoInspectors.inc — C++ macros describing each struct
↓
Build + Run: Print struct sizes and field offsets to stdout

Output example:

=== Struct Sizes and Field Offsets ===
SGNV_PAYLOAD_HEADER (sizeof=40)
  cbSize       @+0  : unsigned long
  version      @+4  : unsigned long
  timestamp    @+8  : unsigned long long
  payload_type @+16 : unsigned short
  flags        @+18 : unsigned short
  session_id   @+20 : char[16]
  checksum     @+36 : unsigned long

SGNV_TRANSACTION_RECORD (sizeof=128)
  ...

Why this exists

When working with Windows SDKs on Linux (cross-platform payment integrations, for example), you often need to know:

  • What is the exact memory layout of a struct from a vendor's header?
  • Are there padding bytes between fields?
  • What's the total size of the struct for buffer allocation?

You can't just #include <windows.h> on Linux. StructProbe gives you the information by:

  1. Generating shim types that fake Win32 primitives on Linux
  2. Using libclang to parse the actual headers with MSVC compatibility mode
  3. Traversing the AST to extract struct field information

Requirements

  • Linux (x86_64, tested with GCC + LLVM/Clang 18)
  • g++ with C++17 support
  • clang + libclang (install libclang-dev and llvm-dev)
  • llvm-config on PATH (or installed LLVM in common locations)
  • make

On Ubuntu/Debian:

sudo apt install build-essential clang libclang-dev llvm

Quick start

git clone https://github.com/shanewas/StructProbe.git
cd StructProbe
make inspect

The Makefile auto-detects your LLVM/Clang installation. By default it looks for llvm-config and falls back to /usr/lib/llvm-{18,17,16,...}/include.

Customizing target structs

By default, structs matching SGNV* are inspected. Change the pattern in Makefile:

TARGET_STRUCTS = SGNV*
# or: TARGET_STRUCTS = PAYLOAD|TRANSACTION|RECORD
# or: TARGET_STRUCTS = *

Project layout

StructProbe/
├── Makefile                    # Build system — auto-detects libclang
├── WinShim.h                   # Win32 type shims for Linux (void*, long, etc.)
├── cpp.hint                    # MSVC compatibility hints for clang
├── gen_headers.cpp             # Generates AllHeaders.h umbrella header
├── gen_autoinspectors.cpp      # AST traversal → AI_BEGIN/AI_FIELD/AI_END macros
├── inspect_structs.cpp         # Runner that executes the generated inspector code
├── AllHeaders.h                # Generated — includes all target headers
├── AutoInspectors.inc          # Generated — struct layout macros
└── HEADERS/                    # Place your .h files here (default scan dir)
    └── SGNV_*.h                # Your SDK headers

How it works

Step 1 — Shim layer (WinShim.h)

Linux doesn't have WORD, DWORD, HANDLE, etc. WinShim.h defines:

#define DWORD unsigned long
#define WORD unsigned short
#define HANDLE void*
#define LPCSTR const char*

This lets Windows headers compile on Linux without modification.

Step 2 — Umbrella header (gen_headers.cpp)

Scans HEADERS/ for *.h files and generates AllHeaders.h:

#include "SGNV_Payment.h"
#include "SGNV_Transaction.h"
#include "SGNV_Crypto.h"
// ... etc

Step 3 — AST parsing (gen_autoinspectors.cpp)

Uses libclang to:

  • Parse the umbrella header with MSVC compatibility flags (-fms-compatibility, -fms-extensions)
  • Walk the AST to find all structs starting with SGNV
  • For each struct, record: field name, field type, byte offset, struct total size
  • Output C++ macros: AI_BEGIN(StructName, size), AI_FIELD(...), AI_END(...)

Step 4 — Runner (inspect_structs.cpp)

Includes the generated AutoInspectors.inc and executes the macros to print human-readable output.

Use cases

  1. Buffer allocation — know the exact struct size for malloc(sizeof(SGNV_Transaction))
  2. Memory inspection — field offsets tell you where to read specific values from a raw packet
  3. ABI compatibility — verify that structs from two different SDK versions have the same layout
  4. Cross-platform debugging — compare struct layouts between Windows and Linux builds of the same codebase

Limitations

  • Requires headers to be MSVC-compatible (this tool uses -fms-compatibility)
  • Field offset calculation accounts for compiler padding but not runtime packing
  • Does not handle bitfields in full detail (reports them as the underlying type)
  • Designed for struct inspection — not for function analysis

What this shows for systems/C++ roles

  • libclang AST traversal — non-trivial use of the Clang toolchain
  • Cross-platform build system design (handling Windows headers on Linux)
  • Understanding of memory layout, struct padding, ABI concerns
  • C++17 template metaprogramming (macro generation for arbitrary struct types)
  • Makefile authoring with toolchain auto-detection

One of a small set of systems programming tools. Related: posix-ipc-dotnet (C# inter-process communication on POSIX systems).

About

A small C++ / libclang utility that parses a set of C/C++ headers and prints struct sizes and field offsets. Designed for working with Windows-style SDK headers on Linux by faking the Win32 types via a lightweight shim.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors