【问题标题】:How to get the length of signing segment of a signed windows executable如何获取已签名 Windows 可执行文件的签名段长度
【发布时间】:2011-02-16 03:55:05
【问题描述】:

我的程序在原始 exe 的末尾结合了一些附加数据。运行程序时,程序会将附加数据提取到磁盘。

但是我的程序在对组合的可执行程序进行签名后无法获得附加数据的正确偏移量。

我比较了签名的exe和原始的exe,签名信息附加在exe的末尾。所以我正在寻找一个 Win32 API 来从签名程序中获取签名段的长度。之后,我的程序可以找到组合数据的正确偏移量,然后正确提取它们。

谁能给我一个提示?

【问题讨论】:

  • google for pe 可执行格式。这个link 可能就是你所需要的。
  • 我知道这并不能直接回答您的问题,但为什么不将您的数据作为资源嵌入,而不仅仅是将其附加到文件中呢?这样它就不会受到代码签名过程的影响。至少比尝试解析 PE 文件要容易。
  • @Luke,程序是c写的。我们正在linux和windows上编译它。所以我们使用这种方式(组合)让它在这两个主机上工作。
  • Kane,语言无所谓,Luke 的建议对 Windows 来说是最好的。如果您正在为两个平台进行编译,请编写更高级别的包装器并为每个平台实现最佳方式。对于 Windows,该代码将使用资源。对于 Linux,如果您的方式有效,请保持这种方式。

标签: windows winapi cryptography code-signing


【解决方案1】:

我找到了一个名为 PEDump(由 Matt Pietrek 为他的书编写)的工具,它带有源代码来演示如何获取签名信息的大小。

下面是从 PEDump 中提取的代码,用于我的目的,

// MakePtr is a macro that allows you to easily add to values (including
// pointers) together without dealing with C's pointer arithmetic.  It
// essentially treats the last two parameters as DWORDs.  The first
// parameter is used to typecast the result to the appropriate pointer type.
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (DWORD)(addValue))

// Names of the data directory elements that are defined
const char *ImageDirectoryNames[] = {
    "EXPORT", "IMPORT", "RESOURCE", "EXCEPTION", "SECURITY", "BASERELOC",
    "DEBUG", "COPYRIGHT", "GLOBALPTR", "TLS", "LOAD_CONFIG",
    "BOUND_IMPORT", "IAT",  // These two entries added for NT 3.51
    "DELAY_IMPORT" };       // This entry added in NT 5

#define NUMBER_IMAGE_DIRECTORY_ENTRYS \
    (sizeof(ImageDirectoryNames)/sizeof(char *))
        HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(getProgramFile()));
        HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if ( hFileMapping == 0 )
        {
            printf("%s", "Couldn't open file mapping with CreateFileMapping()\n");
        } else {
            LPVOID lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
            if ( lpFileBase == 0 )
            {
                printf("%s", "Couldn't map view of file with MapViewOfFile()\n");
            } else {
                PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
                PIMAGE_FILE_HEADER pImgFileHdr = (PIMAGE_FILE_HEADER)lpFileBase;
                // it's EXE file
                if ( dosHeader->e_magic == IMAGE_DOS_SIGNATURE )
                {
                    PIMAGE_NT_HEADERS pNTHeader;
                    DWORD base = (DWORD)dosHeader;

                    pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader, dosHeader->e_lfanew );

                    PIMAGE_OPTIONAL_HEADER optionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNTHeader->OptionalHeader;
                    for ( int i=0; i < optionalHeader->NumberOfRvaAndSizes; i++)
                    {
                        // DataDirectory[4] represents security directory
                        if ( 4 == i ) {
                            signingLength = optionalHeader->DataDirectory[i].Size;
                            break;
                        }
                    }
                }
                UnmapViewOfFile(lpFileBase);
            }
            CloseHandle(hFileMapping);
        }

【讨论】:

    【解决方案2】:

    在您的数据之前和之后放置一个很长的签名行,然后在预期的偏移量处搜索这些行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-24
      • 2023-03-18
      • 2011-07-31
      • 1970-01-01
      相关资源
      最近更新 更多