static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg) { const cs_x86 & x86 = cp.x86(); const cs_x86_op & op = x86.operands[opindex]; arg->segment = SEG_DEFAULT; strcpy_s(arg->mnemonic, cp.OperandText(opindex).c_str()); switch(op.type) { case X86_OP_REG: { const char* regname = cp.RegName((x86_reg)op.reg); arg->type = arg_normal; uint value; if(!valfromstring(regname, &value, true, true)) value = 0; arg->constant = arg->value = value; } break; case X86_OP_IMM: { arg->type = arg_normal; arg->constant = arg->value = (duint)op.imm; } break; case X86_OP_MEM: { arg->type = arg_memory; const x86_op_mem & mem = op.mem; if(mem.base == X86_REG_RIP) //rip-relative arg->constant = cp.Address() + (duint)mem.disp + cp.Size(); else arg->constant = (duint)mem.disp; uint value; if(!valfromstring(arg->mnemonic, &value, true, true)) return; arg->value = value; if(DbgMemIsValidReadPtr(value)) { switch(op.size) { case 1: DbgMemRead(value, (unsigned char*)&arg->memvalue, 1); break; case 2: DbgMemRead(value, (unsigned char*)&arg->memvalue, 2); break; case 4: DbgMemRead(value, (unsigned char*)&arg->memvalue, 4); break; case 8: DbgMemRead(value, (unsigned char*)&arg->memvalue, 8); break; } } } break; } }
bool cbInstrAssemble(int argc, char* argv[]) { if(IsArgumentsLessThan(argc, 3)) return false; duint addr = 0; if(!valfromstring(argv[1], &addr)) { dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid expression: \"%s\"!\n"), argv[1]); return false; } if(!DbgMemIsValidReadPtr(addr)) { dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address: %p!\n"), addr); return false; } bool fillnop = false; if(argc > 3) fillnop = true; char error[MAX_ERROR_SIZE] = ""; int size = 0; if(!assembleat(addr, argv[2], &size, error, fillnop)) { varset("$result", size, false); dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to assemble \"%s\" (%s)\n"), argv[2], error); return false; } varset("$result", size, false); GuiUpdateAllViews(); return true; }
void ValidateExpressionThread::run() { while(!mStopThread) { mExpressionMutex.lock(); QString expression = mExpressionText; bool changed = mExpressionChanged; mExpressionChanged = false; mExpressionMutex.unlock(); if(changed) { duint value; bool validExpression = DbgFunctions()->ValFromString(expression.toUtf8().constData(), &value); bool validPointer = validExpression && DbgMemIsValidReadPtr(value); emit expressionChanged(validExpression, validPointer, value); } Sleep(50); } mStopThread = false; }
extern "C" DLL_EXPORT uint _dbg_getbranchdestination(uint addr) { DISASM_INSTR instr; memset(&instr, 0, sizeof(instr)); disasmget(addr, &instr); if(instr.type != instr_branch) return 0; if(strstr(instr.instruction, "ret")) { uint atcsp = DbgValFromString("@csp"); if(DbgMemIsValidReadPtr(atcsp)) return atcsp; else return 0; } else if(instr.arg[0].type == arg_memory) return instr.arg[0].memvalue; else return instr.arg[0].value; }
// FIXME required size of arg _text_? BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text) //(module.)+label { if(!text || !addr) return false; ADDRINFO info; memset(&info, 0, sizeof(info)); info.flags = flaglabel; if(!_dbg_addrinfoget(addr, segment, &info)) { duint addr_ = 0; if(!DbgMemIsValidReadPtr(addr)) return false; DbgMemRead(addr, (unsigned char*)&addr_, sizeof(duint)); ADDRINFO ptrinfo = info; if(!_dbg_addrinfoget(addr_, SEG_DEFAULT, &ptrinfo)) return false; sprintf_s(info.label, "&%s", ptrinfo.label); } strcpy_s(text, MAX_LABEL_SIZE, info.label); return true; }
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; }