- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我问this几天前的问题。
我想获取堆栈分配大小(在函数创建之后)。答案建议这样做:
if((INS_Opcode(ins) == XED_ICLASS_ADD || INS_Opcode(ins) == XED_ICLASS_SUB) &&
REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR && INS_OperandIsImmediate(ins, 1)
这在理论上是正确的并且确实有道理。但是,它在实践中不起作用(如果我错了,请纠正我)。如果我删除 REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR
检查,它就可以正常工作。为什么?因为当使用 REG(INS_OperandReg(ins, 0))
检测 REG_STACK_PTR
寄存器时,pin 不会检测到它。相反,当我检查 add rsp, 0xffffffffffffff80
指令时,它会检测到 ah
(我相信是 RAX)(因此,每次它给出: register:啊
),如下面我的输出所示:
in
register: rbp
40051e push rbp
register: *invalid*
value: -128
40051f mov rbp, rsp
register: ah
400522 add rsp, 0xffffffffffffff80
register: *invalid*
400526 mov dword ptr [rbp-0x28], 0x7
register: *invalid*
40052d mov dword ptr [rbp-0x64], 0x9
register: eax
400534 mov eax, 0x0
register: *invalid*
400539 call 0x4004e6
register: rbp
4004e6 push rbp
register: *invalid*
value: 64
4004e7 mov rbp, rsp
register: ah
4004ea sub rsp, 0x40
register: *invalid*
4004ee mov dword ptr [rbp-0xc], 0x4
register: rax
4004f5 lea rax, ptr [rbp-0xc]
register: *invalid*
4004f9 mov qword ptr [rbp-0x8], rax
register: rax
4004fd mov rax, qword ptr [rbp-0x8]
register: eax
400501 mov eax, dword ptr [rax]
register: *invalid*
400503 mov esi, eax
register: edi
400505 mov edi, 0x4005d0
register: eax
40050a mov eax, 0x0
register: rdi
40050f call 0x4003f0
register: rdi
4003f0 jmp qword ptr [rip+0x200c22]
register: *invalid*
4003f6 push 0x0
register: *invalid*
4003fb jmp 0x4003e0
register: *invalid*
4003e0 push qword ptr [rip+0x200c22]
register: rdi
4003e6 jmp qword ptr [rip+0x200c24]
4
register: *invalid*
400514 mov dword ptr [rbp-0x3c], 0x3
40051b nop
register: *invalid*
40051c leave
register: *invalid*
40051d ret
register: eax
40053e mov eax, 0x0
register: *invalid*
400543 leave
out
嗯,有趣的是,它对每次出现的 rsp
都会执行此操作(即,它检测 ah
而不是 rsp
)。此外,它总是打印指令 400522 add rsp, 0xffffffffffffff80
,包括 rsp
(那么,为什么它不在这里打印 ah
?)
如果 ah
以某种方式表示 rsp
,那么我总是可以使用以下方法检测 ah
:REG(INS_OperandReg(ins, 0) )) == REG_AH
。但是,我想了解这里发生了什么。
我的代码:
#include <iostream>
#include <fstream>
#include "pin.H"
#include <unordered_map>
// key to open the main Routine
static uint32_t key = 0;
// Ins object mapping
class Insr
{
private:
// Disassembled instruction
string insDis;
INS ins;
public:
Insr(string insDis, INS ins) { this->insDis = insDis; this->ins = ins;}
string get_insDis() { return insDis;}
INS get_ins() { return ins;}
};
// Stack for the Insr structure
static std::unordered_map<ADDRINT, Insr*> insstack;
// This function is called before every instruction is executed
VOID protect(uint64_t addr)
{
if (addr > 0x700000000000)
return;
if (!key)
return;
// Initialize the diassembled instruction
string insdis = insstack[addr]->get_insDis();
INS ins = insstack[addr]->get_ins();
if (INS_OperandCount(ins) > 0)
{
if (REG(INS_OperandReg(ins, 0)) == REG_AH)
std::cout << "register: " << REG_StringShort(REG(INS_OperandReg(ins, 0))) << '\n';
}
if((INS_Opcode(ins) == XED_ICLASS_ADD || INS_Opcode(ins) == XED_ICLASS_SUB) &&
INS_OperandIsImmediate(ins, 1))
{
int value = INS_OperandImmediate(ins, 1);
std::cout << "value: " << dec<<value << '\n';
}
std::cout << hex <<addr << "\t" << insdis << std::endl;
}
// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
if (INS_Address(ins) > 0x700000000000)
return;
insstack.insert(std::make_pair(INS_Address(ins), new Insr(string(INS_Disassemble(ins)),
ins)));
// if (REG_valid_for_iarg_reg_value(INS_MemoryIndexReg(ins)))
// std::cout << "true" << '\n';
// Insert a call to docount before every instruction, no arguments are passed
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)protect, IARG_ADDRINT, INS_Address(ins),
IARG_END);
}
// Lock Routine
void mutex_lock()
{
key = 0;
std::cout<<"out\n";
}
void mutex_unlock()
{
key = 1;
std::cout<<"in\n";
}
void Routine(RTN rtn, VOID *V)
{
if (RTN_Name(rtn) == "main")
{
RTN_Open(rtn);
RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)mutex_unlock, IARG_END);
RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)mutex_lock, IARG_END);
RTN_Close(rtn);
}
}
INT32 Usage()
{
cerr << "This tool counts the number of dynamic instructions executed" << endl;
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
int main(int argc, char * argv[])
{
// Initialize the symbol table
PIN_InitSymbols();
// Initialize pin
if (PIN_Init(argc, argv)) return Usage();
PIN_SetSyntaxIntel();
// Routine instrumentation
RTN_AddInstrumentFunction(Routine, 0);
// Register Instruction to be called to instrument instructions
INS_AddInstrumentFunction(Instruction, 0);
// Start the program, never returns
PIN_StartProgram();
return 0;
}
对此我有几个问题。
我该如何理解这样的行为?如果我愿意的话,我怎样才能检测到 rsp?最后,指令如何打印rsp
,但REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR
检测不到?
最佳答案
INS
对象仅在检测例程内有效,例如您的Instruction
例程。 INS
类型只不过是一个标识指令的 32 位整数。 Pin 运行时内部维护一个表,将这些 32 位整数映射到特定的静态指令。每当它要调用检测例程时,它都会创建这样一个表。当检测例程返回时,不能保证这些标识符中的任何一个都映射到相同的静态指令,并且它们甚至可能无效。因此,当您在以下代码行中保存 INS
对象的拷贝时:
insstack.insert(std::make_pair(INS_Address(ins), new Insr(string(INS_Disassemble(ins)),
ins)));
该拷贝仅在指令
例程的同一实例中有用。下次调用指令
例程(或任何其他检测例程)时,指令标识符可能会被其他指令重用。
如果您确实想将指令传递给分析例程,您有两个选择:
关于c++ - 英特尔引脚 : analysis routine detects ah register instead of rsp (REG_STACK_PTR),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55562784/
我是一名优秀的程序员,十分优秀!