#!/usr/bin/env python import argparse import hashlib import pathlib import shutil ORIGINAL_C2_MD5 = "dcd69f1dd28b02dd03dd7ed02984299a" # original C2.EXE C2_MD5 = ( ORIGINAL_C2_MD5, "e70acde41802ddec06c4263bb357ac30", # patched C2.EXE ) C2_SIZE = 549888 def main(): parser = argparse.ArgumentParser( allow_abbrev=False, description="Path to C2.EXE of Microsoft Visual Studio 4.2.0 to disable C4786 warning", ) parser.add_argument("path", type=pathlib.Path, help="Path of C2.EXE") parser.add_argument( "-f", dest="force", default=False, action="store_true", help="force" ) args = parser.parse_args() if not args.path.is_file(): parser.error("Input is not a file") binary = bytearray(args.path.open("rb").read()) md5 = hashlib.md5(binary).hexdigest() print(md5, C2_MD5) msg_cb = parser.error if not args.force else print if len(binary) != C2_SIZE: msg_cb("file size is not correct") if md5 not in C2_MD5: msg_cb("md5 checksum does not match") if md5 == ORIGINAL_C2_MD5: backup = f"{args.path}.BAK" print(f'Creating backup "{backup}"') shutil.copyfile(args.path, backup) def nop_patch(start, count, expected=None): replacement = [0x90] * count if expected: current = list(binary[start : start + count]) assert len(expected) == count assert current in (expected, replacement) print(f"Nopping {count} bytes at 0x{start:08x}") binary[start : start + count] = replacement print( "Disable C4786 warning: '%Fs' : identifier was truncated to '%d' characters in the debug information" ) nop_patch(0x52F07, 5, [0xE8, 0x4F, 0xB3, 0xFE, 0xFF]) # 0x00453b07 nop_patch(0x74832, 5, [0xE8, 0x24, 0x9A, 0xFC, 0xFF]) # 0x00475432 args.path.open("wb").write(binary) print("done") if __name__ == "__main__": raise SystemExit(main())