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);
相关文章
相关标签/搜索