REpdb

class REpdb.RePdb(completekey='tab', stdin=None, stdout=None)[source]

Extended pdb debugger with functionality useful when reverse engineering Python .pyc/.pyo files without the .py source

cleanup(args)[source]

Cleanup function, currently just stops the callgraph if it has been started

closest(target, collection)[source]

For a list of integers and a given value find the list element it’s closest to

do_auto_remap(remapped_pycs)[source]

Make some best guesses on how to remap the opcodes from the currently running obfuscated runtime.

NOTE: If there is an exiting auto_remap project it will be overwritten

Usage: auto_remap <path to remapped pycs>

do_detect_version(args)[source]

Try to determine the version of the running Python (the runtime we are injected into)

If there is a mismatch between the different ways we can do this you will be prompted to choose for yourself

Usage: detect_version

do_download_runtime(version)[source]

Download the specified Python runtime sourcecode from python.org and decompress it. It is saved to the ‘Downloaded_Runtimes’ subdir and shared between all projects

Usage: download_runtime 2.5.4

do_fs_mem_decompile(path=None)[source]

Decompile obfuscated bytecode by traversing the filesystem from a given start point but do NOT rely on the presence of the marshal module to be able to get thebytecode from the pyc file found. Instead each pyc found is imported and each of its objects are interogated for their bytecode. These bytecode objects are what is decompiled.

Note: If the current obfuscated runtime does not have the marshal module
available but you do have access to the filesystem where the obfuscated pyc’s reside then this is the technique to use.

usage: fs_mem_decompile <path to obfuscated pyc’s> example: fs_mem_decompile /tmp/foo.app/Contents/Resources/runtime/site_packages/

do_fs_um_decompile(path=None)[source]

Decompile obfuscated bytecode by traversing the filesystem from a given start point and using the current runtimes marshal module to unmarshal the bytecode of each .pyc found.

Note: If the current obfuscated runtime does not have the marshal module
available then this decompilation technique cannot be used.

usage: fs_um_decompile <path to obfuscated pyc’s> example: fs_um_decompile /tmp/foo.app/Contents/Resources/runtime/site_packages/

do_gen_obf(obfuscated_modules=None)[source]

Generate obfuscated Python bytecode for the modules at the path specified using the current runtime we are running from. The generated bytecode will be used to diff against the reference bytecode to deduce a modified opcode map. In general you should point this at the directory containing the obfuscated stdlib .pyc’s for the obfuscated runtime

The more commonality between the reference and obfuscated bytecode there the higher the number of opcodes that will be able to be remapped.

Usage: gen_obf <path to directory of obfusctaed python .pyc’s> Example: gen_obf /tmp/foo.app/Contents/Resources/runtime/site_packages/

do_gen_ref(reference_modules=None)[source]

Generate reference bytecode from the .py’s at the path specified using the Python runtime version already set. If not path is specified the relevant Python runtime will be used if it has already been downloaded with download_runtime.

The generated bytecode will be used to diff against the obfuscated bytecode to deduce a modified opcode map. The more commonality between the reference and obfuscated bytecode there the higher the number of opcodes that will be able to be remapped.

Usage: gen_ref [to use the downloaded runtime of the current project
version as the reference source]

gen_ref <path to directory of reference python source code>

Example: gen_ref /tmp/python2.5.4/Lib

do_get_version(args)[source]

Get the reported version of the currently executing Python runtime Note: This may not be accurate, a runtime can be made to report any version.

Use only as an indicator when choosing a reference runtime to use.

usage: get_version

do_is_remapped(args=None)[source]

Determine if the current runtime has remapped its opcode table

Usage: is_remapped

do_obj_mirror(args)[source]

For the supplied object, all of it’s methods/attributes etc are mirrored in the calling objects namespace This is a dirty way of acting as an object proxy meaning we can be injected in place of another object and be sure we won’t break the larger app

If no frame is specified then the frame from which the debugger was called is used If “debugger” is given as the frame the debugger frame is used

Usage: obj_mirror <instantiated object to mirror>

do_pure_mem_decompile(obj=None)[source]

Decompile to source code purely from instantiated objects. This assumes no availability of the marshal module or even access to the filesystem where the pyc files reside, this decompiles directly from the currently executing runtimes namespace. The specified object is decompiled and the objects it contains are traversed and decompiled until no more remain.

[ Currently available objects can be seen by typing dir() at the REpdb prompt]

usage: pure_mem_decompile <name of object to decompile> example: pure_mem_decompile AnObjectsName

do_recompile(path)[source]

For the path specified do a recursive recompilation of all .py’s found using the current runtimes compiler (if available)

Usage: recompile <path to modules> Example: recompile /tmp/python_254/Libs

do_remap(dirs=None)[source]

From the two sets of .pyb’s produced by gen_r2x and gen_o2x do the compares to work out the new opcode map. From this new opcode map create new files opcode.py (for the running stdlib) and opcodes.py (for UnPYC)

Note: the .pyb’s must already have been generated from the gen_xxx calls

Usage: remap

do_restore_opcodes(args)[source]

Restore the original opcode.py and opcodes.py module that was archived by swap_opcodes

Usage: restore_opcodes

do_set_callgraph_exclude(excludes)[source]

Set an exclusion filter for the callgraph functionality, this defines modules/functions that are not included in the callgraph tracing

Argument is a comma seperated list of filter expresions

Usage: set_callgraph_exclude foo,bar*,blat

do_set_project(name)[source]

Create a new project or switch to an existing one

Usage: set_project <project name>

do_set_py24(loc)[source]

Reset the location of the standard Python 2.4 runtime used to generate reference bytecode

Usage: set_py24 /usr/local/bin/python2.4

do_set_py25(loc)[source]

Reset the location of the standard Python 2.5 runtime used to generate reference bytecode

Usage: set_py25 /usr/local/bin/python2.5

do_set_py26(loc)[source]

Reset the location of the standard Python 2.6 runtime used to generate reference bytecode

Usage: set_py26 /usr/local/bin/python2.6

do_set_py27(loc)[source]

Reset the location of the standard Python 2.7 runtime used to generate reference bytecode

Usage: set_py27 /usr/local/bin/python2.7

do_set_version(version)[source]

Set the version number of the runtime we are running in to a specific value

Usage: set_version 2.5.4

do_setprojectroot(location)[source]

Leave the project name the same but change the root directory location on the filesystem. The currently set project is used as the project to relocate

Usage: set_project_root /tmp/pyretic_dump

do_show(args)[source]

Print out all the current settings for this REpdb project

Usage: show

do_start_callgraph(name)[source]

Initialise a callgraph trace using pycallgraph After this is set use the pdb commands ‘n’, ‘c’ etc to step through the application being debugged and generate the callgraph

The callgraph can be stopped & written at anytime by ‘stop_callgraph’, if the debugging exits the callgraph is automatically stopped and written

Usage: start_callgraph <name of callgraph if you want non-default name>

do_stop_callgraph(foo)[source]

Stop & print callgraph

Usage: stop_callgraph

do_swap_opcodes(args=None)[source]

Swap the remapped opcodes.py module for the original module in the UnPYC directory. Until this is done UnPYC will not be able to decompile correctly as it will be using the wrong opcode map. The opcodes.py file that will be used is the one that is located at the PROJECT_DIR/libs

Ssage: swap_modules

does_project_exist(name)[source]

Determine whether a project of the given name already exists

Return boolean

py_ver_downloaded(ver)[source]

Has the specifiedversion of Python already been downloaded ?

remap_complete()[source]

For the current project has a re-mapped opcode table been generated, set var accordingly ?

set_py(loc, ver)[source]

Set the location of the python runtime for the specified version Called from the other do_set_py* functions

switch_project(name)[source]

Switch to another project descriptor

trace_dispatch(frame, event, arg)[source]

Overide the bdb trace_dispatch method so as we can add in more trace hooks for other functionality such as call graphing

Previous topic

pyREtic

Next topic

liveUnPYC

This Page