我正在尝试修补通过使用Objective-C开发的Cydia调整。我想修改一段代码以满足我的需要。

我正在使用IDA Pro V6.8进行检查。检查后,我意识到每个十六进制字节将代表组装线代码的一部分。

下面是我需要更改的代码的屏幕截图。


看上面的屏幕截图,我们需要8个字节(4A F2 A6 50 C0 F2 01 00)来表示“ MOV”指令。让我对这8个字节说些什么:


我知道,前四个字节(4A F2 A6 50)代表“#(cfstr_UnknownCallbac-0x9F56)”,屏幕快照。
后两个字节(C0 F2)代表一条MOV指令。
后两个字节(01 00)会告诉系统将值从字符串移入寄存器,在这种情况下,寄存器是R0。

我对MOV指令和前四个HEX字节(4A F2 A6 50)有些担心。


“ 0x9F56”有什么作用
系统中如何知道前四个字节正确反映为“#(cfstr_UnknownCallbac-0x9F56)”而不是其他任何字符串变量?
我需要创建一个新字符串,然后我将使用它替换现有的“#(cfstr_UnknownCallbac-0x9F56)”。我相信我只需要替换前四个HEX字节即可指向新的字符串,但是我不知道这里应该有什么HEX代码。

任何帮助是感谢,非常感谢。

评论

覆盖原来的字符串实际上不是更容易吗?

我想要一个新字符串,例如“处理您的请求时出错。”

#1 楼

要了解正在发生的事情,您需要了解位置独立代码(PIC)。简而言之,编译器希望可执行代码正确无误,而与要加载的内存位置无关。对于共享库,操作系统可能每次都将其加载到其他位置。即使使用静态链接,PIC也会使链接器的工作变得更轻松。

ARM处理器通常用来生成PIC的“技巧”是使用PC(程序计数器)的相对地址。编译器不会产生表示“该字符串位于地址0x123456”的代码,而是产生“该字符串位于该指令后的0x1234字节”。因此,当程序在内存中移动时,“ 0x1234”保持不变。

这就是为什么第二条指令将程序计数器添加到R0中的相对地址的原因。
现在,要了解ADD R0, PC的实际功能,您需要了解处理器的工作方式。从9F529F54之间的2个字节的差异中可以看出,处理器处于Thumb(2字节指令)模式,并且当处理器执行ADD R0, PC指令时,预取单元将已经读取BLX _MSlog的前两个字节。因此,添加的PC实际上是9F56。这应该回答您的第一个问题:在显示操作码的含义时,IDA减去它知道要在下一条指令中添加的值。

第二个问题:我不知道IDA的内部结构,但是我99%的肯定它会查找ADD Rx, PC指令,并在加载Rx的前一条指令中生成与您类似的字符串引用,只是因为它知道这是在ARM上实现PIC的标准方法。

第三个问题:手动拆卸Thumb很难-确实很难-正如您可以查看是否检查Thumb指令集。不,4a f2 a6 50不仅仅是数据偏移量;它加载值的低16位,而C0 F2 01 00加载值的高16位。在线反汇编程序将这两组4字节指令翻译为
movw r0, #42406 ; 0xa5a6          
movt r0, #1


,您可以在此处阅读有关movwmovt指令的信息。 IDA非常友好,可以将所有这些显示为一个8字节的指令,但是在幕后,还有很多事情要做。

因此,如果您真的想更改这样的偏移量,请获取熟悉我上面链接的拇指手册,学习每一点,并手动组装新的说明。或者,按照我在回答这个问题中概述的方式,仅(ab)使用gnu汇编器。只需编写一个最低限度的汇编程序片段并让as为您处理gory详细信息。

但是,正如@joxeankoret所说:如果您只是想更改一个字符串,而又不需要原始字符串否则,新字符串不会比旧字符串长,用新字符串覆盖字符串比为新字符串找到位置并调整偏移量要容易得多。您可以通过双击IDA中的标签跳到该位置,或者只需滚动到地址2FF4C1A5A6+9F56)。

评论


非常感谢您的详细回答。 PIC和大拇指对我来说很新。我将立即查看这些术语。希望我能尽快找到解决方案。祝你今天愉快!

–乔什
16-8-4在1:04