{"id":13611738,"url":"https://github.com/woodruffw/steg86","last_synced_at":"2025-10-23T20:01:40.010Z","repository":{"id":37158270,"uuid":"287818201","full_name":"woodruffw/steg86","owner":"woodruffw","description":"Hiding messages in x86 programs using semantic duals","archived":false,"fork":false,"pushed_at":"2025-04-21T19:59:08.000Z","size":324,"stargazers_count":299,"open_issues_count":4,"forks_count":14,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-05-12T05:54:18.776Z","etag":null,"topics":["amd64","binary-translation","hacktoberfest","steganography","x86"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/steg86","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/woodruffw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"woodruffw","thanks_dev":"u/gh/woodruffw"}},"created_at":"2020-08-15T20:15:07.000Z","updated_at":"2025-04-28T20:26:04.000Z","dependencies_parsed_at":"2023-10-03T06:39:13.819Z","dependency_job_id":"3b3f0b91-4ae4-455e-a37e-704f2d27ad8c","html_url":"https://github.com/woodruffw/steg86","commit_stats":{"total_commits":269,"total_committers":6,"mean_commits":"44.833333333333336","dds":"0.22676579925650553","last_synced_commit":"ab963b9ff6a338c5a32c4bc4b5bca3f210cb9803"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodruffw%2Fsteg86","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodruffw%2Fsteg86/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodruffw%2Fsteg86/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodruffw%2Fsteg86/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/woodruffw","download_url":"https://codeload.github.com/woodruffw/steg86/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254310515,"owners_count":22049469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amd64","binary-translation","hacktoberfest","steganography","x86"],"created_at":"2024-08-01T19:02:03.419Z","updated_at":"2025-10-23T20:01:39.920Z","avatar_url":"https://github.com/woodruffw.png","language":"Rust","funding_links":["https://github.com/sponsors/woodruffw","https://thanks.dev/u/gh/woodruffw"],"categories":["Rust","Tools"],"sub_categories":["Steganography"],"readme":"steg86\n======\n\n![license](https://raster.shields.io/badge/license-MIT%20with%20restrictions-green.png)\n[![CI](https://github.com/woodruffw/steg86/actions/workflows/ci.yml/badge.svg)](https://github.com/woodruffw/steg86/actions/workflows/ci.yml)\n\n*steg86* is a format-agnostic [steganographic](https://en.wikipedia.org/wiki/Steganography) tool\nfor x86 and AMD64 binaries. You can use it to hide information in compiled programs, regardless of\nexecutable format (PE, ELF, Mach-O, raw, \u0026amp;c). It has no performance *or* size impact on the files\nthat it modifies (adding a message does *not* increase binary size or decrease execution speed).\n\nFor more details on how *steg86* works, see the [Theory of Operation](#theory-of-operation) section.\n\n## Installation\n\n`steg86` can be installed via `cargo`:\n\n```bash\n$ cargo install steg86\n```\n\nAlternatively, you can build it in this repository with `cargo build`:\n\n```bash\n$ cargo build\n```\n\n## Usage\n\nSee `steg86 --help` for a full list of flags and subcommands.\n\n### Profiling\n\nTo profile a binary for steganographic suitability:\n\n```bash\n$ steg86 profile /bin/bash\nSummary for /bin/bash:\n  175828 total instructions\n  27957 potential semantic pairs\n  19 potential commutative instructions\n  27944 bits of information capacity (3493 bytes, approx. 3KB)\n```\n\n### Embedding\n\nTo embed a message into a binary:\n\n```bash\n$ steg86 embed /bin/bash ./bash.steg \u003c\u003c\u003c \"here is my secret message\"\n```\n\nBy default, `steg86 embed` writes its output to `$input.steg`.\nFor example, `/lib64/ld-linux-x86-64.so.2` would become `/lib64/ld-linux-x86-64.so.2.steg`.\n\n`steg86 embed` will exit with a non-zero status if the message cannot be embedded (e.g.,\nif it's too large).\n\n### Extraction\n\nTo extract a message from a binary:\n\n```bash\n$ steg86 extract bash.steg \u003e my_message\n$ cat my_message\nhere is my secret message\n```\n\n`steg86 extract` will exit with a non-zero status if a message cannot be extracted (e.g.,\nif it can't find one).\n\n## Theory of Operation\n\n*steg86* takes advantage of one of x86's encoding peculiarities: the R/M field\nof the ModR/M byte:\n\n```\n  7  6  5  4  3  2  1  0\n -------------------------\n | MOD |  REG  |   R/M   |\n -------------------------\n```\n\nThe ModR/M byte is normally used to support both register-to-memory and memory-to-register variants\nof the same instruction. For example, the `MOV` instruction has the following variants\n(among many others):\n\n| opcode  | mnemonic        |\n----------|------------------\n| `89 /r` | `MOV r/m32,r32` |\n| `8B /r` | `MOV r32,r/m32` |\n\n\nBecause the ModR/M field can encode *either* a memory addressing operation *or* a bare\nregister, opcodes that support both register-to-memory and memory-to-register operations *also*\nsupport multiple encodings of register-to-register operations.\n\nFor example, `mov eax, ebx` can be encoded as *either* `89 d8` *or* `8b c3` *without any semantic\nchanges*. This gives us one bit of information per duplicated instruction semantic. Given enough\nregister-to-register instructions with multiple encodings, we can hide entire messages with those\nbits.\n\nAdditionally, because these semantically identical encodings are frequently the same size,\nwe can modify *preexisting* binaries without having to fix relocations or RIP-relative addressing.\n\n*steg86* does primitive [binary translation](https://en.wikipedia.org/wiki/Binary_translation) to\naccomplish these goals. It uses [iced-x86](https://github.com/0xd4d/iced) for encoding and\ndecoding, and [goblin](https://github.com/m4b/goblin) for binary format wrangling.\n\n### Prior work\n\nThe inspiration for *steg86* came from [@inventednight](https://github.com/inventednight), who\ndescribed it as an adaptation of a similar idea (also theirs) for RISC-V binaries.\n\nThe technique mentioned above is discussed in detail in\n[*Hydan: Hiding Information in Program Binaries*](http://web4.cs.columbia.edu/~angelos/Papers/hydan.pdf) (2004).\n\n*steg86* constitutes a separate discovery of Hydan's technique and was written entirely\nindependently; the refinements discussed in the paper may or may not be more optimal than the ones\nimplemented in *steg86*.\n\n### Future improvements\n\n* *steg86* currently limits the embedded message to 16KB. This is a purely artificial limitation\nthat could be resolved with some small format changes.\n\n* x86 (and AMD64) both have multi-byte NOPs, for alignment purposes. Additional information can be\nhidden in these in a few ways:\n  * The `OF 1F /0`  multi-byte NOP can be up to 9 bytes, of which up to 5 are free\n  (SIB + 4-byte displacement).\n  * There are longer NOPs (11, 15 bytes) that may also be usable.\n\n* Going beyond register-to-register duals and rewriting `add`/`sub`, as Hydan does.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoodruffw%2Fsteg86","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwoodruffw%2Fsteg86","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoodruffw%2Fsteg86/lists"}