1
0
mirror of https://github.com/pumpitupdev/pumptools.git synced 2024-12-25 20:54:50 +01:00
pumptools/doc/development/development.md

6.6 KiB

Development

This document covers various aspects of developing for pumptools. For developing using the API, see the dedicated readme.

Architecture

This document gives an introduction to the architecture of pumptools. This helps you to get familiar with the codebase and its features, definitely recommended to read this first.

Development environment setup

Pumptools is written entirely in C and built using cmake. Various helper scripts are written as bash/shell scripts. Therefore, you need the following tools on your development setup:

  • gcc
  • cmake
  • make
  • bash or compatible shell

Pumptools requires the following dependencies to be installed on your development OS:

  • libcurl4 i386
  • libusb 1.0 i386

Furthermore, header files, which come with the development packages of the libs, of the following libraries are required:

  • fmodex
  • libconfig
  • X11
  • libalsa
  • libusb-0.1 (not 1.0)

The project does not depend on any specific IDE. However, if you use CLion, the project can be imported easily.

Code style

The main style guidelines are defined by the .clang-format file and the code style can be easily applied to the whole src directory using the following command from the root folder:

make clang-format

Make sure that your contributions follow the style and apply it before submitting your changes.

For other source files like shell scripts, cmake, makefile or markdown documents, please follow the already established style in the existing documents.

Building

See the main readme.

Compatibility issues with newer glibc versions

We have experienced various issues with different glibc versions which had a major impact on the builds. The following table gives you a list of tested glibc versions and issues that are either present or not with each version listed. "ok" indicates that the specified glibc version is compatible and the specific issue does not occur, "bad" indicates incompatibility and that the specific issue does occur when using a binary compiled with that glibc version.

Issue/glibc version 2.23 2.30
Issue 1 ok bad
Issue 2 ok bad

The issues are further described in the following sub-sections

Issue 1: Crash during static initialization

For a detailed report on this issue, see the dedicated notes.

Summarized: Fiesta 2 and newer will segfault before even running the application's main method. The application fails on runtime initialization when initializing the static context. This is caused by ABI incompatibility of inlined code of C++'s STL, first occurring with string allocations during static initialization.

Issue 2: sscanf not being detoured

With NX2, Andamiro locked the USB drives to be used to a specific brand which they sold back then. That lock is patched out by detouring sscanf and manipulating the VID/PID and serial number parsing logic in the game to always return the values, the game wants to see to accept the connected USB drive.

However, some incompatibility on newer glibc versions does not setup the sscanf detour properly. The detour function is there and gets called by various parts of the game code in the beginning, but later calls to sscanf always go to the real function instead. Thus, the usb unlock feature does not work.

Unit tests

Unfortunately, this was started very late in the development of pumptools, but it's not too late to keep extending this with every change to ensure existing features don't break and future ones work.

When you have a change to commit, check if there is an existing unit-test which needs to be aligned with your change(s). If not, create one.

For testing code that gets hooked, there is a specific pattern that needs to be applied in order to allow testing hooks without having to actually hook them. As an example, you can take a look at the usb-fix module for piu pro and the corresponding test. It shows you how to setup the hooks and create mocks for the functions that you can trap the calls to the real detoured functions to check if they are getting called or return fixed values for testing.

Debugging

Pumptool's built-in tooling

Pumptools has a few basic debugging features built in which helps analyzing common issues very quickly without the need of external tools.

Help and usage message of hook library

When running a game with any of pumptools's hook.so libs attached, you can always add the parameter -h to display a help/usage message with all available command line and configuration parameters.

For example, when using piueb for bootstrapping:

./piueb run -h

The -h is passed on as a parameter and appended to the execution command. You can make use of that with other available cmd parameters as well (see usage information).

Logging

Logging to console and file as well as the level of verbosity can be controlled using the hook.conf configuration file or via command line arguments provided on execution.

All hooks implement various sanity checks for parameters provided, file checks etc. so there is a good coverage of common mistakes and misconfiguration that can be easily detected by watching out for any ERROR or WARNING level messages showing up in the log.

Example in configuration file:

util.log.file=pumptools.log
util.log.level=4

Furthermore, piueb outputs a separate log file piueb.log which contains logging data of the environment setup process of piueb.

File and IO hook monitoring

In the configuration file or via cmd args, you can enable monitoring of file, filesystem, usb and/or open system calls for tracing and debugging. This can be useful, to check if the game cannot find certain files like game assets.

Example in configuration file:

patch.hook_mon.file=0
patch.hook_mon.fs=0
patch.hook_mon.io=0
patch.hook_mon.open=1
patch.hook_mon.usb=0

Halt on SIGSEGV and attach debugger

Also enabled via configuration or cmd args, the application is halted on SIGSEGV to allow attaching a debugger.

Example in configuration file:

patch.sigsegv.halt_on_segv=1

External tooling

Remote debugging

You can run the application with gdbserver using piueb:

./piueb debug

And connect with your favorite debugger (e.g. IDA).

strace

You can run the application with strace using piueb:

./piueb strace

valgrind

You can run the application with valgrind using piueb:

./piueb valgrind