Assembly 跟踪和反汇编与内核映像文件不匹配的Linux内核指令
我试图验证并理解在模拟框架中执行的指令。 模拟步骤如下所示:Assembly 跟踪和反汇编与内核映像文件不匹配的Linux内核指令,assembly,gcc,linux-kernel,x86,trace,Assembly,Gcc,Linux Kernel,X86,Trace,我试图验证并理解在模拟框架中执行的指令。 模拟步骤如下所示: 二进制文件在主机x86机器上与gcc(带-fPIC标志)交叉编译 然后在名为SimNow的虚拟机x86中移动并执行二进制文件(AMD用于测试其处理器) SimNow机器生成一个已执行指令的列表,这些指令被传递到一个框架,其中包括关于每条指令的信息:虚拟地址、物理地址、大小、操作码 借助x86反汇编程序(名为distorm),该框架生成执行指令的跟踪,包括助记符和操作数。 这是跟踪输出的一个示例: 已执行指令列表包括二进制指令中包含的
-dr
执行objdump来检查Linux映像上的重新定位,但是输出没有改变
我的验证方法对内核指令是错误的?(部分答案/猜测可能会为您指明正确的方向。更新:Jester建议这看起来像ftrace
machine:)
我怀疑这些调用在加载后会被拒绝,可能是在相关跟踪点或其他未启用的情况下。出于某种原因取消调用可以解释为什么存在与NOP关联的调用目标或符号重新定位元数据
我想我已经读过关于Linux使用代码修改来实现低开销跟踪点之类的东西,而自修改代码是Linux通常肯定会做的事情
Linux使用自修改代码,这些代码在启动时修改一次,或者在非常罕见的配置更改时修改一次,以减少每次执行的开销,而不是分支的开销。(例如,在启动的机器上引导SMP内核将不会在原子RMW中发出锁
前缀,该前缀只需要是SMP安全的,而不是硬件设备。)内联asm宏定义符号和自定义部分,以便内核具有必要的元数据。最近也有一些关于修改rel32
调用目标而不是使用间接分支的内容,以避免在这些站点上进行任何幽灵缓解,但这里并不是这样
因此,一般来说,当您尝试验证内核映像文件的执行时,应该会看到一些不匹配,这可能是其中之一
在本例中,这看起来像是一个函数的最顶端(在设置帧指针之前),这听起来像是一个寻找某种特殊调用的地方,可能是为了跟踪(到保留所有寄存器的特殊函数)
gcc生成的代码在推送%rbp/
mov%rsp,%rbp
之前决不会执行调用。首先,这将违反16字节堆栈对齐ABI要求。(虽然内核可能使用-mprefered stack boundary=3
而不是4?在两次推送之后,还有另一个更正常的调用,如果这是一个正常函数,它也会有一个未对齐的RSP。)无论如何,这是另一个迹象,表明存在一些自定义内联asm黑客行为或正在发生的事情。请参阅并使用和。在最近的一次编译中,使用gcc-Wall-fverbose asm-O2-S foo.c
·编译您的foo.c
,并使用查看foo.S
。我在二进制文件中使用了elf、objdump和readelf,它适用于用户指令。但是,它不适用于内核指令,它不应该包含在二进制文件中……不?这些可能是内核在加载后动态修改的内容的占位符吗?e、 g.不使用它们,或者将它们从NOP更改为callq,以实现非常低的开销跟踪?Linux确实有一些内联asm攻击,这些攻击会生成符号,用于为其他事情进行自我修改,例如,如果SMP内核在启动机器上启动,则不使用lock
前缀。我想我已经读过关于Linux使用代码修改来实现低开销跟踪点之类的东西。因此,这可以解释为什么内核在磁盘上的ELF映像与内存中的执行不匹配。是的,这看起来像是一个函数的最顶端(在生成堆栈帧之前),这听起来像是一个查找跟踪调用(对保留所有寄存器的特殊函数)的地方。出于某种原因取消呼叫可以解释为什么在NOP上有呼叫目标的符号