/****************************************************************** Title:movRMHandler Function:Handler to handle instruction "mov REG [mem addr]" Input: INS ins:Instruction to be handled. int srcA:The 1st src operand. int srcB:The 2nd src operand. int srcC:The 3rd src operand. int dstA:The 1st dst operand. int dstB:The 2nd dst operand. int dstC:The 3rd dst operand. Output: int Return value:-1 means unable to handle the instruction ******************************************************************/ int movRMHandler(INS ins,int srcA,int srcB,int srcC,int dstA,int dstB,int dstC) { REG baseReg = INS_OperandMemoryBaseReg(ins,1); INT64 displacement = INS_OperandMemoryDisplacement(ins,1); REG indexReg = INS_OperandMemoryIndexReg(ins,1); UINT32 scale = INS_OperandMemoryScale(ins,1); if(REG_valid(baseReg)){ INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)getRegisterValue, IARG_REG_VALUE,baseReg, IARG_END); } int valueBaseReg = regValue; if(REG_valid(indexReg)){ INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)getRegisterValue, IARG_REG_VALUE,indexReg, IARG_END); } int valueIndexReg = regValue; unsigned int realAddress = displacement+valueBaseReg+valueIndexReg*scale; if(INS_IsMemoryRead(ins)){ INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(movRMHook), IARG_UINT32, REG(INS_OperandReg(ins, 0)), IARG_MEMORYREAD_EA, IARG_END); }else{ fprintf(log,"Error at reading memory\n"); return -1; } countAllIns++; countHandledIns++; return 0; }
INT32 RecordRegisters(BBL bbl, UINT16 * stats) { INT32 count = 0; for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { const UINT32 max_r = INS_MaxNumRRegs(ins); for( UINT32 i=0; i < max_r; i++ ) { const REG reg = INS_RegR(ins, i ); if( REG_is_gr(reg) ) { stats[count++] = REG_GetStatsIndex(reg,FALSE); } #if 0 // This is for arm else if( REG_is_aggregate(reg) ) { REGSET regset = INS_RegAggregateR(ins); for( REG reg = REGSET_PopNext(regset); REG_valid(reg); reg = REGSET_PopNext(regset) ) { stats[count++] = REG_GetStatsIndex(reg,FALSE); } } #endif } const UINT32 max_w = INS_MaxNumWRegs(ins); for( UINT32 i=0; i < max_w; i++ ) { const REG reg = INS_RegW(ins, i ); if( REG_is_gr(reg) ) { stats[count++] = REG_GetStatsIndex(reg,TRUE); } #if 0 else if( REG_is_aggregate(reg) ) { REGSET regset = INS_RegAggregateW(ins); for( REG reg = REGSET_PopNext(regset); REG_valid(reg); reg = REGSET_PopNext(regset) ) { stats[count++] = REG_GetStatsIndex(reg,TRUE); } } #endif } } stats[count++] = 0; return count; }
// There is no verification on the validity of the ID. uint64 PINContextHandler::getFlagValue(uint64 TritFlagID) const { uint64 rflags; REG reg = safecast(PINConverter::convertTritonReg2DBIReg(ID_RFLAGS)); if (!REG_valid(reg)) throw std::runtime_error("Error: getFlagValue() - Invalid PIN register id."); rflags = PIN_GetContextReg(this->_ctx, reg); switch (TritFlagID){ case ID_AF: return (rflags >> 4) & 1; case ID_CF: return (rflags & 1); case ID_DF: return (rflags >> 10) & 1; case ID_IF: return (rflags >> 9) & 1; case ID_OF: return (rflags >> 11) & 1; case ID_PF: return (rflags >> 2) & 1; case ID_SF: return (rflags >> 7) & 1; case ID_TF: return (rflags >> 8) & 1; case ID_ZF: return (rflags >> 6) & 1; default: throw std::runtime_error("Error: getFlagValue() - Invalid Flag id."); } return 0; }
int main(int argc, char * argv[]) { // We accumlate counts into a register, make sure it is 64 bits to // avoid overflow ASSERTX(sizeof(ADDRINT) == sizeof(UINT64)); if (PIN_Init(argc, argv)) return Usage(); OutFile.open(KnobOutputFile.Value().c_str()); ScratchReg = PIN_ClaimToolRegister(); if (!REG_valid(ScratchReg)) { std::cerr << "Cannot allocate a scratch register.\n"; std::cerr << std::flush; return 1; } PIN_AddThreadStartFunction(ThreadStart, 0); PIN_AddThreadFiniFunction(ThreadFini, 0); PIN_AddFiniFunction(Fini, 0); TRACE_AddInstrumentFunction(Trace, 0); PIN_StartProgram(); return 0; }
// argc, argv are the entire command line, including pin -t <toolname> -- ... int main(int argc, char * argv[]) { // Initialize pin PIN_Init(argc, argv); if (KnobLog) { out = fopen("emu_stack.txt", "w"); if (!out) fprintf(stderr, "Can't open log file emu_stack.txt\n"); } scratchReg = PIN_ClaimToolRegister(); if (!REG_valid(scratchReg)) { if (out) fprintf (out, "Cannot allocate a scratch register.\n"); fprintf (stderr, "Cannot allocate a scratch register.\n"); return 1; } // Register instruction instrumentation callback. INS_AddInstrumentFunction(Ins, 0); // Register Fini to be called when the application exits PIN_AddFiniFunction(Fini, 0); // Start the program, never returns PIN_StartProgram(); return 0; }
VOID WriteMem(UINT32 insAddr, std::string insDis, UINT32 opCount, REG reg_r, UINT32 memOp, UINT32 sp) { list<UINT32>::iterator i; list<struct mallocArea>::iterator i2; UINT32 addr = memOp; if (opCount != 2) return; for(i2 = mallocAreaList.begin(); i2 != mallocAreaList.end(); i2++){ if (addr >= i2->base && addr < (i2->base + i2->size) && i2->status == FREE){ std::cout << std::hex << "[UAF in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; return; } } for(i = addressTainted.begin(); i != addressTainted.end(); i++){ if (addr == *i){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; if (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r)) removeMemTainted(addr); if (sp > addr && addr > 0x700000000000) std::cout << std::hex << "[UAF in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; return ; } } if (checkAlreadyRegTainted(reg_r)){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; addMemTainted(addr); } }
int main(int argc, char *argv[]) { if (PIN_Init(argc, argv)) return Usage(); if (PIN_GetDebugStatus() == DEBUG_STATUS_DISABLED) { std::cerr << "Application level debugging must be enabled to use this tool.\n"; std::cerr << "Start Pin with either -appdebug or -appdebug_enable.\n"; std::cerr << std::flush; return 1; } if (!KnobOut.Value().empty()) Output = new std::ofstream(KnobOut.Value().c_str()); // Allocate a virtual register that each thread uses to point to its // TINFO data. Threads can use this virtual register to quickly access // their own thread-private data. // RegTinfo = PIN_ClaimToolRegister(); if (!REG_valid(RegTinfo)) { std::cerr << "Cannot allocate a scratch register.\n"; std::cerr << std::flush; return 1; } PIN_AddDebugInterpreter(DebugInterpreter, 0); PIN_AddThreadStartFunction(OnThreadStart, 0); PIN_AddThreadFiniFunction(OnThreadEnd, 0); PIN_StartProgram(); return 0; }
// There is no verification on the validity of the ID. uint64 PINContextHandler::getRegisterValue(uint64 TritRegID) const { REG reg = safecast(PINConverter::convertTritonReg2DBIReg(TritRegID)); if (!REG_valid(reg) || (TritRegID >= ID_XMM0 && TritRegID <= ID_XMM15)) throw std::runtime_error("Error: getRegisterValue() - Invalid PIN register id."); return PIN_GetContextReg(this->_ctx, reg); }
VOID followData(UINT32 insAddr, std::string insDis, REG reg) { if (!REG_valid(reg)) return; if (checkAlreadyRegTainted(reg)){ std::cout << "[FOLLOW]\t\t" << insAddr << ": " << insDis << std::endl; } }
VOID spreadRegTaint(UINT32 insAddr, std::string insDis, UINT32 opCount, REG reg_r, REG reg_w) { if (opCount != 2) return; if (REG_valid(reg_w)){ if (checkAlreadyRegTainted(reg_w) && (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r))){ std::cout << "[SPREAD]\t\t" << insAddr << ": " << insDis << std::endl; std::cout << "\t\t\toutput: "<< REG_StringShort(reg_w) << " | input: " << (REG_valid(reg_r) ? REG_StringShort(reg_r) : "constant") << std::endl; removeRegTainted(reg_w); } else if (!checkAlreadyRegTainted(reg_w) && checkAlreadyRegTainted(reg_r)){ std::cout << "[SPREAD]\t\t" << insAddr << ": " << insDis << std::endl; std::cout << "\t\t\toutput: " << REG_StringShort(reg_w) << " | input: "<< REG_StringShort(reg_r) << std::endl; taintReg(reg_w); } } }
// There is no verification on the validity of the ID. void PINContextHandler::setRegisterValue(uint64 TritRegID, uint64 value) const { REG reg = safecast(PINConverter::convertTritonReg2DBIReg(TritRegID)); if (!REG_valid(reg) || (TritRegID >= ID_XMM0 && TritRegID <= ID_XMM15)) throw std::runtime_error("Error: setRegisterValue() - Invalid PIN register id."); PIN_SetContextReg(this->_ctx, reg, value); PIN_ExecuteAt(this->_ctx); }
PyObject* Python_REG_valid(PyObject* self, PyObject* args) { PyObject* reg; PyArg_ParseTuple(args, "L", ®); REG reg_object = *(REG*) reg; if (REG_valid(reg_object)) { return Py_BuildValue("O", Py_True); } else { return Py_BuildValue("O", Py_False); } }
VOID spreadRegTaint(INS ins) { REG reg_r, reg_w; if (INS_OperandCount(ins) != 2) return; reg_r = INS_RegR(ins, 0); reg_w = INS_RegW(ins, 0); if (REG_valid(reg_w)){ if (checkAlreadyRegTainted(reg_w) && (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r))){ std::cout << "[SPREAD]\t\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; std::cout << "\t\t\toutput: "<< REG_StringShort(reg_w) << " | input: " << (REG_valid(reg_r) ? REG_StringShort(reg_r) : "constant") << std::endl; removeRegTainted(reg_w); } else if (!checkAlreadyRegTainted(reg_w) && checkAlreadyRegTainted(reg_r)){ std::cout << "[SPREAD]\t\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; std::cout << "\t\t\toutput: " << REG_StringShort(reg_w) << " | input: "<< REG_StringShort(reg_r) << std::endl; taintReg(reg_w); } } }
// There is no verification on the validity of the ID. uint128 PINContextHandler::getSSERegisterValue(uint64 TritRegID) const { REG reg = safecast(PINConverter::convertTritonReg2DBIReg(TritRegID)); uint128 value = 0; PIN_REGISTER tmp; if (!REG_valid(reg) || !(TritRegID >= ID_XMM0 && TritRegID <= ID_XMM15)) throw std::runtime_error("Error: getSSERegisterValue() - Invalid PIN register id."); PIN_GetContextRegval(this->_ctx, reg, reinterpret_cast<uint8 *>(&tmp)); value = *reinterpret_cast<uint128*>(&tmp); return value; }
// There is no verification on the validity of the ID. void PINContextHandler::setSSERegisterValue(uint64 TritRegID, uint128 value) const { REG reg = safecast(PINConverter::convertTritonReg2DBIReg(TritRegID)); unsigned char *tmp = (unsigned char*)malloc(16); if (tmp == nullptr) throw std::runtime_error("Error: setSSERegisterValue() - Not enough memory."); if (!REG_valid(reg) || !(TritRegID >= ID_XMM0 && TritRegID <= ID_XMM15)) throw std::runtime_error("Error: setSSERegisterValue() - Invalid PIN register id."); *(uint128 *)tmp = value; PIN_SetContextRegval(this->_ctx, reg, tmp); PIN_ExecuteAt(this->_ctx); free(tmp); }
int main(int argc, char **argv) { PIN_Init(argc, argv); PIN_InitSymbols(); scratchReg = PIN_ClaimToolRegister(); if (!REG_valid(scratchReg)) { fprintf (stderr, "Cannot allocate a scratch register.\n"); return 1; } PIN_AddThreadStartFunction(OnThread, 0); IMG_AddInstrumentFunction(Image, 0); PIN_StartProgram(); return 0; }
VOID WriteMem(UINT64 insAddr, std::string insDis, UINT32 opCount, REG reg_r, UINT64 memOp) { list<UINT64>::iterator i; UINT64 addr = memOp; if (opCount != 2) return; for(i = addressTainted.begin(); i != addressTainted.end(); i++){ if (addr == *i){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; if (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r)) removeMemTainted(addr); return ; } } if (checkAlreadyRegTainted(reg_r)){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; addMemTainted(addr); } }
VOID WriteMem(INS ins, UINT64 memOp) { list<UINT64>::iterator i; UINT64 addr = memOp; REG reg_r; if (INS_OperandCount(ins) != 2) return; reg_r = INS_OperandReg(ins, 1); for(i = addressTainted.begin(); i != addressTainted.end(); i++){ if (addr == *i){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; if (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r)) removeMemTainted(addr); return ; } } if (checkAlreadyRegTainted(reg_r)){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; addMemTainted(addr); } }
VOID instrument_reg(INS ins, ins_buffer_entry* e){ UINT32 i, maxNumRegsProd, maxNumRegsCons, regReadCnt, regWriteCnt, opCnt, regOpCnt; REG reg; if(!e->setRead){ maxNumRegsCons = INS_MaxNumRRegs(ins); // maximum number of register consumations (reads) regReadCnt = 0; for(i = 0; i < maxNumRegsCons; i++){ // finding all register operands which are read reg = INS_RegR(ins,i); //assert(((UINT32)reg) < MAX_NUM_REGS); /* only consider valid general-purpose registers (any bit-width) and floating-point registers, * i.e. exlude branch, segment and pin registers, among others */ if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){ regReadCnt++; } } e->regReadCnt = regReadCnt; e->regsRead = (REG*) checked_malloc(regReadCnt*sizeof(REG)); regReadCnt = 0; for(i = 0; i < maxNumRegsCons; i++){ // finding all register operands which are read reg = INS_RegR(ins,i); //assert(((UINT32)reg) < MAX_NUM_REGS); /* only consider valid general-purpose registers (any bit-width) and floating-point registers, * i.e. exlude branch, segment and pin registers, among others */ if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){ e->regsRead[regReadCnt++] = reg; } } e->setRead = true; } if(!e->setWritten){ maxNumRegsProd = INS_MaxNumWRegs(ins); regWriteCnt = 0; for(i=0; i < maxNumRegsProd; i++){ reg = INS_RegW(ins, i); //assert(((UINT32)reg) < MAX_NUM_REGS); /* only consider valid general-purpose registers (any bit-width) and floating-point registers, * i.e. exlude branch, segment and pin registers, among others */ if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){ regWriteCnt++; } } e->regWriteCnt = regWriteCnt; e->regsWritten = (REG*)checked_malloc(regWriteCnt*sizeof(REG)); regWriteCnt = 0; for(i=0; i < maxNumRegsProd; i++){ reg = INS_RegW(ins, i); //assert(((UINT32)reg) < MAX_NUM_REGS); /* only consider valid general-purpose registers (any bit-width) and floating-point registers, * i.e. exlude branch, segment and pin registers, among others */ if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){ e->regsWritten[regWriteCnt++] = reg; } } e->setWritten = true; } if(!e->setRegOpCnt){ regOpCnt = 0; opCnt = INS_OperandCount(ins); for(i = 0; i < opCnt; i++){ if(INS_OperandIsReg(ins,i)) regOpCnt++; } /*if(regOpCnt >= MAX_NUM_OPER){ cerr << "BOOM! -> MAX_NUM_OPER is exceeded! (" << regOpCnt << ")" << endl; exit(1); }*/ e->regOpCnt = regOpCnt; e->setRegOpCnt = true; } if(interval_size == -1){ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_full, IARG_PTR, (void*)e, IARG_END); } else{ INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_intervals, IARG_PTR, (void*)e, IARG_END); /* only called if interval is full */ INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_interval, IARG_END); } }
// Returns a pointer to an IRBuilder object. // It is up to the user to delete it when times come. IRBuilder *createIRBuilder(INS ins) { uint64 address = INS_Address(ins); std::string disas = INS_Disassemble(ins); INT32 opcode = INS_Opcode(ins); IRBuilder *ir = nullptr; switch (opcode) { case XED_ICLASS_ADC: ir = new AdcIRBuilder(address, disas); break; case XED_ICLASS_ADD: ir = new AddIRBuilder(address, disas); break; case XED_ICLASS_AND: ir = new AndIRBuilder(address, disas); break; case XED_ICLASS_ANDNPD: ir = new AndnpdIRBuilder(address, disas); break; case XED_ICLASS_ANDNPS: ir = new AndnpsIRBuilder(address, disas); break; case XED_ICLASS_ANDPD: ir = new AndpdIRBuilder(address, disas); break; case XED_ICLASS_ANDPS: ir = new AndpsIRBuilder(address, disas); break; case XED_ICLASS_BSWAP: ir = new BswapIRBuilder(address, disas); break; case XED_ICLASS_CALL_FAR: case XED_ICLASS_CALL_NEAR: ir = new CallIRBuilder(address, disas); break; case XED_ICLASS_CBW: ir = new CbwIRBuilder(address, disas); break; case XED_ICLASS_CDQE: ir = new CdqeIRBuilder(address, disas); break; case XED_ICLASS_CLC: ir = new ClcIRBuilder(address, disas); break; case XED_ICLASS_CLD: ir = new CldIRBuilder(address, disas); break; case XED_ICLASS_CMC: ir = new CmcIRBuilder(address, disas); break; case XED_ICLASS_CMOVB: ir = new CmovbIRBuilder(address, disas); break; case XED_ICLASS_CMOVBE: ir = new CmovbeIRBuilder(address, disas); break; case XED_ICLASS_CMOVL: ir = new CmovlIRBuilder(address, disas); break; case XED_ICLASS_CMOVLE: ir = new CmovleIRBuilder(address, disas); break; case XED_ICLASS_CMOVNB: ir = new CmovnbIRBuilder(address, disas); break; case XED_ICLASS_CMOVNBE: ir = new CmovnbeIRBuilder(address, disas); break; case XED_ICLASS_CMOVNL: ir = new CmovnlIRBuilder(address, disas); break; case XED_ICLASS_CMOVNLE: ir = new CmovnleIRBuilder(address, disas); break; case XED_ICLASS_CMOVNO: ir = new CmovnoIRBuilder(address, disas); break; case XED_ICLASS_CMOVNP: ir = new CmovnpIRBuilder(address, disas); break; case XED_ICLASS_CMOVNS: ir = new CmovnsIRBuilder(address, disas); break; case XED_ICLASS_CMOVNZ: ir = new CmovnzIRBuilder(address, disas); break; case XED_ICLASS_CMOVO: ir = new CmovoIRBuilder(address, disas); break; case XED_ICLASS_CMOVP: ir = new CmovpIRBuilder(address, disas); break; case XED_ICLASS_CMOVS: ir = new CmovsIRBuilder(address, disas); break; case XED_ICLASS_CMOVZ: ir = new CmovzIRBuilder(address, disas); break; case XED_ICLASS_CMP: ir = new CmpIRBuilder(address, disas); break; case XED_ICLASS_CQO: ir = new CqoIRBuilder(address, disas); break; case XED_ICLASS_CWDE: ir = new CwdeIRBuilder(address, disas); break; case XED_ICLASS_DEC: ir = new DecIRBuilder(address, disas); break; case XED_ICLASS_DIV: ir = new DivIRBuilder(address, disas); break; case XED_ICLASS_IDIV: ir = new IdivIRBuilder(address, disas); break; case XED_ICLASS_IMUL: ir = new ImulIRBuilder(address, disas); break; case XED_ICLASS_INC: ir = new IncIRBuilder(address, disas); break; case XED_ICLASS_JB: ir = new JbIRBuilder(address, disas); break; case XED_ICLASS_JBE: ir = new JbIRBuilder(address, disas); break; case XED_ICLASS_JL: ir = new JlIRBuilder(address, disas); break; case XED_ICLASS_JLE: ir = new JleIRBuilder(address, disas); break; case XED_ICLASS_JMP: ir = new JmpIRBuilder(address, disas); break; case XED_ICLASS_JNB: ir = new JnbIRBuilder(address, disas); break; case XED_ICLASS_JNBE: ir = new JnbeIRBuilder(address, disas); break; case XED_ICLASS_JNL: ir = new JnlIRBuilder(address, disas); break; case XED_ICLASS_JNLE: ir = new JnleIRBuilder(address, disas); break; case XED_ICLASS_JNO: ir = new JnoIRBuilder(address, disas); break; case XED_ICLASS_JNP: ir = new JnpIRBuilder(address, disas); break; case XED_ICLASS_JNS: ir = new JnsIRBuilder(address, disas); break; case XED_ICLASS_JNZ: ir = new JnzIRBuilder(address, disas); break; case XED_ICLASS_JO: ir = new JoIRBuilder(address, disas); break; case XED_ICLASS_JP: ir = new JpIRBuilder(address, disas); break; case XED_ICLASS_JS: ir = new JsIRBuilder(address, disas); break; case XED_ICLASS_JZ: ir = new JzIRBuilder(address, disas); break; case XED_ICLASS_LEA: ir = new LeaIRBuilder(address, disas); break; case XED_ICLASS_LEAVE: ir = new LeaveIRBuilder(address, disas); break; case XED_ICLASS_MOV: ir = new MovIRBuilder(address, disas); break; case XED_ICLASS_MOVAPD: ir = new MovapdIRBuilder(address, disas); break; case XED_ICLASS_MOVAPS: ir = new MovapsIRBuilder(address, disas); break; case XED_ICLASS_MOVDQA: ir = new MovdqaIRBuilder(address, disas); break; case XED_ICLASS_MOVDQU: ir = new MovdquIRBuilder(address, disas); break; case XED_ICLASS_MOVHLPS: ir = new MovhlpsIRBuilder(address, disas); break; case XED_ICLASS_MOVHPD: ir = new MovhpdIRBuilder(address, disas); break; case XED_ICLASS_MOVHPS: ir = new MovhpsIRBuilder(address, disas); break; case XED_ICLASS_MOVLHPS: ir = new MovlhpsIRBuilder(address, disas); break; case XED_ICLASS_MOVLPD: ir = new MovlpdIRBuilder(address, disas); break; case XED_ICLASS_MOVLPS: ir = new MovlpsIRBuilder(address, disas); break; case XED_ICLASS_MOVSX: case XED_ICLASS_MOVSXD: ir = new MovsxIRBuilder(address, disas); break; case XED_ICLASS_MOVZX: ir = new MovzxIRBuilder(address, disas); break; case XED_ICLASS_MUL: ir = new MulIRBuilder(address, disas); break; case XED_ICLASS_NEG: ir = new NegIRBuilder(address, disas); break; case XED_ICLASS_NOT: ir = new NotIRBuilder(address, disas); break; case XED_ICLASS_OR: ir = new OrIRBuilder(address, disas); break; case XED_ICLASS_ORPD: ir = new OrpdIRBuilder(address, disas); break; case XED_ICLASS_ORPS: ir = new OrpsIRBuilder(address, disas); break; case XED_ICLASS_POP: ir = new PopIRBuilder(address, disas); break; case XED_ICLASS_PUSH: ir = new PushIRBuilder(address, disas); break; case XED_ICLASS_RET_FAR: case XED_ICLASS_RET_NEAR: ir = new RetIRBuilder(address, disas); break; case XED_ICLASS_ROL: ir = new RolIRBuilder(address, disas); break; case XED_ICLASS_ROR: ir = new RorIRBuilder(address, disas); break; case XED_ICLASS_SAR: ir = new SarIRBuilder(address, disas); break; case XED_ICLASS_SBB: ir = new SbbIRBuilder(address, disas); break; case XED_ICLASS_SETB: ir = new SetbIRBuilder(address, disas); break; case XED_ICLASS_SETBE: ir = new SetbeIRBuilder(address, disas); break; case XED_ICLASS_SETL: ir = new SetlIRBuilder(address, disas); break; case XED_ICLASS_SETLE: ir = new SetleIRBuilder(address, disas); break; case XED_ICLASS_SETNB: ir = new SetnbIRBuilder(address, disas); break; case XED_ICLASS_SETNBE: ir = new SetnbeIRBuilder(address, disas); break; case XED_ICLASS_SETNL: ir = new SetnlIRBuilder(address, disas); break; case XED_ICLASS_SETNLE: ir = new SetnleIRBuilder(address, disas); break; case XED_ICLASS_SETNO: ir = new SetnoIRBuilder(address, disas); break; case XED_ICLASS_SETNP: ir = new SetnpIRBuilder(address, disas); break; case XED_ICLASS_SETNS: ir = new SetnsIRBuilder(address, disas); break; case XED_ICLASS_SETNZ: ir = new SetnzIRBuilder(address, disas); break; case XED_ICLASS_SETO: ir = new SetoIRBuilder(address, disas); break; case XED_ICLASS_SETP: ir = new SetpIRBuilder(address, disas); break; case XED_ICLASS_SETS: ir = new SetsIRBuilder(address, disas); break; case XED_ICLASS_SETZ: ir = new SetzIRBuilder(address, disas); break; case XED_ICLASS_SHL: // XED_ICLASS_SAL is also a SHL ir = new ShlIRBuilder(address, disas); break; case XED_ICLASS_SHR: ir = new ShrIRBuilder(address, disas); break; case XED_ICLASS_STC: ir = new StcIRBuilder(address, disas); break; case XED_ICLASS_STD: ir = new StdIRBuilder(address, disas); break; case XED_ICLASS_SUB: ir = new SubIRBuilder(address, disas); break; case XED_ICLASS_TEST: ir = new TestIRBuilder(address, disas); break; case XED_ICLASS_XADD: ir = new XaddIRBuilder(address, disas); break; case XED_ICLASS_XCHG: ir = new XchgIRBuilder(address, disas); break; case XED_ICLASS_XOR: ir = new XorIRBuilder(address, disas); break; case XED_ICLASS_XORPD: ir = new XorpdIRBuilder(address, disas); break; case XED_ICLASS_XORPS: ir = new XorpsIRBuilder(address, disas); break; default: ir = new NullIRBuilder(address, disas); break; } // Populate the operands const uint32 n = INS_OperandCount(ins); for (uint32 i = 0; i < n; ++i) { IRBuilderOperand::operand_t type; uint32 size = 0; uint64 val = 0; //Effective address = Displacement + BaseReg + IndexReg * Scale uint64 displacement = 0; uint64 baseReg = ID_INVALID; uint64 indexReg = ID_INVALID; uint64 memoryScale = 0; /* Special case */ if (INS_IsDirectBranchOrCall(ins)){ ir->addOperand(TritonOperand(IRBuilderOperand::IMM, INS_DirectBranchOrCallTargetAddress(ins), 0)); if (INS_MemoryOperandIsWritten(ins, 0)) ir->addOperand(TritonOperand(IRBuilderOperand::MEM_W, 0, INS_MemoryWriteSize(ins))); break; } /* Immediate */ if (INS_OperandIsImmediate(ins, i)) { type = IRBuilderOperand::IMM; val = INS_OperandImmediate(ins, i); } /* Register */ else if (INS_OperandIsReg(ins, i)) { type = IRBuilderOperand::REG; REG reg = INS_OperandReg(ins, i); val = PINConverter::convertDBIReg2TritonReg(reg); // store the register ID. if (REG_valid(reg)) { // check needed because instructions like "xgetbv 0" make // REG_Size crash. size = REG_Size(reg); } } /* Memory */ else if (INS_MemoryOperandCount(ins) > 0) { /* Memory read */ if (INS_MemoryOperandIsRead(ins, 0)) { type = IRBuilderOperand::MEM_R; size = INS_MemoryReadSize(ins); } /* Memory write */ else { type = IRBuilderOperand::MEM_W; size = INS_MemoryWriteSize(ins); } } /* load effective address instruction */ else if (INS_OperandIsAddressGenerator(ins, i)) { REG reg; type = IRBuilderOperand::LEA; displacement = INS_OperandMemoryDisplacement(ins, i); memoryScale = INS_OperandMemoryScale(ins, i); reg = INS_OperandMemoryBaseReg(ins, i); if (REG_valid(reg)) baseReg = PINConverter::convertDBIReg2TritonReg(reg); reg = INS_OperandMemoryIndexReg(ins, i); if (REG_valid(reg)) indexReg = PINConverter::convertDBIReg2TritonReg(reg); } /* Undefined */ else { // std::cout << "[DEBUG] Unknown kind of operand: " << INS_Disassemble(ins) << std::endl; continue; } ir->addOperand(TritonOperand(type, val, size, displacement, baseReg, indexReg, memoryScale)); } // Setup the opcode in the IRbuilder ir->setOpcode(opcode); ir->setOpcodeCategory(INS_Category(ins)); ir->setNextAddress(INS_NextAddress(ins)); return ir; }