<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      arm c/c++ 基本結構逆向

      任何平臺的逆向都是從基本語句開始的,我們需要知道if, for, while, do()while, switch等這些基本語句對應 arm 匯編是什么樣子。
      這樣我們的知識就能形成一個閉環,使我們更加深刻的掌握一門語言。

      下面就區分兩種狀態,即debug和release,對它們一一描述,重點是優化后不太一樣。

      以后看匯編時掃一眼就大概知道是什么語句,方便快速的閱讀匯編代碼。

       


      if {} 語句 

      if (i < 9) {
        printf("i < 9\n");
      }
      ; debug
      CMP R0, #8 BGT loc_99E ;BGT的含義是大于8跳到loc_99E,反過來if進入的條件就是 if (i <=8); B loc_992 ; --------------------------------------------------------------------------- loc_992 LDR R0, =(aI9 - 0x998) ADD R0, PC ; "i < 9\n" BL sub_9F4 STR R0, [SP,#0x30+var_28] B loc_99E ; debug模式 這兒都要跳一下,算是一個特點吧 ; --------------------------------------------------------------------------- loc_99E
      ; relese
      CMP R0, #8 BGT loc_9AC ;BGT的含義是大于8跳到loc_9AC,反過來if進入的條件就是 if (i <=8); LDR R0, =(aI9 - 0x9AA) ADD R0, PC ; "i < 9" BLX puts loc_9AC

      重點是這兩行匯編

      CMP  R0, #8

      BGT  loc_99E ;Z清零且(N等于V) 有符號數大于

      意思是大于8 跳走, if內部條件就是反過的,if (i <= 8)

      debug和release 共同點都是將if (i < 9) 編譯成 if (i <=8) 雖然邏輯上是一樣的。但是,我們在逆向的時候盡可能的向原始的代碼上靠

      翻譯匯編時建議寫成 if (i < 9)


      if {} else{} 語句 

      if (i < 9) {
         printf("i < 9\n");
      } else {
         printf("i >= 9\n");
      }
      ; debug
      CMP R0, #8 BGT loc_99E B loc_992 ;這步與單if語句的區別,C里面就是“跳else” ; --------------------------------------------------------------------------- loc_992 LDR R0, =(aI9 - 0x998) ADD R0, PC ; "i < 9\n" BL sub_A04 STR R0, [SP,#0x30+var_28] B loc_9AA ; --------------------------------------------------------------------------- loc_99E LDR R0, =(aI9_0 - 0x9A4) ADD R0, PC ; "i >= 9\n" BL sub_A04 STR R0, [SP,#0x30+var_2C] B loc_9AA ; debug模式這兒要跳一下,算是個特點吧 ; --------------------------------------------------------------------------- loc_9AA
      ; release
      CMP R0, #8 BGT loc_9AA LDR R0, =(aI9 - 0x9AA) ADD R0, PC ; "i < 9" B loc_9AE ;這步與單if語句的區別,C里面就是“跳else” ; --------------------------------------------------------------------------- loc_9AA ; CODE XREF: main+1A↑j LDR R0, =(aI9_0 - 0x9B0) ADD R0, PC ; "i >= 9" loc_9AE ; CODE XREF: main+20↑j BLX puts

      if 與 if else 的區別并不大, 只是多了一個else的強制跳轉


      if {} else if{} else{} 語句 

      if (i == 1) {
        printf("i = 1\n");
      } else if ( i == 2) {
        printf("i = 2\n");
      } else {
        printf("i != 1 && i != 2\n");
      } 
      ; debug
                      CMP             R0, #1
                      BNE             loc_99E   ; 不等于1,檢查下一條 else if 
                      B               loc_992
      ; ---------------------------------------------------------------------------
      loc_992
                      LDR             R0, =(aI1 - 0x998)
                      ADD             R0, PC    ; "i = 1\n"
                      BL              sub_A1C
                      STR             R0, [SP,#0x38+var_28]
                      B               loc_9BE   ; 直接跳到if語句的結尾
      ; ---------------------------------------------------------------------------
      loc_99E
                      LDR             R0, [SP,#0x38+var_18]
                      CMP             R0, #2    ; 檢查else if (i == 2)
                      BNE             loc_9B2   ; 不等于2 跳到 else語句
                      B               loc_9A6   ; 等于2
      ; ---------------------------------------------------------------------------
      loc_9A6
                      LDR             R0, =(aI2 - 0x9AC)
                      ADD             R0, PC  ; "i = 2\n"
                      BL              sub_A1C
                      STR             R0, [SP,#0x38+var_2C]
                      B               loc_9BE   ; 跳到整個if語句的結尾
      ; ---------------------------------------------------------------------------
      loc_9B2                                   ; 此處是最后的 else
                      LDR             R0, =(aI1I2 - 0x9B8)
                      ADD             R0, PC  ; "i != 1 && i != 2\n"
                      BL              sub_A1C
                      STR             R0, [SP,#0x38+var_30]
                      B               loc_9BE
      ; ---------------------------------------------------------------------------
      loc_9BE 
      ; release
                      CMP             R0, #2
                      BEQ             loc_72E  ; 等于2   跳轉
                      CMP             R0, #1
                      BNE             loc_734  ; 不等于1 跳轉
                      LDR             R0, =(aI1 - 0x72E)  ; 此處是 if (i == 1) 基本塊
                      ADD             R0, PC  ; "i = 1"
                      B               endif_738
      ; ---------------------------------------------------------------------------
      
      loc_72E                                 ; CODE XREF: main+A↑j
                      LDR             R0, =(aI2 - 0x734)  ; 此處是 if (i == 2) 基本塊
                      ADD             R0, PC  ; "i = 2"
                      B               endif_738
      ; ---------------------------------------------------------------------------
      
      loc_734                                 ; CODE XREF: main+E↑j
                      LDR             R0, =(aI1I2 - 0x73A) ; 此處是 最后 else 基本塊
                      ADD             R0, PC  ; "i != 1 && i != 2"
      
      endif_738                               ; CODE XREF: main+14↑j
                                              ; main+1A↑j
                      BLX             puts

       if {} else if{} else{} 語句 debug 與 release差別比較大, 但是共同點是每個塊結尾都強制跳轉到if語句的結尾

      如果看到這樣的特點,基本上可以確定是if {} else if{} else{}語句,這點與x86上基本一樣。

      同時,我發現另一個特點,debug在每個塊完成后都要跳一下,release沒有,這樣在debug下會非常影響性能,所以建議發布時不要用debug編譯。


      for 語句 

      for (int j = 0; j < i; j++) {
        printf("j = %d\n", j);
      }
      ; debug
      begin_for_9C6
        LDR   R0, [SP,#0x30+var_1C] ; var_1C 就是變量 j
        LDR   R1, [SP,#0x30+var_18] ; var_18 就是變量 i
        CMP   R0, R1
        BGE   end_for_9E6           ; var_1C >= var_18就跳出for
        B     loc_9D0
      ; ---------------------------------------------------------------------------
      loc_9D0
        LDR   R1, [SP,#0x30+var_1C]
        LDR   R0, =(aJD - 0x9D8)
        ADD   R0, PC  ; "j = %d\n"
        BL    sub_9F0
        STR   R0, [SP,#0x30+var_2C]
        B     loc_9DE
      ; ---------------------------------------------------------------------------
      loc_9DE
        LDR   R0, [SP,#0x30+var_1C] ; var_1C +1
        ADDS  R0, #1
        STR   R0, [SP,#0x30+var_1C]
        B     begin_for_9C6         ; for 循環最典型的特征,從下往上跳
      ; ---------------------------------------------------------------------------
      end_for_9E6
      ; release
        MOV   R4, R0   ; R4就是變量 i
        CMP   R4, #1   
        BLT   endfor_99C ; i < 1 跳出循環
        LDR   R6, =(aJD - 0x990)
        MOVS  R5, #0   ; R5就是變量 j
        ADD   R6, PC  ; "j = %d\n"
      loc_98E
        MOV   R0, R6  ; 此處是循環體,相比debug優化很多
        MOV   R1, R5
        BL    sub_9A8 ; R0 R1 傳遞參數調用printf 
        ADDS  R5, #1
        CMP   R4, R5
        BNE   loc_98E ; for 循環的特征 +1向上跳
      endfor_99C

      可以看出for循環的特點,在循環的尾部 +1向上跳,同時也能看出debug和release在性能的上的差異太大了。
      debug版本需要不停的訪問內存,速度上明顯要慢不少!
      大多數的for循環都是從0開始的,release版本的for循環,剛開始就判斷i是不是<1,這也算是一個release的特點吧。


      while 語句

      int j = 0;
      while(j < i) {
        printf("j = %d\n", j);
        j++;
      } 
      ; debug
      begin_while_9C6
        LDR    R0, [SP,#0x30+var_1C] ; var_1C 就是變量 j
        LDR    R1, [SP,#0x30+var_18] ; var_18 就是變量 i
        CMP    R0, R1
        BGE    end_while_9E4         ; j >= i 跳出循環
        B      loc_9D0               ; debug模式的特點,跳到下一行
      ; ---------------------------------------------------------------------------
      loc_9D0
        LDR    R1, [SP,#0x30+var_1C]
        LDR    R0, =(aJD - 0x9D8)
        ADD    R0, PC  ; "j = %d\n"
        BL     sub_9F0
        LDR    R1, [SP,#0x30+var_1C]
        ADDS   R1, #1
        STR    R1, [SP,#0x30+var_1C]
        STR    R0, [SP,#0x30+var_2C]
        B      begin_while_9C6       ; 強制向上跳, 與for循環很像
      ; ---------------------------------------------------------------------------
      end_while_9E4 
      ; release
        MOV    R4, R0
        CMP    R4, #1 ; R4是變量 i
        BLT    end_while_99C ; R4 < 1 跳出while循環
        LDR    R6, =(aJD - 0x990)
        MOVS   R5, #0
        ADD    R6, PC  ; "j = %d\n"
      loc_98E
        MOV    R0, R6   ; while循環體    
        MOV    R1, R5
        BL     sub_9A8
        ADDS   R5, #1
        CMP    R4, R5
        BNE    loc_98E  ; R4 != R5 
      end_while_99C

       while循環與for循環非常像,區別不大。邏輯上while, do while,都可以寫成for循環。 


       do while 語句 

      int j = 0;
      do {
        printf("j = %d\n", j);
        j++;
      }while(j < i);
      ; debug
      begin_dowhile_9C6
        LDR   R1, [SP,#0x30+var_1C]  ; do while體,沒有判斷直接運行塊中pritnf
        LDR   R0, =(aJD - 0x9CE)
        ADD   R0, PC  ; "j = %d\n"
        BL    sub_9F0
        LDR   R1, [SP,#0x30+var_1C]
        ADDS  R1, #1
        STR   R1, [SP,#0x30+var_1C]
        STR   R0, [SP,#0x30+var_2C]
        B     loc_9DA
      ; ---------------------------------------------------------------------------
      loc_9DA
        LDR   R0, [SP,#0x30+var_1C]
        LDR   R1, [SP,#0x30+var_18]
        CMP   R0, R1                ; 在此判斷條件
        BLT   begin_dowhile_9C6
        B     end_dowhile_9E4
      ; ---------------------------------------------------------------------------
      end_dowhile_9E4
      ; release
        LDR             R6, =(aJD - 0x98C)
        MOV             R4, R0
        MOVS            R5, #0
        ADD             R6, PC  ; "j = %d\n"
      loc_98A
        MOV             R0, R6  ; 直接進入do while基本塊中
        MOV             R1, R5
        BL              sub_9A4
        ADDS            R5, #1  
        CMP             R5, R4  ; 條件判斷
        BLT             loc_98A ; do while結尾判斷條件

      最大的特點是直接進入執行體沒有判斷,與C代碼完全一致。


       switch 語句 

      switch (i) {
      case 1:
        printf("1");
        break;
      case 2:
        printf("2");
        break;
      case 3:
        printf("3");
        break;
      case 4:
        printf("4");
        break;
      default:
        printf("unknow");
      }
      ; debug
        STR      R0, [SP,#0x38+var_18]
        SUBS     R0, #1  ; switch 4 cases
        MOV      R1, R0
        CMP      R0, #3
        STR      R1, [SP,#0x38+var_24]
        BHI      def_9C8 ; jumptable 000009C8 default case
        LDR      R1, [SP,#0x38+var_24]
        TBB.W    [PC,R1] ; switch jump   ; switch最典型的特征,有一個跳轉表
      ; ---------------------------------------------------------------------------
      jpt_9C8    DCB 2                   ; jump table for switch statement
                 DCB 8
                 DCB 0xE
                 DCB 0x14
      ; ---------------------------------------------------------------------------
      loc_9D0
        LDR      R0, =(a1 - 0x9D6) ; jumptable 000009C8 case 1
        ADD      R0, PC  ; "1\n"
        BL       sub_A28
        STR      R0, [SP,#0x38+var_28]
        B        end_switch_A0C
      ; ---------------------------------------------------------------------------
      loc_9DC
        LDR      R0, =(a2 - 0x9E2) ; jumptable 000009C8 case 2
        ADD      R0, PC  ; "2\n"
        BL       sub_A28
        STR      R0, [SP,#0x38+var_2C]
        B        end_switch_A0C
      ; ---------------------------------------------------------------------------
      loc_9E8
        LDR      R0, =(a3 - 0x9EE) ; jumptable 000009C8 case 3
        ADD      R0, PC  ; "3\n"
        BL       sub_A28
        STR      R0, [SP,#0x38+var_30]
        B        end_switch_A0C
      ; ---------------------------------------------------------------------------
      loc_9F4                          ; CODE XREF: main+2C↑j
        LDR      R0, =(a4 - 0x9FA) ; jumptable 000009C8 case 4
        ADD      R0, PC  ; "4\n"
        BL       sub_A28
        STR      R0, [SP,#0x38+var_34]
        B        end_switch_A0C
      ; ---------------------------------------------------------------------------
      def_9C8
        LDR      R0, =(aUnknow - 0xA06) ; jumptable 000009C8 default case
        ADD      R0, PC  ; "unknow"
        BL       sub_A28
        STR      R0, [SP,#0x38+var_38]
        B        end_switch_A0C
      ; ---------------------------------------------------------------------------
      end_switch_A0C
      ; release
        SUBS            R0, #1  ; switch 4 cases
        CMP             R0, #3
        BHI             def_9AE ; jumptable 000009AE default case
        TBB.W           [PC,R0] ; switch jump  ; release版本也一樣存在 TBB, 后面就是跳轉表,這是最重要的特征
      ; ---------------------------------------------------------------------------
      jpt_9AE         DCB 2                   ; jump table for switch statement
        DCB 0xA
        DCB 0xD
        DCB 0x10
      ; ---------------------------------------------------------------------------
      loc_9B6
        LDR             R0, =(a1 - 0x9BC) ; jumptable 000009AE case 1
        ADD             R0, PC  ; "1"
        B               end_switch_9D6
      ; ---------------------------------------------------------------------------
      def_9AE
        LDR             R0, =(aUnknow - 0x9C2) ; jumptable 000009AE default case
        ADD             R0, PC  ; "unknow"
        BL              sub_9F4
        B               loc_9DA
      ; ---------------------------------------------------------------------------
      
      loc_9C6                                 ; CODE XREF: main+E↑j
        LDR             R0, =(a2 - 0x9CC) ; jumptable 000009AE case 2
        ADD             R0, PC  ; "2"
        B               end_switch_9D6
      ; ---------------------------------------------------------------------------
      
      loc_9CC                                 ; CODE XREF: main+E↑j
        LDR             R0, =(a3 - 0x9D2) ; jumptable 000009AE case 3
        ADD             R0, PC  ; "3"
        B               end_switch_9D6
      ; ---------------------------------------------------------------------------
      loc_9D2
        LDR             R0, =(a4 - 0x9D8) ; jumptable 000009AE case 4
        ADD             R0, PC  ; "4"
      end_switch_9D6

       

      arm的匯編基本上都一樣,以后介紹類 class的各種實現。
      class中繼承,派生,虛函數等在arm中是如何實現的。

      說明:目前的編譯器都是ndk的編譯器 armeabi-v7a

       

      posted @ 2019-01-28 16:40  Russinovich`s Blog  閱讀(1324)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲最大在线精品| 少妇人妻偷人精品免费| 国产成人欧美日韩在线电影| 国产亚洲精品久久久久秋霞| 精品久久久久久成人AV| 亚洲人精品午夜射精日韩| 精品熟女少妇免费久久| 内射极品少妇xxxxxhd| 精品国产日韩亚洲一区| 国产精品视频不卡一区二区 | 天天狠天天透天天伊人| 久久精品国产99国产精品严洲| 亚洲国产超清无码专区| 国产精品视频一区二区噜| 狠狠色综合久久丁香婷婷| av无码一区二区大桥久未| 国产18禁一区二区三区| 三人成全免费观看电视剧高清| 国产免费网站看v片元遮挡| 人妻中文字幕亚洲一区| 国产乱码精品一区二区麻豆| 国产-第1页-浮力影院| 日本久久一区二区免高清| 亚洲成人高清av在线| 国产一区二区爽爽爽视频| 大连市| 久久99久久99精品免视看国产成人| 国产精品午夜爆乳美女视频| 国产在线精彩自拍视频| 18禁成人免费无码网站| 欧美成本人视频免费播放| 色吊丝免费av一区二区| 亚洲国产日韩欧美一区二区三区| 亚洲国产色婷婷久久99精品91| 嘉义县| 亚洲综合国产精品第一页| 午夜免费无码福利视频麻豆| 亚洲AV午夜电影在线观看 | 欧美日韩另类国产| 国产美女直播亚洲一区色| 欧洲极品少妇|