str0.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #!/usr/bin/python3
  2. """
  3. Finds the location of strings and patches the first character to the null terminator,
  4. preventing the messages from being displayed in the server console.
  5. This can be executed while the server is running (on Linux, may not be successful on Windows).
  6. """
  7. # to automatically patch after game updates use the following incron:
  8. # /path/to/binary IN_CLOSE_WRITE,loopable=true python3 /path/to/str0.py $@/$# -c /path/to/config.txt
  9. import argparse
  10. import ast
  11. import configparser
  12. import mmap
  13. import os
  14. def patch_to_null(mbin, target):
  15. offset = mbin.find(target.encode('ascii'))
  16. if offset == -1:
  17. return False
  18. mbin.seek(offset)
  19. mbin.write_byte(0)
  20. mbin.flush()
  21. return True
  22. if __name__ == '__main__':
  23. parser = argparse.ArgumentParser(
  24. description = "Patches various strings out of the given binary")
  25. parser.add_argument('binary', help = "Binary file to patch", type = argparse.FileType(mode = 'rb+'))
  26. args = parser.parse_args()
  27. mbin = mmap.mmap(args.binary.fileno(), length = 0, access = mmap.ACCESS_WRITE)
  28. config = configparser.ConfigParser(converters = {
  29. # return multiline value as an evaluated Python literal
  30. 'pyliteral': ast.literal_eval,
  31. }, interpolation = None)
  32. config.read("str0.ini", encoding = "utf8")
  33. for target in config.getpyliteral(os.path.basename(args.binary.name), "strings"):
  34. if not patch_to_null(mbin, target):
  35. print(f'{args.binary.name}: Failed to locate string "{target}"')