如何使用WinApi读取更改后的证书数据?

问题描述 投票:0回答:1

我有一个简单的程序:

int main(){
    int t = 12 + 34;
    return t;
}

该程序的可执行文件已签名,并使用 disitool 实用程序更改签名数据,如本线程中所述:共同设计可执行文件并允许使用命令修改某些字节

python.exe disitool.py inject --paddata HelloWorld.exe id.txt HelloWorld_altered.exe

id.txt的内容:

super_id=test9a0

如果我理解正确,该实用程序会将所需的数据添加到文件末尾的证书部分,并重新计算签名的哈希值。我如何从我的程序中读取这些添加的数据,即读取字符串

super_id=test9a0

c++ winapi code-signing authenticode
1个回答
0
投票

注入的数据位于Authenticode签名之后,该签名位于文件的属性证书表中(PE格式)。这是一些从文件中读取它的示例代码:

#include <windows.h>
#include <wintrust.h>

void ReadAuthenticodeTail(PCWSTR path, LPBYTE* tailData, LPDWORD tailSize)
{
  *tailData = nullptr;
  *tailSize = 0;

  // open file & map it in memory
  auto file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
  if (file != INVALID_HANDLE_VALUE)
  {
    auto mapping = CreateFileMapping(file, nullptr, PAGE_READONLY, 0, 0, nullptr);
    if (mapping)
    {
      auto map = (LPBYTE)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
      if (map)
      {
        // do some checks
        auto dosHeader = (PIMAGE_DOS_HEADER)map;
        if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
        {
          auto headers = (PIMAGE_NT_HEADERS)(map + dosHeader->e_lfanew);
          if (headers->Signature == IMAGE_NT_SIGNATURE)
          {
            // get to Attribute Certificate Table
            auto va = headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
            auto size = headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
            if (va && size)
            {
              // va is in fact a file offset
              // cf https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#the-attribute-certificate-table-image-only
              auto cert = (LPWIN_CERTIFICATE)(map + va);

              // check it's authenticode signature and there's a tail
              if (cert->wRevision == WIN_CERT_REVISION_2_0 &&
                cert->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA &&
                cert->dwLength < size)
              {
                // read what's after certificate (the tail)
                *tailSize = size - cert->dwLength;
                *tailData = new BYTE[*tailSize];
                CopyMemory(*tailData, map + va + cert->dwLength, *tailSize);
              }
            }
          }
        }
        UnmapViewOfFile(map);
      }
      CloseHandle(mapping);
    }
    CloseHandle(file);
  }
}

int main()
{
  LPBYTE tail;
  DWORD size;
  ReadAuthenticodeTail(L"c:\\somepath\\SomeSignedFileWithInjectedData.exe", &tail, &size);
  if (tail)
  {
    // TODO: do something with it...

    delete[] tail;
  }
  return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.