diff --git a/package.json b/package.json index 14e5e35..300536b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "test": "mocha" }, "dependencies": { - "commander": "^9.4.0" }, "devDependencies": { "chai": "^4.3.6", diff --git a/src/argsParser.js b/src/argsParser.js new file mode 100644 index 0000000..5420efb --- /dev/null +++ b/src/argsParser.js @@ -0,0 +1,73 @@ +"use strict"; +const { parseArgs } = require("util"); + +const mainOptions = { + help: { type: 'string', short: "h" }, + "macho-segment-name": { type: "string" }, + "output-api-header": { type: "boolean" }, + overwrite: { type: "boolean" }, +}; + +function helper(command) { + const helpOptionsDescriptions = { + help: "display help for command", + "macho-segment-name": "--macho-segment-name Name for the Mach-O segment (default: \"__POSTJECT\")", + "output-api-header": "--output-api-header Output the API header to stdout", + "overwrite": "--overwrite Overwrite the resource if it already exists" + }; + if (command) { + console.log(helpOptionsDescriptions[command]); + } + else { + console.log("Usage: postject [options] "); + console.log("Inject arbitrary read-only resources into an executable for use at runtime"); + console.log(""); + console.log("Arguments:"); + console.log(" filename The executable to inject the resource into"); + console.log(" resource_name The resource name to use (section name on Mach-O and ELF, resource name for PE)"); + console.log(" resource The resource file to inject"); + console.log("Options:"); + for (const [key, value] of Object.entries(helpOptionsDescriptions)) { + console.log(` ${value}`); + } + } +} + +function argumentsParser(clb) { + + const args = process.argv.slice(2); + if (args.includes('--help') || args.includes('-h')) { + const { values } = parseArgs({ args, options: mainOptions, strict: false, tokens: true }); + if (typeof values.help === 'string') { + helper(values.help); + } + else { + helper(); + } + process.exit(); + } + if (args.length < 3) { + console.log("Missing adequate arguments"); + helper(); + process.exit(1); + } + const positionalArgs = args.slice(args.length - 3); + const subCommandArgs = args.slice(0, args.length - 3); + + const optionValuesObj = parseArgs({ + args: subCommandArgs, + options: mainOptions, + strict: false, + tokens: true, + }).values; + const options = Object.keys(optionValuesObj).reduce((acc, key) => { + const camelCaseKey = key.replace(/-([a-z])/g, (g) => + g[1].toUpperCase() + ); + acc[camelCaseKey] = optionValuesObj[key]; + return acc; + }, {}); + clb(...positionalArgs, options); +} + +module.exports = { argumentsParser }; diff --git a/src/cli.js b/src/cli.js index b68f17c..1f414ed 100755 --- a/src/cli.js +++ b/src/cli.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -const program = require("commander"); const { constants, promises: fs } = require("fs"); const path = require("path"); const { inject } = require("./api.js"); +const { argumentParser } = require("./argsParser.js"); async function main(filename, resourceName, resource, options) { if (options.outputApiHeader) { @@ -36,24 +36,5 @@ async function main(filename, resourceName, resource, options) { } if (require.main === module) { - program - .name("postject") - .description( - "Inject arbitrary read-only resources into an executable for use at runtime" - ) - .argument("", "The executable to inject into") - .argument( - "", - "The resource name to use (section name on Mach-O and ELF, resource name for PE)" - ) - .argument("", "The resource to inject") - .option( - "--macho-segment-name ", - "Name for the Mach-O segment", - "__POSTJECT" - ) - .option("--output-api-header", "Output the API header to stdout") - .option("--overwrite", "Overwrite the resource if it already exists") - .action(main) - .parse(process.argv); + argumentParser(main); }