How to read altered certificate data using WinApi?
See the question and my original answer on StackOverflowThe injected data is located after the Authenticode signature, which is located in the The Attribute Certificate Table of the file (PE Format). Here is some sample code to read it from the file:
#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;
}