zoukankan      html  css  js  c++  java
  • 使用 SVC 修改代码

    #define SVC_0 0
    #define SVC_1 1
    #define SVC_2 2
    
    void SVC_Handler( void )
    {
      asm("TST LR, #4");
      asm("ITE EQ");
      asm("MRSEQ R0, MSP");
      asm("MRSNE R0, PSP");
      asm("B SVC_Handler_main");
    }
    
    void Dummy0_Handler( unsigned int * svc_args )
    {
      svc_args[6] += 4; // skip Dummy0()
    }
    
    void Dummy1_Handler( unsigned int * svc_args )
    {
      svc_args[6] += 8; // skip Dummy0(), Dummy1()
    }
    
    void Dummy0( void )
    {
    }
    
    void Dummy1( void )
    {
    }
    
    //
    void Dummy2_Handler( unsigned int * svc_args )
    {
      unsigned int a0 = svc_args[0];
      unsigned int a1 = svc_args[1];
      unsigned int a2 = svc_args[2];
      unsigned int a3 = svc_args[3];
      unsigned int a4 = svc_args[8];
      unsigned int a5 = svc_args[9];
      svc_args[0] = ( a0 + a1 + a2 ) * ( a3 + a4 + a5 );  // retValue
      svc_args[6] = svc_args[5] - 1;  // return to Caller of Dummy2()
    }
    
    unsigned int Dummy2( unsigned int a0, unsigned int a1, unsigned int a2,
      unsigned int a3, unsigned int a4, unsigned int a5 )
    {
      asm("SVC #2");  // <--- modify first instruct
      return ( a0 + a1 + a2 ) * ( a3 + a4 + a5 );
    }
    
    void SVC_Demo( void )
    {
      unsigned int a0, a1, a2, a3, a4, a5;
      a0 = 0;
      a1 = 1;
      a2 = 2;
      a3 = 3;
      a4 = 4;
      a5 = 5;
      asm("SVC #0"); // Dummy0_handler() : svc_args[6] += 4 Bytes : modifyed PC ( return address )
      Dummy0();      // <---- PC, skipped : 0xF7FF 0xFFCA : BL Dummy0
      Dummy1();
    asm(
    "SVC #1"); // Dummy1_handler() : svc_args[6] += 8 bytes Dummy0(); // <---- PC, skipped : 0xF7FF 0xFFCA 0xF7FF 0xFFC4 Dummy1(); // <-------- skipped
    Dummy2(a0, a1, a2, a3, a4, a5);
    // Dummy2() : SVC #2 : FIRST INSTRUCTION be patched
    // Dummy2_Handler() :
    svc_args[6] = svc_args[5] - 1 : return after caller of dummy2() :: Execute Dummy0()
      Dummy0();
      Dummy1();
    }
    
    //
    //       a0 a1 a2 a3                 | a4          a5
    // xSP : R0 R1 R2 R3 R12 R14 PC xPSR | XX XX XX XX XX XX XX XX
    // xSP : R0 R1 R2 R3 R12 R14 PC xPSR |
    //       |svc_args[0]        |svc_args[6] --> instruction after SVC XX
    //                           |
    //                      00 DF|XX XX XX XX <-- instruction will be executed after reti
    //                      -2 -1|0  1  2  3
    //                           |
    void SVC_Handler_main( unsigned int * svc_args )  // R0 = ( PSP or MSP )
    {
      /*
       * Stack contains:
       * r0, r1, r2, r3, r12, r14, the return address and xPSR
       * First argument (r0) is svc_args[0]
       */
        unsigned int svc_number;
        svc_number = ((char *)svc_args[6])[-2];
      // ( SVC #0 ) 00 DF : XX XX XX XX <-- code will be executed after reti
      // ( SVC #1 ) 01 DF : \______________ PC : (char *)svc_args[6])
      switch(svc_number)
      {
        case SVC_0:
          Dummy0_Handler( svc_args );
          break;
    
        case SVC_1:
          Dummy1_Handler( svc_args );
          break;
    
        case SVC_2:
          Dummy2_Handler( svc_args );
          break;
    
        default:
        break;
      }
    }
    void SVC_Demo( void )
    {
    SVC_Demo:
       0x20004920: 0xe92d 0x43f0  PUSH.W    {R4-R9, LR}
       0x20004924: 0xb083         SUB       SP, SP, #0xc
      a0 = 0;
       0x20004926: 0x2000         MOVS      R0, #0
       0x20004928: 0x0004         MOVS      R4, R0
      a1 = 1;
       0x2000492a: 0x2001         MOVS      R0, #1
       0x2000492c: 0x0005         MOVS      R5, R0
      a2 = 2;
       0x2000492e: 0x2002         MOVS      R0, #2
       0x20004930: 0x0006         MOVS      R6, R0
      a3 = 3;
       0x20004932: 0x2003         MOVS      R0, #3
       0x20004934: 0x0007         MOVS      R7, R0
      a4 = 4;
       0x20004936: 0x2004         MOVS      R0, #4
       0x20004938: 0x4680         MOV       R8, R0
      a5 = 5;
       0x2000493a: 0x2005         MOVS      R0, #5
       0x2000493c: 0x4681         MOV       R9, R0
      asm("SVC #0");
       0x2000493e: 0xdf00         SVC       #0x0
      Dummy0();   // <---- PC, skipped
       0x20004940: 0xf7ff 0xffca  BL        Dummy0          ; 0x200048d8
      Dummy1();
       0x20004944: 0xf7ff 0xffc9  BL        Dummy1          ; 0x200048da
      asm("SVC #1");                                        
       0x20004948: 0xdf01         SVC       #0x1            
      Dummy0();   // <---- PC, skipped                      
       0x2000494a: 0xf7ff 0xffc5  BL        Dummy0          ; 0x200048d8
      Dummy1();   // <-------- skipped                      
       0x2000494e: 0xf7ff 0xffc4  BL        Dummy1          ; 0x200048da
      Dummy2(a0, a1, a2, a3, a4, a5);                       
       0x20004952: 0xf8cd 0x9004  STR.W     R9, [SP, #0x4]  ; a5       
       0x20004956: 0xf8cd 0x8000  STR.W     R8, [SP]        ; a4       
       0x2000495a: 0x003b         MOVS      R3, R7          ; a3       
       0x2000495c: 0x0032         MOVS      R2, R6          ; a2       
       0x2000495e: 0x0029         MOVS      R1, R5          ; a1       
       0x20004960: 0x0020         MOVS      R0, R4          ; a0       
       0x20004962: 0xf7ff 0xffd1  BL        Dummy2          ; 0x20004908 -----------LR=0x20004966+1-----------------------------------------------+
      Dummy0();    ; BL : Branch and Link : LR ---> 0x20004966+1 : BL Dummy0                                                                      |   
       0x20004966: 0xf7ff 0xffb7  BL        Dummy0          ; 0x200048d8 -------------------------------------------------------------------------+
      Dummy1();                                                                                                                                   |  
       0x2000496a: 0xf7ff 0xffb6  BL        Dummy1          ; 0x200048da                                                                          |   
    }                                                                                                                                             |  
       0x2000496e: 0xe8bd 0x83f7  POP.W     {R0-R2, R4-R9, PC}                                                                                    |  
    unsigned int Dymmy2( unsigned int a0, unsigned int a1, unsigned int a2,                                                                       |    
      unsigned int a3, unsigned int a4, unsigned int a5 )     ; modify first instruction : SVC #2                                                 |           
    {                                                                                                                                             | 
    Dummy2:                                                                                                                                       |     
       0x20004908: 0xb430         PUSH      {R4, R5}          ; SP = 0x2000A3C0 : a4 a5                                                           | 
       0x2000490a: 0x9c02         LDR       R4, [SP, #0x8]    ; a4 : SP = 0x2000A3B8 + 8 = 0x2000A3C0                                             | 
       0x2000490c: 0x9d03         LDR       R5, [SP, #0xc]    ; a5 : SP = 0x2000A3B8 + C = 0x2000A3C4                                             |
      asm("SVC #2");                                          ; <--- modify first instruct 0x20004908 to execute Dummy2_Handler() ----------------+
    0x2000490e: 0xdf02 SVC #0x2 ;
    Force Execute this instruction <TEST>
    svc_args[6] = svc_args[5] - 1; ; PC = LR - 1 : Dummy2_Handler() last instruction : LR = 0x20004966+1
    else execute 0x2000490a after exit SVC_Handler_main() ; because svc_args[6] = 0x2000490a when execute SVC #0x02


    old function : first instruction : SVC xx --> execute new function()
    new function : last insturction : svc_args[6] = svc_args[5] - 1 : return to instruction after BL OLD_FUNCTION

    return ( a0 + a1 + a2 ) * ( a3 + a4 + a5 ); ; SP = 0x2000A3A0 : R0 R1 R2 R3 R12 R14 PC xPSR a4 a5 0x20004910: 0x1808 ADDS R0, R1, R0 ; skipped 0x20004912: 0x1810 ADDS R0, R2, R0 0x20004914: 0x18e1 ADDS R1, R4, R3 0x20004916: 0x1869 ADDS R1, R5, R1 0x20004918: 0x4348 MULS R0, R1, R0 0x2000491a: 0xbc30 POP {R4, R5} 0x2000491c: 0x4770 BX LR 0x2000491e: 0x0000 MOVS R0, R0 ; skipped SVC_Handler: 0x200048b4: 0xf01e 0x0f04 TST.W LR, #4 ; SP = 0x2000A3A0 : R0 R1 R2 R3 R12 R14 PC xPSR a4 a5 asm("ITE EQ"); 0x200048b8: 0xbf0c ITE EQ asm("MRSEQ R0, MSP"); 0x200048ba: 0xf3ef 0x8008 MRSEQ R0, MSP asm("MRSNE R0, PSP"); 0x200048be: 0xf3ef 0x8009 MRSNE R0, PSP asm("B SVC_Handler_main"); 0x200048c2: 0xf000 0xb856 B.W SVC_Handler_main } void SVC_Handler_main( unsigned int * svc_args ) // R0 = ( PSP or MSP ) { SVC_Handler_main: 0x20004972: 0xb538 PUSH {R3-R5, LR} ; SP = 0x2000A3A0 : R0 R1 R2 R3 R12 R14 PC xPSR a4 a5 0x20004974: 0x0004 MOVS R4, R0 ; SP = 0x2000A390 : R3 R4 R5 LR : R0 R1 R2 R3 R12 R14 PC xPSR a4 a5 svc_number = ((char *)svc_args[6])[-2]; ; R0 = 0x2000A3A0 : ( svc_args ) 0x20004976: 0x69a0 LDR R0, [R4, #0x18] 0x20004978: 0xf810 0x0c02 LDRB.W R0, [R0, #-0x2] 0x2000497c: 0x0005 MOVS R5, R0 switch(svc_number) 0x2000497e: 0x2d00 CMP R5, #0 0x20004980: 0xd003 BEQ.N ??SVC_Handler_main_0 0x20004982: 0x2d02 CMP R5, #2 0x20004984: 0xd009 BEQ.N ??SVC_Handler_main_1 0x20004986: 0xd304 BCC.N ??SVC_Handler_main_2 0x20004988: 0xe00b B.N ??SVC_Handler_main_3 SVC_0_Handler( svc_args ); ??SVC_Handler_main_0: 0x2000498a: 0x0020 MOVS R0, R4 0x2000498c: 0xf7ff 0xff9c BL SVC_0_Handler break; 0x20004990: 0xe007 B.N ??SVC_Handler_main_3 SVC_1_Handler( svc_args ); ??SVC_Handler_main_2: 0x20004992: 0x0020 MOVS R0, R4 0x20004994: 0xf7ff 0xff9c BL SVC_1_Handler break; 0x20004998: 0xe003 B.N ??SVC_Handler_main_3 Dummy2_Handler( svc_args ); ??SVC_Handler_main_1: 0x2000499a: 0x0020 MOVS R0, R4 ; R0 = 0x2000A3A0 : ( svc_args ) 0x2000499c: 0xf7ff 0xff9e BL Dummy2_Handler ; 0x200048dc break; 0x200049a0: 0xe7ff B.N ??SVC_Handler_main_3 ; 0x200049a2 } ??SVC_Handler_main_3: ??SVC_Handler_main_4: 0x200049a2: 0xbd31 POP {R0, R4, R5, PC} ; PC <-- 0xFFFFFFF9, ( R0 : dont care ), Reti : restore registers ; R0 R1 R2 R3 R12 R14 PC xPSR : restore from stack void Dummy2_Handler( unsigned int * svc_args ) ; PC be modified : svc_args[6] = svc_args[5]-1 { Dummy2_Handler: ; SP(Dummy2.Entry) -------------------------------------------| 0x200048dc: 0xb4f0 PUSH {R4-R7} ; R0 = 0x2000A3A0 ----------------| | unsigned int a0 = svc_args[0]; ; SP = 0x2000A390 : R3 R4 R5 LR : R0 R1 R2 R3 R12 R14 PC xPSR a4 a5 0x200048de: 0x6801 LDR R1, [R0] ; SP = 0x2000A380 : R4 R5 R6 R7 : R3 R4 R5 LR : R0 R1 R2 R3 R12 R14 PC xPSR a4 a5 unsigned int a1 = svc_args[1]; ; svc_args[0] : R0 0x200048e0: 0x6842 LDR R2, [R0, #0x4] ; svc_args[1] : R1 unsigned int a2 = svc_args[2]; ; svc_args[8] : a4 0x200048e2: 0x6883 LDR R3, [R0, #0x8] ; svc_args[9] : a5 0x20004962 : BL Dummy2 unsigned int a3 = svc_args[3]; ; svc_args[5] : LR : 0x20004966+1 : BL Dummy0 -------+ 0x200048e4: 0x68c4 LDR R4, [R0, #0xc] ; | unsigned int a4 = svc_args[8]; ; 0x2000490E : SVC #2 | 0x200048e6: 0x6a05 LDR R5, [R0, #0x20] ; svc_args[6] : PC : 0x20004910 : XXXXXX | unsigned int a5 = svc_args[9]; ; svc_args[6] = svc_args[5]-1 -----------------------+ 0x200048e8: 0x6a46 LDR R6, [R0, #0x24] ; svc_args[0] = ( a0 + a1 + a2 ) * ( a3 + a4 + a5 ); ; svc_args[0] = result 0x200048ea: 0x1857 ADDS R7, R2, R1 0x200048ec: 0x19df ADDS R7, R3, R7 0x200048ee: 0xeb15 0x0c04 ADDS.W R12, R5, R4 0x200048f2: 0xeb16 0x0c0c ADDS.W R12, R6, R12 0x200048f6: 0xfb0c 0xf707 MUL R7, R12, R7 0x200048fa: 0x6007 STR R7, [R0] svc_args[6] = svc_args[5] - 1; ; svc_args[6] = svc_args[5]-1 0x200048fc: 0x6947 LDR R7, [R0, #0x14] ; return to Caller of Dummy2() after exit SVC_Handler_main() 0x200048fe: 0x1e7f SUBS R7, R7, #1 ; 0x20004900: 0x6187 STR R7, [R0, #0x18] ; } 0x20004902: 0xbcf0 POP {R4-R7} ; 0x20004904: 0x4770 BX LR ; return to SVC_Handler_main()| 0x20004906: 0x0000 MOVS R0, R0 ; | 0x2000499c: 0xf7ff 0xff9e BL Dummy2_Handler ; 0x200048dc | break; ; | 0x200049a0: 0xe7ff B.N ??SVC_Handler_main_3 ; 0x200049a2 <----------------+ } ??SVC_Handler_main_3: ??SVC_Handler_main_4: ; PC be modified : svc_args[6] = svc_args[5]-1 0x200049a2: 0xbd31 POP {R0, R4, R5, PC} ; return to Caller of Dummy2()| ; PC <-- 0xFFFFFFF9 | 0x20004962: 0xf7ff 0xffd1 BL Dummy2 ; | Dummy0(); ; | 0x20004966: 0xf7ff 0xffb7 BL Dummy0 ; 0x200048d8 <----------------+ Dummy1(); ; 0x2000496a: 0xf7ff 0xffb6 BL Dummy1 ; 0x200048da } 0x2000496e: 0xe8bd 0x83f7 POP.W {R0-R2, R4-R9, PC} ; return to caller of SVC_Demo()

  • 相关阅读:
    常见的排序算法
    322. Coin Change
    C++ STL中的lower_bound,upper_bound使用小结
    滑动窗口题汇总
    1658. Minimum Operations to Reduce X to Zero
    739. Daily Temperatures
    240. Search a 2D Matrix II
    474. Ones and Zeroes
    221. Maximal Square
    javac不是内部或外部命令
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3052696.html
Copyright © 2011-2022 走看看