Co-authored-by: Maijin <maijin21@gmail.com>
This commit is contained in:
parent
129903687e
commit
d28ddde0e7
7 changed files with 171 additions and 40 deletions
51
examples/api/syscall/linux_x64.c
Normal file
51
examples/api/syscall/linux_x64.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Maijin <maijin21@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only
|
||||||
|
|
||||||
|
#include <rz_syscall.h>
|
||||||
|
#include <rz_util.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
RzPath *path = rz_path_new();
|
||||||
|
if (!path) {
|
||||||
|
fprintf(stderr, "Failed to create RzPath\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RzSyscall *sc = rz_syscall_new();
|
||||||
|
if (!sc) {
|
||||||
|
fprintf(stderr, "Failed to create RzSyscall\n");
|
||||||
|
rz_path_free(path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup for Linux x86_64
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve syscall number 1 (write)
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve syscall name 'open'
|
||||||
|
int num;
|
||||||
|
if (rz_syscall_get_num(sc, "open", &num)) {
|
||||||
|
printf("Syscall 'open' on Linux x86_64 is %d\n", num);
|
||||||
|
} else {
|
||||||
|
printf("Syscall 'open' not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
rz_syscall_free(sc);
|
||||||
|
rz_path_free(path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -4,4 +4,10 @@ if get_option('enable_examples')
|
||||||
dependencies: [rz_hash_dep],
|
dependencies: [rz_hash_dep],
|
||||||
install: false
|
install: false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
executable('linux_x64', 'api/syscall/linux_x64.c',
|
||||||
|
include_directories: [platform_inc],
|
||||||
|
dependencies: [rz_syscall_dep, rz_util_dep],
|
||||||
|
install: false
|
||||||
|
)
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
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
|
||||||
|
|
||||||
|
```c
|
||||||
|
#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.
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#echo "_=0x80"
|
|
||||||
awk -F '(=|,)' '{
|
|
||||||
# 0x80.1=exit
|
|
||||||
if ($1 == "_") {
|
|
||||||
print $1"="$2
|
|
||||||
} else {
|
|
||||||
print $2"."$3"="$1
|
|
||||||
# exit=0x80,1,1,i
|
|
||||||
print $1"="$2","$3","$4","$5
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
grep '{ "'|tr '{",}' ' ' |sed -e 's,NULL,,g' | awk '{ print $1"="$2","$3","$4","$5}'
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
awk -F '(=|,)' '{
|
|
||||||
print $2"."$3"="$1
|
|
||||||
# exit=0x80,1,1,i
|
|
||||||
print $1"="$2","$3
|
|
||||||
}'
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
from bochs: http://bochs.sourceforge.net/techspec/PORTS.LST
|
|
||||||
|
|
||||||
0x0000-0x001F The first legacy DMA controller, often used for transfers to floppies.
|
|
||||||
0x0020-0x0021 The first Programmable Interrupt Controller
|
|
||||||
0x0022-0x0023 Access to the Model-Specific Registers of Cyrix processors.
|
|
||||||
0x0040-0x0047 The PIT (Programmable Interval Timer)
|
|
||||||
0x0060-0x0064 The "8042" PS/2 Controller or its predecessors, dealing with keyboards and mice.
|
|
||||||
0x0070-0x0071 The CMOS and RTC registers
|
|
||||||
0x0080-0x008F The DMA (Page registers)
|
|
||||||
0x0092 The location of the fast A20 gate register
|
|
||||||
0x00A0-0x00A1 The second PIC
|
|
||||||
0x00C0-0x00DF The second DMA controller, often used for soundblasters
|
|
||||||
0x00E9 Home of the Port E9 Hack. Used on some emulators to directly send text to the hosts' console.
|
|
||||||
0x0170-0x0177 The secondary ATA harddisk controller.
|
|
||||||
0x01F0-0x01F7 The primary ATA harddisk controller.
|
|
||||||
0x0278-0x027A Parallel port
|
|
||||||
0x02F8-0x02FF Second serial port
|
|
||||||
0x03B0-0x03DF The range used for the IBM VGA, its direct predecessors, as well as any modern video card in legacy mode.
|
|
||||||
0x03F0-0x03F7 Floppy disk controller
|
|
||||||
0x03F8-0x03FF First serial port
|
|
||||||
Loading…
Reference in a new issue