User Tools

Site Tools


reverse_engineering:ghidra:memory_map

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revisionBoth sides next revision
reverse_engineering:ghidra:memory_map [2022/03/13 15:33] – created kitorreverse_engineering:ghidra:memory_map [2022/03/13 15:50] kitor
Line 14: Line 14:
  
 Visual explanation may make more sense. Image below contains a complete memory map for EOS R 1.8.0 (7.3.9) ROM. Visual explanation may make more sense. Image below contains a complete memory map for EOS R 1.8.0 (7.3.9) ROM.
-Cacheable RAM mirror on this model is available between ''0x40000000'' and '0xBFFFFFFF''+Cacheable RAM mirror on this model is available between ''0x40000000'' and ''0xBFFFFFFF''.
  
-Because DryOS loads some chunks into locations inside that region (see ''0x40100000'' and ''40700000''), those were added to a memory map first. Later all remaining "undefined" area between ''0x40000000'' and '0xBFFFFFFF'' was defined as uninitialized RAM to complete that part of a memory map.+Because DryOS loads some chunks into locations inside that region (see ''0x40100000'' and ''40700000''), those were added to a memory map first.
  
-{{ :reverse_engineering:ghidra:ghidra_r180_memory.jpg|}}+Later all remaining "undefined" area between ''0x40000000'' and ''0xBFFFFFFF'' was defined as uninitialized RAM to complete that part of a memory map. 
 + 
 +{{:reverse_engineering:ghidra:ghidra_r180_memory.jpg|}} 
 + 
 +===== Sourcing information about ROMCOPY regions ===== 
 + 
 +There are two possible sources: QEMU and static analysis. 
 + 
 +Ideally you want to do both, as each method has it pros and cons.  
 + 
 +==== QEMU ==== 
 + 
 +[[reverse_engineering:qemu:run_firmware|Running firmware in QEMU]] with ''-d romcpy'' option set will produce ''romcpy.sh'' in a camera model subdirectory. 
 + 
 +File is generated using naïve approach - QEMU watches all the memory transfers and tries to write down any bulk transfer from ROM location to somewhere else. This means that file will contain false positives, as well as may be missing some data. 
 + 
 +=== ''romcpy.sh'' syntax === 
 + 
 +Example file from SX740.102: 
 + 
 +<code> 
 +dd if=ROM0.BIN of=SX740.0xDF001000.bin bs=1 skip=$((0x88F0)) count=$((0x400)) 
 +dd if=ROM0.BIN of=SX740.0xDF000000.bin bs=1 skip=$((0x8CF0)) count=$((0x100)) 
 +dd if=ROM0.BIN of=SX740.0x40100000.bin bs=1 skip=$((0x8E0C)) count=$((0x12EA0)) 
 +dd if=ROM0.BIN of=SX740.0x40700000.bin bs=1 skip=$((0x0)) count=$((0x4900)) 
 +dd if=ROM0.BIN of=SX740.0x1F1740.bin bs=1 skip=$((0x40000)) count=$((0x230)) 
 +dd if=ROM0.BIN of=SX740.0x4000.bin bs=1 skip=$((0x101CED8)) count=$((0x55F14)) 
 +dd if=ROM0.BIN of=SX740.0xDF002800.bin bs=1 skip=$((0x1072DEC)) count=$((0xB9C)) 
 +</code> 
 + 
 +If you are not familiar with ''dd'' command syntax, example based on 1st row: 
 +  * ''if='' is input (source) file, in that case ''ROM0.bin'', which (SX740 is DIGIC 8) means ''0xE0000000'' rom base 
 +  * ''of='' contains output file name. After a dot ''.'' we add destination memory address (''0xDF001000''
 +  * ''skip='' contains offset inside input file ''0x88F0'' 
 +  * ''count='' is the length of copied data ''0x400'' 
 + 
 +Thus in this example, data from ''0x400'' bytes from ''0xE00088F0'' (''0xE0000000 + 0x88F0'') was copied to ''0xDF001000'' 
 + 
 +=== Extracting chunks === 
 + 
 +You can run this script in terminal (it has no executable flag and shebang, thus you may want to do ''bash ./romcpy.sh'') to produce new files containing only the regions that were copied to RAM. 
 + 
 +This is not necessarily needed, as ROMCPY regions can be defined in Ghidra without extracting files. 
 + 
 +==== Static firmware analysis ==== 
 + 
 +2nd way is to make a temporary Ghidra project, but load only code ROM image. This is enough to disassemble / decompile DryOS bootloader and find all the important regions simply by looking at the decompiled code. 
 + 
 +While qemu ''-d romcpy'' is (arguably) the easiest way to obtain list of all chunks moved from ROM to RAM, as described in previous section - it is imperfect. 
 + 
 +First of all, it includes all things - including bootloader FROMUTIL that is not needed and may mess up analysis ( it is not available after DryOS boots anyway). 2nd, it just tries to detect bulk memory moves - so a lot of "small regions" are false positives, and sometimes it misses other bits. 
 + 
 +QEMU result might be slightly off as compared to code, as reads/writes are often aligned to bigger chunks. 
 + 
 +=== Obtaining list of ROMCOPY regions from DryOS (2nd stage) bootloader === 
 + 
 +Navigate to ''firmware_entry'' (see [[reverse_engineering:ghidra:create_a_project|Create a Ghidra project]]). Look in the decompiled code for ''for'' loops. Some will just write zeroes (we are not interested in those), other read from one address (in code rom range) and write to another address.  
 + 
 +Read the code, note down each source address, destination start address and destination end address. Calculate region sizes. 
 + 
 +In disassembled code those may look like: 
 +<code> 
 +// src holds address of data source in rom 
 +src = &DAT_e101ced8; 
 + 
 +// loop reads src, writes to dst and increases both pointers by 1 
 +// as long as "end" destination address is reached 
 +for (dst = &DAT_00004000; dst < &DAT_00023770; dst = dst + 1) { 
 +  *dst = *src; 
 +  src = src + 1; 
 +
 +</code> 
 + 
 +Example, from SX740.102: 
 +^ source     ^ to:start              ^ to:end                ^ size                 ^ 
 +| ''0xe101ced8'' | ''0x4000''                | ''0x23770''               | ''0x1F770''              | 
 +| ''0xe103c648'' | ''0x23770''               | ''0x59f14''               | ''0x367A4''              | 
 +| -              | <del>''0x59f14''</del>    | <del>''0xddd1c''</del>    | <del>ram erase</del>     | 
 +| ''0xe1072dec'' | ''0xdf002800''            | ''0xdf00339c''            | ''0xB9C''                | 
 +| -              | <del>''0xdf00339c''</del> | <del>''0xdf0033a8''</del> | <del>ram erase</del>     |
  
  
  
reverse_engineering/ghidra/memory_map.txt · Last modified: 2022/03/13 19:47 by kitor