我正在写一个ARMv7反汇编器,ARM和Thumb模式之间切换的方法在ARM参考手册中有清楚的描述,但是你怎么知道程序 * 启动 * 的模式呢?我使用的Xcode默认编译为Thumb,所以我知道我自己的所有程序都将在Thumb中启动,除非我强制编译为ARM模式。但是,我希望能够采用任意的mach-o可执行文件,并在代码开始时找到指令集模式。在mach-o头文件中是否有地方指定了入口点的指令集?
roqulrg31#
处理器通过打开程序计数器的最低有效位,使程序计数器具有奇数值,从而知道它处于Thumb模式。为了获取指令,此位被忽略,您可以通过切换此位在ARM和Thumb模式之间切换。当你创建一个ARM二进制文件时,链接器会根据一个符号是指向ARM还是Thumb代码来设置这个符号地址的最低有效位,这样处理器在程序启动时会自动选择正确的模式。你不需要关心这个。
nwwlzxa72#
大多数操作系统都会在应用程序的入口点(C运行时支持)之前插入一些代码。它们会以编写代码的任何模式启动应用程序。然后,当调用main()或其他入口点时,代码会根据需要更改模式。在iOS的情况下,这是我假设你的目标,因为你正在使用Xcode,该代码是在/usr/local/lib/crt0.o在您的iOS SDK目录。分解它显示符号start是ARM代码。也就是说,iOS应用程序总是在ARM模式下开始运行,但他们可以改变模式很早之后。
/usr/local/lib/crt0.o
start
m4pnthwp3#
取决于你所指的入口点。答案就在那个定义中。一个操作系统必须有一个定义,因为它必须处于正确的模式。所以要么操作系统总是定义arm模式,比如说,然后代码可以根据需要进行切换。或者,如果您使用像elf这样的文件格式,并使用入口点,那么您可能会获得一个偶数地址为arm,一个奇数地址为thumb,与bx/blx指令相匹配。如果您正在谈论其中一个内核,则armv7 m将始终启动,并且必须保持在thumb模式。armv 7a和r将以arm模式启动(重置,其他在arm文档中定义,可能是arm模式),然后代码可以切换。如果您只是尝试反汇编某个通用对象文件,那么您可能无法理解它。当您看到大量的0xE时,视觉效果就像人类查看十六进制的arm二进制文件一样(每个字开始),0x 6或0x 7,0xE不多或没有(每半字)那么这可能是thumb代码。但这不是你可以依赖的东西为这个任务,因为前几个指令很可能会切换模式,如果有一个切换将发生。另外,如果你能从块头中分辨出一个elf文件,我想这就是gnu工具的工作原理,因为它们肯定不会在运行中检测到它。所以这很可能是你想做的,检查一下elf文件。如果这是一个原始的二进制文件,只有指令和数据...祝你好运...
3条答案
按热度按时间roqulrg31#
处理器通过打开程序计数器的最低有效位,使程序计数器具有奇数值,从而知道它处于Thumb模式。为了获取指令,此位被忽略,您可以通过切换此位在ARM和Thumb模式之间切换。
当你创建一个ARM二进制文件时,链接器会根据一个符号是指向ARM还是Thumb代码来设置这个符号地址的最低有效位,这样处理器在程序启动时会自动选择正确的模式。你不需要关心这个。
nwwlzxa72#
大多数操作系统都会在应用程序的入口点(C运行时支持)之前插入一些代码。它们会以编写代码的任何模式启动应用程序。然后,当调用main()或其他入口点时,代码会根据需要更改模式。
在iOS的情况下,这是我假设你的目标,因为你正在使用Xcode,该代码是在
/usr/local/lib/crt0.o
在您的iOS SDK目录。分解它显示符号start
是ARM代码。也就是说,iOS应用程序总是在ARM模式下开始运行,但他们可以改变模式很早之后。m4pnthwp3#
取决于你所指的入口点。答案就在那个定义中。一个操作系统必须有一个定义,因为它必须处于正确的模式。所以要么操作系统总是定义arm模式,比如说,然后代码可以根据需要进行切换。或者,如果您使用像elf这样的文件格式,并使用入口点,那么您可能会获得一个偶数地址为arm,一个奇数地址为thumb,与bx/blx指令相匹配。
如果您正在谈论其中一个内核,则armv7 m将始终启动,并且必须保持在thumb模式。armv 7a和r将以arm模式启动(重置,其他在arm文档中定义,可能是arm模式),然后代码可以切换。
如果您只是尝试反汇编某个通用对象文件,那么您可能无法理解它。当您看到大量的0xE时,视觉效果就像人类查看十六进制的arm二进制文件一样(每个字开始),0x 6或0x 7,0xE不多或没有(每半字)那么这可能是thumb代码。但这不是你可以依赖的东西为这个任务,因为前几个指令很可能会切换模式,如果有一个切换将发生。
另外,如果你能从块头中分辨出一个elf文件,我想这就是gnu工具的工作原理,因为它们肯定不会在运行中检测到它。所以这很可能是你想做的,检查一下elf文件。如果这是一个原始的二进制文件,只有指令和数据...祝你好运...