Module: PWN::Plugins::Ghidra
- Defined in:
- lib/pwn/plugins/ghidra.rb
Overview
Headless Ghidra analyzeHeadless wrapper with r2 fallback.
Class Method Summary collapse
- .analyze(opts = {}) ⇒ Object
- .authors ⇒ Object
- .decompile(opts = {}) ⇒ Object
- .help ⇒ Object
- .required_bins ⇒ Object
Class Method Details
.analyze(opts = {}) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/pwn/plugins/ghidra.rb', line 16 public_class_method def self.analyze(opts = {}) path = (opts[:bin] || opts[:path]).to_s raise 'ERROR: bin is required' if path.empty? raise "ERROR: file not found: #{path}" unless File.file?(path) if PWN::Plugins::PreflightChecker.bin?(name: 'analyzeHeadless') proj = opts[:project_dir].to_s proj = File.join(Dir.home, '.pwn', 'ghidra') if proj.empty? FileUtils.mkdir_p(proj) stdout, stderr, status = Open3.capture3('analyzeHeadless', proj, 'pwn', '-import', path, '-deleteProject') return { stdout: stdout, stderr: stderr, exit: status.exitstatus, engine: 'ghidra' } end return r2_fallback(path: path) if PWN::Plugins::PreflightChecker.bin?(name: 'r2') { error: 'analyzeHeadless missing', hint: 'install Ghidra or r2; pwn setup --profile re' } end |
.authors ⇒ Object
62 63 64 |
# File 'lib/pwn/plugins/ghidra.rb', line 62 public_class_method def self. "AUTHOR(S):\n 0day Inc. <[email protected]>\n" end |
.decompile(opts = {}) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/pwn/plugins/ghidra.rb', line 34 public_class_method def self.decompile(opts = {}) path = (opts[:bin] || opts[:path]).to_s raise 'ERROR: bin is required' if path.empty? sha = Digest::SHA256.file(path).hexdigest if File.file?(path) cache = File.join(Dir.home, '.pwn', 'cache', 'decompile', "#{sha}.json") if sha return JSON.parse(File.read(cache), symbolize_names: true).merge(cached: true) if cache && File.file?(cache) row = analyze(opts) fn = opts[:function].to_s row[:function] = fn unless fn.empty? FileUtils.mkdir_p(File.dirname(cache)) if cache File.write(cache, JSON.generate(row)) if cache row end |
.help ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/pwn/plugins/ghidra.rb', line 66 public_class_method def self.help puts "USAGE: # List host binaries this module expects to be installed. #{self}.required_bins # Run analyzeHeadless (or r2 pdg) against a binary. #{self}.analyze( bin: 'required - filesystem path of the binary', path: 'optional - alias for bin', project_dir: 'optional - Ghidra project directory under ~/.pwn/ghidra' ) # Decompile a binary; same as #analyze when Ghidra/r2 is the engine. #{self}.decompile( bin: 'required - filesystem path of the binary', path: 'optional - alias for bin', project_dir: 'optional - Ghidra project directory', function: 'optional - function name to decompile instead of the whole program' ) # Print the AUTHOR(S) string for this module. #{self}.authors " constants.sort end |
.required_bins ⇒ Object
12 13 14 |
# File 'lib/pwn/plugins/ghidra.rb', line 12 public_class_method def self.required_bins %w[analyzeHeadless] end |