Skip to content

Instantly share code, notes, and snippets.

@dwaq
Created April 12, 2018 17:12
Show Gist options
  • Select an option

  • Save dwaq/6bd16d60a3469d2a1397b135c83fc0af to your computer and use it in GitHub Desktop.

Select an option

Save dwaq/6bd16d60a3469d2a1397b135c83fc0af to your computer and use it in GitHub Desktop.

Revisions

  1. dwaq created this gist Apr 12, 2018.
    110 changes: 110 additions & 0 deletions Scanlime How does it boot? Notes
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,110 @@
    https://www.youtube.com/watch?v=rA7u0l9QbJg

    https://github.com/scanlime/metalkit

    list all nested files in directory
    $ find . | less

    find text in files recursively
    $ grep -t text2find .

    try and run linux (from file found in /boot in linux file system)
    $ qemu-system-i386 -kernel vmlinux-3.19.0-84-generic
    runs, but kernel panics because there's no root file system
    $ qemu-system-i386 -kernel core.img
    boots into grub rescue>

    want to load this `core.img` onto the voting machine
    use gub installer to load grub onto a disk from a linux VM
    then patch the image to load RAM.ABS

    this can tell what the file is (it's an elf):
    $ arm-none-eabi-readelf -a memtest86+_multiboot.bin | less
    difference between program headers and section headers:
    section headers: used for communication between different build tools (object files, or between linker and disassembler) debug data is only in section headers because it's only relevant to the tools - binary analysis tools might get more info out of section headers because it's intended for tool use
    program headers: specifically what gets loaded into memory and made available to the program when it's running - loaders only need this info

    load addresses are all 0 -> just applying this to the beginning of physical memory, so can't boot into memtest, but should be able to boot into this from grub

    https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
    multiboot header: 0xab1b
    next lines are memory offsets
    then memory address where we want local jump to end up

    Python3 tests:
    assert(statement == assumed_val)
    assert(magic == 0x1badb002)

    $ xxd RAM.ASM | head
    now we know what the 1st byte is

    let's write some asm!
    then use
    $ nasm boot-test.asm
    to compile it
    then use
    $ ndisasm boot-test
    to decompile it and check that we did it right

    modified the RAM.ABS to use GRUB jump
    copied the newly modified RAM.ABS over the RAM.ABS on the CF card
    $ sync
    commits all files to disk on linux

    trying to make PSOSBOOT.img chain back onto itself by erasing the jump instructions and exporting a new .img
    boot it as a hdd image:
    $ qemu-system-i386 -hda tmp.img
    doesn't do anything special, but now the bootloader is interrupted so we can try to get to this screen on the real machine
    machine automcatically points to RAM.ABS, but we're going to change it to PSOSBOOT.SYS
    gets 2 dots and no other message -> something different is happening, but don't know what...

    putting the original RAM.ABS on there (monolythic operating system) and pasting the new modifications over the beginning
    $ dd if=/grub.RAM.ABS of=RAM.ABS bs=25191 conv=notruc
    didn't work

    search command history for some text
    $ history | grep some-text

    add line numbers to a file (useful for logs)
    $ cat -n file.log > file.ln.log

    Dug into reverse engineering with IDA, found a point (and address) where we want to set a breakpoint
    freeze CPU at startup
    $ qemu-system-i386 -s -S -hda tmp.img
    then in another window, connect to it with GDB
    $ gdb
    can also use "set arch"
    $ set architecture i386
    $ target remote localhost:1234
    print the value of expression:
    $ p/x 0x1b26 + 0x7e00
    set breakpoint at address. Address locations begin with "*" and specify an exact address in the program.
    $ b *0x9929
    continue running code until breakpoint
    $ cont
    delete breakpoint
    $ del 1
    List of integer registers and their contents
    can also use "i reg"
    $ info registers
    Step one instruction exactly.
    $ stepi
    can hold enter to repeat last command
    print 20 instructions ($eip seems to be program counter, so start printing at current instruction?)
    $ x/20i $eip
    Step one instruction, but proceed through subroutine calls.
    $ nexti
    Disable all breakpoints (but doesn't delete them)
    $ dis
    View all breakpoints
    $ i br
    @ 4:00:00 into video
    memory breakpoints @ address
    $ watch -l *0xcd24
    print data at address (this time a register)
    p *(int)$eax
    set a value into a register
    set *(int)$eax = 0xa0
    @ 5:20:00
    output new data in 1st file to 2nd file
    $ tail -F alldata.log > newdata.log