• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env node
2
3const program = require("commander");
4const { constants, promises: fs } = require("fs");
5const path = require("path");
6const { inject } = require("./api.js");
7
8const logger = {
9  info: (message) => console.log("\x1b[36m%s\x1b[0m", message),
10  success: (message) => console.log("\x1b[32m%s\x1b[0m", message),
11  error: (message) => console.log("\x1b[31mError: %s\x1b[0m", message),
12};
13
14async function main(filename, resourceName, resource, options) {
15  if (options.outputApiHeader) {
16    // Handles --output-api-header.
17    console.log(
18      await fs.readFile(path.join(__dirname, "postject-api.h"), "utf-8")
19    );
20    process.exit();
21  }
22
23  let resourceData;
24
25  try {
26    await fs.access(resource, constants.R_OK);
27    resourceData = await fs.readFile(resource);
28  } catch {
29    logger.error("Can't read resource file");
30    process.exit(1);
31  }
32
33  try {
34    logger.info(
35      "Start injection of " + resourceName + " in " + filename + "..."
36    );
37    await inject(filename, resourceName, resourceData, {
38      machoSegmentName: options.machoSegmentName,
39      overwrite: options.overwrite,
40      sentinelFuse: options.sentinelFuse,
41    });
42    logger.success("�� Injection done!");
43  } catch (err) {
44    logger.error(err.message);
45    process.exit(1);
46  }
47}
48
49if (require.main === module) {
50  program
51    .name("postject")
52    .description(
53      "Inject arbitrary read-only resources into an executable for use at runtime"
54    )
55    .argument("<filename>", "The executable to inject into")
56    .argument(
57      "<resource_name>",
58      "The resource name to use (section name on Mach-O and ELF, resource name for PE)"
59    )
60    .argument("<resource>", "The resource to inject")
61    .option(
62      "--macho-segment-name <segment_name>",
63      "Name for the Mach-O segment",
64      "__POSTJECT"
65    )
66    .option(
67      "--sentinel-fuse <sentinel_fuse>",
68      "Sentinel fuse for resource presence detection",
69      "POSTJECT_SENTINEL_fce680ab2cc467b6e072b8b5df1996b2"
70    )
71    .option("--output-api-header", "Output the API header to stdout")
72    .option("--overwrite", "Overwrite the resource if it already exists")
73    .action(main)
74    .parse(process.argv);
75}
76