ARM、THUMB硬patch技巧

下面內容涵蓋硬patch時會使用的技巧:算法

1、修改函數中調用的字符串變量c#

一、在data段找個位置存放字符串以\00結尾,記下地址A函數

二、找到函數中的 spa

    09 48  LDR  R0, =(aDataLocalTmpTe - 0xD62)     ,記下地址Bcode

.   78 44  ADD     R0, PC ;記下地址C字符串

    LDR  R0, =(aDataLocalTmpTe - 0xD62)  等於 LDR R0,[pc, #100],也就是說aDataLocalTmpTe - 0xD62計算的這個偏移存放在當前pc+100處的位置,記地址D,此時pc+100處的數據如:get

text:0000F168 9C 6D 00 00 off_F168        DCD aDataLocalTmpTe - 0xF14A


道先計算字符串離當前PC的位置存放到當前函數下面的數據偏移裏,
io

一、字符串到調用PC :偏移A=地址A-地址C-4class

二、偏移A存放到函數尾部的F168處pdf

三、計算地址B處的Opcode,詳情查看thumb指令的LDR opcode格式(https://ece.uwaterloo.ca/~ece222/ARM/ARM7-TDMI-manual-pt3.pdf),

48主要是操做哪一個寄存器,偏移主要是09這個字節,這個偏移的計算方法是:

(地址D-地址B-2)/4=opcode


2、函數調用相關

指令action:         B <Target Addr> PC = PC + (#OFF << 1)

指令opcode:       B <Target Addr> 1 1 1 0 0 #Offset[0-10]    ;其中15個字節中的0-10位爲偏移

0000F0F8 01 E0    B       locret_F0FE            ;F0FE-F0F8=#6

E001對應的二進制爲  11100 00000000001,也就是偏移爲1使用action計算以下,pc=pc+1<<1=pc+2,此處注意pc會自動加4,也就是pc+2=4+2=6,恰好等於B #6

1.向後跳轉

0012 00F001F8 bl .Lhelo

.Lhelo:

0018 05F0D1F7 pld [r1, r5]

計算方式:

取高位 f000, 取後11位 => 000

取低位 f801, 取後11位 => 001

計算: (000 << 12) | (001 << 1) = 2

因爲這個最高位符號位爲0. 表明向後跳轉, 只須要保留該值2便可

而後計算獲得的目標地址爲 : 0x0012 + 4 + 2 = 0x0018


向前跳轉

00001164 FF F7 BE FF BL _Z4testv

_Z4testv

000010E4 07 B5 PUSH {R0-R2,LR}

計算方式:

取高位 f7ff, 取後11位 => 7ff

取低位 ffbe, 取後11位 => 7be

計算: (7ff << 12) | (7be << 1) = 7fff7c

因爲這個最高位符號位爲1 表明向前跳轉, 須要-1而後取反 獲得值爲 ff800084。取84便可

而後算獲得的目標地址爲 : 0x1164 + 4 - 0x84 = 0x10e4

逆向過程:

BL <label>

由BL指令獲得機器碼算法:

offset = dstAddr - srcAddr;
offset = (offset -4) & 0x007ffffff
high = offset >> 12;
low = (offset & 0x00000fff) >> 1;
machineCode = ((0xFF00 | low) << 16) | (0xF000 | high);


BLX <label>

與BL相似。

offset = dstAddr - srcAddr;
offset = (offset -4) & 0x007fffff;
high = offset >> 12;
low = (offset & 0x00000fff) >> 1;
if(low%2 != 0) {
low++;
}
machineCode = ((0xEF00 | low) << 16) | (0xF000 | high);
相關文章
相關標籤/搜索