我有一个简单的程序:
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
。
注入的数据位于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;
}