https://github.com/urpagin/syslang
Invoke Linux syscalls from the CLI + interpret syslang source files.
https://github.com/urpagin/syslang
cli dsl language linux programming-language rust syscalls
Last synced: 11 months ago
JSON representation
Invoke Linux syscalls from the CLI + interpret syslang source files.
- Host: GitHub
- URL: https://github.com/urpagin/syslang
- Owner: Urpagin
- License: gpl-3.0
- Created: 2025-05-10T22:32:31.000Z (11 months ago)
- Default Branch: master
- Last Pushed: 2025-05-12T22:14:50.000Z (11 months ago)
- Last Synced: 2025-05-12T23:24:59.675Z (11 months ago)
- Topics: cli, dsl, language, linux, programming-language, rust, syscalls
- Language: Rust
- Homepage:
- Size: 37.1 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Dynamic Syscalls
## Syslang
The project has now evolved into a very simple programming language. You can interpret `.scx` files using the `--interpret ` argument.
The language currently supports:
* One keyword: `syscall`
* Two data types: numbers like `42`, and strings like `"this is a string"`
* Comments: **start a line** with `#` to write a comment
What it doesn't have (yet):
* Variables
* Loops
* Functions
* Transpilation or compilation
* And more. I'm not even sure if it qualifies as a full programming language at this point. Maybe it's more of a DSL (domain-specific language).
## Purpose
The purpose of this project is to reduce the friction involved in making a system call directly from userspace. It allows you to invoke syscalls without the need to write or compile a full C or Rust program — just provide the syscall number and up to six arguments, and it will do the rest.
## Usage
The first argument is the **syscall number**. You do **not** need to type-hint it.
The next arguments (up to a maximum of six) **must** be type-hinted:
* Use `n:` to indicate an unsigned number (`usize`)
* Use `s:` to indicate a string whose pointer should be passed
Arguments are passed in the order expected by the syscall.
### Interpreting syslang source files
`--interpret <.scx source file>` to interpret the file.
`--quiet` to enable quiet mode **when interpreting** a source file. (silences any prints)
To get a grasp on the syntax, check out the `.scx` files under the `examples/` directory.
## Examples
If you want to use the `write(2)` syscall — instead of bothering with `echo(1)` or `printf(1)` — you can use this program to directly interface with the kernel.
Reference for syscall numbers: [Linux System Call Table (x86\_64)](https://filippo.io/linux-syscall-table/)
(**Double click on a row** to reveal the arguments list)
### Writing to stdout
System call number 1 corresponds to `write`, which takes:
1. A file descriptor (e.g., `1` for `stdout`)
2. A pointer to the buffer (e.g., `"Hello, World\n"`)
3. The number of bytes to write (e.g., `13`, including the newline)
Example:
```bash
./dynamic-syscall 1 n:1 $'s:Hello, World\n' n:13
```
**Note:** To correctly pass special characters like `\n`, use **ANSI C quoting** by prefixing your string with `$` and enclosing it in single quotes. Otherwise, characters like `\n` will be passed as literal backslashes and `n` (i.e., `"\\n"`), due to how BASH handles escaping.
### Sending SIGKILL to a process
1. Identify the PID of the target process (e.g., `414195`).
2. Run:
```bash
./dynamic-syscall 62 n:414195 n:9
```
Explanation:
* Syscall 62 is `kill(2)`, which takes:
* A `pid` (`pid_t`) — the ID of the process to signal
* A signal number (`int`) — in this case, `9` (`SIGKILL`) to immediately terminate the process
## Limitations
Currently, only two argument types are supported:
* `s:` — string (converted to a pointer)
* `n:` — unsigned number (`usize`)
You **can** pass negative numbers, and they usually work, because casting from `i32` to `usize` preserves the bit pattern. However, this is architecture-dependent and not type-safe — be cautious.
## Future Improvements (TODO)
* Allow plain numbers (e.g., `42`) to default to `usize` without requiring the `n:` prefix?
* Add support for additional types (`i32`, `NULL`, raw pointers, flags, etc.)
* Optional unescaping of common character sequences (`\n`, `\t`, etc.) internally
* For debug printing, have a map for each sysno and print their names (e.g., 1 would be "write")
* Allow for non-base10 numbers. (e.g., 0xFF or 0o644).