@@ -136,6 +136,7 @@ def create_prefix(name, value):
136136reg_order = ['RAX' , 'RCX' , 'RDX' , 'RBX' , 'RSP' , 'RBP' , 'RSI' , 'RDI' ]
137137new_reg_order = ['R8' , 'R9' , 'R10' , 'R11' , 'R12' , 'R13' , 'R14' , 'R15' ]
138138x64_regs = reg_order + new_reg_order
139+ # Rip is now addressable but is a special case
139140
140141registers_32_bits = {'R15D' : 'R15' , 'R14D' : 'R14' , 'ESP' : 'RSP' , 'R9D' : 'R9' ,
141142'EDI' : 'RDI' , 'R11D' : 'R11' , 'R8D' : 'R8' , 'R10D' : 'R10' , 'EAX' : 'RAX' ,
@@ -170,6 +171,10 @@ def is_32b_reg(name):
170171 except AttributeError : # Not a string
171172 return False
172173
174+ @staticmethod
175+ def is_rip (name ):
176+ return name is not None and name .upper () == "RIP"
177+
173178 @staticmethod
174179 def is_mem_acces (data ):
175180 return isinstance (data , mem_access )
@@ -201,6 +206,9 @@ def create_displacement(base=None, index=None, scale=None, disp=0, prefix=None):
201206 raise ValueError ("Cannot create displacement with scale and no index" )
202207 if scale and index .upper () == "RSP" :
203208 raise ValueError ("Cannot create displacement with index == RSP" )
209+ if base and X64 .is_rip (base ):
210+ if index is not None or scale is not None :
211+ raise ValueError ("Bad use of RIP in mem expression <{0}> : only [RIP+DISP32] is possible" .format (data ))
204212 return mem_access (base , index , scale , disp , prefix )
205213
206214
@@ -251,10 +259,14 @@ def mem(data):
251259 parsed_items ['index' ] = index
252260 else :
253261 # displacement / base / index alone
254- if X64 .is_reg (item ):
262+ if X64 .is_reg (item ) or X64 . is_rip ( item ) :
255263 if 'base' not in parsed_items :
256264 parsed_items ['base' ] = item
257265 continue
266+ # RIP is only usable on the format [RIP+DISP32]
267+ # So no index when base is RIP & no index as RIP
268+ if X64 .is_rip (item ) or X64 .is_rip (parsed_items ['base' ]):
269+ raise ValueError ("Bad use of RIP in mem expression <{0}> : only [RIP+DISP32] is possible" .format (data ))
258270 # Already have base + index -> cannot avec another register in expression
259271 if 'index' in parsed_items :
260272 raise ValueError ("Multiple index / index*scale in mem expression <{0}>" .format (data ))
@@ -656,18 +668,18 @@ def __init__(self, arg1, arg2, reversed, instr_state):
656668 instr_state .prefixes .append (x64_segment_selectors [arg2 .prefix ])
657669 # # ARG1 : REG
658670 # # ARG2 : [MEM]
659- # # this encode [rip + disp]
660- # # TODO :)
661- # if X64.mem_access_has_only (arg2, ["disp"] ):
662- # self.mod = BitArray(2, "00")
663- # self.setup_reg_as_register(arg1)
664- # self.rm = BitArray(3, "101")
665- # try:
666- # self.after = BitArray.from_string(accept_as_32immediat(arg2.disp))
667- # except ImmediatOverflow:
668- # raise ImmediatOverflow("Interger32 overflow for displacement {0}".format(hex(arg2.disp)))
669- # self.direction = not reversed
670- # return
671+
672+ # Special case [RIP+DISP32]
673+ if X64 .is_rip (arg2 . base ):
674+ self .mod = BitArray (2 , "00" )
675+ self .setup_reg_as_register (arg1 )
676+ self .rm = BitArray (3 , "101" )
677+ try :
678+ self .after = BitArray .from_string (accept_as_32immediat (arg2 .disp ))
679+ except ImmediatOverflow :
680+ raise ImmediatOverflow ("Interger32 overflow for displacement {0}" .format (hex (arg2 .disp )))
681+ self .direction = not reversed
682+ return
671683
672684 # Those registers cannot be addressed without SIB
673685 FIRE_UP_SIB = not arg2 .base or arg2 .base .upper () in ["RSP" , "RBP" ] or arg2 .index
@@ -1098,6 +1110,8 @@ class Retf(Instruction):
10981110 default_32_bits = True
10991111 encoding = [(RawBits .from_int (8 , 0xcb ),)]
11001112
1113+ class Retfq (Instruction ): # Give an explicit name to retf-64bits as it cannot be guessed from the mnemonic alone
1114+ encoding = [(RawBits .from_int (8 , 0x48 ), RawBits .from_int (8 , 0xcb ))]
11011115
11021116class Retf32 (Instruction ):
11031117 encoding = [(RawBits .from_int (8 , 0xcb ),)]
@@ -1115,11 +1129,15 @@ def JmpAt(addr):
11151129
11161130class Raw (Instruction ):
11171131 """Output raw data"""
1132+
11181133 def __init__ (self , * initial_args ):
11191134 if len (initial_args ) != 1 :
11201135 raise ValueError ("raw 'opcode' only accept one argument" )
1121- # Accept space
1122- self .data = binascii .unhexlify (initial_args [0 ].replace (" " , "" ))
1136+ if isinstance (initial_args [0 ], int ):
1137+ self .data = struct .pack ("B" , initial_args [0 ])
1138+ else :
1139+ # Accept space
1140+ self .data = binascii .unhexlify (initial_args [0 ].replace (" " , "" ))
11231141
11241142 def get_code (self ):
11251143 return self .data
@@ -1300,6 +1318,12 @@ def assemble_instructions_generator(str):
13001318 except :
13011319 raise ValueError ("Unknow mnemonic <{0}>" .format (mnemo ))
13021320
1321+ if issubclass (instr_object , Raw ):
1322+ # Raw should received the raw buffer as it expect encoded hex
1323+ # The transformation may transform 'raw 9090' (nopnop) as 0n9090
1324+ # If other fake-instr need this : make a class attribute
1325+ yield instr_object (* args_raw )
1326+ continue
13031327 args = []
13041328 if args_raw :
13051329 for arg in args_raw [0 ].split ("," ):
0 commit comments