コード例 #1
0
/******************************************************************
 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;
}
コード例 #2
0
ファイル: regmix.cpp プロジェクト: alagenchev/school_code
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;
}
コード例 #3
0
// 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;
}
コード例 #4
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;
}
コード例 #5
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;
}
コード例 #6
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);
  }
}
コード例 #7
0
ファイル: own_gdb_cmds.cpp プロジェクト: hexgolems/schem
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;
}
コード例 #8
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);
}
コード例 #9
0
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;
  }
}
コード例 #10
0
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);
    }
  }
}
コード例 #11
0
// 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);
}
コード例 #12
0
ファイル: REG.cpp プロジェクト: ancat/python-pin
PyObject* Python_REG_valid(PyObject* self, PyObject* args) {
    PyObject* reg;
    PyArg_ParseTuple(args, "L", &reg);

    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);
    }
  }
}
コード例 #14
0
// 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;
}
コード例 #15
0
// 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);
}
コード例 #16
0
ファイル: callapp9.cpp プロジェクト: alagenchev/school_code
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;
}
コード例 #17
0
ファイル: example3.cpp プロジェクト: cl-wood/stubble
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);
  }
}
コード例 #19
0
ファイル: mica_reg.cpp プロジェクト: Caian/MICA
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);
	}
}
コード例 #20
0
// 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;
}