-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Open
Description
Environment information
- Operating System: macOS Sonoma 14.4.1 (23E224)
- Cutter version: 2.3.4-stable-209c26b
- Obtained from:
- Built from source
- Downloaded release from Cutter website or GitHub
- Distribution repository (brew)
- File format: mach0
Describe the bug
- I wanted to disassemble a hello world program written in C to get a feel of Cutter's workflow. Unfortunately,
jsdecdied as soon as I pointed it to amainfunction. TheGhidradecompiler worked fine.
The code in question, compiled with $ gcc main.c:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
}Error log:
[0x100003f6c]> pddi
{"name":"issue_1716306668046","arch":"arm","archbits":64,"graph":[{"name":"entry0","blocks":[{"address":4294983532,"ops":[{"offset":4294983532,"opcode":"stp fp, lr, [sp, -0x10]!","disasm":"stp fp, lr, [var_10h]!","type":"store","comment":"[00] -r-x section size 32 named 0.__TEXT.__text"},{"offset":4294983536,"val":0,"opcode":"mov fp, sp","disasm":"mov fp, sp","type":"add"},{"offset":4294983540,"ptr":4294979584,"opcode":"adrp x0, 0x100003000","disasm":"adrp x0, data.100003000","type":"lea"},{"offset":4294983544,"val":3992,"opcode":"add x0, x0, 0xf98","disasm":"add x0, x0, 0xf98","type":"add"},{"offset":4294983548,"opcode":"bl 0x100003f8c","disasm":"bl printf","type":"call","jump":4294983564,"fail":4294983552},{"offset":4294983552,"ptr":0,"val":0,"opcode":"mov w0, 0","disasm":"mov w0, 0","type":"mov"},{"offset":4294983556,"ptr":0,"opcode":"ldp fp, lr, [sp], 0x10","disasm":"ldp fp, lr, [sp], 0x10","type":"load"},{"offset":4294983560,"opcode":"ret","disasm":"ret","type":"ret"}]}]}],"isj":[{"name":"__mh_execute_header","flagname":"sym.__mh_execute_header","realname":"__mh_execute_header","ordinal":0,"bind":"GLOBAL","size":0,"type":"FUNC","vaddr":4294967296,"paddr":0,"is_imported":false,"lib":""},{"name":"_main","flagname":"sym._main","realname":"_main","ordinal":1,"bind":"GLOBAL","size":0,"type":"FUNC","vaddr":4294983532,"paddr":16236,"is_imported":false,"lib":""},{"name":"imp.printf","flagname":"sym.imp.printf","realname":"printf","ordinal":2,"bind":"LOCAL","size":0,"type":"FUNC","vaddr":4294983564,"paddr":16268,"is_imported":true,"lib":""},{"name":"func.100003f6c","flagname":"sym.func.100003f6c","realname":"func.100003f6c","ordinal":3,"bind":"LOCAL","size":0,"type":"FUNC","vaddr":4294983532,"paddr":16236,"is_imported":false,"lib":""}],"Csj":[{"offset":4294983576,"type":"Cs","name":"SGVsbG8sIFdvcmw=","enc":"ascii","ascii":true}],"icj":[],"afvj":Usage: a [abdefFghoprxstc] [...]| a* same as afl*;ah*;ax*| aa[?] analyze all (fcns + bbs) (aa0 to avoid sub renaming)| a8 [hexpairs] analyze bytes| ab[?] [addr] analyze block| ad[?] analyze data trampoline (wip)| ad [from] [to] analyze data pointers to (from-to)| ae[?] [expr] analyze opcode eval expression (see ao)| af[?] analyze Functions| aF same as above, but using analysis.depth=1| ag[?] [options] draw graphs in various formats| ah[?] analysis hints (force opcode size, ...)| ai [addr] address information (show perms, stack, heap, ...)| aj same as a* but in json (aflj)| aL list all asm/analysis plugins (e asm.arch=?)| an [name] [@addr] show/rename/create whatever flag/function is used at addr| ao[?] [len] analyze Opcodes (or emulate it)| aO[?] [len] Analyze N instructions in M bytes| ap find prelude for current offset| ar[?] like 'dr' but for the esil vm. (registers)| as[?] [num] analyze syscall using dbg.reg| av[?] [.] show vtables| ax[?] manage refs/xrefs (see also afx?),"afcfj":[{"name":"entry0","noreturn":false,"ret":"void","cc":"arm64","args":[]},{"name":"entry0","noreturn":false,"ret":"void","cc":"arm64","args":[]},{"name":"entry0","noreturn":false,"ret":"void","cc":"arm64","args":[]},{"name":"entry0","noreturn":false,"ret":"void","cc":"arm64","args":[]},{"name":"entry0","noreturn":false,"ret":"void","cc":"arm64","args":[]},{"name":"entry0","noreturn":false,"ret":"void","cc":"arm64","args":[]},{"name":"entry0","noreturn":false,"ret":"void","cc":"arm64","args":[]},{"name":"entry0","noreturn":false,"ret":"void","cc":"arm64","args":[]}],"aflj":[{"offset":4294983532,"name":"entry0","size":32,"is-pure":false,"realsz":32,"noreturn":false,"stackframe":16,"calltype":"arm64","cost":2,"cc":1,"loops":0,"bits":64,"type":"fcn","nbbs":1,"edges":0,"ebbs":1,"signature":"entry0();","minbound":4294983532,"maxbound":4294983564,"callrefs":[{"from":4294983548,"to":4294983564,"type":"CALL"}],"datarefs":[{"from":4294983536,"to":1540080,"type":"DATA"},{"from":4294983540,"to":4294979584,"type":"DATA"},{"from":4294983544,"to":4294983576,"type":"DATA"},{"from":4294983556,"to":1540080,"type":"DATA"},{"from":4294983556,"to":1540088,"type":"DATA"}],"codexrefs":[],"dataxrefs":[],"indegree":0,"outdegree":1,"nlocals":2,"nargs":0,"stackvars":[{"name":"var_10h","arg":false,"type":"int64_t","storage":{"type":"stack","stack":-16}},{"name":"var_8h","arg":false,"type":"int64_t","storage":{"type":"stack","stack":-8}}],"regvars":[]},{"offset":4294983564,"name":"sym.imp.printf","size":12,"is-pure":false,"realsz":12,"noreturn":false,"stackframe":0,"calltype":"arm64","cost":0,"cc":1,"loops":0,"bits":64,"type":"sym","nbbs":1,"edges":0,"ebbs":1,"signature":"int sym.imp.printf(const char *format);","minbound":4294983564,"maxbound":4294983576,"callrefs":[{"from":4294983572,"to":4295016456,"type":"CODE"}],"datarefs":[{"from":4294983564,"to":4294983680,"type":"STRING"},{"from":4294983568,"to":4294983680,"type":"DATA"},{"from":4294983568,"to":4295016456,"type":"DATA"}],"codexrefs":[{"from":4294983548,"to":4294983564,"type":"CALL"}],"dataxrefs":[],"indegree":1,"outdegree":0,"nlocals":0,"nargs":0,"stackvars":[],"regvars":[]}]}
- To add insult to the injury, the
mainfunction was not detected automatically, and I had to resort to manually selecting the offset from theentry0blob. It might be related to the first issue, but I honestly have no idea.
To Reproduce
Steps to reproduce the behavior:
- Compile the above code using
gcc(soclangin a trenchcoat, since I'm on macOS). - Load
a.outinto Cutter, analysis level: auto. - Select the right offset.
Expected behavior
- The disassembler should not crash.
- The
mainfunction should be visible in the sidebar.
Screenshots
Additional context
I did not raise the issue in the jsdec repository, because it seems to be a problem with Cutter calling it incorrectly.
In case you'd like to inspect the binary yourself, I can send it in a .zip file here.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels