Search code examples
linuxassemblymipsreverse-engineeringgnu-assembler

Linux Binutils using 'as' to assemble Mips


I've extracted D-Link firmware that I'm attempting to Reverse Engineer.

I don't have any previous experience with Mips. I've downloaded Mars to learn Mips. But now that I kind of get the just of Mips I would like to build the machine code. I can export it from Mars as a dump and radare2 disassembles it just fine however I would prefer a terminal utility.

I heard that as is capable of this however it doesn't have a option under -march for mips32, mips1, mips2 etc.

I've torn through Google to see why that is and had no success thus far. Could someone put me on the right path to get these features in as enabled correctly?

Thanks so much for the help.


Solution

  • I found a solution after some headache, however this is great for those who are looking to learn mips quickly on linux.

    test.asm:

    .text
    main:
    li $t1, 100
    li $t2, 50
    add $t3, $t1, $t2
    li $t4, 25
    

    With your asm file do the following to assemble it to machine code by installing spim which is oddly enough mips spelled backwards:

    apt-get update
    apt-get install spim
    spim
    (spim) load "test.asm"
    (spim) dumpnative "test.bin"
    

    This will dump a bin files for you with the machine code. Yes you need the quotes around the files names or spim will throw a fit.

    To disassemble your code do this:

    apt-get update
    apt-get install radare2
    radare2 -a mips test.bin
    [0x00000000]>b 32
    [0x00000000]>aa
    [0x00000000]>af
    [0x00000000]>pd
    

    Though this is a quick way to do this with qemu and it's much more accurate than spim:

    First download DTC here. *Note: The reason this has to be done is because the way qemu is setup it only looks for DTC in the folder contained in the DTC folder that comes with the source not within /usr/lib or /usr/include etc.

    Let's start compiling qemu:

    apt-get update
    apt-get -y install git build-essential
    git clone git://git.qemu-project.org/qemu.git
    tar -xzvf dtc-1760e7c.tar.gz
    cd dtc-1760e7c
    cp * ../qemu/dtc
    cp -r Documentation/ ../qemu/dtc
    cp -r libfdt/ ../qemu/dtc
    cp -r scripts/ ../qemu/dtc
    cp -r tests/ ../qemu/dtc
    cd ..
    cd qemu/dtc
    make
    cd ..
    ./configure
    make
    make install
    

    After qemu is installed let's now create a virtual machine that qemu can use it will be the mips version of Debian Squeeze.

    First let's get the required files:

    wget http://ftp.de.debian.org/debian/dists/squeeze/main/installer-mips/current/images/malta/netboot/initrd.gz
    wget http://ftp.de.debian.org/debian/dists/squeeze/main/installer-mips/current/images/malta/netboot/vmlinux-2.6.32-5-4kc-malta
    

    Now make the virtual drive for qemu:

    qemu-img create -f qcow2 debian_mips.qcow2 2G
    

    Run the installer:

    qemu-system-mips -hda debian_mips.qcow2 -kernel vmlinux-2.6.32-5-4kc-malta -initrd initrd.gz -append "root=/dev/ram console=ttyS0" -nographic
    

    Follow all the prompts and install to your preference.

    To boot into Debian Squeeze running emulated mips do the following:

    qemu-system-mips -hda debian_mips.qcow2 -kernel vmlinux-2.6.32-5-4kc-malta -append "root=/dev/sda1 console=ttyS0" -nographic
    

    While in here login with your credentials you setup during the installation and do the following to setup ssh for ease of use:

    apt-get update
    apt-get -y install ssh
    

    Close this instance of qemu and launch another with the following:

    qemu-system-mips -hda debian_mips.qcow2 -kernel vmlinux-2.6.32-5-4kc-malta -append "root=/dev/sda1 console=ttyS0" -nographic -redir tcp:10022::22
    

    Connect to ssh doing the following on the host computer:

    ssh -p 10022 localhost
    

    Now once logged in let's now install the things we need to do mips assembly:

    apt-get update
    apt-get -y install build-essential gdb
    

    Now let's write a simple mips asm file assemble it and disassemble it and compare the code.

    nano test.asm
    
    --start test.asm--
    .global __start
    .text
    __start:
    li $t0, 100
    li $t1, 50
    add $t2, $t0, $t1
    --end test.asm--
    
    CTRL + O, CTRL + X
    
    as -march=mips32 -o test.o test.asm
    objdump -d test.o
    
    --start objdump output--
    0:  24080064    li  t0,100
       4:   24090032    li  t1,50
       8:   01095020    add t2,t0,t1
       c:   00000000    nop
    --end objdump output--
    

    You can see we do get the exact commands this way where as spim sometimes doesn't match.

    Your disassembler will interpret it to it's best and output the assembly instructions some may not look exactly the same based on the decompiler however it works very good for most instructions and still should be valid.

    The reason this is great is you don't have to have Mars open to do this. Mars is a good tool to simulate getting the machine code for mips but spim and qemu certainly is lightweight and keeps it in the terminal for you. I hope this helps someone else as well.

    --lillypad