postject

license: MIT

type: git

build: zx ./scripts/build.mjs

clean: rimraf ./build

format: npm run format:cpp && npm run format:js

format:cpp: clang-format -style=chromium -i postject-api.h src/**.cpp test/**.c test/**.cpp

format:js: prettier --write src/**.js scripts/**.mjs test/**.mjs

lint: npm run lint:cpp && npm run lint:js

lint:cpp: clang-format -style=chromium --dry-run --Werror postject-api.h src/**.cpp test/**.c test/**.cpp

lint:js: prettier --check src/**.js scripts/**.mjs test/**.mjs

test: mocha

npm-signature:
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org

wsFzBAEBCAAGBQJjM+67ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b
EgJ2VmrmEhAApC4fLW8mLDzXpMR+1oBKZ+tRoYnxjMDOFJhKBFaZ6dKqXbBF
g9q9oa7kyEsxveAxPBrshauOIj5GWalfwCU3yadMbUB2gzoL59lir0TQCnnX
fs3acvS2eE0T/3RXfAV2X/kbrzNMj2Twek3E7ARDvZmIUyWn+5GK8NII67wf
x6szUeSh2UQvWQn6T4iPqbD2o0758ELbtvHjmV2Wh3fjO57WmY7Vr+n+2MPN
u9ZJfftbnDCL8ifT6B/5ggeN/susqhbycpfaYrDQsAZMLSNmNWFJA/nguDGI
Z3udlssq2nnEhaJBCB8o3+vp5NIkVbAI7z3TgSC0OQVHgkQsffyTQ0I+IAwI
EXMumK/9suSh6dGgolAc5TiNbZE+UuYd8HYGRE8P2xg3l/4NWs/+gMMFIHLa
fbkEaz0cr5HCDSAqTv6pHcgoL/rahcwbjzCNXhP8dofM6NJPWOaHSpd48ARd
wl+RNb7sUb4HlGVx5Pynl7ishG7wjUx0wWunQJIgf8Vs/DsrlIXe404jd2ev
sdn0llK4q0eWAwpaDNUtB0ESjnKGb/XQPQfnTzw2TLIWSEjP50y9Nro2UvIi
+HLz1ATCoH3qbhE9+qGo4pO2HZwMEnNCeT3KyTpLTrRk639AeP+Q4GlFnJmD
EYyBXFjvs04vYdH8izvcHqKr65Q50FHXbqQ=
=dlGr
-----END PGP SIGNATURE-----

npm-signature:
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org

wsFzBAEBCAAGBQJjNua/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b
EgJ2VmoiDw//T++/aMoFWtmGvcjeqJElct5HMWsmwIYv4HHUR+PrjiO9oF3M
x1xv0UnynmEVd4lYiw5AQbsgGoxeaTSjivaWpFjTh28DHx/bD5M0v3bZDMRt
w+WOW0uOybk7hE/IIfB4+rosMVP/0O1q6LBweflT5qaEqi1OCQLDztQpW1Mu
kEh6NG87XQdWv7SJrLdVgzn+ftTWDn0mH2M7Y2Wf/hdusecTA0mYmUCdftQw
CbYQAxemq4Dq5eV+E/t/XmyECUKm+ptNe+7sR3ivrb7CcE9ypZ8a/Z2U2kf1
A8OvzhhrNUThShtX/zM4qdcfxDGJ6rfeU5Q+W+AjTOsKpnoj0VZG/4uqWG9L
+tupmERuE0JHJH3H0rdn0ckFhXGzLQIswJJjzEk7aF6fijLu3afBEZpuNlWW
HdeuygHuq0eR0K0BD6ATAE2cepO2Kmxu7M24L3rC4EqRCOng3qncboQ2Iang
RKkqMxoO4ERbXJeIuT9iIz4lf+x3KQnBImn7Ce+/G4KgLmZhnXEvQ5OlS/0L
n9Fg5GspIxksacQ/Rizw9xJbpba+BP8XUOrtgpc4+g6WFp1uYPx6fXEiXdKd
k4Mm3DAlXay6ro3qNlUiLdSJKuG662snfLoNiqzzrmXacVMoftdY4v3rCLgB
ihuNL/b67Yf41oswBOtxu+6EQzLvdy0IF1U=
=GyNX
-----END PGP SIGNATURE-----

npm-signature:
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org

wsFzBAEBCAAGBQJjR8d6ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b
EgJ2VmpGgA/6Ajz4ix7w3xiYlffupDUID1Jmo/SadD47WXBHCj69p37ppq/E
BzVubAZ3PDgekRgrCXARbQlJqW94c1QVAP9dAaS8oZXIEH8Xhb2aMyTXEokB
hJ/UyRAa79rxPPYC0Lbg4KC/qF4+p/MvxhKmQM7USe/5DITaINjTb2Ve8nJF
KMONGktR1DAZM99SpRWc7uewFKNup5yguxcprjOLUESQfElfsE5PQpruO7sw
eCU0vyQIFFYweLr3VAavnrBRe3XOl3hi9ssH0IUw3CL7kZXVwWdwqC7tCnHY
Skmp8zpmDwRl5O5pPEo0AI/cpNk1CQDz+4rc7S4YyTQ5nVKf8S24O4ZGBpPv
sfSPpN2tBSFDGSAKKWPl7LjIV7nKflaZvByFVdNrpt8h1M/lMzU3U7O6Q7Yz
QN/JqnPNUZbPFGY8GeutpV7B4HBD773chQDr/CbEpz7AdGIseW9bEgrr3f35
QgIV1w8M6MB4jBmZAyoMy+uPnhcW/35yMjBnbhediV19bsJDVREphGulrnl5
xwCZDcQQZnkABAb7kS4RH/Yov8MyufUrro9wILRH/gb2NpHk6MofW6HIswj5
ZtQAgK3Hyg9S9YlC0EX9z5YwIwbT7d8JfqRccUeUOD5kw47jd4XPnN9PssmT
u2LCM8KxZVy4WvAi3owHOhyQu22tzdV/Esc=
=mH+V
-----END PGP SIGNATURE-----

npm-signature:
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org

wsFzBAEBCAAGBQJjvQdpACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b
EgJ2VmovjQ//XIMMSENr2bdraH1W1MaxSfDwgRHoIMSUH0DLtjOnKpMpSgMp
qtfojH4XrlH4tLH+8U8ptI0kjfGYUjHYq8bzxZc+CVBEEqERifuwAH6b4wqj
ivyX+fmZi4yo7xFwZ1Y7/07BgiuolpCMDqAd3ChrxSk0A7QMBG8SDmn71GoW
dwU6onj+9l8Beq/TK1YiWzLdEPF5Uz80brUZr8P3soppm/uqUMThiQ8O6tDF
LUbVC8ZvKAedLYhoRM0fSSQ6ycW5Uwq4/h74NXDezvlaMJc+EuEd44TVOyHg
naaOnNodbfuvQOWjSRQosDr2oxNY+7enFajU975rCuStW3ctfPpBHM18USN8
FWVFZbUbjGtNJTRy9hI0kBq6eniA+Zf7PjrUIBvrcZCnXNPfaz1mumj2Ao4i
WRzY/iD35I4pjaD/ZT150s8fSmMpFuNZhOK61fMlzEMUtxzsjNNEIqBHSmhA
4NoS1fLCqUVJUFjkJoJLnNxgd28BlqqryzjCYc3klKuQte+MgFzA92beD0+L
6WHKtLx1UhRxufwB7nkN4sYUVQm05eSuMTRqY01ug3OnE2v7eZQcapSn2NiM
bdY7ysWljFoX65tI5SSqRvNEqR07b615lOhIjMZjA+eahLkFkdyMEH3x3PWk
0avsfqFxZeybfQFuxDrFML/DtQM7BxBeIOQ=
=mLax
-----END PGP SIGNATURE-----

npm-signature:
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org

wsFzBAEBCAAGBQJkAdZpACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b
EgJ2VmrcJg//aYh0fdIxJNsbBTJRp7cPKc57qBJA5/yaY5wZBwMwWKmTRu4+
h6Aoj4k2tvPnYZOJX09Hv3zRDZlSNNF9mMF98pmSz5AO85FefpjW8b1ToQ3J
BUcfo4zs1LKNE0/EGfS0iNDPDYFE6OF5KO59K/amAewhURvbXQ52NqtszQw+
MCyucnvE26krRPZJdpHVrRnYuibm3WBLmqH7sHfNkuR7CQWsy7jl0sOsQ6kH
9FweHUhHbvFPKl9MiSgV90RjBItZf89O/hpEHkJbZmR6dSf9U/s+ZtHsUiFp
sRgLqVWRBwx/7wdm8x3FegdU6s0lnarpVJ+vW5f8gZFOiBl6OijleCk0G6zA
HdPmEL1xpI/p//OhUsSTbHy1uyU8uNoPAIgFUNIBKTEdaywn0MdE0ogI+nOX
CBn/hXUkyPMT0+la8SX+xkxzjXsWg7OLQ1wkJgYZnb0KI8E9wfMCG2rNcZmq
xd3m3+jVQIuE48Xr7w4hXyB6AyhpP5yP5BJrwBiIEDQ09TsGImNbEXwA8yJe
Qi/drtrSOYAluh0eHfEnfGkPLSNRvd+5ZIifqopffFKkgL2mhxPOqW57WJ09
NCK02nZ5rXq6rqVRlErsTJDUR2sOvFtQx7fLEtUtQyQIjrVQ9VOYC1wJgBZn
SupwRoTWwFB0eK5cI62xWBmV9V/qjoQZ5NA=
=BG+R
-----END PGP SIGNATURE-----

_source_registry_name: default

readme:
# postject

[![CircleCI](https://dl.circleci.com/status-badge/img/gh/postmanlabs/postject/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/postmanlabs/postject/tree/main)
[![npm version](http://img.shields.io/npm/v/postject.svg)](https://npmjs.org/package/postject)

Easily inject arbitrary read-only resources into executable formats
(Mach-O, PE, ELF) and use it at runtime.

## Install

```sh
npm i -g postject
```

## Usage

### Command line utility

```sh
$ postject -h
Usage: postject [options] <filename> <resource_name> <resource>

Inject arbitrary read-only resources into an executable for use at runtime

Arguments:
  filename                             The executable to inject into
  resource_name                        The resource name to use (section name on Mach-O and ELF, resource name for PE)
  resource                             The resource to inject

Options:
  --macho-segment-name <segment_name>  Name for the Mach-O segment (default: "__POSTJECT")
  --output-api-header                  Output the API header to stdout
  --overwrite                          Overwrite the resource if it already exists
  -h, --help                           display help for command
```

### Using Programatically

```js
const { inject } = require('postject');

await inject('a.out', 'lol', Buffer.from('Hello, world!'));
```

## Building

### Prerequisites

* CMake
* Ninja
* [Emscripten (emsdk)](https://emscripten.org/docs/getting_started/downloads.html)

### Build Command

```sh
$ npm run build
```

The final output is placed in `dist/`, with `main.js` being the
entrypoint.

### Testing

```sh
$ npm test
```

## Design

To ensure maximum capatibility and head off unforeseen issues, the
implementation for each format tries to use that format's standard
practices for embedding binary data. As such, it should be possible
to embed the binary data at build-time as well. The CLI provides the
ability to inject the resources into pre-built executables, with the
goal that the end result should be as close as possible to what is
obtained by embedding them at build-time.

Note: Other runtime injection implementers should search the binary
compiled with `postject-api.h` for the
`POSTJECT_SENTINEL_fce680ab2cc467b6e072b8b5df1996b2:0` fuse and
flip the last character to `1` to indicate that a resource has been
injected. A different fuse can also be used by defining the
`POSTJECT_SENTINEL_FUSE` macro before including `postject-api.h` and
passing the same string to postject with
`--sentinel-fuse <sentinel_fuse>`.

### Windows

For PE executables, the resources are added into the `.rsrc` section,
with the `RT_RCDATA` (raw data) type.

The build-time equivalent is adding the binary data as a resource in
the usual manner, such as the Resource Compiler, and marking it as
`RT_RCDATA`.

The run-time lookup uses the `FindResource` and `LoadResource` APIs.

### macOS

For Mach-O executables, the resources are added as sections inside a
new segment.

The build-time equivalent of embedding binary data with this approach
uses a linker flag: `-sectcreate,__FOO,__foo,content.txt`

The run-time lookup uses APIs from `<mach-o/getsect.h>`.

### Linux

For ELF executables, the resources are added as notes.

The build-time equivalent is to use a linker script.