I have a simple program:
int main(){
int t = 12 + 34;
return t;
}
The executable of this program is signed and the sign data altered with this disitool utility as described in in this thread: Codesign an executable and allow the modification of some bytes with command:
python.exe disitool.py inject --paddata HelloWorld.exe id.txt HelloWorld_altered.exe
The contents of id.txt:
super_id=test9a0
If I understand it correctly this utility adds desired data into certificate section at the end of the file and recalulates hash of the sign. How can I read this added data from within my program, that is to read string super_id=test9a0
.
The 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;
}