如何使用QEMU获取虚拟机中i386架构指令的操作数
Hey there! Let's figure out how to grab that target operand (like 0x400400 from your callq example) in QEMU for i386 instructions. The short answer is: there's no single "get operand" C function that works for all instructions, but you can access the value directly in QEMU's instruction decoding/translation pipeline. Here's how:
1. Understand QEMU's i386 Instruction Handling
QEMU translates x86 instructions to TCG (Tiny Code Generator) intermediate code behind the scenes. For each instruction type (like callq), there's a dedicated translation function in target/i386/translate.c. This is where operand values are calculated and processed.
2. Target the callq Instruction Specifically
For your example, the callq uses relative addressing. QEMU calculates the absolute target address by adding the relative offset to the address of the next instruction. Here's how to access this value:
- Open
target/i386/translate.cand look for thetrans_callfunction (or similar handlers for call instructions liketrans_call_nop). - Inside this function, you'll find code that computes the target address, which looks roughly like this:
Theint32_t disp = /* parsed relative offset from the instruction bytes */; target_ulong target = ctx->pc_next + disp;targetvariable here is exactly the0x400400you're after.ctx->pc_nextrefers to the address of the instruction immediately following thecallq.
3. General Approach for Other Instructions
If you need operands for other i386 instructions, follow this pattern:
- Identify the translation function for the instruction (check the opcode table in
translate.cto map opcodes to their handlers). - Inside the handler, look for variables storing resolved operand values. For immediate operands, memory addresses, or register references, these will be computed and stored either in the
DisasContextstruct (thectxvariable) or local variables within the handler.
4. Using the Disassembler (Alternative)
If you just need to disassemble instructions and extract operands for debugging or logging, leverage QEMU's built-in disassembler. Look at target/i386/disas.c and the print_insn_i386 function. You can modify or wrap this function to capture operand values instead of just printing them—for example, adding logic to parse decoded call instructions and return their target addresses.
Key Notes
- QEMU's internal APIs aren't designed as a generic "instruction operand extractor"—you'll need to work within its translation/disassembly pipeline.
- Make sure you're referencing the correct QEMU version, as code structure can vary slightly between releases.
内容的提问来源于stack exchange,提问作者William

