Skip to content

Commit 1a8461f

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 1a8461f

File tree

2 files changed

+83
-14
lines changed

2 files changed

+83
-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: 82 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,8 @@ 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)
197+
-> DecodedInstruction;
196198
}
197199

198200
impl InstructionDecoding for yaxpeax_x86::amd64::Arch {
@@ -204,15 +206,70 @@ impl InstructionDecoding for yaxpeax_x86::amd64::Arch {
204206
yaxpeax_x86::amd64::InstDecoder::default()
205207
}
206208

207-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction {
209+
fn stringify_inst(
210+
rel_address: u32,
211+
offset: u32,
212+
inst: Self::Instruction,
213+
) -> DecodedInstruction {
214+
let (mut intel_insn, mut c_insn) = (
215+
inst.display_with(yaxpeax_x86::amd64::DisplayStyle::Intel)
216+
.to_string(),
217+
inst.display_with(yaxpeax_x86::amd64::DisplayStyle::C)
218+
.to_string(),
219+
);
220+
221+
fn is_relative_branch(opcode: Opcode) -> bool {
222+
matches!(
223+
opcode,
224+
Opcode::JMP
225+
| Opcode::JRCXZ
226+
| Opcode::LOOP
227+
| Opcode::LOOPZ
228+
| Opcode::LOOPNZ
229+
| Opcode::JO
230+
| Opcode::JNO
231+
| Opcode::JB
232+
| Opcode::JNB
233+
| Opcode::JZ
234+
| Opcode::JNZ
235+
| Opcode::JNA
236+
| Opcode::JA
237+
| Opcode::JS
238+
| Opcode::JNS
239+
| Opcode::JP
240+
| Opcode::JNP
241+
| Opcode::JL
242+
| Opcode::JGE
243+
| Opcode::JLE
244+
| Opcode::JG
245+
)
246+
}
247+
248+
if is_relative_branch(inst.opcode()) {
249+
match inst.operand(0) {
250+
Operand::ImmediateI8(rel) => {
251+
let dest = rel_address as i64
252+
+ offset as i64
253+
+ inst.len().to_const() as i64
254+
+ rel as i64;
255+
intel_insn = format!("{} 0x{:x}", inst.opcode(), dest);
256+
c_insn = intel_insn.clone();
257+
}
258+
Operand::ImmediateI32(rel) => {
259+
let dest = rel_address as i64
260+
+ offset as i64
261+
+ inst.len().to_const() as i64
262+
+ rel as i64;
263+
intel_insn = format!("{} 0x{:x}", inst.opcode(), dest);
264+
c_insn = intel_insn.clone();
265+
}
266+
_ => {}
267+
};
268+
}
269+
208270
DecodedInstruction {
209271
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-
],
272+
decoded_string_per_syntax: vec![intel_insn, c_insn],
216273
}
217274
}
218275
}
@@ -226,7 +283,11 @@ impl InstructionDecoding for yaxpeax_x86::protected_mode::Arch {
226283
yaxpeax_x86::protected_mode::InstDecoder::default()
227284
}
228285

229-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction {
286+
fn stringify_inst(
287+
_rel_address: u32,
288+
offset: u32,
289+
inst: Self::Instruction,
290+
) -> DecodedInstruction {
230291
DecodedInstruction {
231292
offset,
232293
decoded_string_per_syntax: vec![inst.to_string()],
@@ -243,7 +304,11 @@ impl InstructionDecoding for yaxpeax_arm::armv8::a64::ARMv8 {
243304
yaxpeax_arm::armv8::a64::InstDecoder::default()
244305
}
245306

246-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction {
307+
fn stringify_inst(
308+
_rel_address: u32,
309+
offset: u32,
310+
inst: Self::Instruction,
311+
) -> DecodedInstruction {
247312
DecodedInstruction {
248313
offset,
249314
decoded_string_per_syntax: vec![inst.to_string()],
@@ -271,7 +336,11 @@ impl InstructionDecoding for yaxpeax_arm::armv7::ARMv7 {
271336
yaxpeax_arm::armv7::InstDecoder::default_thumb()
272337
}
273338

274-
fn stringify_inst(offset: u32, inst: Self::Instruction) -> DecodedInstruction {
339+
fn stringify_inst(
340+
_rel_address: u32,
341+
offset: u32,
342+
inst: Self::Instruction,
343+
) -> DecodedInstruction {
275344
DecodedInstruction {
276345
offset,
277346
decoded_string_per_syntax: vec![inst.to_string()],
@@ -300,7 +369,7 @@ where
300369
let before = u64::from(reader.total_offset()) as u32;
301370
match decoder.decode(&mut reader) {
302371
Ok(inst) => {
303-
instructions.push(A::stringify_inst(offset, inst));
372+
instructions.push(A::stringify_inst(rel_address, offset, inst));
304373
let after = u64::from(reader.total_offset()) as u32;
305374
offset += after - before;
306375
}

0 commit comments

Comments
 (0)