Re: tclkit signing

"Pat Thoyts" <[email protected]> Sun, 12 Aug 2007 10:05:33 +0100
Newsgroups gmane.comp.lang.tcl.starkit
Message-ID <[email protected]>
On 09/08/07, Pat Thoyts <[email protected]> wrote:
> On 31/05/07, [email protected] <[email protected]> wrote:
> > It seems codesigning tclkit based applications, as explained here:
> >
> > http://www.matthew-jones.com/articles/codesigning.html
> >
> > corrupt the tclkits, raising an "unable to find setup.tcl" error.
> > This
> > happens both with signcode and signtool, as if no vfs payload was
> > present. The  vfs
> > payload does not disappear, but somehow it is getting corrupted? In
> > theory the codesigning should not affect it
> >
> > anybody has any ideas on how to work around this problem?
>
> I know its been a while but I happened to get around to trying out
> code signing recently and tested it out on a starpack. Signing a
> starpack does indeed appear to damage the file so that the vfs cannot
> be mounted. However you can use the mksplit subcommand in the sdx
> utility to split the starpack into an executable and a vfs section.
> You can then process the binary portion and glue them back together.
> In my case I also wanted the icon to be modified so I started with a
> plain, non-upxed tclkit binary
>   sdx wrap tkchat.exe -runtime tclkit-gui.exe
>   sdx mksplit tkchat.exe
>   upx -9 tkchat.head
>   signtool sign /f signing.p12 tkchat.head
>   copy /b tkchat.head + tkchat.tail tkchat.exe
> Now I have a working, compressed, signed starpack.

A bit more investigation shows that while the above procedure creates
a functional starpack, its signature cannot be validated.

Metakit seeks to the end of the binary to locate the terminating
metakit signature and the size of the metakit image. The authenticode
signature is also appended to the end of the image and has a couple of
entries inserted into the PE header to mark where. In order that the
image can be verified it seems we must have the signing done last. It
is possible when opening the metakit image to check for the presence
of the PE header and if necessary limit the metakit section to exclude
the authenticode signature.
I've done this to the vlerq metakit reader and created a signed copy
of the tkchat application (it can be obtained from
http://tclers.tk/~jabber/tkchat.exe ). The following code can adjust
the metakit size if necessary.

/* If we are opening a Windows PE executable with an attached metakit
 * then we must check for the presence of an Authenticode certificate
 * and reduce the length of our mapped region accordingly
 */
static DWORD
SignedPECertificateOffset(LPBYTE pData, DWORD cbData)
{
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pData;

    if (pDos->e_magic == IMAGE_DOS_SIGNATURE)
    {
        PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)(pData + pDos->e_lfanew);
        if (pNT->Signature == IMAGE_NT_SIGNATURE) {
            DWORD dwCheckSum = 0;
            DWORD dwDirectories = 0;
            PIMAGE_DATA_DIRECTORY pCertDir = NULL;
            if (pNT->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
                dwCheckSum = pNT->OptionalHeader.CheckSum;
                dwDirectories = pNT->OptionalHeader.NumberOfRvaAndSizes;
                if (dwDirectories > 4) {
                    pCertDir = &pNT->OptionalHeader.DataDirectory[4];
                }
            } else {
                PIMAGE_NT_HEADERS64 pNT64 = (PIMAGE_NT_HEADERS64)pNT;
                dwCheckSum = pNT64->OptionalHeader.CheckSum;
                dwDirectories = pNT64->OptionalHeader.NumberOfRvaAndSizes;
                if (dwDirectories > 4) {
                    pCertDir = &pNT64->OptionalHeader.DataDirectory[4];
                }
            }

            if (pCertDir && pCertDir->Size > 0) {
                int n = 0;
                cbData = pCertDir->VirtualAddress-1;
                /* need to eliminate any zero padding - up to 8 bytes */
                while (n < 8 && pData[cbData] == 0 && pData[cbData-16]
!= 0x80) {
                    --cbData, ++n;
                }
            }
        }
    }
    return cbData;
}

Pat Thoyts