Exemple #1
0
HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version)
{
    static const WCHAR format[] = {'%','u','.','%','u','.','%','u','.','%','u',0};

    ASSEMBLYTABLE *asmtbl;
    LONG offset;

    *version = NULL;

    offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
    if (offset == -1)
        return E_FAIL;

    asmtbl = assembly_data_offset(assembly, offset);
    if (!asmtbl)
        return E_FAIL;

    *version = HeapAlloc(GetProcessHeap(), 0, sizeof(format) + 4 * strlen("65535") * sizeof(WCHAR));
    if (!*version)
        return E_OUTOFMEMORY;

    sprintfW(*version, format, asmtbl->MajorVersion, asmtbl->MinorVersion,
             asmtbl->BuildNumber, asmtbl->RevisionNumber);

    return S_OK;
}
Exemple #2
0
HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name)
{
    BYTE *ptr;
    LONG offset;
    DWORD stridx;

    offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
    if (offset == -1)
        return E_FAIL;

    ptr = assembly_data_offset(assembly, offset);
    if (!ptr)
        return E_FAIL;

    ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey) + assembly->blobsz;
    if (assembly->stringsz == sizeof(DWORD))
        stridx = *(DWORD *)ptr;
    else
        stridx = *(WORD *)ptr;

    *name = assembly_dup_str(assembly, stridx);
    if (!*name)
        return E_OUTOFMEMORY;

    return S_OK;
}
Exemple #3
0
static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset)
{
    DWORD i, count;
    ULONG currofs;
    ULONGLONG mask;

    currofs = offset;
    assembly->tableshdr = assembly_data_offset(assembly, currofs);
    if (!assembly->tableshdr)
        return E_FAIL;

    assembly->stringsz = (assembly->tableshdr->HeapOffsetSizes & MD_STRINGS_BIT) ?
                         sizeof(DWORD) : sizeof(WORD);
    assembly->guidsz = (assembly->tableshdr->HeapOffsetSizes & MD_GUIDS_BIT) ?
                       sizeof(DWORD) : sizeof(WORD);
    assembly->blobsz = (assembly->tableshdr->HeapOffsetSizes & MD_BLOBS_BIT) ?
                       sizeof(DWORD) : sizeof(WORD);

    currofs += sizeof(METADATATABLESHDR);
    assembly->numrows = assembly_data_offset(assembly, currofs);
    if (!assembly->numrows)
        return E_FAIL;

    memset(assembly->tables, -1, MAX_CLR_TABLES * sizeof(CLRTABLE));

    for (i = count = 0, mask = 1; i < MAX_CLR_TABLES; i++, mask <<= 1)
    {
        if (assembly->tableshdr->MaskValid.QuadPart & mask)
            assembly->tables[i].rows = assembly->numrows[count++];
    }
    assembly->numtables = count;
    currofs += assembly->numtables * sizeof(DWORD);

    for (i = 0, mask = 1; i < MAX_CLR_TABLES; i++, mask <<= 1)
    {
        if (assembly->tableshdr->MaskValid.QuadPart & mask)
        {
            assembly->tables[i].offset = currofs;
            currofs += get_table_size(assembly, i) * assembly->tables[i].rows;
        }
    }

    return S_OK;
}
Exemple #4
0
static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
{
    METADATASTREAMHDR *streamhdr;
    ULONG rva, i, ofs;
    LPSTR stream;
    HRESULT hr;
    DWORD hdrsz;
    BYTE *ptr;

    hr = parse_metadata_header(assembly, &hdrsz);
    if (FAILED(hr))
        return hr;

    rva = assembly->corhdr->MetaData.VirtualAddress;
    ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva + hdrsz, NULL);
    if (!ptr)
        return E_FAIL;

    for (i = 0; i < assembly->metadatahdr->Streams; i++)
    {
        streamhdr = (METADATASTREAMHDR *)ptr;
        ofs = rva_to_offset(assembly->nthdr, rva + streamhdr->Offset);

        ptr += sizeof(METADATASTREAMHDR);
        stream = (LPSTR)ptr;

        if (!lstrcmpA(stream, "#~"))
        {
            hr = parse_clr_tables(assembly, ofs);
            if (FAILED(hr))
                return hr;
        }
        else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings"))
            assembly->strings = assembly_data_offset(assembly, ofs);
        else if (!lstrcmpA(stream, "#Blob") || !lstrcmpA(stream, "Blob"))
            assembly->blobs = assembly_data_offset(assembly, ofs);

        ptr += lstrlenA(stream) + 1;
        ptr = (BYTE *)(((UINT_PTR)ptr + 3) & ~3); /* align on DWORD boundary */
    }

    return S_OK;
}
Exemple #5
0
HRESULT assembly_get_external_files(ASSEMBLY *assembly, LPWSTR **files, DWORD *count)
{
    LONG offset;
    INT i, num_rows;
    WCHAR **ret;
    BYTE *ptr;
    DWORD idx;

    *count = 0;

    offset = assembly->tables[TableFromToken(mdtFile)].offset;
    if (offset == -1)
        return S_OK;

    ptr = assembly_data_offset(assembly, offset);
    if (!ptr)
        return S_OK;

    num_rows = assembly->tables[TableFromToken(mdtFile)].rows;
    if (num_rows <= 0)
        return S_OK;

    ret = HeapAlloc(GetProcessHeap(), 0, num_rows * sizeof(WCHAR *));
    if (!ret)
        return E_OUTOFMEMORY;

    for (i = 0; i < num_rows; i++)
    {
        ptr += sizeof(DWORD); /* skip Flags field */
        if (assembly->stringsz == sizeof(DWORD))
            idx = *(DWORD *)ptr;
        else
            idx = *(WORD *)ptr;

        ret[i] = assembly_dup_str(assembly, idx);
        if (!ret[i])
        {
            for (; i >= 0; i--) HeapFree(GetProcessHeap(), 0, ret[i]);
            HeapFree(GetProcessHeap(), 0, ret);
            return E_OUTOFMEMORY;
        }
        ptr += assembly->stringsz; /* skip Name field */
        ptr += assembly->blobsz; /* skip Hash field */
    }
    *count = num_rows;
    *files = ret;
    return S_OK;
}
Exemple #6
0
HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token)
{
    ULONG i, size;
    LONG offset;
    BYTE *hashdata, *pubkey, *ptr;
    HCRYPTPROV crypt;
    HCRYPTHASH hash;
    BYTE tokbytes[BYTES_PER_TOKEN];
    HRESULT hr = E_FAIL;
    LPWSTR tok;
    DWORD idx;

    *token = NULL;

    offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
    if (offset == -1)
        return E_FAIL;

    ptr = assembly_data_offset(assembly, offset);
    if (!ptr)
        return E_FAIL;

    ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey);
    if (assembly->blobsz == sizeof(DWORD))
        idx = *(DWORD *)ptr;
    else
        idx = *(WORD *)ptr;

    pubkey = assembly_get_blob(assembly, idx, &size);

    if (!CryptAcquireContextA(&crypt, NULL, NULL, PROV_RSA_FULL,
                              CRYPT_VERIFYCONTEXT))
        return E_FAIL;

    if (!CryptCreateHash(crypt, CALG_SHA1, 0, 0, &hash))
        return E_FAIL;

    if (!CryptHashData(hash, pubkey, size, 0))
        return E_FAIL;

    size = 0;
    if (!CryptGetHashParam(hash, HP_HASHVAL, NULL, &size, 0))
        return E_FAIL;

    hashdata = HeapAlloc(GetProcessHeap(), 0, size);
    if (!hashdata)
    {
        hr = E_OUTOFMEMORY;
        goto done;
    }

    if (!CryptGetHashParam(hash, HP_HASHVAL, hashdata, &size, 0))
        goto done;

    for (i = size - 1; i >= size - 8; i--)
        tokbytes[size - i - 1] = hashdata[i];

    tok = HeapAlloc(GetProcessHeap(), 0, (TOKEN_LENGTH + 1) * sizeof(WCHAR));
    if (!tok)
    {
        hr = E_OUTOFMEMORY;
        goto done;
    }

    token_to_str(tokbytes, tok);

    *token = tok;
    hr = S_OK;

done:
    HeapFree(GetProcessHeap(), 0, hashdata);
    CryptDestroyHash(hash);
    CryptReleaseContext(crypt, 0);

    return hr;
}