Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>
  • Loading branch information
egibs committed Jun 9, 2024
1 parent d5376d4 commit c4173fc
Show file tree
Hide file tree
Showing 9 changed files with 613 additions and 1 deletion.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/" # Location of package manifests
schedule:
interval: "daily"
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: rsd CI

on:
push:
pull_request:
branches:
- main

env:
CARGO_TERM_COLOR: always

jobs:
rust-ci:
runs-on: ubuntu-latest
steps:
- uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6
with:
egress-policy: audit
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- run: |
sudo apt-get update
sudo apt-get install -y curl
curl https://sh.rustup.rs -sSf | sh -s -- -y
export PATH="$HOME/.cargo/bin:$PATH"
rustup default stable
rustup component add rustfmt
- name: Run Checks
run: |
cargo fmt --all -- --check
cargo build --all --release
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ Cargo.lock

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# Binaries
rsd
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "rsd"
version = "0.1.0"
edition = "2021"

[dependencies]
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM cgr.dev/chainguard/rust as build

WORKDIR /build

COPY . .

RUN make build

FROM cgr.dev/chainguard/static

COPY --from=build /build/rsd /rsd

ENTRYPOINT ["/rsd"]
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.PHONY: build

build:
rustc -C target-feature=+crt-static src/main.rs -o rsd

docker:
docker buildx build -t rsd:latest .

fmt:
cargo fmt --all

fmt-check:
cargo fmt --all -- --check

test:
cargo test --all --release

release:
cargo build --all --release
146 changes: 145 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,146 @@
# rsd
Rust implemention of xxd -e -l 64

`rsd` Rust implemention of something resembling `xxd -e -l 64`. Its functionality is limited to looking at the headers of ELF binaries and outputting the details in a mostly- human-readable format.

## Why?

I wanted to learn Rust a little better; I also wanted a more readable version of `xxd -e -l 64` when parsing ELF headers rather than parsing something like this:
```
ced27abc2bef:/# xxd -e -l 64 /bin/sh
00000000: 464c457f 00010102 00000000 00000000 .ELF............
00000010: 00b70003 00000001 0000a780 00000000 ................
00000020: 00000040 00000000 000a0348 00000000 @.......H.......
00000030: 00000000 00380040 00400009 00180019 ....@.8...@.....
```
or this:
```
ced27abc2bef:/# xxd -l 64 /bin/sh
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 b700 0100 0000 80a7 0000 0000 0000 ................
00000020: 4000 0000 0000 0000 4803 0a00 0000 0000 @.......H.......
00000030: 0000 0000 4000 3800 0900 4000 1900 1800 ....@.8...@.....
```

I've been writing YARA rules recently and knowing how to locate information like this can prove useful, though making it more human-readable is more efficient as well.

## What works for now?

- Building locally via `rustc` or via Dockerfile
- ELF binaries

## Usage

`./rsd <program name>`

Example (run from Wolfi):
```
./rsd /bin/sh
Full header:
7F 45 4C 46 02 01 01 00 00 00 00 00 00 00 00 00 03 00 B7 00 01 00 00 00 80 A7 00 00 00 00 00 00 40 00 00 00 00 00 00 00 48 03 0A 00 00 00 00 00 00 00 00 00 40 00 38 00 09 00 40 00 19 00 18 00 ELF File Type: Shared (0x03)
Machine Type: AArch64 (0x00B7)
ELF Class: 64-bit
Data Encoding: Little-endian
ELF Version: 1
Entry Point Address: 42880
Program Header Table Offset: 64
Section Header Table Offset: 656200
ELF Header Size: 64 bytes
Program Header Table Entry Size: 56 bytes
Number of Program Header Table Entries: 9
Section Header Table Entry Size: 64 bytes
Number of Section Header Table Entries: 25
Section Header String Table Index: 24
Segment Information:
Segment 0:
Type: PT_NOTE (0x00000004)
Offset: 64
Virtual Address: 64
Physical Address: 64
File Size: 0x00000000000001F8 (504 bytes)
Memory Size: 0x00000000000001F8 (504 bytes)
Flags: Unknown (0x00000008)
Segment 1:
Type: PT_NOTE (0x00000004)
Offset: 568
Virtual Address: 568
Physical Address: 568
File Size: 0x000000000000001B (27 bytes)
Memory Size: 0x000000000000001B (27 bytes)
Flags: R (0x00000001)
Segment 2:
Type: PT_SHLIB (0x00000005)
Offset: 0
Virtual Address: 0
Physical Address: 0
File Size: 0x000000000008F118 (586008 bytes)
Memory Size: 0x000000000008F118 (586008 bytes)
Flags: Unknown (0x00010000)
Segment 3:
Type: PT_PHDR (0x00000006)
Offset: 646864
Virtual Address: 646864
Physical Address: 646864
File Size: 0x0000000000002399 (9113 bytes)
Memory Size: 0x0000000000002A00 (10752 bytes)
Flags: Unknown (0x00010000)
Segment 4:
Type: PT_PHDR (0x00000006)
Offset: 651720
Virtual Address: 651720
Physical Address: 651720
File Size: 0x0000000000000220 (544 bytes)
Memory Size: 0x0000000000000220 (544 bytes)
Flags: Unknown (0x00000008)
Segment 5:
Type: PT_NOTE (0x00000004)
Offset: 596
Virtual Address: 596
Physical Address: 596
File Size: 0x0000000000000020 (32 bytes)
Memory Size: 0x0000000000000020 (32 bytes)
Flags: X (0x00000004)
Segment 6:
Type: PT_NOTE (0x00000004)
Offset: 585820
Virtual Address: 585820
Physical Address: 585820
File Size: 0x0000000000000034 (52 bytes)
Memory Size: 0x0000000000000034 (52 bytes)
Flags: X (0x00000004)
Segment 7:
Type: PT_PHDR (0x00000006)
Offset: 0
Virtual Address: 0
Physical Address: 0
File Size: 0x0000000000000000 (0 bytes)
Memory Size: 0x0000000000000000 (0 bytes)
Flags: Unknown (0x00000010)
Segment 8:
Type: PT_NOTE (0x00000004)
Offset: 646864
Virtual Address: 646864
Physical Address: 646864
File Size: 0x0000000000002130 (8496 bytes)
Memory Size: 0x0000000000002130 (8496 bytes)
Flags: R (0x00000001)
```

Running `rsd` from MacOS will result in this:
```
❯ ./rsd /bin/sh
/bin/sh is not an ELF file (CAFEBABE).
```

## Will anything be added to this project?

Maybe -- I want to start automating various things in whatever language seems right. Analyizing Mach-O bianries (i.e., MacOS binaries) doesn't seem to be as common but that would be easy to support.
9 changes: 9 additions & 0 deletions src/display.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use std::fmt;

pub struct HexAddress(pub u64);

impl fmt::Display for HexAddress {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "0x{:016X} ({} bytes)", self.0, self.0)
}
}
Loading

0 comments on commit c4173fc

Please sign in to comment.