bool CapstoneTokenizer::tokenizeRegOperand(const cs_x86_op & op) { auto registerType = TokenType::GeneralRegister; auto reg = op.reg; if(reg >= X86_REG_FP0 && reg <= X86_REG_FP7) registerType = TokenType::FpuRegister; else if(reg >= X86_REG_ST0 && reg <= X86_REG_ST7) registerType = TokenType::FpuRegister; else if(reg >= X86_REG_MM0 && reg <= X86_REG_MM7) registerType = TokenType::MmxRegister; else if(reg >= X86_REG_XMM0 && reg <= X86_REG_XMM31) registerType = TokenType::XmmRegister; else if(reg >= X86_REG_YMM0 && reg <= X86_REG_YMM31) registerType = TokenType::YmmRegister; else if(reg >= X86_REG_ZMM0 && reg <= X86_REG_ZMM31) registerType = TokenType::ZmmRegister; addToken(registerType, _cp.RegName(x86_reg(reg))); return true; }
String Capstone::OperandText(int opindex) const { if(opindex >= mInstr->detail->x86.op_count) return ""; const auto & op = mInstr->detail->x86.operands[opindex]; String result; char temp[32] = ""; switch(op.type) { case X86_OP_REG: { result = RegName(x86_reg(op.reg)); } break; case X86_OP_IMM: { if(InGroup(CS_GRP_JUMP) || InGroup(CS_GRP_CALL) || IsLoop()) sprintf_s(temp, "%" fext "X", op.imm + mInstr->size); else sprintf_s(temp, "%" fext "X", op.imm); result = temp; } break; case X86_OP_MEM: { const auto & mem = op.mem; if(op.mem.base == X86_REG_RIP) //rip-relative { sprintf_s(temp, "%" fext "X", mInstr->address + op.mem.disp + mInstr->size); result += temp; } else //normal { bool prependPlus = false; if(mem.base) { result += RegName(x86_reg(mem.base)); prependPlus = true; } if(mem.index) { if(prependPlus) result += "+"; result += RegName(x86_reg(mem.index)); sprintf_s(temp, "*%X", mem.scale); result += temp; prependPlus = true; } if(mem.disp) { char operatorText = '+'; if(mem.disp < 0) { operatorText = '-'; sprintf_s(temp, "%" fext "X", mem.disp * -1); } else sprintf_s(temp, "%" fext "X", mem.disp); if(prependPlus) result += operatorText; result += temp; } } } break; case X86_OP_FP: case X86_OP_INVALID: { } break; } return result; }
bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op) { //memory size const char* sizeText = _cp.MemSizeName(op.size); if(!sizeText) return false; addToken(TokenType::MemorySize, QString(sizeText) + " ptr"); addToken(TokenType::Space, " "); //memory segment const auto & mem = op.mem; const char* segmentText = _cp.RegName(x86_reg(mem.segment)); if(mem.segment == X86_REG_INVALID) //segment not set { switch(x86_reg(mem.base)) { case X86_REG_ESP: case X86_REG_RSP: case X86_REG_EBP: case X86_REG_RBP: segmentText = "ss"; break; default: segmentText = "ds"; break; } } addToken(TokenType::MemorySegment, segmentText); addToken(TokenType::Uncategorized, ":"); //memory opening bracket auto bracketsType = TokenType::MemoryBrackets; switch(x86_reg(mem.base)) { case X86_REG_ESP: case X86_REG_RSP: case X86_REG_EBP: case X86_REG_RBP: bracketsType = TokenType::MemoryStackBrackets; default: break; } addToken(bracketsType, "["); //stuff inside the brackets if(mem.base == X86_REG_RIP) //rip-relative (#replacement) { duint addr = _cp.Address() + duint(mem.disp) + _cp.Size(); TokenValue value = TokenValue(op.size, addr); // TODO auto displacementType = DbgMemIsValidReadPtr(addr) ? TokenType::Address : TokenType::Value; addToken(displacementType, printValue(value, false, _maxModuleLength), value); } else //#base + #index * #scale + #displacement { bool prependPlus = false; if(mem.base != X86_REG_INVALID) //base register { addToken(TokenType::MemoryBaseRegister, _cp.RegName(x86_reg(mem.base))); prependPlus = true; } if(mem.index != X86_REG_INVALID) //index register { if(prependPlus) addMemoryOperator('+'); addToken(TokenType::MemoryIndexRegister, _cp.RegName(x86_reg(mem.index))); if(mem.scale > 1) { addMemoryOperator('*'); addToken(TokenType::MemoryScale, QString().sprintf("%d", mem.scale)); } prependPlus = true; } if(mem.disp) { char operatorText = '+'; TokenValue value(op.size, duint(mem.disp)); auto displacementType = DbgMemIsValidReadPtr(duint(mem.disp)) ? TokenType::Address : TokenType::Value; QString valueText; if(mem.disp < 0) { operatorText = '-'; valueText = printValue(TokenValue(op.size, duint(mem.disp * -1)), false, _maxModuleLength); } else valueText = printValue(value, false, _maxModuleLength); if(prependPlus) addMemoryOperator(operatorText); addToken(displacementType, valueText, value); } } //closing bracket addToken(bracketsType, "]"); return true; }