5.5 Comparison

Welcome to the IDA v5.5 comparison page! Below you will find side-by-side comparisons of IDA v5.4 and v5.5 disassemblies. Please maximize the window too see both columns simultaneously.

The following original exhibits are displayed on this page:

  1. ARM: support for SUB Rx, R11, #fpoff stack variable references

  2. ARM: floating-point constants in instructions

  3. ARM: type info and argument names

  4. ARM: simplified instructions

  5. ARM: support for more switch idioms

  6. PDB: function argument names

  7. MIPS: much improved analysis

NOTE: these are just some selected examples, that can be illustrated as a side-by-side difference. IDA v5.5 includes are many other improvements and new features that are not mentioned on this page – simply because there was nothing to compare them with. For more information, please refer to IDA v5.5 feature list.

ARM: support for SUB Rx, R11, #fpoff stack variable references

; —————————————————————– SUB R0, R11, #0x94 LDR R1, [R11,#var_58] BL _ZN6HBufC83DesEv ; HBufC8::Des(void) SUB R3, R11, #0x94 SUB R0, R11, #0x4C MOV R1, R3 LDR R2, [R11,#var_5C] LDR R3, [R11,#var_60] BL _ZNK6TDesC83MidEii ; TDesC8::Mid(int,int)

; —————————————————————– SUB R0, R11, #-var_94 LDR R1, [R11,#var_58] BL _ZN6HBufC83DesEv ; HBufC8::Des(void) SUB R3, R11, #-var_94 SUB R0, R11, #-var_4C MOV R1, R3 LDR R2, [R11,#var_5C] LDR R3, [R11,#var_60] BL _ZNK6TDesC83MidEii ; TDesC8::Mid(int,int)

Please note that more stack variable references have been recognized. Previous versions of IDA could not handle negative stack offsets.ARM: floating-point constants in instructions

; —————————————————————– loc_30071630 ; CODE XREF: _log1pf+12Cj FLDS S14, flt_300716E4 FLDS S13, flt_300716E8 FLDS S12, flt_300716EC

; —————————————————————– loc_30071630 ; CODE XREF: _log1pf+12Cj FLDS S14, =2.0 FLDS S13, =0.14798 FLDS S12, =0.15314

The code on the right is more readable, isn’t it?ARM: type info and argument names

; —————————————————————– ADD R3, SP, #0x4B4+var_4A0 LDR R0, [SP,#0x4B4+hKey] ; hKey STR R3, [SP,#0x4B4+dwInitParam] MOV R2, #0 ; ulOptions MOV R3, #0 ; samDesired ADD R1, SP, #0x4B4+SubKey ; lpSubKey BL RegOpenKeyExW LDR R3, [SP,#0x4B4+var_4A0]

; —————————————————————– ADD R3, SP, #0x4B4+phkResult LDR R0, [SP,#0x4B4+hKey] ; hKey STR R3, [SP,#0x4B4+dwInitParam] ; phkResult MOV R2, #0 ; ulOptions MOV R3, #0 ; samDesired ADD R1, SP, #0x4B4+SubKey ; lpSubKey BL RegOpenKeyExW LDR R3, [SP,#0x4B4+phkResult]

We made numerous tiny improvements to the analysis engine. The above example illustrates just one particular case: function arguments that are passed by references are handled more properly. While there are lots of similar examples, we will limit ourselves to this single snippet. Anyway, you get the idea…ARM: simplified instructions

; —————————————————————– ADDS R1, R6, #0 ADDS R3, R4, #0 ADDS R0, R5, #0 MOVS R2, #2 BLX j____dtoa LDR R3, =0x270F ADDS R6, R0, #0

; —————————————————————– MOVS R1, R6 MOVS R3, R4 MOVS R0, R5 MOVS R2, #2 BLX j____dtoa LDR R3, =0x270F MOVS R6, R0

More instructions are simplified to MOV’s – easier to read.ARM: support for more switch idioms

CMP R4, #6 BCS loc_46CD0A TBB.W [PC,R4] ; —————————————————————– DCB 0x54 ; T DCB 0x17 DCB 3 DCB 0x1E DCB 3 DCB 6 DCB 0x8C ; Œ DCB 0xB2 ; ² DCB 6 DCB 0x46 ; F DCB 6 DCB 0xE0 ; à DCB 0x28 ; ( DCB 0x78 ; x DCB 0x76 ; v

CMP R4, #6 ; switch 6 cases BCS loc_46CD0A ; default ; jumptable 0046CC5E case 0 TBB.W [PC,R4] ; switch jump ; —————————————————————– jpt_46CC5E DCB 0x54 ; jump table for switch statement DCB 0x17 DCB 3 DCB 0x1E DCB 3 DCB 6 ; —————————————————————– loc_46CC68 ; CODE XREF: sub_46CC38+26j UXTH R4, R1 ; jumptable 0046CC5E cases 2,4 MOV R6, R0 B loc_46CC7C ; —————————————————————– loc_46CC6E ; CODE XREF: sub_46CC38+26j LDRB R0, [R5] ; jumptable 0046CC5E case 5 MOV R6, LR

This example illustrates analysis of TBB/TBH instructions.PDB: function argument names

; =============== S U B R O U T I N E ============================= ; Attributes: bp-based frame ; int __cdecl genfname(char *, unsigned int, unsigned int) genfname proc near ; CODE XREF: __tmpnam_helper+6Ep ; __tmpfile_helper+119p … pext = byte ptr -0Ch var_4 = dword ptr -4 fnameSize = dword ptr 8 tmp_max = dword ptr 0Ch fname = ecx push ebp mov ebp, esp sub esp, 0Ch mov eax, ___security_cookie xor eax, ebp mov [ebp+var_4], eax push ebx push esi push edi mov edi, fname push 2Eh ; unsigned int push edi ; char * call __mbsrchr mov esi, eax push 20h ; int xor ebx, ebx inc esi push ebx ; char ** push esi ; char * call _strtoul

; =============== S U B R O U T I N E ============================= ; Attributes: bp-based frame ; int __usercall genfname<eax>(char *fname<ecx>, unsigned int fnameSize, unsigned int tmp_max) genfname proc near ; CODE XREF: __tmpnam_helper+6Ep ; __tmpfile_helper+119p … pext = byte ptr -0Ch var_4 = dword ptr -4 fnameSize = dword ptr 8 tmp_max = dword ptr 0Ch fname = ecx push ebp mov ebp, esp sub esp, 0Ch mov eax, ___security_cookie xor eax, ebp mov [ebp+var_4], eax push ebx push esi push edi mov edi, fname push 2Eh ; c push edi ; str call __mbsrchr mov esi, eax push 20h ; ibase xor ebx, ebx inc esi push ebx ; endptr push esi ; nptr call _strtoul

Check the function prototype: IDA now knows about the exact locations of all input arguments and can propagate them through the database. The previous prototype can be even called misleading…MIPS: much improved analysis

; —————————————————————– lw $t9, (get_terminal_width_height_ptr – 0x46D120)($gp) move $a0, $0 addiu $a1, $sp, 0x40+var_28 jalr $t9 move $a2, $0 lw $gp, 0x40+var_30($sp) lw $v1, 0x40+var_28($sp) lw $v0, (bb_msg_full_version_ptr – 0x46D120)($gp) lw $a0, (off_465138 – 0x46D120)($gp) lw $t9, (off_465A74 – 0x46D120)($gp) addiu $v1, –0x14 lw $a1, 0($v0) sw $v1, 0x40+var_28($sp) jalr $t9 addiu $a0, –0x55F0 lw $gp, 0x40+var_30($sp) lw $v0, (off_465138 – 0x46D120)($gp) lw $t9, (off_465A74 – 0x46D120)($gp) addiu $s4, $v0, –0x5498 lw $v0, (off_465138 – 0x46D120)($gp) lw $s1, (applets_ptr – 0x46D120)($gp) lw $s6, (off_465138 – 0x46D120)($gp) lw $s5, (off_465138 – 0x46D120)($gp) move $s2, $t9 b loc_406644 addiu $s3, $v0, –0x1158

; —————————————————————– la $t9, get_terminal_width_height move $a0, $0 addiu $a1, $sp, 0x40+var_28 jalr $t9 ; get_terminal_width_height move $a2, $0 lw $gp, 0x40+var_30($sp) lw $v1, 0x40+var_28($sp) la $v0, bb_msg_full_version la $a0, 0x460000 la $t9, printf addiu $v1, –0x14 lw $a1, (bb_msg_full_version – 0x463E8C)($v0) sw $v1, 0x40+var_28($sp) jalr $t9 ; printf addiu $a0, (aSUsageBusyboxF – 0x460000) # “%s\n\nUsage: busybox [function] [argument”… lw $gp, 0x40+var_30($sp) la $v0, 0x460000 la $t9, printf addiu $s4, $v0, (asc_45AB68 – 0x460000) # “\t” la $v0, 0x460000 la $s1, applets la $s6, 0x460000 la $s5, 0x460000 move $s2, $t9 b loc_406644 addiu $s3, $v0, (asc_45EEA8 – 0x460000) # “, “

This sample is very spectacular: we switch from inhuman names and hex addresses to a highly readable code. The transition is possible because we handle handle dynamic symbols in MIPS ELF files and improved the MIPS module in many ways.

Last updated