Arm ldr 在 # 和 = 之间不同

逆向工程 二元分析 手臂
2021-07-01 07:19:54

在ARM汇编中,有什么区别

ldr r4, =0x44454433

ldr r4, #0x44454433 ?

2个回答

第一个ldr r4, =0x44454433是一个有效的伪指令

第二个无效

顺便说一句,语法不是用于真正的指令,而是用于伪指令的别名

汇编程序针对立即值创建正确的指令

大多数这些问题可以通过组装一条指令并反汇编来回答
你可以使用 msvc 中的 armasm 或者你可以使用 python 的 keystone 或
使用无数的在线汇编反汇编站点

import sys
from keystone import *
instruction = raw_input("Enter your arm instruction :  ")
print instruction

ks = Ks(KS_ARCH_ARM,KS_MODE_ARM|KS_MODE_THUMB)
blah = ks.asm(instruction)
for i in blah[0]:
    print "%02x " % i, 
print "\n"

执行脚本以获取

:\>python asmarm.py
Enter your arm instruction :  ldr r4,=0x44455533
ldr r4,=0x44455533
00  4c  00  bf  33  55  45  44

另一方面,如果您尝试组装第二条指令,它将引发错误意外标记

:\>python asmarm.py
Enter your arm instruction :  ldr r4,=#0x44554533
ldr r4,=#0x44554533
Traceback (most recent call last):
  File "asmarm.py", line 7, in <module>
    blah = ks.asm(instruction)
  File "c:\python27\lib\site-packages\keystone\keystone.py", line 198, in asm
    raise KsError(errno, stat_count.value)
keystone.keystone.KsError: Unknown token in expression (KS_ERR_ASM_EXPR_TOKEN)

或者您可以使用 capstone 反汇编十六进制字节序列

如下

import sys
from capstone import *
import binascii
inp = binascii.unhexlify( ''.join(sys.argv[1].split()))
cs = Cs(CS_ARCH_ARM , CS_MODE_THUMB)
cs.Detail = True
dis = cs.disasm( inp,  int(sys.argv[2],16))
for i in dis:
    print("0x%x:\t" % i.address),
    print(binascii.hexlify(i.bytes)),
    print("\t%s\t%s" %(i.mnemonic, i.op_str)) 

执行脚本

:\>discap.py "00  4c  00  bf  33  55  45  44" 0x440000
0x440000:       004c    ldr     r4, [pc, #0]
0x440002:       00bf    nop
0x440004:       3355    strb    r3, [r6, r4]
0x440006:       4544    add     r5, r8

如果您使用 msvc 路由,则需要使用适当的架构打开 vsdev cmdprompt 并简单地使用 armasm 和如下输入文件

设置正确的拱门和主机

C:\>cat bld.bat
pushd ..    
call "C:\Program Files\Microsoft Visual Studio\2017\Community\Common7\Tools\vsdevcmd.bat" -arch=arm -host_arch=x86   

src 文件内容

C:\>cat myasm.asm
    AREA .text, CODE, ARM
test PROC
    ldr r4,=0x44455533
    ENDP    
    END

执行并打开一个 msvc arm devprompt

C:\>bld.bat

C:\>pushd ..

C:\>call "C:\Program Files\Microsoft Visual Studio\2017\Community\Common7\Tools\vsdevcmd.bat" -arch=arm -host_arch=x86
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.6.1
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
C:\>popd

组装输入文件

C:\>armasm myasm.asm
Microsoft (R) ARM Macro Assembler Version 14.13.26128.0
Copyright (C) Microsoft Corporation.  All rights reserved.

反汇编 obj 文件

C:\>dumpbin /disasm myasm.obj
Microsoft (R) COFF/PE Dumper Version 14.13.26128.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file myasm.obj

File Type: COFF OBJECT

test:
  00000000: 4C00      ldr         r4,00000004
  00000002: 0000      movs        r0,r0
  00000004: 5533      strb        r3,[r6,r4]
  00000006: 4445      add         r5,r5,r8

  Summary

          60 .debug$S
           8 .text

C:\> 

虽然这是一个简单的LMGTFY问题,但我还是要回答,因为我花了一些时间才找到它。

假设它是 32 位 ARM,所有操作码都是 4 字节长,所以这就提出了一个问题,如果具有如此大数据的操作码不能容纳在 4 字节中,如何在操作码中包含 32 位值。

ldr r4, =0x44454433

是伪指令。

LDR Rd,=const 伪指令生成加载任何 32 位数字的最有效的单条指令。- 第6-111

另一个 const#0x44454433只是一个 const 值,但是使用这种形式(其中包含 32 位值并且只有值)似乎无效(不是 ARM 专家)。