cutter icon indicating copy to clipboard operation
cutter copied to clipboard

Cutter.cmdj / Json parsing error / afbj / "Cannot find function"

Open Semnodime opened this issue 2 years ago • 5 comments

Environment information

  • Operating System:
  • Cutter version:
  • Obtained from:
    • [ ] Built from source
    • [x] Downloaded release from Cutter website or GitHub
    • [ ] Distribution repository
  • File format:

Describe the bug The call to the cutter python api raises an JSONDecodeError along the way. This is due to the rizin command afbj outputting a non-json disclaimer (Cannot find function in 0xcaffeebeef) before outputting the actual json [] in a new line.

To Reproduce

Steps to reproduce the behavior: Rizin

  1. Open a the shellcode 0x00 in rizin
  2. Seek to any offset above 0x01 (so there is no function at the current offset)
  3. Run the rizin command afbj
  4. See non-json disclaimer causing the error

Cutter

  1. Use the simple most template for a Cutter python plugin from your website at cutter.re
  2. Add this line in the update_contents section to be executed: cutter.cmd('s 0xcaffeebeef') and cutter.cmdj('afbj')[0]

Expected behavior Either

  • Rizin should probably not print the disclaimer when in json mode. If so, then migrate this bug to rizin.
  • Cutter should parse the rizin output correctly even when no function is available

In any case, cutter.cmdj('afbj') should return an empty python list or tuple instead of raising an exception.

Additional Context

  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
No functions at 0x11Traceback (most recent call last):
  File "/home/user/.local/share/rizin/cutter/plugins/python/nop_bb.py", line 47, in nop_bb
    bb_info = cutter.cmdj('afbj')[0]
  File ":/python/cutter.py", line 15, in cmdj
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
No functions at 0x11Traceback (most recent call last):
  File "/home/user/.local/share/rizin/cutter/plugins/python/nop_bb.py", line 47, in nop_bb
    bb_info = cutter.cmdj('afbj')[0]
  File ":/python/cutter.py", line 15, in cmdj
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
No functions at 0x11Traceback (most recent call last):
  File "/home/user/.local/share/rizin/cutter/plugins/python/nop_bb.py", line 47, in nop_bb
    bb_info = cutter.cmdj('afbj')[0]
  File ":/python/cutter.py", line 15, in cmdj
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
No functions at 0x11Traceback (most recent call last):
  File "/home/user/.local/share/rizin/cutter/plugins/python/nop_bb.py", line 47, in nop_bb
    bb_info = cutter.cmdj('afbj')[0]
  File ":/python/cutter.py", line 15, in cmdj
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
No functions at 0x11Traceback (most recent call last):
  File "/home/user/.local/share/rizin/cutter/plugins/python/nop_bb.py", line 47, in nop_bb
    bb_info = cutter.cmdj('afbj')[0]
  File ":/python/cutter.py", line 15, in cmdj
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/tmp/.mount_CutteraNU2r6/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None

Semnodime avatar Nov 22 '21 07:11 Semnodime

@imbillow part of the https://github.com/rizinorg/cutter/issues/2666 - probably worth to put this one in the first or the second batch.

XVilka avatar Dec 21 '21 14:12 XVilka

So what should cmdj return when empty, is None ok?

diff --git a/src/python/cutter.py b/src/python/cutter.py
index d8c73049..b9b3cbf0 100644
--- a/src/python/cutter.py
+++ b/src/python/cutter.py
@@ -12,6 +12,7 @@ except ImportError:
 
 def cmdj(command):
     """Execute a JSON command and return the result as a dictionary"""
-    return json.loads(cmd(command))
-
-
+    x = cmd(command)
+    if x == '':
+        return None
+    return json.loads(x)

imbillow avatar Jan 20 '22 14:01 imbillow

Maybe it is useful to provide some way of returning the cause (e.g. "Cannot find function"). E.g. via some custom Exception that can be caught specifically when calling cmdj with some parameter like explicit=True or such.

Semnodime avatar Jan 20 '22 16:01 Semnodime

I think this should/will be fixed in the main branch as the current Rizin is used. During the rafactoring of afb and the move to rzshell, the message No function found in 0x00000000. was moved the RZ_LOG_ERROR and I think that is not/should not be considered when getting the command output in rzpipe

ret2libc avatar Jan 24 '22 10:01 ret2libc

@Semnodime could you please retest with the latest Cutter dev branch?

XVilka avatar May 14 '22 12:05 XVilka