Search code examples
assemblyreverse-engineeringmipsmips32disassembly

MIPS Linux assembler code understanding about load byte


I have the following question here

I need to understand the following MIPS disassembling code:

.text:00489060             la      $v0, 0x4D0000

.text:00489064             la      $v0, 0x4D0000

.text:00489068             addiu   $v1, $v0, (aBig5 - 0x4D0000)  # "BIG-5"

.text:0048906C             lw      $v0, (aBig5 - 0x4D0000)($v0)  # "BIG-5"

.text:00489070             lbu     $a0, (aBig5+5 - 0x4D6A68)($v1)

.text:00489074             lbu     $v1, (aBig5+4 - 0x4D6A68)($v1)

.text:00489078             swl     $v0, 0($s1)

.text:0048907C             swr     $v0, 3($s1)

.text:00489080             sb      $a0, 5($s1)

.text:00489084             b       loc_48A190

.text:00489088             sb      $v1, 4($s1)

.text:0048908C  # ---------------------------------------------------------------------------

.text:0048908C

.text:0048908C loc_48908C:              # CODE XREF: cgiGetVar+B8j

.text:0048908C             lw      $v1, (dword_4D6A5C - 0x4D0000)($v0) #"ISO-"

.text:00489090             addiu   $v0, (dword_4D6A5C - 0x4D0000)

.text:00489094             lw      $a0, (dword_4D6A60 - 0x4D6A5C)($v0) #"8859"

.text:00489098             swl     $v1, 0($s1)

.text:0048909C             lbu     $a1, (byte_4D6A66 - 0x4D6A5C)($v0)  # zero byte

.text:004890A0             lbu     $a2, (byte_4D6A64 - 0x4D6A5C)($v0)  # "-"

.text:004890A4             lbu     $v0, (byte_4D6A65 - 0x4D6A5C)($v0)  # "1"

.text:004890A8             swr     $v1, 3($s1)

.text:004890AC             swl     $a0, 4($s1)

.text:004890B0             swr     $a0, 7($s1)

.text:004890B4             sb      $a1, 0xA($s1)

.text:004890B8             sb      $a2, 8($s1)

.text:004890BC             b       loc_48A190

.text:004890C0             sb      $v0, 9($s1)

.text:004890C4  #

The task I need to solve is, to change Web Language ID from BIG-5 to ISO-8859-5 in my router firmware manager (without sources :) ) So ISO-8859-5 is 5 letters longer then BIG-5. I've moved the right hand (of BIG-5) text block in .rodata section )here is hex fragment:

  4d6a50:   68746d6c 63686172 73657400 49534f2d     htmlcharset.ISO-
  4d6a60:   38383539 2d310000 4249472d 35000000     8859-1..BIG-5...
  4d6a70:   53757043 484c616e 67000000 636f6e6e     SupCHLang...conn

& changed the pointer in .text section. However when I run the program it loads just 6 bytes (I see "ISO-88" instead of (ISO-8859-5) in HTML-code page of router. So I guess I have to find where is the number of developing bytes is fixed and change it. Could somebody comments this code. Thanks a lot :)


Solution

  • The number of bytes is not specified. It just loads a word and two bytes and that's it:

    ; load one word (4 bytes) into v0
    lw      $v0, (aBig5 - 0x4D0000)($v0)
    ; load one byte into a0
    lbu     $a0, (aBig5+5 - 0x4D6A68)($v1)
    ; load one byte into v1
    lbu     $v1, (aBig5+4 - 0x4D6A68)($v1)
    ; store left part of the word from v0
    swl     $v0, 0($s1)
    ; store right part of the word from v0
    swr     $v0, 3($s1)
    ; store byte from a0
    sb      $a0, 5($s1)
    ; store byte from v1
    sb      $v1, 4($s1)
    

    So it's basically fixed for a 5-char string and a longer one won't work without patching the code. You might be able to patch it for a 7-char one (8 bytes) by loading words and replacing the two sb by swl and swr. Another option, if you are certain that s1 is aligned, is to load three words (12 bytes) and store the latter two using just sw instead of swl/swr pair.