1# coding=utf-8 2# Copyright 2018 Sascha Schirra 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are met: 6# 7# 1. Redistributions of source code must retain the above copyright notice, this 8# list of conditions and the following disclaimer. 9# 10# 2. Redistributions in binary form must reproduce the above copyright notice, 11# this list of conditions and the following disclaimer in the documentation 12# and/or other materials provided with the distribution. 13# 14# 3. Neither the name of the copyright holder nor the names of its contributors 15# may be used to endorse or promote products derived from this software without 16# specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" A ND 19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29from ropper.common.abstract import * 30from ropper.common.enum import Enum 31from ropper.common.error import NotSupportedError 32from ropper.search import Searcher, Searcherx86, SearcherARM, SearcherMIPS 33from re import compile 34from capstone import * 35from . import gadget 36try: 37 import sys 38 import archinfo 39except: 40 pass 41 42# Optional keystone support 43try: 44 import keystone 45except: 46 pass 47 48def byte_regexp(bitmask, bitvalues): 49 r = b'[' 50 for value in range(256): 51 if value & bitmask == bitvalues: 52 # Generates unencoded string (bytes) in both Python 2 and 3. 53 r += bytes(bytearray([value])) 54 r += b']' 55 return r 56 57class Endianess(Enum): 58 _enum_ = 'LITTLE BIG' 59 60class Architecture(AbstractSingleton): 61 62 def __init__(self, arch, mode, addressLength, align, endianess=Endianess.LITTLE, branch_delay_slot=False): 63 super(Architecture, self).__init__() 64 self._name = 'raw' 65 self._arch = arch 66 self._mode = mode 67 self._info = None 68 69 self._ksarch = (None,None) 70 71 self._addressLength = addressLength 72 self._align = align 73 74 self._endings = {} 75 self._badInstructions = [] 76 self._categories = {} 77 self._maxInvalid = 1 78 79 self._endianess = endianess 80 81 self._searcher = Searcher() 82 83 self._initGadgets() 84 self._initBadInstructions() 85 self._initCategories() 86 87 self._initEndianess(endianess) 88 self._hasBranchDelaySlot = branch_delay_slot 89 90 self._endings[gadget.GadgetType.ALL] = self._endings[ 91 gadget.GadgetType.ROP] + self._endings[gadget.GadgetType.JOP] + self._endings[gadget.GadgetType.SYS] 92 93 def _initGadgets(self): 94 self._endings[gadget.GadgetType.ROP] = [] 95 self._endings[gadget.GadgetType.JOP] = [] 96 self._endings[gadget.GadgetType.SYS] = [] 97 98 def _initBadInstructions(self): 99 pass 100 101 def _initCategories(self): 102 pass 103 104 def _initEndianess(self, endianess): 105 if endianess == Endianess.BIG: 106 for key in self.endings: 107 tmp = [] 108 for pattern, size in self.endings[key]: 109 tmp.append((pattern[::-1], size)) 110 self.endings[key] = tmp 111 112 @property 113 def info(self): 114 return self._info 115 116 117 @property 118 def ksarch(self): 119 return self._ksarch 120 121 @property 122 def arch(self): 123 return self._arch 124 125 @property 126 def align(self): 127 return self._align 128 129 @property 130 def mode(self): 131 return self._mode 132 133 @property 134 def addressLength(self): 135 return self._addressLength 136 137 @property 138 def endings(self): 139 return self._endings 140 141 @property 142 def badInstructions(self): 143 return self._badInstructions 144 145 @property 146 def searcher(self): 147 return self._searcher 148 149 @property 150 def maxInvalid(self): 151 return self._maxInvalid 152 153 @property 154 def endianess(self): 155 return self._endianess 156 157 @property 158 def hasBranchDelaySlot(self): 159 return self._hasBranchDelaySlot 160 161 def getRegisterName(self, reg): 162 if self.info is None: 163 return reg 164 info = self.info.registers.get(reg) 165 if not info: 166 return reg 167 return self.info.translate_register_name(info[0], info[1]*8) 168 169 def __str__(self): 170 return self._name 171 172 def __repr__(self): 173 return repr(str(self)) 174 175 176class ArchitectureX86(Architecture): 177 178 def __init__(self): 179 super(ArchitectureX86, self).__init__( CS_ARCH_X86, CS_MODE_32, 4, 1) 180 self._name = 'x86' 181 self._maxInvalid = 6 182 if 'keystone' in globals(): 183 self._ksarch = (keystone.KS_ARCH_X86, keystone.KS_MODE_32) 184 185 if 'archinfo' in globals(): 186 self._info = archinfo.ArchX86() 187 188 self._searcher = Searcherx86() 189 self._pprs = [b'[\x58-\x5f]{2}\xc3', # pop reg; pop reg; ret 190 b'\x83\xc4\x04[\x58-\x5f]\xc3', # add esp, 4; pop reg; ret 191 b'[\x58-\x5f]\x83\xc4\x04\xc3', # pop reg; add esp, 4; ret 192 b'\x83\xc4\x08\xc3', # add esp, 8; ret; 193 b'\xff\x54\x24[\x08\x14\x1c\x2c\x44\x50]', # call [esp+n] 194 b'\xff\x64\x24[\x08\x14\x1c\x2c\x44\x50]', # jmp [esp+n] 195 b'\xff\x65[\x0c\x24\x30\xfc\xf4\xe8]', # jmp [ebp+n] 196 b'\xff\x55[\x0c\x24\x30\xfc\xf4\xe8]' # call [ebp+n] 197 ] 198 199 @property 200 def pprs(self): 201 return self._pprs 202 203 def _initGadgets(self): 204 super(ArchitectureX86, self)._initGadgets() 205 self._endings[gadget.GadgetType.ROP] = [(b'\xc3', 1), # ret 206 (b'\xc2[\x00-\xff]{2}', 3)] # ret xxx 207 208 self._endings[gadget.GadgetType.SYS] = [(b'\xcd\x80', 2), # int 0x80 209 (b'\x0f\x05',2), # syscall 210 (b'\x0f\x34',2), # sysenter 211 (b'\x65\xff\x15\x10\x00\x00\x00', 7)] # call gs:[10] 212 213 self._endings[gadget.GadgetType.JOP] = [( 214 b'\xff[\x20\x21\x22\x23\x26\x27]', 2), # jmp [reg] 215 (b'\xf2\xff[\x20\x21\x22\x23\x26\x27]', 3), # bnd jmp [reg] 216 (b'\xff[\xe0\xe1\xe2\xe3\xe4\xe6\xe7]', 2), # jmp reg 217 (b'\xf2\xff[\xe0\xe1\xe2\xe3\xe4\xe6\xe7]', 3), # bnd jmp reg 218 (b'\xff[\x10\x11\x12\x13\x16\x17]', 2), # call [reg] 219 (b'\xf2\xff[\x10\x11\x12\x13\x16\x17]', 3), # bnd call [reg] 220 (b'\xff[\xd0\xd1\xd2\xd3\xd4\xd6\xd7]', 2), # call reg 221 (b'\xf2\xff[\xd0\xd1\xd2\xd3\xd4\xd6\xd7]', 3), # bnd call reg 222 (b'\xff[\x14\x24]\x24', 3), # call/jmp [esp] 223 (b'\xf2\xff[\x14\x24]\x24', 4), # bnd call/jmp [esp] 224 (b'\xff[\x55\x65]\x00', 3), # call/jmp [ebp] 225 (b'\xf2\xff[\x55\x65]\x00', 4), # bnd call/jmp [ebp] 226 (b'\xff[\xa0\xa1\xa2\xa3\xa6\xa7][\x00-\x0ff]{4}', 6), # jmp [reg+value] 227 (b'\xf2\xff[\xa0\xa1\xa2\xa3\xa6\xa7][\x00-\x0ff]{4}', 7), # bnd jmp [reg+value] 228 (b'\xff\xa4\x24[\x00-\xff]{4}', 7), 229 (b'\xf2\xff\xa4\x24[\x00-\xff]{4}', 8), 230 (b'\xff[\x50-\x53\x55-\x57][\x00-\xff]{1}', 3), # call [reg + value] 231 (b'\xf2\xff[\x50-\x53\x55-\x57][\x00-\xff]{1}', 4), # call [reg + value] 232 (b'\xff[\x60-\x63\x65-\x67][\x00-\xff]{1}', 3), # jmp [reg + value] 233 (b'\xf2\xff[\x60-\x63\x65-\x67][\x00-\xff]{1}', 4), # jmp [reg + value] 234 #(b'\xe9[\x00-\xff]{4}', 5), # jmp value 235 #(b'\xe8[\x00-\xff]{4}', 5), # call value 236 (b'\xff[\x90\x91\x92\x93\x94\x96\x97][\x00-\x0ff]{4}', 6)] 237 238 def _initBadInstructions(self): 239 self._badInstructions = ['enter','loop','loopne','int3', 'db', 'ret', 'jmp'] 240 241 def _initCategories(self): 242 self._categories = { 243 gadget.Category.STACK_PIVOT : (('^sub (?P<dst>.sp), (?P<src>[x0-9a-fA-F]+)$','^add (?P<dst>.sp), (?P<src>[x0-9a-fA-F]+)$','^mov (?P<dst>.sp), .+ ptr \[(?P<src>...)\]$','^mov (?P<dst>.sp), (?P<src>...)$','^xchg (?P<dst>.sp), (?P<src>...)$','^xchg (?P<dst>...), (?P<src>.sp)$','ret.+'),('mov','call','jmp')), 244 gadget.Category.LOAD_MEM : (('mov (?P<dst>...), .+ ptr \[(?P<src>...)\]',),('mov','call','jmp')), 245 gadget.Category.WRITE_MEM : (('^mov .+ ptr \[(?P<dst>...)\], (?P<src>...)$',),('mov','call','jmp')), 246 gadget.Category.LOAD_REG : (('pop (?P<dst>...)',),('mov','call','jmp')), 247 gadget.Category.JMP : (('^jmp (?P<dst>...)$',),()), 248 gadget.Category.CALL : (('^call (?P<dst>...)$',),('mov','call','jmp')), 249 gadget.Category.INC_REG : (('^inc (?P<dst>...)$', '^add (?P<dst>e?..), 1$'),('mov','call','jmp')), 250 gadget.Category.CLEAR_REG : (('^xor (?P<dst>...), (?P<src>...)$',),('mov','call','jmp')), 251 gadget.Category.SUB_REG : (('^sub (?P<dst>...), (?P<src>...)$',),('mov','call','jmp')), 252 gadget.Category.ADD_REG : (('^add (?P<dst>...), (?P<src>...)$',),('mov','call','jmp')), 253 gadget.Category.XCHG_REG : (('^xchg (?P<dst>...), (?P<src>...)$',),('mov','call','jmp')), 254 gadget.Category.PUSHAD : (('^pushal$',),('mov','call','jmp')), 255 gadget.Category.NEG_REG : (('^neg (?P<dst>...)$',),('mov','call','jmp')), 256 gadget.Category.SYSCALL : (('^int (?P<dst>0x80)$',),('mov','call','jmp'))} 257 258 259 260class ArchitectureX86_64(ArchitectureX86): 261 262 def __init__(self): 263 super(ArchitectureX86_64, self).__init__() 264 self._name = 'x86_64' 265 self._maxInvalid = 8 266 if 'keystone' in globals(): 267 self._ksarch = (keystone.KS_ARCH_X86, keystone.KS_MODE_64) 268 269 self._endings[gadget.GadgetType.SYS] = [(b'\x0f\x05',2), 270 (b'\x0f\x05\xc3',3)] # syscall 271 272 self._mode = CS_MODE_64 273 if 'archinfo' in globals(): 274 self._info = archinfo.ArchAMD64() 275 276 self._addressLength = 8 277 self._pprs = [b'[\x58-\x5f]{2}\xc3', # pop reg; pop reg; ret 278 b'\x83\xc4\x08[\x58-\x5f]\xc3', # add esp, 4; pop reg; ret 279 b'[\x58-\x5f]\x83\xc4\x08\xc3', # pop reg; add esp, 4; ret 280 b'\x83\xc4\x10\xc3' # add esp, 8; ret; 281 ] 282 self._pprs.append(b'\x41?[\x58-\x5f]\x48\x83\xc4\x08\xc3') 283 self._pprs.append(b'\x48\x83\xc4\x08\x41?[\x58-\x5f]\xc3') 284 self._pprs.append(b'(\x41?[\x58-\x5f]){2}\xc3') 285 self._pprs.append(b'\x48\x83\xc4\x10\xc3') 286 287 def _initBadInstructions(self): 288 super(ArchitectureX86_64, self)._initBadInstructions() 289 self._badInstructions.append('jrcxz') 290 291 def _initCategories(self): 292 self._categories = { 293 gadget.Category.STACK_PIVOT : (('^mov (?P<dst>.sp), .+ ptr \[(?P<src>...)\]$','^mov (?P<dst>.sp), (?P<src>...)$','^xchg (?P<dst>.sp), (?P<src>...)$','^xchg (?P<dst>...), (?P<src>.sp)$','ret.+'),('mov','call','jmp')), 294 gadget.Category.LOAD_MEM : (('mov (?P<dst>r..), .+ ptr \[(?P<src>r..)\]',),('mov','call','jmp')), 295 gadget.Category.WRITE_MEM : (('^mov .+ ptr \[(?P<dst>r..)\], (?P<src>r..)$',),('mov','call','jmp')), 296 gadget.Category.LOAD_REG : (('pop (?P<dst>r..)',),('mov','call','jmp')), 297 gadget.Category.JMP : (('^jmp (?P<dst>r..)$',),()), 298 gadget.Category.CALL : (('^call (?P<dst>r..)$',),('mov','call','jmp')), 299 gadget.Category.INC_REG : (('^inc (?P<dst>...)$', '^add (?P<dst>[er]?..), 1$'),('mov','call','jmp')), 300 gadget.Category.CLEAR_REG : (('^xor (?P<dst>...), (?P<src>...)$',),('mov','call','jmp')), 301 gadget.Category.SUB_REG : (('^sub (?P<dst>...), (?P<src>...)$',),('mov','call','jmp')), 302 gadget.Category.ADD_REG : (('^add (?P<dst>...), (?P<src>...)$',),('mov','call','jmp')), 303 gadget.Category.XCHG_REG : (('^xchg (?P<dst>...), (?P<src>...)$',),('mov','call','jmp')), 304 gadget.Category.PUSHAD : (('^pushal$',),('mov','call','jmp')), 305 gadget.Category.NEG_REG : (('^neg (?P<dst>...)$',),('mov','call','jmp')), 306 gadget.Category.SYSCALL : (('^syscall$',),('mov','call','jmp'))} 307 308 309 310 311 312 313class ArchitectureMips(Architecture): 314 315 def __init__(self, endianess=Endianess.LITTLE): 316 super(ArchitectureMips,self).__init__(CS_ARCH_MIPS, CS_MODE_32, 4, 4, endianess, branch_delay_slot=True) 317 self._name = 'MIPS' 318 319 if 'keystone' in globals(): 320 self._ksarch = (keystone.KS_ARCH_MIPS, keystone.KS_MODE_MIPS32) 321 322 if 'archinfo' in globals(): 323 self._info = archinfo.ArchMIPS32() 324 325 self._searcher = SearcherMIPS() 326 327 def _initGadgets(self): 328 super(ArchitectureMips, self)._initGadgets() 329 self._endings[gadget.GadgetType.ROP] = [] 330 self._endings[gadget.GadgetType.JOP] = [(b'\x09\xf8\x20\x03', 4), # jalr t9 331 (b'\x08\x00\x20\x03', 4), # jr t9 332 (b'\x08\x00\xe0\x03', 4)] # jr ra 333 334 335class ArchitectureMipsBE(ArchitectureMips): 336 337 def __init__(self): 338 super(ArchitectureMipsBE, self).__init__(Endianess.BIG) 339 self._name = 'MIPSBE' 340 self._mode |= CS_MODE_BIG_ENDIAN 341 if 'keystone' in globals(): 342 self._ksarch = (self._ksarch[0], self._ksarch[1] + keystone.KS_MODE_BIG_ENDIAN) 343 344class ArchitectureMips64(ArchitectureMips): 345 346 def __init__(self, endianess=Endianess.LITTLE): 347 super(ArchitectureMips64, self).__init__(endianess) 348 self._name = 'MIPS64' 349 350 if 'keystone' in globals(): 351 self._ksarch = (keystone.KS_ARCH_MIPS, keystone.KS_MODE_64) 352 353 self._mode = CS_MODE_MIPS64 354 if 'archinfo' in globals(): 355 self._info = archinfo.ArchMIPS64() 356 357 self._addressLength = 8 358 359 def _initGadgets(self): 360 super(ArchitectureMips64, self)._initGadgets() 361 362 363class ArchitectureMips64BE(ArchitectureMips64): 364 365 def __init__(self): 366 super(ArchitectureMips64BE, self).__init__(Endianess.BIG) 367 self._name = 'MIPS64BE' 368 self._mode |= CS_MODE_BIG_ENDIAN 369 if 'keystone' in globals(): 370 self._ksarch = (self._ksarch[0], self._ksarch[1] + keystone.KS_MODE_BIG_ENDIAN) 371 372class ArchitectureArm(Architecture): 373 374 def __init__(self, endianess=Endianess.LITTLE): 375 super(ArchitectureArm,self).__init__(CS_ARCH_ARM, CS_MODE_ARM, 4, 4, endianess) 376 self._searcher = SearcherARM() 377 self._name = 'ARM' 378 379 if 'archinfo' in globals(): 380 self._info = archinfo.ArchARM() 381 if 'keystone' in globals(): 382 self._ksarch = (keystone.KS_ARCH_ARM, keystone.KS_MODE_ARM) 383 384 def _initGadgets(self): 385 super(ArchitectureArm, self)._initGadgets() 386 self._endings[gadget.GadgetType.ROP] = [(b'[\x01-\xff]\x80\xbd\xe8', 4)] # pop {[reg]*,pc} 387 self._endings[gadget.GadgetType.JOP] = [(b'[\x10-\x1e]\xff\x2f\xe1', 4), # bx <reg> 388 (b'[\x30-\x3e]\xff\x2f\xe1', 4), # blx <reg> 389 (b'[\x00-\x0f]\xf0\xa0\xe1', 4), # mov pc, <reg> 390 (b'\x01\x80\xbd\xe8', 4)] # ldm sp! ,{pc} 391 392 393class ArchitectureArmBE(ArchitectureArm): 394 395 def __init__(self): 396 super(ArchitectureArmBE, self).__init__(Endianess.BIG) 397 self._name = 'ARMBE' 398 self._mode |= CS_MODE_BIG_ENDIAN 399 if 'keystone' in globals(): 400 self._ksarch = (self._ksarch[0], self._ksarch[1] + keystone.KS_MODE_BIG_ENDIAN) 401 402 def _initEndianess(self, endianess): 403 super(ArchitectureArmBE, self)._initEndianess(endianess) 404 self._endings[gadget.GadgetType.ROP] = [(b'\xe8\xbd\x80[\x01-\xff]', 4)] # pop {[reg]*,pc} 405 self._endings[gadget.GadgetType.JOP] = [(b'\xe1\x2f\xff[\x10-\x1e]', 4), # bx <reg> 406 (b'\xe1\x2f\xff[\x30-\x3e]', 4), # blx <reg> 407 (b'\xe1\xa0\xf0[\x00-\x0f]', 4), # mov pc, <reg> 408 (b'\xe8\xdb\x80\x01', 4)] # ldm sp! ,{pc} 409 410class ArchitectureArmThumb(Architecture): 411 412 def __init__(self): 413 super(ArchitectureArmThumb, self).__init__(CS_ARCH_ARM, CS_MODE_THUMB, 4, 2) 414 self._searcher = SearcherARM() 415 self._name = 'ARMTHUMB' 416 self._maxInvalid = 2 417 418 if 'archinfo' in globals(): 419 self._info = archinfo.ArchARM() 420 421 if 'keystone' in globals(): 422 self._ksarch = (keystone.KS_ARCH_ARM, keystone.KS_MODE_THUMB) 423 424 def _initGadgets(self): 425 super(ArchitectureArmThumb, self)._initGadgets() 426 self._endings[gadget.GadgetType.ROP] = [(b'[\x00-\xff]\xbd', 2)] # pop {[regs]*,pc} 427 self._endings[gadget.GadgetType.JOP] = [(b'[\x00-\x7f]\x47', 2), # bx <reg> 428 (b'[\x80\x88\x90\x98\xa0\xa8\xb0\xb8\xc0\xc8\xd0\xd8\xe0\xe8\xf0\xf8]\x47', 2) # blx <reg> 429 ] 430 431 432 433 434class ArchitectureArm64(Architecture): 435 436 def __init__(self): 437 super(ArchitectureArm64, self).__init__(CS_ARCH_ARM64, CS_MODE_ARM, 8, 4) 438 self._name = 'ARM64' 439 440 if 'archinfo' in globals(): 441 self._info = archinfo.ArchAArch64() 442 if 'keystone' in globals(): 443 self._ksarch = (keystone.KS_ARCH_ARM64, keystone.KS_MODE_LITTLE_ENDIAN) 444 445 def _initGadgets(self): 446 super(ArchitectureArm64, self)._initGadgets() 447 self._endings[gadget.GadgetType.ROP] = [(b'[\x00\x20\x40\x60\x80\xa0\xc0\xe0][\x00-\x02]\x5f\xd6', 4), # ret <reg> 448 (b'[\x00\x20\x40\x60\x80]\x03\x5f\xd6', 4), # ret <reg> (x24 - x28) 449 (b'\xc0\x03\x5f\xd6', 4)] # ret 450 451 self._endings[gadget.GadgetType.JOP] = [(b'[\x00\x20\x40\x60\x80\xa0\xc0\xe0][\x00-\x02]\x1f\xd6', 4), # br <reg> 452 (b'[\x00\x20\x40\x60\x80]\x03\x1f\xd6', 4), # br <reg> 453 (b'[\x00\x20\x40\x60\x80\xa0\xc0\xe0][\x00-\x02]\\?\xd6', 4), # blr <reg> 454 (b'[\x00\x20\x40\x60\x80]\x03\\?\xd6', 4)] # blr <reg> 455 456 457 458class ArchitecturePPC(Architecture): 459 460 def __init__(self): 461 super(ArchitecturePPC, self).__init__(CS_ARCH_PPC, CS_MODE_32 + CS_MODE_BIG_ENDIAN, 4, 4) 462 self._name = 'PPC' 463 464 if 'keystone' in globals(): 465 self._ksarch = (keystone.KS_ARCH_PPC, keystone.KS_MODE_32) 466 467 def _initGadgets(self): 468 super(ArchitecturePPC, self)._initGadgets() 469 self._endings[gadget.GadgetType.ROP] = [(b'\x4e\x80\x00\x20', 4)] # blr 470 self._endings[gadget.GadgetType.JOP] = [(b'\x4e\x80\x04[\x20-\x21]', 4)] # bctr, bctrl 471 self._endings[gadget.GadgetType.SYS] = [(b'\x44\x00\x00\x02', 4)] # sc 472 473 474class ArchitecturePPC64(ArchitecturePPC): 475 476 def __init__(self): 477 478 Architecture.__init__(self, CS_ARCH_PPC, CS_MODE_64 + CS_MODE_BIG_ENDIAN, 8, 4) 479 self._name = 'PPC64' 480 481 if 'keystone' in globals(): 482 self._ksarch = (keystone.KS_ARCH_PPC, keystone.KS_MODE_64) 483 484class ArchitectureSPARC(Architecture): 485 486 def __init__(self): 487 super(ArchitectureSPARC, self).__init__(CS_ARCH_SPARC, CS_MODE_32 + CS_MODE_BIG_ENDIAN, 4, 4, 488 branch_delay_slot=True) 489 self._name = 'SPARC' 490 491 if 'keystone' in globals(): 492 self._ksarch = (keystone.KS_ARCH_SPARC, keystone.KS_MODE_32) 493 494 def _initGadgets(self): 495 super(ArchitectureSPARC, self)._initGadgets() 496 self._endings[gadget.GadgetType.ROP] = [] 497 self._endings[gadget.GadgetType.JOP] = [] 498 self._endings[gadget.GadgetType.SYS] = [] 499 500 501class ArchitectureSPARC64(ArchitectureSPARC): 502 503 def __init__(self): 504 505 Architecture.__init__(self, CS_ARCH_SPARC, CS_MODE_V9 + CS_MODE_BIG_ENDIAN, 8, 4, branch_delay_slot=True) 506 self._name = 'SPARC64' 507 508 if 'keystone' in globals(): 509 self._ksarch = (keystone.KS_ARCH_SPARC, keystone.KS_MODE_64) 510 511 def _initGadgets(self): 512 super(ArchitectureSPARC, self)._initGadgets() 513 self._endings[gadget.GadgetType.ROP] = [ 514 (byte_regexp(0b11000001, 0b10000001) + b'[\xc8-\xcf][\x00-\xff][\x00-\xff]', 4), # return 515 (byte_regexp(0b11000001, 0b10000001) + b'[\xe8-\xef][\x00-\xff][\x00-\xff]', 4)] # restore 516 self._endings[gadget.GadgetType.JOP] = [ 517 (byte_regexp(0b11000001, 0b10000001) + b'[\xc0-\xc7][\x00-\xff][\x00-\xff]', 4)] # jmpl (ret, retl) 518 self._endings[gadget.GadgetType.SYS] = [(b'\x91\xd0\x20\x6d', 4)] # ta 0x6d 519 520 521 522x86 = ArchitectureX86() 523x86_64 = ArchitectureX86_64() 524MIPS = ArchitectureMips() 525MIPSBE = ArchitectureMipsBE() 526MIPS64 = ArchitectureMips64() 527MIPS64BE = ArchitectureMips64BE() 528ARM = ArchitectureArm() 529ARMBE = ArchitectureArmBE() 530ARMTHUMB = ArchitectureArmThumb() 531ARM64 = ArchitectureArm64() 532PPC = ArchitecturePPC() 533PPC64 = ArchitecturePPC64() 534SPARC64 = ArchitectureSPARC64() 535 536def getArchitecture(archString): 537 arch = globals().get(archString, None) 538 539 if isinstance(arch, Architecture): 540 return arch 541 542 raise NotSupportedError('Architecture is not supported: ' + archString + '\nSupported architectures are: x86, x86_64, MIPS, MIPS64, ARM, ARMTHUMB, ARM64, PPC, PPC64, SPARC64') 543