这意味着它必须被模拟,因为GCC依赖于%gs寄存器的存在.
目前我有一个包装器,当程序试图访问%gs寄存器并模拟它时捕获异常.但这是狗慢.有没有办法可以使用等效指令提前修改ELF中的 *** 作码,以避免陷阱和模拟?
解决方法 (这是假设Adam RosenfIElds解决方案不适用.它或类似的方法可能是解决它的更好方法.)你还没有说明你是如何模仿%gs寄存器的,但是除非你对这个程序有一些特殊的了解,否则你可能很难修补每个用法,因为否则你只有2个字节(在最坏的情况下,常见情况)您可以使用补丁进行修改.当然,如果你使用像%es =%gs这样的东西,它应该是相对简单的.
假设这可以以某种方式在您的情况下工作,策略是扫描ELF文件的可执行部分并修补使用或修改GS寄存器的任何指令.这至少是以下说明:
>任何带有GS段的指令都会覆盖前缀(65表示分支指令,在这种情况下,前缀表示其他内容)
>推gs(0F A8)
> pop gs(0F A9)
> mov r / m16,gs(8C / r)
> mov gs,r / m16(8E / r)
> mov gs,r / m64(REX.W 8E / r)(如果支持64位模式)
还有其他任何允许段寄存器的指令(我认为不是那么多,但我不是100%肯定).
这一切都是从Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes 2A and 2B: Instruction Set Reference,A-Z开始的.请注意,指令有时会以其他前缀为前缀,有时不会,因此您应该使用library来执行指令解码,而不是盲目地搜索字节序列.
上面的一些说明应该相对简单地转换成调用my_patch或类似的,但你可能很难找到适合两个字节的东西并且一般都可以工作. int XX(CD XX)可能是一个很好的候选者,如果你可以设置一个中断向量,但我不确定它会比你目前使用的方法更快.您当然需要记录哪个指令被修补并让中断处理程序(或其他)根据返回地址(处理程序收到的)做出不同的反应.
如果你能在-128..127字节内找到空间并使用JMP rel8(EB cb)跳转到蹦床(通常是另一个JMP,但这次有更多的空间用于目标地址),你可能能够设置蹦床,然后处理指令仿真并跳转到修补后的%gs使用后的指令.
最后,我建议保持运行陷阱和模拟代码以捕获您可能没有想过的任何情况(例如,自我修改或注入代码).这样,您还可以记录任何未处理的案例并将其添加到您的解决方案中.
总结以上是内存溢出为你收集整理的linux – 没有%gs寄存器的x86子集:使用%gs而不是捕获到仿真的二进制修补代码?全部内容,希望文章能够帮你解决linux – 没有%gs寄存器的x86子集:使用%gs而不是捕获到仿真的二进制修补代码?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)