arm反编译-四则运算

ARM 116浏览

int main() {
   
int a, b, c, d;
    unsigned int
ua;
   
a = 100;
   
b = a;
   
//字符串
    char say[] = "hello";
   
scanf("%d,%d", &a, &b);
   
printf("a=%d,b=%d", a, b);
   
b = 5;
   
//
    c = a + b;
   
printf("c=%d", c);
   
//
    d = a - b;
   
printf("d=%d", d);
   
//
    c = a * b;
   
printf("c=%d", c);
   
//
    d = a / b;
   
printf("d=%d", d);
}

 

.rodata.str1.1:0000000000000150 $d.1 (命名)           DCB "hello",0

.rodata.str1.1:0000000000000156 aDD             DCB "%d,%d",0

.rodata.str1.1:000000000000015C aADBD           DCB "a=%d,b=%d",0

.rodata.str1.1:0000000000000166 aCD             DCB "c=%d",0

.rodata.str1.1:000000000000016B aDD_0           DCB "d=%d",0

DCB 表示一个字节,可以通过右键设置数据类型。

DBW表示双字节,即一个字。还有double word等。字符串在C语言中以0结尾。

 

.rodata:000020E8 aHello          DCB "hello",0

//aHello,命名。DCB表示一个字节;B为byte,还有word,double word等。分配的不一定是正确的。该句表示定义一个字符串,hello,命令为aHello。aHello=”hello“

 

.rodata:000020EE aDD             DCB "%d,%d",0           ; DATA XREF: main+2Ao

.rodata:000020EE                                         ; .text:off_870o

//aDD,命名。DCB同理。

//该句可以理解为aDD=”%d,%d”;后面的DATA XREF是交叉编译,表示引用的位置。

//两行相同的地址,是ida做一个信息补充的作用

 

 

.text:000007A8                 CODE16

         //指令集,16位,2个字节。

 

         //代码段中的分号”;”表示注释

         //LB,LBX表示调用方法

         //STR写数据到内存

         //LDR从内存中读取数据

         //SUBS 表示除法

         //MULS表示乘

         //BL __divsi3 调用除法

 

.text:000007A8                 PUSH            {R7,LR}

.text:000007AA                 MOV             R7, SP

.text:000007AC                 SUB             SP, SP, #0x48

.text:000007AE                 LDR             R0, =(__stack_chk_guard_ptr - 0x7B4)

.text:000007B0                 ADD             R0, PC ; __stack_chk_guard_ptr

.text:000007B2                 LDR             R0, [R0] ; __stack_chk_guard

.text:000007B4                 LDR             R1, [R0]

.text:000007B6                 STR             R1, [SP,#0x50+var_C]

.text:000007B8                 MOVS            R1, #0x64

         //MOVS ,移动0x64到R1;对应C代码中的a=100

.text:000007BA                 STR             R1, [SP,#0x50+var_18]

         //STR将寄存器R1的内容写入内存中。

         //[xxx]寻址操作,表示地址:sp+(0x50+var_18)

.text:000007BC                 LDR             R1, [SP,#0x50+var_18]

         //LDR表示定位一个全局资源

.text:000007BE                 STR             R1, [SP,#0x50+var_1C]

.text:000007C0                 MOVS            R1, #0x6F

.text:000007C2                 STRH.W          R1, [SP,#0x50+var_10]

.text:000007C6                 MOV             R1, #0x6C6C6568

.text:000007CE                 STR             R1, [SP,#0x50+var_14]

 

scanf(“%d,%d”,&a,&b);

.text:000007D0                 LDR             R1, =(aDD - 0x7D6)

.text:000007D2                 ADD             R1, PC  ; "%d,%d"

         //LDR+ADD,该句表示R1指向了”%d,%d”字符串,

.text:000007D4                 ADD             R2, SP, #0x50+var_18

         //ADD三个参数,表示R2=SP+第三个参数;这里是取地址,

//对应C中的&a

.text:000007D6                 ADD             R3, SP, #0x50+var_1C

         //取地址,对应C语言中的&b

.text:000007D8                 STR             R0, [SP,#0x50+var_2C]

         //STR:写入内存

.text:000007DA                 MOV             R0, R1  ; format

.text:000007DC                 MOV             R1, R2

.text:000007DE                 MOV             R2, R3

.text:000007E0                 BLX             scanf

         //scanf(“%d,%d”,&a,&b);

         //通过07DA-07E0分析,scanf的参数有R0,R1,R2,其中R0的值由R1赋,即“%d,%d”,同理推出scanf(“%d,%d”,&a,&b)这一段代码。

         question:我怎么知道这个函数需要几个参数

         answer:一般是由R0-R3来传递前四个参数。四个以上暂时不知道。

 

 

printf(“a=%d,b=%d”,a,b)

.text:000007E4                 LDR             R1, [SP,#0x50+var_18]

         //LDR:从内存中加载数据

.text:000007E6                 LDR             R2, [SP,#0x50+var_1C]

.text:000007E8                 LDR             R3, =(aADBD - 0x7EE)

.text:000007EA                 ADD             R3, PC  ; "a=%d,b=%d"

         //R3指向了字符串” a=%d,b=%d"

.text:000007EC                 STR             R0, [SP,#0x50+var_30]

.text:000007EE                 MOV             R0, R3  ; format

.text:000007F0                 BLX             printf

         //RO对应参数是字符串xxx,R1和R2在E4,E6分别取值

         //printf(“a=%d,b=%d”,a,b)

 

b=5;c=a+b;printf c

 

.text:000007F4                 MOVS            R1, #5

         // R1=5,对应b=5

.text:000007F6                 STR             R1, [SP,#0x50+var_1C]

         //b的地址为0X50+VAR_1C

.text:000007F8                 LDR             R1, [SP,#0x50+var_18]

         //加载a的数据到R1

.text:000007FA                 LDR             R2, [SP,#0x50+var_1C]

         //加载b的数据到R2

.text:000007FC                 ADD             R1, R2

         //R1=R1+R2

.text:000007FE                 STR             R1, [SP,#0x50+var_20]

         //将R1的值赋给0x50+var_20

.text:00000800                 LDR             R1, [SP,#0x50+var_20]

         //加载值R1=c

.text:00000802                 LDR             R2, =(aCD - 0x808)

.text:00000804                 ADD             R2, PC  ; "c=%d"

         //加载字符串

.text:00000806                 STR             R0, [SP,#0x50+var_34]

.text:00000808                 MOV             R0, R2 

         //R0=”c=%d”

.text:0000080A                 STR             R2, [SP,#0x50+format]

.text:0000080C                 BLX             printf

         //printf(“c=%d”,c)

         question:赋值R2的意义在哪里,因为R2,R3都没有用到

 

 

.text:00000810                 LDR             R1, [SP,#0x50+var_18]

.text:00000812                 LDR             R2, [SP,#0x50+var_1C]

.text:00000814                 SUBS            R1, R1, R2

.text:00000816                 STR             R1, [SP,#0x50+var_24]

.text:00000818                 LDR             R1, [SP,#0x50+var_24]

.text:0000081A                 LDR             R2, =(aDD_0 - 0x820)

.text:0000081C                 ADD             R2, PC  ; "d=%d"

.text:0000081E                 STR             R0, [SP,#0x50+var_3C]

.text:00000820                 MOV             R0, R2  ; format

.text:00000822                 STR             R2, [SP,#0x50+var_40]

.text:00000824                 BLX             printf

.text:00000828                 LDR             R1, [SP,#0x50+var_18]

.text:0000082A                 LDR             R2, [SP,#0x50+var_1C]

.text:0000082C                 MULS            R1, R2

.text:0000082E                 STR             R1, [SP,#0x50+var_20]

.text:00000830                 LDR             R1, [SP,#0x50+var_20]

.text:00000832                 LDR             R2, [SP,#0x50+format]

.text:00000834                 STR             R0, [SP,#0x50+var_44]

.text:00000836                 MOV             R0, R2  ; format

.text:00000838                 BLX             printf

.text:0000083C                 LDR             R1, [SP,#0x50+var_18]

.text:0000083E                 LDR             R2, [SP,#0x50+var_1C]

.text:00000840                 STR             R0, [SP,#0x50+var_48]

.text:00000842                 MOV             R0, R1

.text:00000844                 MOV             R1, R2

.text:00000846                 BL              __divsi3

.text:0000084A                 STR             R0, [SP,#0x50+var_24]

.text:0000084C                 LDR             R1, [SP,#0x50+var_24]

.text:0000084E                 LDR             R0, [SP,#0x50+var_40] ; format

.text:00000850                 BLX             printf

.text:00000854                 LDR             R1, [SP,#0x50+var_2C]

.text:00000856                 LDR             R2, [R1]

.text:00000858                 LDR             R3, [SP,#0x50+var_C]

.text:0000085A                 CMP             R2, R3

.text:0000085C                 STR             R0, [SP,#0x50+var_4C]

.text:0000085E                 BNE             loc_868

.text:00000860                 B               loc_862

.text:00000862 ; ---------------------------------------------------------------------------

.text:00000862

.text:00000862 loc_862                                 ; CODE XREF: main+B8j

.text:00000862                 MOVS            R0, #0

.text:00000864                 ADD             SP, SP, #0x48

.text:00000866                 POP             {R7,PC}

.text:00000868 ; ---------------------------------------------------------------------------

.text:00000868

.text:00000868 loc_868                                 ; CODE XREF: main+B6j

.text:00000868                 BLX             __stack_chk_fail

.text:00000868 ; End of function main

 

 

 

 

总结:

  1. 在这个简单的加减乘除读写中,过程无非是读内存值---取内存值---运算---写入内存---执行输出函数
  2. 留意寄存器变量的值从哪里得到,一层一层得到一个不可变的值,最终就能得到该寄存器的最终值
  3. 留意各个变量的地址。变量在汇编中几乎都是以地址的方式出现,不好确定。