@@ -547,27 +547,34 @@ def __init__(self, elf="", minimalist=False):
547
547
548
548
with open (elf , "rb" ) as fd :
549
549
# off 0x0
550
- self .e_magic , self .e_class , self .e_endianness , self .e_eiversion = struct .unpack (">IBBB" , fd .read (7 ))
550
+ self .e_magic , self .e_class , self .e_endianness , self .e_eiversion = struct .unpack (
551
+ ">IBBB" , fd .read (7 ))
551
552
552
553
# adjust endianness in bin reading
553
554
endian = "<" if self .e_endianness == Elf .LITTLE_ENDIAN else ">"
554
555
555
556
# off 0x7
556
- self .e_osabi , self .e_abiversion = struct .unpack ("{}BB" .format (endian ), fd .read (2 ))
557
+ self .e_osabi , self .e_abiversion = struct .unpack (
558
+ "{}BB" .format (endian ), fd .read (2 ))
557
559
# off 0x9
558
560
self .e_pad = fd .read (7 )
559
561
# off 0x10
560
- self .e_type , self .e_machine , self .e_version = struct .unpack ("{}HHI" .format (endian ), fd .read (8 ))
562
+ self .e_type , self .e_machine , self .e_version = struct .unpack (
563
+ "{}HHI" .format (endian ), fd .read (8 ))
561
564
# off 0x18
562
565
if self .e_class == Elf .ELF_64_BITS :
563
566
# if arch 64bits
564
- self .e_entry , self .e_phoff , self .e_shoff = struct .unpack ("{}QQQ" .format (endian ), fd .read (24 ))
567
+ self .e_entry , self .e_phoff , self .e_shoff = struct .unpack (
568
+ "{}QQQ" .format (endian ), fd .read (24 ))
565
569
else :
566
570
# else arch 32bits
567
- self .e_entry , self .e_phoff , self .e_shoff = struct .unpack ("{}III" .format (endian ), fd .read (12 ))
571
+ self .e_entry , self .e_phoff , self .e_shoff = struct .unpack (
572
+ "{}III" .format (endian ), fd .read (12 ))
568
573
569
- self .e_flags , self .e_ehsize , self .e_phentsize , self .e_phnum = struct .unpack ("{}HHHH" .format (endian ), fd .read (8 ))
570
- self .e_shentsize , self .e_shnum , self .e_shstrndx = struct .unpack ("{}HHH" .format (endian ), fd .read (6 ))
574
+ self .e_flags , self .e_ehsize , self .e_phentsize , self .e_phnum = struct .unpack (
575
+ "{}HHHH" .format (endian ), fd .read (8 ))
576
+ self .e_shentsize , self .e_shnum , self .e_shstrndx = struct .unpack (
577
+ "{}HHH" .format (endian ), fd .read (6 ))
571
578
return
572
579
573
580
def is_valid (self ):
@@ -577,10 +584,31 @@ def is_valid(self):
577
584
class Instruction :
578
585
"""GEF representation of a CPU instruction."""
579
586
580
- def __init__ (self , address , location , mnemo , operands ):
581
- self .address , self .location , self .mnemonic , self .operands = address , location , mnemo , operands
587
+ def __init__ (self , address , location , mnemo , operands , opcodes ):
588
+ self .address , self .location , self .mnemonic , self .operands , self . opcodes = address , location , mnemo , operands , opcodes
582
589
return
583
590
591
+ # Allow formatting an instruction with {:o} to show opcodes.
592
+ # The number of bytes to display can be configured, e.g. {:4o} to only show 4 bytes of the opcodes
593
+ def __format__ (self , format_spec ):
594
+ if len (format_spec ) == 0 or format_spec [- 1 ] != "o" :
595
+ return str (self )
596
+
597
+ if format_spec == "o" :
598
+ opcodes_len = len (self .opcodes )
599
+ else :
600
+ opcodes_len = int (format_spec [:- 1 ])
601
+
602
+ opcodes_text = "" .join ("{:02x}" .format (b ) for b in self .opcodes [:opcodes_len ])
603
+ if opcodes_len < len (self .opcodes ):
604
+ opcodes_text += "..."
605
+ return "{:#10x} {:{:d}} {:16} {:6} {:s}" .format (self .address ,
606
+ opcodes_text ,
607
+ opcodes_len * 2 + 3 ,
608
+ self .location ,
609
+ self .mnemonic ,
610
+ ", " .join (self .operands ))
611
+
584
612
def __str__ (self ):
585
613
return "{:#10x} {:16} {:6} {:s}" .format (
586
614
self .address , self .location , self .mnemonic , ", " .join (self .operands )
@@ -1279,7 +1307,9 @@ def gdb_disassemble(start_pc, **kwargs):
1279
1307
loc = gdb_get_location_from_symbol (address )
1280
1308
location = "<{}+{}>" .format (* loc ) if loc else ""
1281
1309
1282
- yield Instruction (address , location , mnemo , operands )
1310
+ opcodes = read_memory (insn ["addr" ], insn ["length" ])
1311
+
1312
+ yield Instruction (address , location , mnemo , operands , opcodes )
1283
1313
1284
1314
1285
1315
def gdb_get_nth_previous_instruction_address (addr , n ):
@@ -1378,7 +1408,7 @@ def cs_insn_to_gef_insn(cs_insn):
1378
1408
sym_info = gdb_get_location_from_symbol (cs_insn .address )
1379
1409
loc = "<{}+{}>" .format (* sym_info ) if sym_info else ""
1380
1410
ops = [] + cs_insn .op_str .split (", " )
1381
- return Instruction (cs_insn .address , loc , cs_insn .mnemonic , ops )
1411
+ return Instruction (cs_insn .address , loc , cs_insn .mnemonic , ops , cs_insn . bytes )
1382
1412
1383
1413
capstone = sys .modules ["capstone" ]
1384
1414
arch , mode = get_capstone_arch (arch = kwargs .get ("arch" , None ), mode = kwargs .get ("mode" , None ), endian = kwargs .get ("endian" , None ))
@@ -6395,7 +6425,7 @@ class CapstoneDisassembleCommand(GenericCommand):
6395
6425
"""Use capstone disassembly framework to disassemble code."""
6396
6426
6397
6427
_cmdline_ = "capstone-disassemble"
6398
- _syntax_ = "{:s} [LOCATION] [[length=LENGTH] [option=VALUE]] " .format (_cmdline_ )
6428
+ _syntax_ = "{:s} [LOCATION] [[length=LENGTH] [OPCODES] [ option=VALUE]] " .format (_cmdline_ )
6399
6429
_aliases_ = ["cs-dis" ,]
6400
6430
_example_ = "{:s} $pc length=50" .format (_cmdline_ )
6401
6431
@@ -6414,21 +6444,32 @@ def __init__(self):
6414
6444
@only_if_gdb_running
6415
6445
def do_invoke (self , argv ):
6416
6446
location = None
6447
+ show_opcodes = False
6417
6448
6418
6449
kwargs = {}
6419
6450
for arg in argv :
6420
6451
if "=" in arg :
6421
6452
key , value = arg .split ("=" , 1 )
6422
6453
kwargs [key ] = value
6423
6454
6455
+ elif "opcodes" .startswith (arg .lower ()):
6456
+ show_opcodes = True
6457
+
6424
6458
elif location is None :
6425
6459
location = parse_address (arg )
6426
6460
6427
6461
location = location or current_arch .pc
6428
6462
length = int (kwargs .get ("length" , get_gef_setting ("context.nb_lines_code" )))
6429
6463
6464
+ insns = []
6465
+ opcodes_len = 0
6430
6466
for insn in capstone_disassemble (location , length , skip = length * self .repeat_count , ** kwargs ):
6431
- text_insn = str (insn )
6467
+ insns .append (insn )
6468
+ opcodes_len = max (opcodes_len , len (insn .opcodes ))
6469
+
6470
+ for insn in insns :
6471
+ insn_fmt = "{{:{}o}}" .format (opcodes_len ) if show_opcodes else "{}"
6472
+ text_insn = insn_fmt .format (insn )
6432
6473
msg = ""
6433
6474
6434
6475
if insn .address == current_arch .pc :
@@ -7571,6 +7612,7 @@ def __init__(self):
7571
7612
self .add_setting ("show_source_code_variable_values" , True , "Show extra PC context info in the source code" )
7572
7613
self .add_setting ("show_stack_raw" , False , "Show the stack pane as raw hexdump (no dereference)" )
7573
7614
self .add_setting ("show_registers_raw" , False , "Show the registers pane with raw values (no dereference)" )
7615
+ self .add_setting ("show_opcodes_size" , 0 , "Number of bytes of opcodes to display next to the disassembly" )
7574
7616
self .add_setting ("peek_calls" , True , "Peek into calls" )
7575
7617
self .add_setting ("peek_ret" , True , "Peek at return address" )
7576
7618
self .add_setting ("nb_lines_stack" , 8 , "Number of line in the stack pane" )
@@ -7783,6 +7825,7 @@ def context_code(self):
7783
7825
nb_insn = self .get_setting ("nb_lines_code" )
7784
7826
nb_insn_prev = self .get_setting ("nb_lines_code_prev" )
7785
7827
use_capstone = self .has_setting ("use_capstone" ) and self .get_setting ("use_capstone" )
7828
+ show_opcodes_size = self .has_setting ("show_opcodes_size" ) and self .get_setting ("show_opcodes_size" )
7786
7829
past_insns_color = get_gef_setting ("theme.old_context" )
7787
7830
cur_insn_color = get_gef_setting ("theme.disassemble_current_instruction" )
7788
7831
pc = current_arch .pc
@@ -7801,9 +7844,14 @@ def context_code(self):
7801
7844
line = []
7802
7845
is_taken = False
7803
7846
target = None
7804
- text = str (insn )
7805
7847
bp_prefix = Color .redify (BP_GLYPH ) if self .addr_has_breakpoint (insn .address , bp_locations ) else " "
7806
7848
7849
+ if show_opcodes_size == 0 :
7850
+ text = str (insn )
7851
+ else :
7852
+ insn_fmt = "{{:{}o}}" .format (show_opcodes_size )
7853
+ text = insn_fmt .format (insn )
7854
+
7807
7855
if insn .address < pc :
7808
7856
line += "{} {}" .format (bp_prefix , Color .colorify (text , past_insns_color ))
7809
7857
0 commit comments