Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] BinWalk integration #231

Open
PROPHESSOR opened this issue Mar 5, 2024 · 2 comments
Open

[Feature Request] BinWalk integration #231

PROPHESSOR opened this issue Mar 5, 2024 · 2 comments

Comments

@PROPHESSOR
Copy link

It's useful to have BinWalk integration to add comments on different parts of the file automatically.

This feature is partially implemented in HexWalk but it doesn't have comments functionality.

image

@solemnwarning
Copy link
Owner

I'm not familiar with BinWalk, but it looks like you can run it on the command line and get some kind of parsable output, so it might be easily implemented as a plugin (see the pcap plugin for an example).

@solemnwarning
Copy link
Owner

I made an attempt at making a Binwalk plugin, I've only briefly tested it on Linux so far (requires Python and Binwalk to be installed), let me know how you get on with it!

-- Binwalk analysis plugin for REHex
-- Copyright (C) 2024 Daniel Collins <solemnwarning@solemnwarning.net>
--
-- This program is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License version 2 as published by
-- the Free Software Foundation.
--
-- This program is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-- more details.
--
-- You should have received a copy of the GNU General Public License along with
-- this program; if not, write to the Free Software Foundation, Inc., 51
-- Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

-- Name or path of the Python interpreter.
local PYTHON_INTERP = "python3"

-- This is a stub program we pipe into the Python interpreter to do binwalk
-- analysis and then read the output it pipes back to us.
local BINWALK_STUB = [[
import binwalk
import os

results = binwalk.scan(os.environ["BINWALK_ANALYSIS_FILE"], signature=True, quiet=True)

for module in results:
    for result in module.results:
        print("%u\t%u\t%s" % (result.offset, result.size, result.description))
]]

-- Error codes which may be returned by wx.wxProcess.Kill()
local WXK_ERRORS = {
	[wx.wxKILL_BAD_SIGNAL]    = "wxKILL_BAD_SIGNAL",
	[wx.wxKILL_ACCESS_DENIED] = "wxKILL_ACCESS_DENIED",
	[wx.wxKILL_NO_PROCESS]    = "wxKILL_NO_PROCESS",
	[wx.wxKILL_ERROR]         = "wxKILL_ERROR",
}

rehex.AddToToolsMenu("Binwalk signature analysis", function(mainwindow)
	local doc = mainwindow:active_document()
	
	local progress_dialog = wx.wxProgressDialog(
		"Analysing file",
		"Running binwalk...",
		100,
		mainwindow,
		wx.wxPD_CAN_ABORT | wx.wxPD_ELAPSED_TIME | wx.wxPD_APP_MODAL)
	progress_dialog:Show()
	
	doc:transact_begin("Binwalk signature analysis")
	
	local ok, err = pcall(function()
		local cancelled = false
		
		local timer = wx.wxTimer.new()
		
		-- We store the name of the current file in the environment for the stub process.
		wx.wxSetEnv("BINWALK_ANALYSIS_FILE", doc:get_filename())
		
		local proc = wx.wxProcess.new()
		proc:Redirect()
		
		local stdout_buf = ""
		local stderr_buf = ""
		
		proc:Connect(wx.wxID_ANY, wx.wxEVT_END_PROCESS, function(event)
			-- The binwalk child process has finished.
			
			if cancelled
			then
				-- User already pressed the cancel button.
				return
			end
			
			-- Buffer any output from the child process
			
			local stdout = proc:GetInputStream()
			local stderr = proc:GetErrorStream()
			
			while not stdout:Eof()
			do
				stdout_buf = stdout_buf .. stdout:Read(1024)
			end
	
			while not stderr:Eof()
			do
				stderr_buf = stderr_buf .. stderr:Read(1024)
			end
			
			if event:GetExitCode() == 0
			then
				-- Child exited gracefully, add comments for anything it found and
				-- commit the transaction.
				
				for offset, length, desc in string.gmatch(stdout_buf, "(%d+)\t(%d+)\t(.-)\n") do
					doc:set_comment(
						rehex.BitOffset(tonumber(offset), 0),
						rehex.BitOffset(tonumber(length), 0),
						rehex.Comment.new(desc))
				end
				
				doc:transact_commit()
			else
				-- Child died, rollback the transaction and display anything
				-- written to its stderr.
				
				doc:transact_rollback()
				wx.wxMessageBox(stderr_buf, "Error executing binwalk")
			end
			
			timer:Stop()
			timer = nil
			
			progress_dialog:Destroy()
		end)
		
		wx.wxExecute(PYTHON_INTERP, wx.wxEXEC_ASYNC, proc)
		
		local stdin = proc:GetOutputStream()
		stdin:Write(BINWALK_STUB, BINWALK_STUB:len())
		stdin:Close()
		
		timer:Connect(wx.wxID_ANY, wx.wxEVT_TIMER, function(event)
			progress_dialog:Pulse()
			
			if progress_dialog:WasCancelled() and not cancelled
			then
				-- User has pushed the cancel button, we rollback the transaction
				-- and kill the child, ignoring any further data from it.
				
				cancelled = true
				
				local ke = wx.wxProcess.Kill(proc:GetPid())
				if ke ~= wx.wxKILL_OK
				then
					if WXK_ERRORS[ke] ~= nil
					then
						rehex.print_error("Unexpected error when killing binwalk process: " .. WXK_ERRORS[ke])
					else
						rehex.print_error("Unexpected error when killing binwalk process: " .. ke)
					end
				end
				
				doc:transact_rollback()
				
				timer:Stop()
				timer = nil
				
				progress_dialog:Destroy()
			end
		end)
		
		timer:Start(100, wxTIMER_CONTINUOUS)
	end)
	
	wx.wxUnsetEnv("BINWALK_ANALYSIS_FILE")
	
	if not ok
	then
		-- An error occured while starting the analysis, rollback the transaction and
		-- display the exception message.
		
		doc:transact_rollback()
		wx.wxMessageBox(err, "Error")
		
		progress_dialog:Destroy()
	end
end)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants