Patch: Win32 stack overflow
Christian Tismer
tismer at appliedbiometrics.com
Wed Jun 2 06:13:05 EDT 1999
Patch for python15.dll
stack152.py
--
Christian Tismer :^) <mailto:tismer at appliedbiometrics.com>
Applied Biometrics GmbH : Have a break! Take a ride on Python's
Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net
10553 Berlin : PGP key -> http://wwwkeys.pgp.net
PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF
we're tired of banana software - shipped green, ripens at home
-------------- next part --------------
######################################
# patching Python 1.5.2 dll file
# to adjust maximum recusion depth.
# CT 990602
"""
What is this patch for?
Python 1.5.2 calls eval_code recursively for every
call of a python function. The current maximum
recursion depth is compiled into python15.dll
to be 10000.
My measures have shown that each recursive call
costs 104 bytes, when Python is compiled with MS VC++ 5.0.
The default stack size for a Windows program is 1 MB, and
this is slightly too few for 10000 calls.
The secure limit seems to be below 9610.
Note that this is no problem with MS VC++ 6.0, since
due to better register spilling, the stack growth per
recursion is only 100 byte :-)
Note also that for certain applications with different
stack requirements/compilation options, this patch might
be used to set the maximum recusion depth to any
arbitrary limit.
Test program:
def f():return f()
f()
After applying the patch, this sequence should give
a stack overflow error, but no general protection fault
any longer.
good luck - chris
"""
import string, struct, win32api
ORIG_OFFSET = 49785 # offset of signature in 1.5.2 orig dll
SIGNATURE = "\x89\x57\x0c\x3d"
DEF_FNAME = win32api.GetModuleFileName(win32api.GetModuleHandle("python15.dll"))
LIMIT = 9610 # secure under VC++ 5.0
def _get_stacksize(fname):
"""determine stack size of a Python 1.5.2 dll file"""
f = open(fname, "rb")
bin = f.read()
if not string.find(bin, SIGNATURE) or len(string.split(bin, SIGNATURE)) != 2 :
raise SystemError, "this is no python 1.5.2 dll file"
else:
offset = string.find(bin, SIGNATURE)
off2 = offset+4
word = bin[off2:off2+4]
return offset, struct.unpack("i", word)[0]
def stacksize(fname):
offset, stack = _get_stacksize(fname)
if offset != ORIG_OFFSET:
print "this is no standard Python 1.5.2 dll, but it seems to be valid"
return stack
def patch(fnold, fnnew, size):
bin = open(fnold, "rb").read()
left, right = string.split(bin, SIGNATURE)
right = struct.pack("i", size) + right[4:]
bin = left + SIGNATURE + right
open(fnnew, "wb").write(bin)
if __name__ == "__main__":
ssize = stacksize(DEF_FNAME)
print "Your current python recursion depth is %d" % ssize
newsize = raw_input("stacksize = %d. Enter new size (to be sure, below %d)" \
% (ssize, LIMIT))
try:
newsize = string.atoi(string.strip(newsize))
old = DEF_FNAME
new = old+".NEW"
patch(old, new, newsize)
print "File %s created with recusion depth of %d." % (new, newsize)
print "please quit python, delete %s\n and rename %s to %s" % \
(old, new, old)
except ValueError:
print "Recursion depth not changed."
# simply run this program.
# (c) Christian Tismer
# Professional Net Service GmbH
More information about the Python-list
mailing list