https://github.com/tontinton/panther
A shellcode compiler
https://github.com/tontinton/panther
bytecode compiler language llvm nim nim-lang parser shellcode shellcode-development
Last synced: 3 months ago
JSON representation
A shellcode compiler
- Host: GitHub
- URL: https://github.com/tontinton/panther
- Owner: tontinton
- Created: 2020-09-28T20:09:04.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2021-04-17T17:55:09.000Z (almost 5 years ago)
- Last Synced: 2023-04-05T19:34:14.013Z (almost 3 years ago)
- Topics: bytecode, compiler, language, llvm, nim, nim-lang, parser, shellcode, shellcode-development
- Language: Nim
- Homepage:
- Size: 37.1 MB
- Stars: 32
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README

## Introduction
The panther language is a language made for exploitations.
It's main focus is **minimal code size** through code size
optimizations and compiling directly to a **shellcode** (position independent code).
## Flow
1. **Lexer**: Parse text file into tokens
2. **Parser**: Parse tokens into AST
3. **Analyzer**: Validate that the AST is correct panther syntax
4. **Bytecode**: Parse AST into bytecode
5. **LLVM**: Parse bytecode into LLVM IR
6. **Optimizations + Backend**: llvm
## What can it do currently?
Currently, the panther binary can compile a single file using the llvm backend, with minimal type inference and type checking.
When running the panther compiler on ``main.pan``
```bash
# Compile the panther compiler
nimble build -d:release
# Panther compiles an object file, in this example I compile to a windows COFF
./panther c -i main.pan -o output.o -t x86_64-pe-windows-coff
# Link the object file to an executable, needed to get rid of relocations
ld -nostartfiles output.o -o output.exe
# Extract the .shell section created by the compiler
objcopy -j .shell -O binary output.exe shellcode.bin
```
When ``main.pan`` looks like:
```rust
proc _start(); // First function in the shellcode
proc fib(a: s32) -> s32 {
if a < 2 {
return a;
} else {
return fib(a - 1) + fib(a - 2);
}
}
// The printf symbol predetermined by an address.
// In the future I would like to add a feature of searching for a symbol at runtime.
let printf = 0x402ba0 as proc(fmt: string, num1: s32, num2: s32);
proc _start() {
let i = 1;
while i <= 15 {
printf("%d: %d\n", i, fib(i));
i = i + 1;
}
}
```
Results in a shellcode (``shellcode.bin``) that prints the the first 15 fibonnaci numbers.