r2pipe.el
r2pipe.el
As it turns out we can script radare2 with emacs , Found this code snippet online
;;
;; R2PIPE in Emacs Lisp
;; Judge Dredd (jjdredd @ github) the.guard@mail.ru
;;
(require 'json)
;; Temporary storage for r2 process std output
(setq r2-pipe-out-string nil)
(defun r2-pipe-filter (process output)
"This filter callback is used by emacs whenever a process has output"
(setq r2-pipe-out-string (concat r2-pipe-out-string output)))
(defun r2-pipe-new (cmdline)
"Spawn r2 with cmdline and return process object on success or nil on failure"
(let ((process (start-process "radare2" nil "r2" "-q0" cmdline)))
(if (equal (process-status process) 'run)
(progn (set-process-filter process 'r2-pipe-filter) process)
nil)))
(defun r2-cmd (process command)
"Executes an r2 command and returns output in a string"
(setq r2-pipe-out-string nil)
(process-send-string process (format "%s\n" command))
(accept-process-output process)
r2-pipe-out-string)
(defun r2-cmd-json (process command)
"Executes a json r2 command and returns output in an elisp object"
(json-read-from-string (r2-cmd process command)))
(defun r2-pipe-close (process)
"Closes r2"
(process-send-string process "q!!\n"))
(defun r2-kill (process)
"Kills r2"
(kill-process process))
(provide 'r2pipe)
Now we can script our reversing tasks from emacs lisp . Mainly there are three function
-
r2-pipe-new
: It opens up radare with the given argument and returns a process object with which we can later interact . -
r2-cmd
: Runs a command and returns the output . -
r2-cmd-json
: Just like the previous but it parses the json output and returns a elisp object.
That’s all you need . Let’s look at an example
First we need to create a new session
(setq process (r2-pipe-new "/bin/ls"))
Let’s run a simple command
(r2-cmd-json process "iIj")
((arch . x86) (binsz . 128811) (bintype . elf) (bits . 64) (canary . t) (class . ELF64) (compiled . ) (crypto . :json-false) (dbg_file . ) (endian . little) (havecode . t) (guid . ) (intrp . /lib64/ld-linux-x86-64.so.2) (lang . c) (linenum . :json-false) (lsyms . :json-false) (machine . AMD x86-64 architecture) (maxopsz . 16) (minopsz . 1) (nx . t) (os . linux) (pcalign . 0) (pic . t) (relocs . :json-false) (relro . partial) (rpath . NONE) (static . :json-false) (stripped . t) (subsys . linux) (va . t) (checksums))
So it returned a alist , for more detail about json parsing in emacs i recommend to read the json.el file . Now we can use elisp to manipulate the data
(format "Architecture: %s " (cdr (assoc 'arch (r2-cmd-json process "iIj"))))
Architecture: x86
(setq output (r2-cmd-json process "pdj 10 @ main"))
;; We are iterating over the vector to retrive the
(setq result "")
(let ((len (length output))
(i 0))
(while (< i len)
(setq result
(concat result
(format "%s \n" ( cdr (assoc 'opcode (aref output i))))))
(setq i (+ i 1 )))
)
result
push r15
push r14
push r13
push r12
mov r12d, edi
push rbp
push rbx
mov rbp, rsi
sub rsp, 0x48
mov rdi, qword [rsi]