【问题标题】:Determine if instruction has indirect memory operand判断指令是否有间接内存操作数
【发布时间】:2016-08-30 11:12:15
【问题描述】:

查看 PIN 的 Inspection API Page 有一个名为 INS_IsLea() 的方法,如果当前指令是 LEA 指令,则该方法返回 true。这很有用,但我需要确定其中一个指令操作数是否是间接引用。例如:

MOV rax, (%rdi)

我希望能够确定第二个操作数实际上是间接引用,但似乎没有可用的方法。

【问题讨论】:

  • 您是否尝试过查看说明参考?如果您检查机器代码,您会发现可以告诉您这一点的模式(实际上它们已记录在案)。

标签: c++ linux assembly intel-pin


【解决方案1】:

我只是在这里猜测,因为在阅读这个问题之前我从未听说过这个库,但是......

我认为如果INS_IsMemoryRead()INS_IsMemoryWrite() 之一为真,它必须有一个间接内存操作数。

另外,从不同的角度,INS_MemoryOperand*() 函数检查操作数。

【讨论】:

    【解决方案2】:

    INS_OperandIsMemory() 如果您只想检查其中一个操作数是否为内存操作数。

    请注意,第二个参数 n 表示 Intel 语法中的操作数编号(索引为 0),例如

    ; rax = destination op; rdi = source op
    mov rax, [rdi] ; rax = op #0 ; rdi = op #1
    

    【讨论】:

    • 那么即使操作数通过寄存器间接调用内存,INS_OperandIsMemory() 也会在该操作数上返回 true?
    • @TypeKazt: MOV (%rdi), %rax 是尽可能直接的内存引用。 IDK 在这种情况下,您所说的“间接”是什么意思。通常,直接与间接的术语适用于跳转,其中直接跳转具有在指令中编码的目标地址(作为相对偏移量),而间接跳转设置RIP = register(寄存器间接jmp *%rax又名jmp rax)或RIP = [memory](内存间接jmp *(%rsi)又名jmp QWORD PTR [rsi]。)
    • 如果有的话,隐式内存引用是我担心检测的特殊情况,例如lodsbMASKMOVDQU xmm1, xmm2(存储到(%rdi))。或push/pop.
    【解决方案3】:

    您似乎在寻找两种情况:

    1. 如果操作数是包含内存地址的寄存器。这用于间接跳转或调用。可以通过INS_IsIndirectBranchOrCall(ins)检测到
    2. 如果第二个操作数是用于算术或移动操作的内存位置。可以被(!INS_IsBranchOrCall(ins) && (INS_MemoryOperandCount(ins) > 0))检测到

    注意: lea 指令只是将内存地址加载到寄存器中。它从不实际访问内存地址。阅读hereINS_IsLea 返回 true 是指令操作码是 lea。因此,MOV rax, (%rdi) 将返回 false

    【讨论】:

      猜你喜欢
      • 2016-04-24
      • 2011-06-03
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 2017-11-12
      • 1970-01-01
      • 2010-12-26
      • 1970-01-01
      相关资源
      最近更新 更多