title: How to write custom data into signature field of an EXE after signing?
body: <p>I've an EXE which is code signed and saved on the server. When any user wants to download the EXE, I've to embed a user specific information into the EXE which I get to know when the download request comes from the user.</p>
  <p>Constraints:</p>
  <ol>
  <li>I can't rebuild EXE.</li>
  <li>I can't resign EXE.</li>
  <li>Whatever I do, I have to make sure the integrity of content and signature remains intact.</li>
  </ol>
  <p>I came to know that it is possible to store custom data in the signature field from this <a href="https://vcsjones.dev/authenticode-stuffing-tricks/" rel="nofollow noreferrer">blog</a> post signing. This blog mentioned three ways:</p>
  <ol>
  <li>Padding/stuffing</li>
  <li>Unauthenticated attributes of signature</li>
  <li>Additional certificate field of signature</li>
  </ol>
  <p>The first technique mentioned over there is padding. In this technique we can leverage the unsed bytes in the last 8 bytes of the signature as signature always takes up space which is in multiles of 8.</p>
  <p>So let's say if signature is of 60 bytes then 64 bytes will be allocated which is the nearest multiple of 8. Signature will use 60 bytes and we can use remaining 4 bytes to stuff our custom data.</p>
  <p>I observed a couple of signed EXEs saw that we can indeed get 1 to 7 bytes:</p>
  <ol>
  <li>git-bash.exe   - 2 byte</li>
  <li>cmtrace.exe    - 3 bytes</li>
  <li>chrome.exe     - 0 bytes</li>
  <li>iisexpress.exe - 0 bytes</li>
  <li>iexplore.exe   - 2 bytes</li>
  </ol>
  <p>But as you can see above in some cases it can be zero as well. The C# .NET Core code below tells me the starting position of signature and length of signature in any EXE:</p>
  <pre><code>public static byte[] ExtractPadding(string filePath, out long signatureStartLocation, out int signatureLengthInUse)
  {
      signatureLengthInUse = 0;
      using (var file = new PortableExecutable(filePath))
      {
          var dosHeader = file.GetDosHeader();
          var peHeader = file.GetPEHeader(dosHeader);
          var signatureLocation = peHeader.DataDirectories[ImageDataDirectoryEntry.IMAGE_DIRECTORY_ENTRY_SECURITY];
          signatureStartLocation = signatureLocation.VirtualAddress;
          using (var signatureData = file.ReadDataDirectory(signatureLocation))
          {
              using (var reader = new BinaryReader(signatureData))
              {
                  var winCertLength = reader.ReadUInt32();
                  var winCertRevision = reader.ReadUInt16();
                  var winCertType = reader.ReadUInt16();
                  if (winCertRevision != 0x200 &amp;&amp; winCertRevision != 0x100)
                  {
                      return null;
                  }
                  if (winCertType != 0x0002)
                  {
                      return null;
                  }
                  using (var memoryStream = new MemoryStream())
                  {
                      int read;
                      Span&lt;byte&gt; buffer = stackalloc byte[0x400];
                      while ((read = reader.Read(buffer)) &gt; 0)
                      {
                          memoryStream.Write(buffer.Slice(0, read));
                      }
                      var winCertificate = memoryStream.ToArray();
                      var signer = new SignedCms();
                      signer.Decode(winCertificate);
                      var roundTrip = signer.Encode();
                      var sizeDifference = winCertificate.Length - roundTrip.Length;
                      var difference = new byte[sizeDifference];
                      signatureLengthInUse = roundTrip.Length;
                      Buffer.BlockCopy(winCertificate, roundTrip.Length, difference, 0, difference.Length);
                      return difference;
                  }
              }
          }
      }
  }
  </code></pre>
  <p>For my use case 7 bytes of space is very limiting as I need to pass data little more than that. Can someone help me in this if there is any other way or extension of the current approach which can help me write more data in signature field without invalidating the EXE or signature?</p>