Package envi :: Module cli
[hide private]
[frames] | no frames]

Source Code for Module envi.cli

  1  ''' 
  2  Unified CLI code for things like vivisect and vdb. 
  3  ''' 
  4   
  5  import os 
  6  import re 
  7  import sys 
  8  import code 
  9  import shlex 
 10  import json 
 11  import optparse 
 12  import traceback 
 13  import threading 
 14  import collections 
 15   
 16  import envi.bits as e_bits 
 17  import envi.memory as e_mem 
 18  import envi.config as e_config 
 19  import envi.memcanvas as e_canvas 
 20  import envi.expression as e_expr 
 21  import envi.symstore.resolver as e_resolv 
 22  import envi.memcanvas.renderers as e_render 
 23   
 24  from cmd import Cmd 
 25  from getopt import getopt 
 26   
27 -def splitargs(cmdline):
28 cmdline = cmdline.replace('\\\\"', '"').replace('\\"', '') 29 patt = re.compile('\".+?\"|\S+') 30 for item in cmdline.split('\n'): 31 return [s.strip('"') for s in patt.findall(item)]
32
33 -def columnstr(slist):
34 msize = 0 35 for s in slist: 36 if len(s) > msize: 37 msize = len(s) 38 return [x.ljust(msize) for x in slist]
39 40
41 -class CliExtMeth:
42 """ 43 This is used to work around the difference 44 between functions and bound methods for extended 45 command modules 46 """
47 - def __init__(self, cli, func):
48 self.cli = cli 49 self.func = func 50 self.__doc__ = func.__doc__
51
52 - def __call__(self, line):
53 return self.func(self.cli, line)
54 55 cfgdefs = { 56 'cli':{ 57 'verbose':False, 58 'aliases':{ 59 } 60 } 61 } 62
63 -class VOptionParser(optparse.OptionParser):
64 ''' 65 overloads error function that prints to stdout/stderr. 66 67 error is overloaded to raise an exception if an error occurs during the 68 parse of arguments. normally optionparser sends it to stderr. 69 '''
70 - def __init__(self, *args, **kwargs):
71 optparse.OptionParser.__init__(self, *args, add_help_option=False, **kwargs)
72
73 - def error(self, msg):
74 raise Exception(msg)
75
76 -class EnviCli(Cmd):
77
78 - def __init__(self, memobj, config=None, symobj=None):
79 80 self.extcmds = {} 81 self.basecmds = [] 82 self.extsubsys = collections.defaultdict(list) 83 self.scriptpaths = [] 84 self.addScriptPathEnvVar('ENVI_SCRIPT_PATH') 85 86 Cmd.__init__(self, stdout=self) 87 88 for name in dir(self): 89 if name.startswith('do_'): 90 self.basecmds.append( name[3:] ) 91 92 self.shutdown = threading.Event() 93 94 # If they didn't give us a resolver, make one. 95 if symobj == None: 96 symobj = e_resolv.SymbolResolver() 97 98 if config == None: 99 config = e_config.EnviConfig(defaults=cfgdefs) 100 101 # Force it to be there if its not 102 config.getSubConfig('cli') 103 104 self.config = config 105 self.memobj = memobj 106 self.symobj = symobj 107 self.canvas = e_canvas.MemoryCanvas(memobj, syms=symobj) 108 109 self.aliases = {} # For *runtime* aliases only!
110
111 - def addCmdAlias(self, alias, cmd, persist=False):
112 ''' 113 Add a command alias and optionally save it. 114 115 Specify persist=True to save the alias. 116 117 Example: 118 cli.addRuntimeAlias('woot', 'woot -F -T') 119 ''' 120 if not persist: 121 self.aliases[ alias ] = cmd 122 return 123 self.config.cli.aliases[ alias ] = cmd
124
125 - def addScriptPathEnvVar(self, pathenv):
126 ''' 127 Reads a script environment variable in, parses it, and stores the paths 128 ''' 129 scriptdirs = os.getenv( pathenv ) 130 if scriptdirs != None: 131 for scriptdir in scriptdirs.split(os.pathsep): 132 if scriptdir in self.scriptpaths: 133 continue 134 135 self.scriptpaths.append( scriptdir )
136
137 - def setCanvas(self, canvas):
138 """ 139 Set a new canvas for the CLI and add all the current renderers 140 to the new one. 141 """ 142 for name in self.canvas.getRendererNames(): 143 canvas.addRenderer(name, self.canvas.getRenderer(name)) 144 self.canvas = canvas
145
146 - def write(self, data):
147 # For stdout/stderr 148 self.canvas.write(data)
149
150 - def get_names(self):
151 ret = [] 152 ret.extend(Cmd.get_names(self)) 153 ret.extend(self.extcmds.keys()) 154 return ret
155
156 - def getExpressionLocals(self):
157 """ 158 Over-ride this to have things like the eval command 159 and the python command use more locals than the sybolic 160 defaults. 161 """ 162 return e_expr.MemoryExpressionLocals(self.memobj, symobj=self.symobj)
163
164 - def registerCmdExtension(self, func, subsys='extended'):
165 self.extcmds["do_%s" % func.__name__] = CliExtMeth(self, func) 166 self.extsubsys[ subsys ].append( func.__name__ )
167
168 - def vprint(self, msg, addnl=True):
169 ''' 170 Print output to the CLI's output handler. This allows routines to 171 print to the terminal or the GUI depending on which mode we're in. 172 173 Example: 174 vprint('hi mom!') 175 ''' 176 if addnl: 177 msg = msg+"\n" 178 self.canvas.write(msg)
179
180 - def __getattr__(self, name):
181 func = self.extcmds.get(name, None) 182 if func == None: 183 raise AttributeError(name) 184 return func
185
186 - def aliascmd(self, line):
187 # Check the "runtime" aliases first 188 for alias,cmd in self.aliases.items(): 189 if line.startswith(alias): 190 return line.replace(alias,cmd) 191 192 # Now the "configured" aliases 193 for alias,cmd in self.config.cli.aliases.items(): 194 if line.startswith(alias): 195 return line.replace(alias,cmd) 196 197 return line
198
199 - def cmdloop(self, intro=None):
200 if intro != None: 201 self.vprint(intro) 202 203 while not self.shutdown.isSet(): 204 try: 205 Cmd.cmdloop(self, intro=intro) 206 except: 207 traceback.print_exc()
208
209 - def onecmd(self, line):
210 lines = line.split("&&") 211 try: 212 for line in lines: 213 line = self.aliascmd( line ) 214 Cmd.onecmd(self, line) 215 except SystemExit: 216 raise 217 except Exception, msg: 218 if self.config.cli.verbose: 219 self.vprint(traceback.format_exc()) 220 self.vprint("\nERROR: (%s) %s" % (msg.__class__.__name__,msg)) 221 222 if self.shutdown.isSet(): 223 return True
224
225 - def do_help(self, line):
226 if line: 227 return Cmd.do_help(self,line) 228 229 self.basecmds.sort() 230 self.vprint('\nbasics:') 231 232 #self.vprint( self.columnize( self.basecmds ) ) 233 self.columnize( self.basecmds ) 234 235 subsys = self.extsubsys.keys() 236 subsys.sort() 237 238 for sub in subsys: 239 self.vprint('\n%s:' % sub) 240 241 cmds = self.extsubsys.get(sub) 242 cmds.sort() 243 244 self.columnize(cmds) 245 246 self.vprint('\n')
247
248 - def do_clear(self, line):
249 ''' 250 Clears the CLI output. (GUI only) 251 ''' 252 self.canvas.clearCanvas()
253
254 - def do_EOF(self, line):
255 self.vprint("Use quit")
256
257 - def do_quit(self, line):
258 """ 259 Quit 260 261 Usage: quit 262 """ 263 self.shutdown.set()
264
265 - def do_config(self, line):
266 ''' 267 Show, edit, or save config options from the command line. 268 269 Usage: config [-s] [config option[=value]] 270 271 no options display config 272 -s save config to default location AFTER setting any options. 273 ''' 274 parser = VOptionParser() 275 parser.add_option('-s', action='store_true', dest='do_save') 276 277 argv = shlex.split(line) 278 try: 279 options, args = parser.parse_args(argv) 280 except Exception as e: 281 self.vprint(repr(e)) 282 return self.do_help('config') 283 284 if len(args) <= 0 and not options.do_save: 285 #FIXME for now we will hard code one level of sections 286 subnames = self.config.getSubConfigNames() 287 subnames.sort() 288 for subname in subnames: 289 subcfg = self.config.getSubConfig(subname) 290 options = subcfg.keys() 291 options.sort() 292 for optname in options: 293 optval = subcfg.get(optname) 294 self.vprint('%s.%s=%s' % (subname, optname, json.dumps(optval))) 295 296 return 297 298 # 1 option per run 299 if len(args) > 1: 300 return self.do_help('config') 301 302 if len(args) == 1: 303 parts = args[0].split('=', 1) 304 subname, optname = parts[0].split('.', 1) 305 306 subcfg = self.config.getSubConfig(subname, add=False) 307 if subcfg == None: 308 self.vprint('No Such Config Section: %s' % subname) 309 return 310 311 optval = subcfg.get(optname) 312 if optval == None: 313 self.vprint('No Such Config Option: %s' % optname) 314 return 315 316 if len(parts) == 2: 317 newval = json.loads(parts[1]) 318 319 if type(newval) not in (str,unicode) or type(optval) not in (str,unicode): 320 if type(newval) != type(optval): 321 self.vprint('Invalid Type Mismatch: %r - %r' % (newval,optval)) 322 return 323 324 optval = newval 325 subcfg[optname] = newval 326 327 self.vprint('%s.%s=%s' % (subname, optname, json.dumps(optval))) 328 329 if options.do_save: 330 self.config.saveConfigFile() 331 self.vprint('saved configuration file to: %s' % self.config.filename)
332
333 - def do_alias(self, line):
334 """ 335 Add an alias to the command line interpreter's aliases dictionary 336 Usage: alias <alias_word> rest of the alias command 337 338 To delete an alias: 339 Usage: alias <alias_word> 340 """ 341 if len(line): 342 row = line.split(None, 1) 343 self.config.cli.aliases.pop(row[0]) 344 if len(row) > 1: 345 self.config.cli.aliases[ row[0] ] = row[1] 346 347 self.vprint('') 348 self.vprint('Runtime Aliases (not saved):') 349 aliases = self.aliases.keys() 350 aliases.sort() 351 for alias in aliases: 352 self.vprint('%s -> %s' % (alias,self.aliases.get(alias))) 353 self.vprint('') 354 355 self.vprint('Configured Aliases:') 356 aliases = self.config.cli.aliases.keys() 357 aliases.sort() 358 for alias in aliases: 359 self.vprint('%s -> %s' % (alias,self.config.cli.aliases.get(alias))) 360 self.vprint('') 361 return
362
363 - def do_python(self, line):
364 """ 365 Start an interactive python interpreter. The namespace of the 366 interpreter is updated with expression nicities. You may also 367 specify a line of python code as an argument to be exec'd without 368 beginning an interactive python interpreter on the controlling 369 terminal. 370 371 Usage: python [pycode] 372 """ 373 locals = self.getExpressionLocals() 374 if len(line) != 0: 375 cobj = compile(line, 'cli_input', 'exec') 376 exec(cobj, locals) 377 else: 378 code.interact(local=locals)
379
380 - def parseExpression(self, expr):
381 l = self.getExpressionLocals() 382 return long(e_expr.evaluate(expr, l))
383
384 - def do_binstr(self, line):
385 ''' 386 Display a binary representation of the given value expression 387 (padded to optional width in bits) 388 389 Usage: binstr <val_expr> [<bitwidth_expr>] 390 ''' 391 argv = splitargs(line) 392 if len(argv) == 0: 393 return self.do_help('binstr') 394 bitwidth = None 395 value = self.parseExpression(argv[0]) 396 if len(argv) > 1: 397 bitwidth = self.parseExpression(argv[1]) 398 binstr = e_bits.binrepr(value, bitwidth=bitwidth) 399 self.canvas.addText("0x%.8x (%d) %s\n" % (value, value, binstr))
400
401 - def do_eval(self, line):
402 """ 403 Evaluate an expression on the CLI to show it's value. 404 405 Usage: eval (ecx+edx)/2 406 """ 407 if not line: 408 return self.do_help("eval") 409 410 value = self.parseExpression(line) 411 412 self.canvas.addText("%s = " % line) 413 if self.memobj.isValidPointer(value): 414 self.canvas.addVaText("0x%.8x" % value, value) 415 sym = self.symobj.getSymByAddr(value, exact=False) 416 if sym != None: 417 self.canvas.addText(" ") 418 self.canvas.addVaText("%s + %d" % (repr(sym),value-long(sym)), value) 419 else: 420 self.canvas.addText("0x%.8x (%d)" % (value, value)) 421 422 self.canvas.addText("\n")
423
424 - def do_script(self, line):
425 ''' 426 Execute a python file. 427 428 The script file is arbitrary python code which is run with the 429 full complement of expression extensions mapped in as locals. 430 431 The script command sources the env var ENVI_SCRIPT_PATH. 432 433 NOTE: additional command line arguments may be passed in and will 434 appear as the list "argv" in the script namespace! (They will 435 all be strings) 436 437 Usage: script <scriptfile> [<argv[0]>, ...] 438 ''' 439 if len(line) == 0: 440 return self.do_help('script') 441 442 argv = splitargs(line) 443 locals = self.getExpressionLocals() 444 locals['argv'] = argv 445 446 # TODO: unify vdb.extensions.loadExtensions VDB_EXT_PATH with this 447 # TODO: where should env var parsing live? 448 scriptpath = None 449 if os.path.exists(argv[0]): 450 scriptpath = argv[0] 451 else: 452 for scriptdir in self.scriptpaths: 453 # allow scripts to import things from the script dir 454 if scriptdir not in sys.path: 455 sys.path.append(scriptdir) 456 457 spath = os.path.join(scriptdir, argv[0]) 458 if os.path.exists(spath): 459 scriptpath = spath 460 461 if scriptpath == None: 462 self.vprint('failed to find script') 463 return 464 465 with open(scriptpath, 'rb') as f: 466 contents = f.read() 467 468 try: 469 cobj = compile(contents, scriptpath, 'exec') 470 exec(cobj, locals) 471 except Exception, e: 472 self.vprint( traceback.format_exc() ) 473 self.vprint('SCRIPT ERROR: %s' % e)
474
475 - def do_maps(self, line):
476 """ 477 Display either a list of all the memory maps or the memory map 478 details for the given address expression. 479 480 Usage: maps [addr_expression] 481 """ 482 argv = splitargs(line) 483 if len(argv): 484 expr = " ".join(argv) 485 va = self.parseExpression(expr) 486 map = self.memobj.getMemoryMap(va) 487 if map == None: 488 self.vprint("Memory Map Not Found For: 0x%.8x"%va) 489 490 else: 491 addr,size,perm,fname = map 492 pname = e_mem.reprPerms(perm) 493 self.canvas.addText("Memory Map For: ") 494 self.canvas.addVaText("0x%.8x" % va, va) 495 self.canvas.addText("\n") 496 self.canvas.addVaText("0x%.8x" % addr, addr) 497 self.canvas.addText("\t%d\t%s\t%s\n" % (size,pname,fname)) 498 else: 499 totsize = 0 500 self.vprint("[ address ] [ size ] [ perms ] [ File ]") 501 for addr,size,perm,fname in self.memobj.getMemoryMaps(): 502 pname = e_mem.reprPerms(perm) 503 totsize += size 504 self.canvas.addVaText("0x%.8x" % addr, addr) 505 sizestr = ("%dK" % (size/1024,)).rjust(8) 506 self.canvas.addText("%s\t%s\t%s\n" % (sizestr,pname,fname)) 507 self.vprint("Total Virtual Memory: %.2f MB" % ((float(totsize)/1024)/1024))
508
509 - def do_saveout(self, line):
510 ''' 511 saves output to file for any command. still outputs to whatever 512 canvas the command normally outputs to. 513 514 saveout <output file> <cli command> 515 516 Example: 517 saveout out.txt search -c MZ 518 ''' 519 argv = shlex.split(line) 520 if len(argv) < 2: 521 return self.do_help('saveout') 522 523 fname = argv[0] 524 command = ' '.join(argv[1:]) 525 526 strcanvas = e_canvas.StringMemoryCanvas(self.canvas.mem) 527 with e_canvas.TeeCanvas(self, (self.canvas, strcanvas)) as tc: 528 self.onecmd(command) 529 530 with open(fname, 'wb') as f: 531 f.write(str(strcanvas))
532
533 - def do_search(self, line):
534 ''' 535 search memory for patterns. 536 537 search [options] <pattern> 538 539 -e <codec> encode the pattern with a codec (hex, utf-16le, etc) 540 -X pattern is in hex (ie. 41414242 is AABB) 541 -E pattern is an envi memory expression (numeric search) 542 -r pattern is a regular expression 543 -R <baseexpr:sizeexpr> search a range of memory (base + size) 544 -c show context (32 bytes) after each hit 545 ''' 546 parser = VOptionParser() 547 parser.add_option('-e', action='store', dest='encode_as') 548 parser.add_option('-X', action='store_true', dest='is_hex') 549 parser.add_option('-E', action='store_true', dest='is_expr') 550 parser.add_option('-r', action='store_true', dest='is_regex') 551 parser.add_option('-R', action='store', dest='range_search') 552 parser.add_option('-c', action='store_const', dest='num_context_bytes', 553 const=32) 554 555 argv = shlex.split(line) 556 try: 557 options, args = parser.parse_args(argv) 558 except Exception as e: 559 self.vprint(repr(e)) 560 return self.do_help('search') 561 562 pattern = ' '.join(args) 563 if len(pattern) == 0: 564 self.vprint('you must specify a pattern') 565 return self.do_help('search') 566 567 if options.is_expr: 568 import struct #FIXME see below 569 sval = self.parseExpression(pattern) 570 pattern = struct.pack('<L', sval) # FIXME 64bit (and alt arch) 571 572 if options.is_hex: 573 pattern = pattern.decode('hex') 574 575 if options.encode_as != None: 576 pattern = pattern.encode(options.encode_as) 577 578 if options.range_search: 579 try: 580 addrexpr, sizeexpr = options.range_search.split(":") 581 except Exception, e: 582 self.vprint(repr(e)) 583 return self.do_help('search') 584 addr = self.parseExpression(addrexpr) 585 size = self.parseExpression(sizeexpr) 586 587 self.canvas.addText('searching from ') 588 self.canvas.addVaText('0x%.8x' % addr, addr) 589 self.canvas.addText(' for %d bytes\n' % size) 590 res = self.memobj.searchMemoryRange(pattern, addr, size, regex=options.is_regex) 591 else: 592 self.vprint('searching all memory...') 593 res = self.memobj.searchMemory(pattern, regex=options.is_regex) 594 595 if len(res) == 0: 596 self.vprint('pattern not found: %s (%s)' % (pattern.encode('hex'), repr(pattern))) 597 return 598 599 brend = e_render.ByteRend() 600 self.vprint('matches for: %s (%s)' % (pattern.encode('hex'), repr(pattern))) 601 for va in res: 602 mbase,msize,mperm,mfile = self.memobj.getMemoryMap(va) 603 pname = e_mem.reprPerms(mperm) 604 sname = self.reprPointer(va) 605 606 self.canvas.addVaText('0x%.8x' % va, va) 607 self.canvas.addText(': ') 608 self.canvas.addText('%s ' % pname) 609 self.canvas.addText(sname) 610 611 if options.num_context_bytes != None: 612 self.canvas.addText('\n') 613 self.canvas.renderMemory(va, options.num_context_bytes, rend=brend) 614 615 self.canvas.addText('\n') 616 617 self.vprint('done (%d results).' % len(res))
618
619 - def reprPointer(self, va):
620 """ 621 Do your best to create a humon readable name for the 622 value of this pointer. 623 """ 624 if va == 0: 625 return "NULL" 626 627 mbase,msize,mperm,mfile = self.memobj.getMemoryMap(va) 628 ret = mfile 629 sym = self.symobj.getSymByAddr(va, exact=False) 630 if sym != None: 631 ret = "%s + %d" % (repr(sym),va-long(sym)) 632 return ret
633
634 - def do_memdump(self, line):
635 """ 636 Dump memory to a file. If no size is given, the entire memory map that 637 contains the given va is dumped to disk. 638 639 Usage: memdump <va_expression> <filename> [size_expression] 640 """ 641 argv = shlex.split(line) 642 if len(argv) not in (2, 3): 643 return self.do_help('memdump') 644 645 va = self.parseExpression(argv[0]) 646 fname = argv[1] 647 648 if len(argv) == 2: 649 va, size, perm, name = self.memobj.getMemoryMap(va) 650 elif len(argv) == 3: 651 size = self.parseExpression(argv[2]) 652 else: 653 return self.do_help('memdump') 654 655 mem = self.memobj.readMemory(va, size) 656 with open(fname, 'wb') as f: 657 f.write(mem) 658 659 self.vprint('wrote %d bytes.' % len(mem))
660
661 - def do_memcmp(self, line):
662 ''' 663 Compare memory at the given locations. Outputs a set of 664 differences showing bytes at their given offsets.... 665 666 Usage: memcmp <addr_expr1> <addr_expr2> <size_expr> 667 ''' 668 if len(line) == 0: 669 return self.do_help('memcmp') 670 671 argv = splitargs(line) 672 if len(argv) != 3: 673 return self.do_help('memcmp') 674 675 addr1 = self.parseExpression(argv[0]) 676 addr2 = self.parseExpression(argv[1]) 677 size = self.parseExpression(argv[2]) 678 679 bytes1 = self.memobj.readMemory(addr1, size) 680 bytes2 = self.memobj.readMemory(addr2, size) 681 682 res = e_mem.memdiff(bytes1, bytes2) 683 if len(res) == 0: 684 self.vprint('No Differences!') 685 return 686 687 for offset, offsize in res: 688 diff1 = addr1+offset 689 diff2 = addr2+offset 690 self.canvas.addText('==== %d byte difference at offset %d\n' % (offsize,offset)) 691 self.canvas.addVaText("0x%.8x" % diff1, diff1) 692 self.canvas.addText(":") 693 self.canvas.addText(bytes1[offset:offset+offsize].encode('hex')) 694 self.canvas.addText('\n') 695 self.canvas.addVaText("0x%.8x" % diff2, diff2) 696 self.canvas.addText(":") 697 self.canvas.addText(bytes2[offset:offset+offsize].encode('hex')) 698 self.canvas.addText('\n')
699
700 - def do_mem(self, line):
701 """ 702 Show some memory (with optional formatting and size) 703 704 Usage: mem [-F <format>] <addr expression> [size] 705 706 NOTE: use -F ? for a list of the formats 707 """ 708 fmtname = "bytes" 709 710 if len(line) == 0: 711 return self.do_help("mem") 712 713 argv = splitargs(line) 714 try: 715 opts,args = getopt(argv, "F:") 716 except: 717 return self.do_help("mem") 718 719 for opt,optarg in opts: 720 if opt == "-F": 721 fmtname = optarg 722 fnames = self.canvas.getRendererNames() 723 724 if fmtname == "?": 725 self.vprint("Registered renderers:") 726 for name in fnames: 727 self.vprint(name) 728 return 729 730 if fmtname not in fnames: 731 self.vprint("Unknown renderer: %s" % fmtname) 732 return 733 734 if len(args) == 0: 735 return self.do_help("mem") 736 737 size = 256 738 addr = self.parseExpression(args[0]) 739 if len(args) == 2: 740 size = self.parseExpression(args[1]) 741 742 self.canvas.setRenderer(fmtname) 743 self.canvas.renderMemory(addr, size)
744
745 -class EnviMutableCli(EnviCli):
746 """ 747 Cli extensions which require a mutable memory object 748 (emulator/trace) rather than a static one (viv workspace) 749 """ 750
751 - def do_memcpy(self, line):
752 ''' 753 Copy memory from one location to another... 754 755 Usage: memcpy <dest_expr> <src_expr> <size_expr> 756 ''' 757 argv = splitargs(line) 758 if len(argv) != 3: 759 return self.do_help('memcpy') 760 761 762 dst = self.parseExpression(argv[0]) 763 src = self.parseExpression(argv[1]) 764 siz = self.parseExpression(argv[2]) 765 766 mem = self.memobj.readMemory(src, siz) 767 self.memobj.writeMemory(dst, mem)
768
769 - def do_memprotect(self, line):
770 """ 771 Change the memory permissions of a given page/map. 772 773 Usage: memprotect [options] <addr_expr> <perms> 774 -S <size> Specify the size of the region to change (default == whole memory map) 775 <perms> = "rwx" string "rw", "rx" "rwx" etc... 776 """ 777 if len(line) == 0: 778 return self.do_help("memprotect") 779 780 size = None 781 argv = splitargs(line) 782 try: 783 opts, args = getopt(argv, "S:") 784 except Exception, e: 785 return self.do_help("memprotect") 786 787 for opt,optarg in opts: 788 if opt == "-S": 789 size = self.parseExpression(optarg) 790 791 if len(args) != 2: 792 return self.do_help("memprotect") 793 794 795 addr = self.parseExpression(args[0]) 796 perm = e_mem.parsePerms(args[1]) 797 798 if size == None: 799 map = self.memobj.getMemoryMap(addr) 800 if map == None: 801 raise Exception("Unknown memory map for 0x%.8x" % addr) 802 size = map[1] 803 804 self.memobj.protectMemory(addr, size, perm)
805
806 - def do_writemem(self, args):
807 """ 808 Over-write some memory in the target address space. 809 Usage: writemem [options] <addr expression> <string> 810 -X The specified string is in hex (ie 414141 = AAA) 811 -U The specified string needs to be unicode in mem (AAA -> 410041004100) 812 """ 813 dohex = False 814 douni = False 815 816 try: 817 argv = splitargs(args) 818 opts,args = getopt(argv, "XU") 819 except: 820 return self.do_help("writemem") 821 822 if len(args) != 2: 823 return self.do_help("writemem") 824 825 for opt,optarg in opts: 826 if opt == "-X": 827 dohex = True 828 elif opt == "-U": 829 douni = True 830 831 exprstr, memstr = args 832 if dohex: memstr = memstr.decode('hex') 833 if douni: memstr = ("\x00".join(memstr)) + "\x00" 834 835 addr = self.parseExpression(exprstr) 836 self.memobj.writeMemory(addr, memstr)
837