rizin/librz/syscall/README.md
Maijin d28ddde0e7
doc(syscall): improve README and add example (#5135) (#5619)
Co-authored-by: Maijin <maijin21@gmail.com>
2025-12-15 14:02:55 +08:00

3.4 KiB

RzSyscall

RzSyscall provides functionality to manage system calls and system registers for different architectures and operating systems. It allows mapping between syscall numbers and names, as well as resolving system register values.

Architecture

The core structure is RzSyscall, which holds the database of system calls loaded from SDB files.

Key Structures

  • RzSyscall: Main handle, contains the SDB database and context information (OS, Arch, CPU, Bits).
  • RzSyscallItem: Represents a single system call with its name, number, arguments, etc.
  • RzPath: Helper structure used during initialization to locate SDB files.

Workflow

graph TD
    A[RzPath New] --> B[RzSyscall New]
    B --> C{rz_syscall_setup}
    C -->|Locates SDBs| D[Load Syscall DB]
    D --> E[Ready for Query]
    E --> F[rz_syscall_get]
    E --> G[rz_syscall_get_num]

Usage

Using RzSyscall involves the following steps:

  1. Initialize RzPath: Create an RzPath instance to help locate system files.
  2. Create RzSyscall: Allocate a new RzSyscall instance.
  3. Setup: Configure the instance with the desired OS, Architecture, and bitness using rz_syscall_setup().
  4. Query: Use functions like rz_syscall_get() or rz_syscall_get_num() to resolve syscalls.

Example: Resolving a Syscall on Linux x86_64

#include <rz_syscall.h>
#include <rz_util.h>
#include <stdio.h>

int main(void) {
	// 1. Create RzPath to locate SDB files
	RzPath *path = rz_path_new();
	if (!path) {
		fprintf(stderr, "Failed to create RzPath\n");
		return 1;
	}

	// 2. Create RzSyscall instance
	RzSyscall *sc = rz_syscall_new();
	if (!sc) {
		fprintf(stderr, "Failed to create RzSyscall\n");
		rz_path_free(path);
		return 1;
	}

	// 3. Setup for Linux x86_64
	// rz_syscall_setup(sc, path, arch, bits, cpu, os)
	if (!rz_syscall_setup(sc, path, "x86", 64, NULL, "linux")) {
		fprintf(stderr, "Failed to setup RzSyscall for linux-x86-64\n");
		rz_syscall_free(sc);
		rz_path_free(path);
		return 1;
	}

	// 4. Query a syscall (e.g., write = 1 on Linux x86_64)
	int syscall_num = 1;
	RzSyscallItem *item = rz_syscall_get(sc, syscall_num, -1);
	if (item) {
		printf("Syscall %d on Linux x86_64 is '%s'\n", syscall_num, item->name);
		rz_syscall_item_free(item);
	} else {
		printf("Syscall %d not found\n", syscall_num);
	}

	// Cleanup
	rz_syscall_free(sc);
	rz_path_free(path);
	return 0;
}

Syscall Database (SDB)

The syscall database is stored in librz/syscall/d as plain text files with the .sdb.txt extension. These files are compiled into binary SDB files during the build process.

File Format

Each line represents a syscall definition in the following format:

name=swi,num,args,types
  • name: Name of the syscall (e.g., write, open).
  • swi: Software interrupt number (usually 0x80 for Linux x86).
  • num: Syscall number.
  • args: Number of arguments.
  • types: String representing the types of arguments (optional).

Key-Value Pairs for Lookup:

The SDB file assumes specific keys for lookup:

  • _: Stores the default SWI number (e.g., _=0x80).
  • name: Lookup by name (e.g., write -> 0x80,1,3,izi).
  • swi.num: Lookup by SWI and number (e.g., 0x80.1 -> write).

Adding a New Database

  1. Create a new file in librz/syscall/d/ named <os>-<arch>-<bits>.sdb.txt.
  2. Populate it with syscall definitions.
  3. Add the new file to librz/syscall/d/meson.build to ensure it gets compiled and installed.