Skip to content

Instantly share code, notes, and snippets.

@JohnHammond
Created June 20, 2021 14:44
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save JohnHammond/f78a9d878585bad232cba060c1d79623 to your computer and use it in GitHub Desktop.
Save JohnHammond/f78a9d878585bad232cba060c1d79623 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""
# NOTE, you must change the string below for data you want.
# This script does not take arguments in its current form. Sorry!
"""
from pwn import *
string = b"foobar"
full = "eax"
half = "ax"
little = "al"
pieces = []
for i in range(0, len(string), 4):
chunk = string[i : i + 4]
pieces.append((hex(unpack(chunk, "all")), chunk.decode("utf-8")))
counter = 0
for each in pieces[::-1]:
piece, value = each
if len(piece) <= 10:
register = full
if len(piece) <= 6:
print(f'"xor {full}, {full};" # zero out {full}')
register = half
print(f'"mov {register}, {piece}"; # ensure nullbyte')
print(f"\"push {full};\" # end of string '{value}' with nullbyte")
counter += 1
continue
if len(piece) <= 4:
print(f'"xor {full}, {full};" # zero out {full}')
register = little
print(f'"mov {register}, {piece};" # ensure nullbyte')
print(f"\"push {full};\" # end of string '{value}' with nullbyte")
counter += 1
continue
if counter == 0:
print(f'"xor {full}, {full};" # zero out {full}')
print(f'"push {full};" # ensure nullbyte')
print(f"\"push {piece};\" # push '{value}' onto stack")
counter += 1
@esp0xdeadbeef
Copy link

hi John,

I've successfully used your script and added argument functionality. Here's the slight modified version:

#!/usr/bin/env python3

"""
This script takes an argument for the desired string.

Original script by John Hammond:
https://gist.github.com/JohnHammond/f78a9d878585bad232cba060c1d79623

Edited by esp0xdeadbeef
"""

import argparse
from pwn import *

# argparse setup
parser = argparse.ArgumentParser(description="Process a given string for pwn purposes.")
parser.add_argument("string", type=str, help="Input string to process")
parser.add_argument("--as-python-string", action='store_true', help="Output as a Python string format")
args = parser.parse_args()

if not args.string:
    print("Error: Please provide a non-empty string.")
    exit(1)

string = args.string.encode()

full = "eax"
half = "ax"
little = "al"

pieces = []
for i in range(0, len(string), 4):
    chunk = string[i : i + 4]
    pieces.append((hex(unpack(chunk, "all")), chunk.decode("utf-8")))

def output_instruction(instruction, comment, as_python_string):
    if as_python_string:
        print(f'"{instruction};" # {comment}')
    else:
        print(f'{instruction} ; # {comment}')

counter = 0
for each in pieces[::-1]:
    piece, value = each
    if len(piece) <= 10:
        register = full
    if len(piece) <= 6:
        output_instruction(f'xor {full}, {full}', f'zero out {full}', args.as_python_string)
        register = half
        output_instruction(f'mov {register}, {piece}', f'ensure nullbyte', args.as_python_string)
        output_instruction(f'push {full}', f"end of string '{value}' with nullbyte", args.as_python_string)
        counter += 1
        continue
    if len(piece) <= 4:
        output_instruction(f'xor {full}, {full}', f'zero out {full}', args.as_python_string)
        register = little
        output_instruction(f'mov {register}, {piece}', f'ensure nullbyte', args.as_python_string)
        output_instruction(f'push {full}', f"end of string '{value}' with nullbyte", args.as_python_string)
        counter += 1
        continue
    if counter == 0:
        output_instruction(f'xor {full}, {full}', f'zero out {full}', args.as_python_string)
        output_instruction(f'push {full}', 'ensure null byte', args.as_python_string)

    output_instruction(f'push {piece}', f"push '{value}' onto stack", args.as_python_string)
    counter += 1
$ ./stack_string_edit.py "foobar"
xor eax, eax ; # zero out eax
mov ax, 0x7261 ; # ensure nullbyte
push eax ; # end of string 'ar' with nullbyte
push 0x626f6f66 ; # push 'foob' onto stack
$ ./stack_string_edit.py --as-python-string "foobar"
"xor eax, eax;" # zero out eax
"mov ax, 0x7261;" # ensure nullbyte
"push eax;" # end of string 'ar' with nullbyte
"push 0x626f6f66;" # push 'foob' onto stack
$ ./stack_string.py # Original code's output for comparison
"xor eax, eax;" # zero out eax
"mov ax, 0x7261"; # ensure nullbyte
"push eax;" # end of string 'ar' with nullbyte
"push 0x626f6f66;" # push 'foob' onto stack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment