是否可以使用 GNU 工具(gcc、binutils 等)将所有出现的汇编指令修改为无操作?具体来说,带有 -pg 选项的 gcc 生成以下程序集 (ARM):
0x0: e1a0c00d mov ip, sp
0x4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
0x8: e24cb004 sub fp, ip, #4 ; 0x4
0xc: ebfffffe bl 0 <mcount>
我想记录最后一条指令的地址,然后将其更改为nop,如下面的代码所示
0x0: e1a0c00d mov ip, sp
0x4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
0x8: e24cb004 sub fp, ip, #4 ; 0x4
0xc: e1a00000 nop (mov r0,r0)
Linux 内核可以在运行时执行类似的操作,但我正在寻找构建时解决方案。
您可以使用
gcc -S
编译代码以输出汇编程序列表,而不是完全编译为目标文件或可执行文件。 然后,只需将所需的指令替换为无操作(例如使用 sed
),然后从那里继续编译。
如果您还想对没有原始源代码的目标文件或库执行此操作,则必须使用诸如
objdump(1)
之类的工具来反汇编它们并获取它们的地址您想要替换的说明。 然后,解析目标文件头以查找这些指令在文件中的偏移量,然后直接在目标文件中将机器指令替换为无操作。 这有点棘手,但可行。
使用 RISC 型固定长度指令格式肯定会比例如 RISC 等更容易。 x86.
使用 libelf 应该相对简单(这里有很好的教程:http://people.freebsd.org/~jkoshy/download/libelf/article.html)或 libbfd(http://sourceware.org/binutils) /docs-2.19/bfd/index.html)打开目标文件,修改 .text 部分中的指令,然后使用提供的 API 再次将其写出。是否值得付出努力将取决于非技术考虑(不过我有点好奇......)。
值得一提的是,如果需要在交叉开发环境中工作,使用 libelf 或 libbfd 可能会出现一些问题。