When to reach for this
Crash hit, EIP overwritten with garbage, need to know the exact offset from buffer start to EIP. Send a known cyclic pattern, read EIP from the debugger, look up the offset.
The snippet — pure-python pattern generation
No pattern_create.rb dependency. The Metasploit pattern
is Aa0Aa1Aa2...Zz9 (uppercase × lowercase × digit), each
triplet unique within the first 20,280 bytes.
import string
def cyclic(length: int) -> bytes:
out = bytearray()
for u in string.ascii_uppercase:
for l in string.ascii_lowercase:
for d in string.digits:
if len(out) >= length:
return bytes(out[:length])
out.extend((ord(u), ord(l), ord(d)))
return bytes(out)
def offset(needle: bytes, length: int = 20280) -> int:
"""needle: 4 bytes, e.g. value of EIP at crash, in send-order.
Note: x86 is little-endian, so EIP=0x37674136 was sent as b'6Ag7'."""
return cyclic(length).find(needle)
# usage in exploit script:
buf = cyclic(2000)
# ... after crash, EIP shown in debugger as e.g. 0x37624136 ('6Ab7')
print(offset(b'6Ab7')) # -> integer offsetVariants
mona pattern_create 2000in WinDbg / Immunity: same idea, runs in the debugger- For lengths beyond 20,280, append more variations (mona uses extended charsets)
Source / origin
Reimplementation of Metasploit’s pattern_create.rb
algorithm. Keeping it as Python avoids a Ruby dependency in your exploit
pipeline.