public void Process(string[] args) { if (args.Length != 2) { P.Info("print command usage"); P.Info(" authentipatch print <filename>"); return; } var inputFile = args[1]; using (var parser = new PeParser(inputFile)) { parser.Parse(); PrintFields(parser.Fields); } }
static void PatchAuthenticode(PeParser parser, string inputFile, string outputFile, byte[] payload) { if (payload.Length % 8 != 0) { P.Error($"Payload length must be multiple of 8 (was {payload.Length})"); return; } // This technique won't work if the target exe has a debug symbols section after the certificates area, // it will overwrite that and the signature will not be valid anymore. var certificateSizeField = parser.Find(null, "Size of Certificate table").FirstOrDefault(); var certificateStartField = parser.Find(null, "Certificate table").FirstOrDefault(); var winCertificateLenField = parser.Find("WIN_CERTIFICATE", "Length").FirstOrDefault(); if (certificateSizeField == null || certificateStartField == null || winCertificateLenField == null) { P.Error("This file has no signature"); return; } P.Info($"Patching authenticode with {payload.Length} new bytes."); // Make a copy of the original file File.Copy(inputFile, outputFile, true); // Then patch the copied file using (var w = File.OpenWrite(outputFile)) { var certificateStart = (int)certificateStartField.ULongValue; var certificateSize = (int)certificateSizeField.ULongValue; var endOffset = certificateStart + certificateSize; uint newSize = (uint)(certificateSize + payload.Length); var newSizeBytes = BitConverter.GetBytes(newSize); Patch(w, newSizeBytes, winCertificateLenField.Offset); Patch(w, newSizeBytes, certificateSizeField.Offset); Patch(w, payload, endOffset); } P.Success($"Patched successfully. {payload.Length} of payload added at the end the file."); }
public static (long, uint) ParseOffset(PeParser parser, string offset) { var result = ParseNumber(offset); if (result != -1) { return(result, 0); } // Try section names var section = parser.FindSection(offset); if (section != null) { return(section.RawDataPointer, section.RawDataSize); } throw new Exception($"Invalid offset '{offset}'"); // TODO: Try group.name combination }
public void Process(string[] args) { if (args.Length != 4) { P.Info("addAuthPayload usage:"); P.Info(" authentipatch addAuthPayload <inputfile> <payloadFile> <outputFile>"); P.Info(" PayloadFile size should be a multipe of 8, because of PE format."); return; } var inputFile = args[1]; var outputFile = args[3]; var payloadFile = args[2]; using (var parser = new PeParser(inputFile)) { parser.Parse(); var payload = File.ReadAllBytes(payloadFile); PatchAuthenticode(parser, inputFile, outputFile, payload); } }
public void Process(string[] args) { if (args.Length < 4) { P.Info("dump command usage"); P.Info(" authentipatch dump <format> <filename> <offset> [size]"); P.Info(" format can be any of:"); //P.Info(" raw raw bytes printed to the output. Recomended redirection."); P.Info(" hex 00 4F 3B AB 00 44 01 0A 00 4F 3B AB 00 44 01 0A"); P.Info(" sx \\x00\\x4F\\x3B\\xAB\\x00\\x44\\x01\\x0A\\x00\\x4F\\x3B\\xAB\\x00\\x44\\x01\\x0A"); P.Info(" zx 0x00,0x4F,0x3B,0xAB,0x00,0x44,0x01,0x0A,0x00,0x4F,0x3B,0xAB,0x00,0x44,0x01,0x0A"); P.Info(" offset can be any of:"); P.Info(" section name: .text In this case, size is not required"); P.Info(" decimal value: 34563"); P.Info(" hex value: 0x34A63"); P.Info(""); P.Info("Samples:"); P.Info(" authentipatch dump sx c:\\windows\\system32\\calc.exe .text"); P.Info(" authentipatch dump hex c:\\windows\\system32\\calc.exe .text"); P.Info(" authentipatch dump raw c:\\windows\\system32\\calc.exe 307200 0x345"); return; } var format = args[1]; var inputFile = args[2]; long offset, size; byte[] content; Action <byte[]> formatter; switch (format.ToLower()) { //case "raw": formatter = DumpRawContent; break; case "hex": formatter = DumpHexContent; break; case "sx": formatter = DumpSXContent; break; case "zx": formatter = DumpZXContent; break; default: throw new Exception($"Invalid format '{format}'"); } using (var parser = new PeParser(inputFile)) { parser.Parse(); (offset, size) = OffsetUtils.ParseOffset(parser, args[3]); if (args.Length > 4) { size = OffsetUtils.ParseNumber(args[4]); } if (size == 0 || size == -1) { throw new Exception("Must specify a size"); } // load the target content parser.SeekAbsolute(offset); content = parser.Reader.ReadBytes((int)size); } formatter(content); }