ida能反汇编linux嘛,阅读IDA的ARM反汇编代码(1)

脑袋抽筋,忽而觉得很少留意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"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值