From 3f462a2d07d9da5b0e4e66f0065078853ccfbc6f Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Fri, 28 Feb 2020 16:42:46 +0100 Subject: [PATCH] disasm: support block disassembly (eg 80000000:4k). --- Makefile | 0 README.md | 16 ++++++++-------- fxos/disassembly.cpp | 41 +++++++++++++++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 16 deletions(-) mode change 100644 => 100755 Makefile diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 diff --git a/README.md b/README.md index 0b45352..10c3b7c 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,11 @@ instruction tables to lists of named syscalls. These resources are usually public for the most part, but some of the reverse-engineering results of the community are kept private. -A set of base files for a working library can be found [on my section of the -Planète Casio bible](https://bible.planet-casio.com/lephenixnoir/fxos-library/). -You can use your own files, but you probably want the assembler tables anyway. +A set of base files for a working library can be found in the +[`base-library` folder](base-library) of this repository, +which includes a suitable configuration file. Though unless you want to redo +the research by yourself, you can get shared community data from the +[fxdoc repository](/Lephenixnoir/fxdoc). Next, fxos should be told where to find these files. A small configuration file should be added at `$HOME/.config/fxos/config` to do this. The configuration @@ -56,14 +58,14 @@ With the default library, the configuration file should look like this: ``` library: /path/to/fxos-library -load: /path/to/fxos-library/asm +load: /path/to/fxos-library/asmtables load: /path/to/fxos-library/targets load: /path/to/fxos-library/symbols ``` This means that fxos data files will be automatically loaded at startup from -the `asm`, `targets` and `symbols` directories. Targets refer to OS files and -RAM dumps by path, and these paths will be interpreted relatively to the +the `asmtables`, `targets` and `symbols` directories. Targets refer to OS files +and RAM dumps by path, and these paths will be interpreted relatively to the `fxos-library` folder. If you create `$PREFIX/share/fxos`, it will also be used as if mentioned on a `library:` line. @@ -216,8 +218,6 @@ Some of the advertised interface is not yet implemented: object to understand what it is used for. An example would be: given a 32-bit value, find all places in the code where it is loaded from memory, and match these places with the known OS structure to see what kind of code uses it. -* The location specified `
:` is not supported right now, though I - don't know how long I'll last without it. ## Reporting issues and results diff --git a/fxos/disassembly.cpp b/fxos/disassembly.cpp index 65f4781..7713976 100644 --- a/fxos/disassembly.cpp +++ b/fxos/disassembly.cpp @@ -18,17 +18,19 @@ int disassembly(Library &library, Target &target, char const *ref, std::vector passes) { Disassembly disasm(target); + int len=0; /* Observe the target only if it has an OS mapped */ std::unique_ptr os; - if(target.covers(MemoryRegion::ROM)) - os = std::make_unique(target); + if(target.covers(MemoryRegion::ROM)) os = std::make_unique(target); - uint32_t address; + /* Parameters inside the ref */ + uint32_t address = -1; + uint32_t blocklen; int syscall_id; - int len = 0; + char blockmul[2] = { 0 }; - enum { RefNone=0, RefSyscall, RefAddress } reftype = RefNone; + enum { RefNone=0, RefSyscall, RefAddress, RefBlock } reftype = RefNone; /* Parse different flavors of references. %: syscall */ if(sscanf(ref, "%%%x", &syscall_id) == 1) @@ -36,6 +38,21 @@ int disassembly(Library &library, Target &target, char const *ref, /* Pure hexa: address */ else if(sscanf(ref, "%x%n", &address, &len) == 1 && !ref[len]) reftype = RefAddress; + /* Hexa with a size: a block */ + else if(sscanf(ref,"%x:%x%n",&address,&blocklen,&len)==2 && !ref[len]) + reftype = RefBlock; + /* Variant of block size that includes a letter k/M/G (note that the + "%[]" specifier never matches empty strings */ + else if(sscanf(ref, "%x:%x%1[kMG]%n", &address, &blocklen, blockmul, + &len) == 3 && !ref[len]) + { + reftype = RefBlock; + + int mul = blockmul[0]; + if(mul == 'k') blocklen <<= 10; + if(mul == 'M') blocklen <<= 20; + if(mul == 'G') blocklen <<= 30; + } /* Anything else: look up symbols */ else { @@ -71,7 +88,7 @@ int disassembly(Library &library, Target &target, char const *ref, address = os->syscall(syscall_id); } - else if(reftype == RefAddress) + if(reftype == RefAddress || reftype == RefBlock) { if(address & 1) { @@ -80,7 +97,15 @@ int disassembly(Library &library, Target &target, char const *ref, address++; } } - else + if(reftype == RefBlock) + { + /* Load the block into memory */ + for(uint32_t pc = address; pc < address + blocklen; pc += 2) + { + disasm.readins(pc); + } + } + if(reftype == RefNone) { log(ERR "cannot interpret '%s' (not a syscall id, not an " "address, and no such symbol in library)", ref); @@ -92,7 +117,7 @@ int disassembly(Library &library, Target &target, char const *ref, auto start = timer_start(); log(LOG "Running pass %s...\\", pass); - if(pass == "cfg") + if(pass == "cfg" && reftype != RefBlock) { CfgPass p(disasm); p.run(address);