Skip to content

Commit 81fd61c

Browse files
committed
Display the absolute address for relative jumps on x86
yaxpeax doesn't have support for doing this natively so just shim it on top.
1 parent d4b3fa2 commit 81fd61c

File tree

2 files changed

+61
-14
lines changed

2 files changed

+61
-14
lines changed

‎fixtures/snapshots/asm_x86_64.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"startAddress":"0x17a20","size":"0x3d","arch":"x86_64","syntax":["Intel","C style"],"instructions":[[0,"jl $-0x64","if /* signed */ less(rflags) then jmp $-0x64"],[2,"add eax, dword [rax]","eax += [rax]"],[4,"mov edx, 0x38","edx = 0x38"],[9,"mov rcx, r15","rcx = r15"],[12,"call 0x39c6f","0x39c6f = call(0x39c6f)"],[17,"xor eax, eax","eax ^= eax"],[19,"jmp $+0x9a","jmp $+0x9a"],[24,"mov rbx, qword [r15]","rbx = [r15]"],[27,"cmp rbx, rax","rflags = flags(rbx - rax)"],[30,"jz $+0x35","if zero(rflags) then jmp $+0x35"],[32,"mov rdx, qword [r15 + 0x8]","rdx = [r15 + 0x8]"],[36,"mov qword [rdx], rbx","[rdx] = rbx"],[39,"mov rdx, qword [rbx + 0x8]","rdx = [rbx + 0x8]"],[43,"mov qword [rdx], rax","[rdx] = rax"],[46,"mov rdx, qword [rax + 0x8]","rdx = [rax + 0x8]"],[50,"mov qword [rdx], r15","[rdx] = r15"],[53,"mov rdx, qword [rax + 0x8]","rdx = [rax + 0x8]"],[57,"mov rbp, qword [rbx + 0x8]","rbp = [rbx + 0x8]"]]}
1+
{"startAddress":"0x17a20","size":"0x3d","arch":"x86_64","syntax":["Intel","C style"],"instructions":[[0,"jl 0x179be","jl 0x179be"],[2,"add eax, dword [rax]","eax += [rax]"],[4,"mov edx, 0x38","edx = 0x38"],[9,"mov rcx, r15","rcx = r15"],[12,"call 0x39c6f","0x39c6f = call(0x39c6f)"],[17,"xor eax, eax","eax ^= eax"],[19,"jmp 0x17ad2","jmp 0x17ad2"],[24,"mov rbx, qword [r15]","rbx = [r15]"],[27,"cmp rbx, rax","rflags = flags(rbx - rax)"],[30,"jz 0x17a75","jz 0x17a75"],[32,"mov rdx, qword [r15 + 0x8]","rdx = [r15 + 0x8]"],[36,"mov qword [rdx], rbx","[rdx] = rbx"],[39,"mov rdx, qword [rbx + 0x8]","rdx = [rbx + 0x8]"],[43,"mov qword [rdx], rax","[rdx] = rax"],[46,"mov rdx, qword [rax + 0x8]","rdx = [rax + 0x8]"],[50,"mov qword [rdx], r15","[rdx] = r15"],[53,"mov rdx, qword [rax + 0x8]","rdx = [rax + 0x8]"],[57,"mov rbp, qword [rbx + 0x8]","rbp = [rbx + 0x8]"]]}

‎samply-api/src/asm/mod.rs

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use samply_symbols::{
55
FileAndPathHelperError, LibraryInfo, SymbolManager,
66
};
77
use serde_json::json;
8-
use yaxpeax_arch::{Arch, DecodeError, Reader, U8Reader};
8+
use yaxpeax_arch::{Arch, DecodeError, LengthedInstruction, Reader, U8Reader};
9+
use yaxpeax_x86::amd64::{Opcode, Operand};
910

1011
use crate::asm::response_json::DecodedInstruction;
1112

@@ -192,7 +193,7 @@ trait InstructionDecoding: Arch {
192193
const SYNTAX: &'static [&'static str];
193194
const ADJUST_BY_AFTER_ERROR: usize;
194195
fn make_decoder() -> Self::Decoder;
195-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction;
196+
fn stringify_inst(rel_address: u32, offset: u32, inst: Self::Instruction) -> DecodedInstruction;
196197
}
197198

198199
impl InstructionDecoding for yaxpeax_x86::amd64::Arch {
@@ -204,15 +205,61 @@ impl InstructionDecoding for yaxpeax_x86::amd64::Arch {
204205
yaxpeax_x86::amd64::InstDecoder::default()
205206
}
206207

207-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction {
208+
fn stringify_inst(rel_address: u32, offset: u32, inst: Self::Instruction) -> DecodedInstruction {
209+
let (mut intel_insn, mut c_insn) = (
210+
inst.display_with(yaxpeax_x86::amd64::DisplayStyle::Intel)
211+
.to_string(),
212+
inst.display_with(yaxpeax_x86::amd64::DisplayStyle::C)
213+
.to_string(),
214+
);
215+
216+
fn is_relative_branch(opcode: Opcode) -> bool {
217+
match opcode {
218+
Opcode::JMP
219+
| Opcode::JRCXZ
220+
| Opcode::LOOP
221+
| Opcode::LOOPZ
222+
| Opcode::LOOPNZ
223+
| Opcode::JO
224+
| Opcode::JNO
225+
| Opcode::JB
226+
| Opcode::JNB
227+
| Opcode::JZ
228+
| Opcode::JNZ
229+
| Opcode::JNA
230+
| Opcode::JA
231+
| Opcode::JS
232+
| Opcode::JNS
233+
| Opcode::JP
234+
| Opcode::JNP
235+
| Opcode::JL
236+
| Opcode::JGE
237+
| Opcode::JLE
238+
| Opcode::JG => true,
239+
_ => false,
240+
}
241+
}
242+
243+
if is_relative_branch(inst.opcode()) {
244+
match inst.operand(0) {
245+
Operand::ImmediateI8(rel) => {
246+
let dest = rel_address as i64 + offset as i64 + inst.len().to_const() as i64 + rel as i64;
247+
intel_insn = format!("{} 0x{:x}", inst.opcode(), dest);
248+
c_insn = intel_insn.clone();
249+
}
250+
Operand::ImmediateI32(rel) => {
251+
let dest = rel_address as i64 + offset as i64 + inst.len().to_const() as i64 + rel as i64;
252+
intel_insn = format!("{} 0x{:x}", inst.opcode(), dest);
253+
c_insn = intel_insn.clone();
254+
}
255+
_ => {
256+
}
257+
};
258+
}
259+
208260
DecodedInstruction {
209261
offset,
210-
decoded_string_per_syntax: vec![
211-
inst.display_with(yaxpeax_x86::amd64::DisplayStyle::Intel)
212-
.to_string(),
213-
inst.display_with(yaxpeax_x86::amd64::DisplayStyle::C)
214-
.to_string(),
215-
],
262+
decoded_string_per_syntax: vec![intel_insn, c_insn],
216263
}
217264
}
218265
}
@@ -226,7 +273,7 @@ impl InstructionDecoding for yaxpeax_x86::protected_mode::Arch {
226273
yaxpeax_x86::protected_mode::InstDecoder::default()
227274
}
228275

229-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction {
276+
fn stringify_inst(_rel_address: u32, offset: u32, inst: Self::Instruction) -> DecodedInstruction {
230277
DecodedInstruction {
231278
offset,
232279
decoded_string_per_syntax: vec![inst.to_string()],
@@ -243,7 +290,7 @@ impl InstructionDecoding for yaxpeax_arm::armv8::a64::ARMv8 {
243290
yaxpeax_arm::armv8::a64::InstDecoder::default()
244291
}
245292

246-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction {
293+
fn stringify_inst(_rel_address: u32, offset: u32, inst: Self::Instruction) -> DecodedInstruction {
247294
DecodedInstruction {
248295
offset,
249296
decoded_string_per_syntax: vec![inst.to_string()],
@@ -271,7 +318,7 @@ impl InstructionDecoding for yaxpeax_arm::armv7::ARMv7 {
271318
yaxpeax_arm::armv7::InstDecoder::default_thumb()
272319
}
273320

274-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction {
321+
fn stringify_inst(_rel_address: u32, offset: u32, inst: Self::Instruction) -> DecodedInstruction {
275322
DecodedInstruction {
276323
offset,
277324
decoded_string_per_syntax: vec![inst.to_string()],
@@ -300,7 +347,7 @@ where
300347
let before = u64::from(reader.total_offset()) as u32;
301348
match decoder.decode(&mut reader) {
302349
Ok(inst) => {
303-
instructions.push(A::stringify_inst(offset, inst));
350+
instructions.push(A::stringify_inst(rel_address, offset, inst));
304351
let after = u64::from(reader.total_offset()) as u32;
305352
offset += after - before;
306353
}

0 commit comments

Comments
 (0)