Ghidra 对 ARMv7 strb.w 指令的反编译是否被破坏了?

逆向工程 反编译 C 手臂 吉德拉
2021-07-08 03:24:25

我目前正在拆卸一些固件,当我偶然发现 Ghidra 生成的以下代码片段时(名称已经是我自己的):

void memset(byte *addr,byte value,int count)
                            assume LRset = 0x0
                            assume TMode = 0x1
  undefined         r0:1           <RETURN>                                
  byte *            r0:4           addr                                    
  byte              r1:1           value
  int               r2:4           count
  undefined4        r0:4           iPtr                                    

22 b1           cbz        count,LAB_FIN
02 44           add        count,addr
                      LAB_LOOP
00 f8 01 1b     strb.w     value,[iPtr],#0x1
90 42           cmp        iPtr,count
fb d1           bne        LAB_LOOP
                      LAB_FIN  
70 47           bx         lr
00              ??         00h
bf              ??         BFh

Ghidra 的反编译器产生以下输出(设置某些类型后):

void memset(byte *addr,byte value,int count)
{
  byte *iPtr;

  if (count != 0) {
    iPtr = addr;
    do {
      iPtr = iPtr + 1;
      *iPtr = value;                // write to iPtr AFTER the pointer was increased
      iPtr = iPtr;
    } while (iPtr != addr + count);
  }
  return;
}

现在,我有两个问题:

  1. 反编译函数表明该memset函数不会将给定地址(addr)设置为指定值,而是始终以addr+1. 但是,这感觉不对,据我了解strb.w它使用后索引指令。因此 - 我认为 - 指针增量和赋值指令的顺序是错误的。我是对的还是我错过了什么?

  2. 在 bx 指令之后还有两个字节。我一点也不知道它们是什么。鉴于它们不是“00”,我不认为它们(仅)用于对齐目的。(下一个函数明确地直接在这两个字节之后开始。)有没有人知道?

1个回答

确实,这似乎是不正确的。语法[R0],#1称为 后索引:首先执行存储(或加载),然后将基地址递增(或递减)指定的值。所以分配和增量应该交换。

至于00 BF,它是NOP指令的操作码,可能插入以在 4 字节边界上对齐下一个函数。