阅读IDA的ARM反汇编代码(1)

4320阅读 0评论2014-02-15 AoyamaRyo
分类:嵌入式

      脑袋抽筋,忽而觉得很少留意STMFD、LDMFD指令,于是反汇编一个简单程序观察其用法。
        手册给出的说法是:
    
STMFD SP!,{R0-R7,LR}

    SP = SP - 9×4;

      address = SP; 

     for i = 0 to 7

        Memory[address] = Ri;

        address  = address + 4;

    Memory[address] = LR;

        也就是,最终栈顶SP指向的是R0,如果直接取栈顶的元素,得到的是最先入栈的数据。大概不能用数据结构中“栈”的概念来套用这种行为,只要STMFD与LDMFD成对使用就行了。

int main()
{
int ret = isIfceExist("192.168.0.3");
return ret;
} 

ARM Linux G++ 4.3.2 版本 O1优化级别时,IDA 6.4给出的结果如下: 

.text:00008B1C                                         EXPORT main
.text:00008B1C                         main                                    ; DATA XREF: .text:000085E0o
.text:00008B1C                                                                 ; .text:off_85F4o
.text:00008B1C
.text:00008B1C                         var_8           = -8
.text:00008B1C
.text:00008B1C 00 48 2D E9                             STMFD   SP!, {R11,LR}
.text:00008B20 04 B0 8D E2                             ADD     R11, SP, #4         ;将LR内存副本的地址存入R11
.text:00008B24 08 D0 4D E2                             SUB     SP, SP, #8           ;开辟8字节临时堆栈空间
.text:00008B28 18 00 9F E5                             LDR     R0, =aWoca         ; "192.168.0.3" 传递参数
.text:00008B2C B8 FF FF EB                             BL      _ZL11isIfceExistPKc ; isIfceExist(char const*) 调用函数
.text:00008B30 00 30 A0 E1                             MOV     R3, R0                  ;返回值转存于R3
.text:00008B34 08 30 0B E5                             STR     R3, [R11,#var_8]     ;临时变量,即SP-4位置
.text:00008B38 08 30 1B E5                             LDR     R3, [R11,#var_8]     ;
.text:00008B3C 03 00 A0 E1                             MOV     R0, R3                    ;main()函数的返回值
.text:00008B40 04 D0 4B E2                             SUB     SP, R11, #4             ;恢复SP,收回临时分配的8字节堆栈空间
.text:00008B44 00 88 BD E8                             LDMFD   SP!, {R11,PC}      ;main()函数返回
.text:00008B44                         ; End of function main
 

O3优化级别时,就很简洁了: 
.text:00008674                                         EXPORT main
.text:00008674                         main                                    ; DATA XREF: .text:00008480o
.text:00008674                                                                 ; .text:off_8494o
.text:00008674 00 00 9F E5                             LDR     R0, =aWoca      ; "woca"
.text:00008678 A3 FF FF EA                             B       _ZL11isIfceExistPKc ; isIfceExist(char const*)
.text:00008678                         ; End of function main
.text:00008678
.text:00008678                         ; ---------------------------------------------------------------------------
.text:0000867C 78 87 00 00             off_867C        DCD aWoca               ; DATA XREF: mainr
.text:0000867C                                                                 ; "woca"


isIfceExist(const char *ifceName)源码:
static int isIfceExist(const char *ifceName){
    int sock_fd = -1;
    if((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
        perror("socket");
        return FAIL;
    }
    struct ifconf ifconf;
    char buf[512];
    ifconf.ifc_len = 512; 
    ifconf.ifc_buf = buf; 

    ioctl(sock_fd, SIOCGIFCONF, &ifconf);
    struct ifreq *ifr;
    ifr = (struct ifreq*)buf;
    int i = 0;
    for(i = (ifconf.ifc_len / sizeof(struct ifreq)); i > 0; i--){
        printf("local addr = [%s]\n",inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr));
        ifr++;
     }
    return OK;
}


.text:0000850C                         ; isIfceExist(char const*)
.text:0000850C                         _ZL11isIfceExistPKc                     ; CODE XREF: main+4j
.text:0000850C
.text:0000850C                         in              = -0x204
.text:0000850C                         var_1F8         = -0x1F8
.text:0000850C                         var_18          = -0x18
.text:0000850C                         var_14          = -0x14
.text:0000850C
.text:0000850C 02 00 A0 E3                             MOV     R0, #2          ; domain
.text:00008510 70 40 2D E9                             STMFD   SP!, {R4-R6,LR}
.text:00008514 00 10 A0 E1                             MOV     R1, R0          ; type
.text:00008518 82 DF 4D E2                             SUB     SP, SP, #0x208
.text:0000851C 00 20 A0 E3                             MOV     R2, #0          ; protocol
.text:00008520 C5 FF FF EB                             BL      socket
.text:00008524 00 00 50 E3                             CMP     R0, #0
.text:00008528 2B 00 00 BA                             BLT     loc_85DC
.text:0000852C 02 3C A0 E3                             MOV     R3, #0x200      ; 512
.text:00008530 B4 10 9F E5                             LDR     R1, =0x8912     ; request
.text:00008534 02 2C 8D E2                             ADD     R2, SP, #0x218+var_18 ; R2 = SP + 512
.text:00008538 00 32 8D E5                             STR     R3, [SP,#0x218+var_18] ; [SP + 512] = 512;
.text:00008538                                                                 ; ifconf.ifc_len = 512;
.text:00008538                                                                 ; =====================
.text:0000853C 04 D2 8D E5                             STR     SP, [SP,#0x218+var_14] ; [SP + 512 + 4] = SP,
.text:0000853C                                                                 ; 可以看出SP开始的512Bytes空间即char buf[512],
.text:0000853C                                                                 ; ifconf.ifc_buf = buf;
.text:0000853C                                                                 ; =====================
.text:00008540 C0 FF FF EB                             BL      ioctl           ; R0为socket()函数的返回值,未曾改变,作为第一个参数
.text:00008540                                                                 ; R1是SIOCGIFCONF的数值
.text:00008540                                                                 ; R2为SP+512,也就是ifconf结构体的地址。
.text:00008540                                                                 ; =========================================
.text:00008544 00 62 9D E5                             LDR     R6, [SP,#0x218+var_18] ; 获取ifconf.ifc_len,即ioctl返回的长度
.text:00008548 0D 40 A0 E1                             MOV     R4, SP
.text:0000854C A6 62 B0 E1                             MOVS    R6, R6,LSR#5
.text:00008550 1E 00 00 0A                             BEQ     loc_85D0        ; 这个东西就是,i = ifconf_len/sizeof(struct ifreq)的一部分,
.text:00008550                                                                 ; ifreq是32字节,逻辑右移5位若为0,则i=0,即不存在该IP地址。
.text:00008550                                                                 ; 此时函数返回0。
.text:00008550                                                                 ; ================================================
.text:00008554 14 00 9D E5                             LDR     R0, [SP,#0x218+in] ; in = -0x204  偏移0x14,
                                                                            ;
inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr)
                                                                            ; 也就是说sin_addr在ifreq中的偏移是0x14

.text:00008558 AE FF FF EB                             BL      inet_ntoa       ; sin_addr在sockaddr_in结构体中的偏移。
.text:00008558                                                                 ; 即将sin_addr的值传递给inet_ntoa()函数。
.text:00008558                                                                 ; ======================================
.text:0000855C 01 60 46 E2                             SUB     R6, R6, #1
.text:00008560 20 40 8D E2                             ADD     R4, SP, #0x218+var_1F8 ;地址增加32,移至下一个ifreq结构首地址
.text:00008564 00 10 A0 E1                             MOV     R1, R0
.text:00008568 80 00 9F E5                             LDR     R0, =aLocalAddrSN ; "local addr = [%s]/n"
.text:0000856C B8 FF FF EB                             BL      printf
.text:00008570 00 50 56 E2                             SUBS    R5, R6, #0
.text:00008574 01 60 06 E2                             AND     R6, R6, #1
.text:00008578 14 00 00 0A                             BEQ     loc_85D0
.text:0000857C 00 00 56 E3                             CMP     R6, #0
.text:00008580 03 00 00 0A                             BEQ     loc_8594
.text:00008584 14 00 94 E5                             LDR     R0, [R4,#0x14]  ; in     ;sin_addr距该结构体首地址的偏移为0x14
.text:00008588 A2 FF FF EB                             BL      inet_ntoa
.text:0000858C 00 10 A0 E1                             MOV     R1, R0
.text:00008590 09 00 00 EA                             B       loc_85BC
.text:00008594                         ; ---------------------------------------------------------------------------
.text:00008594
.text:00008594                         loc_8594                                ; CODE XREF: isIfceExist(char const*)+74j
.text:00008594                                                                 ; isIfceExist(char const*)+C0j
.text:00008594 14 00 94 E5                             LDR     R0, [R4,#0x14]  ; in
.text:00008598 9E FF FF EB                             BL      inet_ntoa
.text:0000859C 20 40 84 E2                             ADD     R4, R4, #0x20
.text:000085A0 01 50 45 E2                             SUB     R5, R5, #1
.text:000085A4 00 10 A0 E1                             MOV     R1, R0
.text:000085A8 40 00 9F E5                             LDR     R0, =aLocalAddrSN ; "local addr = [%s]/n"
.text:000085AC A8 FF FF EB                             BL      printf
.text:000085B0 14 00 94 E5                             LDR     R0, [R4,#0x14]  ; in
.text:000085B4 97 FF FF EB                             BL      inet_ntoa
.text:000085B8 00 10 A0 E1                             MOV     R1, R0
.text:000085BC
.text:000085BC                         loc_85BC                                ; CODE XREF: isIfceExist(char const*)+84j
.text:000085BC 2C 00 9F E5                             LDR     R0, =aLocalAddrSN ; "local addr = [%s]/n"
.text:000085C0 A3 FF FF EB                             BL      printf
.text:000085C4 01 50 55 E2                             SUBS    R5, R5, #1
.text:000085C8 20 40 84 E2                             ADD     R4, R4, #0x20
.text:000085CC F0 FF FF 1A                             BNE     loc_8594
.text:000085D0
.text:000085D0                         loc_85D0                                ; CODE XREF: isIfceExist(char const*)+44j
.text:000085D0                                                                 ; isIfceExist(char const*)+6Cj
.text:000085D0 00 00 A0 E3                             MOV     R0, #0
.text:000085D4
.text:000085D4                         loc_85D4                                ; CODE XREF: isIfceExist(char const*)+DCj
.text:000085D4 82 DF 8D E2                             ADD     SP, SP, #0x208
.text:000085D8 70 80 BD E8                             LDMFD   SP!, {R4-R6,PC}    ;函数返回,返回值0
.text:000085DC                         ; ---------------------------------------------------------------------------
.text:000085DC
.text:000085DC                         loc_85DC                                ; CODE XREF: isIfceExist(char const*)+1Cj
.text:000085DC 10 00 9F E5                             LDR     R0, =aSocket    ; "socket"
.text:000085E0 92 FF FF EB                             BL      perror
.text:000085E4 00 00 E0 E3                             MOV     R0, #0xFFFFFFFF
.text:000085E8 F9 FF FF EA                             B       loc_85D4                       ;错误返回,错误码-1
.text:000085E8                         ; End of function isIfceExist(char const*)
.text:000085E8
.text:000085E8                         ; ---------------------------------------------------------------------------
.text:000085EC                         ; unsigned __int32 request
.text:000085EC 12 89 00 00             request         DCD 0x8912              ; DATA XREF: isIfceExist(char const*)+24r
.text:000085F0                         ; char *format
.text:000085F0 E8 86 00 00             format          DCD aLocalAddrSN        ; DATA XREF: isIfceExist(char const*)+5Cr
.text:000085F0                                                                 ; isIfceExist(char const*)+9Cr ...
.text:000085F0                                                                 ; "local addr = [%s]/n"
.text:000085F4                         ; char *s
.text:000085F4 E0 86 00 00             s               DCD aSocket             ; DATA XREF: isIfceExist(char const*):loc_85DCr
.text:000085F4                                                                 ; "socket" 

上一篇:C++浑浑噩噩的一天:Linux 定时器、多线程、Qt封装
下一篇:Qt死循环中响应事件