Created
July 13, 2012 17:00
-
-
Save mkmik/3105991 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import dis | |
import inspect | |
def lineno(): | |
"""Returns the current line number in our program.""" | |
return inspect.currentframe().f_back.f_lineno | |
def test(): | |
print "hello, from line", lineno() | |
print "hello, again from line", lineno() | |
def clone_code(c, firstlineno, lnotab): | |
return (type(c)(c.co_argcount,c.co_nlocals,c.co_stacksize,c.co_flags,c.co_code,c.co_consts,c.co_names,c.co_varnames,c.co_filename,c.co_name,firstlineno,lnotab,c.co_freevars,c.co_cellvars)) | |
def patch(f, line_mapping=dict()): | |
tab = [i for i in f.func_code.co_lnotab] | |
print "Line number table" | |
print repr(''.join(tab)) | |
for op_pos, line_delta in zip((ord(tab[i]) for i in xrange(0, len(tab)-1, 2)), (ord(tab[i]) for i in xrange(1, len(tab), 2))): | |
print op_pos, line_delta + f.func_code.co_firstlineno | |
print "----" | |
for i, line_delta in ((i, ord(tab[i])) for i in xrange(1, len(tab), 2)): | |
print 'IDX', line_delta | |
tab[i] = chr(line_delta + 1) | |
print repr(''.join(tab)) | |
print "Before patching" | |
dis.disassemble(f.func_code) | |
f.func_code = clone_code(f.func_code, f.func_code.co_firstlineno, ''.join(tab)) | |
print "After patching" | |
dis.disassemble(f.func_code) | |
if __name__ == '__main__': | |
test() | |
patch(test) | |
test() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
hello, from line 11 | |
hello, again from line 13 | |
Line number table | |
'\x00\x01\x0c\x02' | |
0 11 | |
12 12 | |
---- | |
IDX 1 | |
IDX 2 | |
'\x00\x02\x0c\x03' | |
Before patching | |
11 0 LOAD_CONST 1 ('hello, from line') | |
3 PRINT_ITEM | |
4 LOAD_GLOBAL 0 (lineno) | |
7 CALL_FUNCTION 0 | |
10 PRINT_ITEM | |
11 PRINT_NEWLINE | |
13 12 LOAD_CONST 2 ('hello, again from line') | |
15 PRINT_ITEM | |
16 LOAD_GLOBAL 0 (lineno) | |
19 CALL_FUNCTION 0 | |
22 PRINT_ITEM | |
23 PRINT_NEWLINE | |
24 LOAD_CONST 0 (None) | |
27 RETURN_VALUE | |
After patching | |
12 0 LOAD_CONST 1 ('hello, from line') | |
3 PRINT_ITEM | |
4 LOAD_GLOBAL 0 (lineno) | |
7 CALL_FUNCTION 0 | |
10 PRINT_ITEM | |
11 PRINT_NEWLINE | |
15 12 LOAD_CONST 2 ('hello, again from line') | |
15 PRINT_ITEM | |
16 LOAD_GLOBAL 0 (lineno) | |
19 CALL_FUNCTION 0 | |
22 PRINT_ITEM | |
23 PRINT_NEWLINE | |
24 LOAD_CONST 0 (None) | |
27 RETURN_VALUE | |
hello, from line 12 | |
hello, again from line 15 |
There is a trick to add new statements to python, but it breaks line positions in debugger and exception stack traces.
This was the first attempt to play with that. I have a complete solution at:
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Shell codes for a new virus?