Skip to content

Getting Started: Integrating Sigminer

qasimk edited this page May 18, 2026 · 2 revisions

Sigminer should be relatively simple to integrate into C or C++ codebases, this page assumes that the projects fall into these categories. Only cmake and make build tools have been tested during development, Sigminer can be extended to support other build systems if their is a request for it.

Dependencies

Sigminer currently requires the LLVM CMake package and LLVM development libraries. Consumer machines must have LLVM development packages installed and discoverable by CMake. If Sigminer is built with testing enabled, additional network access or cached dependencies may be needed because tests currently use googletest via FetchContent.

Here is a list of all the packages that will be required on a few different systems:

System Required Packages
RHEL 8 cmake, llvm, llvm-devel, gcc-toolset-11-gcc-c++
Ubuntu / Debian cmake, llvm, llvm-dev, clang, libclang-dev, g++
Fedora cmake, llvm, llvm-devel, clang, clang-devel, gcc-c++
Arch Linux cmake, llvm, clang, gcc

If the LLVM or Clang CMake package files are installed in a non-standard location, you may also need to set CMAKE_PREFIX_PATH so CMake can find them.

C++ Project Setup

To make use of the Sigminer libraries, first clone the Sigminer repository into a directory of your choosing. In most cases, the simplest option is to vendor it beside the main project and add it as a CMake subdirectory.

git clone https://github.com/qasimkamran/Sigminer.git <external/Sigminer>

Next, update the consumer project's CMakeLists.txt so that it pulls Sigminer into the build and links the Sigminer static library into the target that will call it.

Here is an example excerpt for the CMakeLists.txt change:

cmake_minimum_required(VERSION 3.20)
project(ConsumerProject LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_subdirectory(external/Sigminer)

add_executable(consumer_demo
	src/main.cpp
)

target_link_libraries(consumer_demo
	PRIVATE
		sigminer
)

In code, include the public header and call sigminer::GetSignatureFromSharedObjectBySymbol(...) with the path to the binary or shared object you want to inspect and the symbol name you want resolved.

Example usage:

#include <iostream>
#include <sigminer/sigminer.h>

int main()
{
	const sigminer::Result result =
			sigminer::GetSignatureFromSharedObjectBySymbol(
					"./libexample.so",
					"target_function"
			);

    if (!result.sig) {
		    std::cerr << "Sigminer failed with code "
					  << static_cast<int>(result.retCode) << '\n';
			return 1;
    }

	std::cout << "parameter count: " << result.sig->params.size() << '\n';
	return 0;
}

For Sigminer to return useful data, the target artifact should be built with debug information available. In practice, that means using flags such as -g and avoiding workflows that strip DWARF data before Sigminer runs, this is crucial for Sigminer to work correctly.

That's it! You have many helpers under the src/ directory to manipulate the ELF file whichever way suits your needs and your project best.

For normal integrations, prefer the public APIs under include/sigminer/. The C++ API is exposed through sigminer/sigminer.h, and the stable C ABI is exposed through sigminer/sigminer_c.h. Reaching into src/ should be treated as an internal-extension path, not the default integration surface.

C Project Setup

C projects integrate Sigminer in much the same way as C++ projects. The main difference is that C consumers should use the C ABI header and exported C entry points instead of the native C++ API.

As with C++ projects, the simplest approach is usually to vendor the Sigminer repository into the source tree (by cloning) and add it to the build. The Sigminer library itself is still built as part of the overall project, but the consuming C code should include sigminer/sigminer_c.h.

For Makefile based projects, the same trend follows except that the Sigminer library is added to the build manually like so (excerpt of Makefile):

CPPFLAGS += -Iexternal/Sigminer/include

CXX ?= c++
SIGMINER_DIR := external/Sigminer
SIGMINER_BUILD := $(SIGMINER_DIR)/build
SIGMINER_LIB := $(SIGMINER_BUILD)/libsigminer.a

# Example LLVM link flags for systems where llvm-config is available.
LLVM_LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs Object DebugInfoDWARF Support)

my_program: main.o $(SIGMINER_LIB)
    $(CXX) -o $@ main.o $(SIGMINER_LIB) $(LLVM_LDFLAGS) -lstdc++

$(SIGMINER_LIB):
    cmake -S $(SIGMINER_DIR) -B $(SIGMINER_BUILD) -DBUILD_TESTING=OFF
    cmake --build $(SIGMINER_BUILD)

Even when the consumer source file is written in C and uses the C ABI, the Sigminer static library is still implemented in C++. For that reason, the final link step typically still needs C++ and LLVM link flags.

An example usage usage of the C ABI is presented below:

#include <stdio.h>
#include <sigminer/sigminer_c.h>

int main(void)
{
    Result result =
        SIGMINER_GetSignatureFromSharedObjectBySymbol(
                "./libexample.so",
                "target_function"
                );

    if (!result.HasSignature) {
        fprintf(stderr, "Sigminer failed with code %d\n", result.RetCode);
        SIGMINER_FreeResult(&result);
        return 1;
    }

    printf("parameter count: %zu\n", result.Sig.ParamCount);
    SIGMINER_FreeResult(&result);
    return 0;
}

The same general requirements still apply: the target binary or shared object should include DWARF debug information, and the build environment must provide the LLVM and Clang packages that Sigminer depends on.

If the consumer project uses CMake, the integration steps are the same as in the C++ example, except the consuming source files remain C files and include the C ABI header instead of the C++ header.

Clone this wiki locally