Example #1
0
static int LoadInfoVariable(PQUERY_KEY pVarBlob, const char * szLineBegin, const char * szLineEnd, bool bHexaValue)
{
    const char * szLinePtr = szLineBegin;

    // Sanity checks
    assert(pVarBlob->pbData == NULL);
    assert(pVarBlob->cbData == 0);

    // Check length of the variable
    while(szLinePtr < szLineEnd && szLinePtr[0] != '|')
        szLinePtr++;

    // Allocate space for the blob
    if(bHexaValue)
    {
        // Initialize the blob
        pVarBlob->pbData = CASC_ALLOC(BYTE, (szLinePtr - szLineBegin) / 2);
        pVarBlob->cbData = (DWORD)((szLinePtr - szLineBegin) / 2);
        return ConvertStringToBinary(szLineBegin, (size_t)(szLinePtr - szLineBegin), pVarBlob->pbData);
    }

    // Initialize the blob
    pVarBlob->pbData = CASC_ALLOC(BYTE, (szLinePtr - szLineBegin) + 1);
    pVarBlob->cbData = (DWORD)(szLinePtr - szLineBegin);

    // Check for success
    if(pVarBlob->pbData == NULL)
        return ERROR_NOT_ENOUGH_MEMORY;

    // Copy the string
    memcpy(pVarBlob->pbData, szLineBegin, pVarBlob->cbData);
    pVarBlob->pbData[pVarBlob->cbData] = 0;
    return ERROR_SUCCESS;
}
Example #2
0
// Parses single line from Overwatch.
// The line structure is: "#MD5|CHUNK_ID|FILENAME|INSTALLPATH"
// The line has all preceding spaces removed
int ParseRootFileLine(const char * szLinePtr, const char * szLineEnd, PQUERY_KEY PtrEncodingKey, char * szFileName, size_t nMaxChars)
{
    size_t nLength;
    int nError;

    // Check the MD5 (aka encoding key)
    if(szLinePtr[MD5_STRING_SIZE] != '|')
        return ERROR_BAD_FORMAT;

    // Convert the encoding key to binary
    PtrEncodingKey->cbData = MD5_HASH_SIZE;
    nError = ConvertStringToBinary(szLinePtr, MD5_STRING_SIZE, PtrEncodingKey->pbData);
    if(nError != ERROR_SUCCESS)
        return nError;

    // Skip the MD5
    szLinePtr += MD5_STRING_SIZE+1;

    // Skip the chunk ID
    szLinePtr = SkipInfoVariable(szLinePtr, szLineEnd);

    // Get the archived file name
    szLineEnd = SkipInfoVariable(szLinePtr, szLineEnd);
    nLength = (size_t)(szLineEnd - szLinePtr - 1);

    // Get the file name
    if(nLength > nMaxChars)
        return ERROR_INSUFFICIENT_BUFFER;

    memcpy(szFileName, szLinePtr, nLength);
    szFileName[nLength] = 0;
    return ERROR_SUCCESS;
}
Example #3
0
static const char * CaptureSingleHash(const char * szDataPtr, const char * szDataEnd, LPBYTE HashValue, size_t HashLength)
{
    const char * szHashString;
    size_t HashStringLength = HashLength * 2;

    // Skip all whitespaces
    while (szDataPtr < szDataEnd && IsWhiteSpace(szDataPtr))
        szDataPtr++;
    szHashString = szDataPtr;

    // Count all hash characters
    for (size_t i = 0; i < HashStringLength; i++)
    {
        if (szDataPtr >= szDataEnd || isxdigit(szDataPtr[0]) == 0)
            return NULL;
        szDataPtr++;
    }

    // There must be a separator or end-of-string
    if (szDataPtr > szDataEnd || IsWhiteSpace(szDataPtr) == false)
        return NULL;

    // Give the values
    ConvertStringToBinary(szHashString, HashStringLength, HashValue);
    return szDataPtr;
}
Example #4
0
static int LoadBlobArray(
    PQUERY_KEY pBlob,
    const char * szLineBegin,
    const char * szLineEnd,
    DWORD dwMaxBlobs)
{
    LPBYTE pbBufferEnd = pBlob->pbData + pBlob->cbData;
    LPBYTE pbBuffer = pBlob->pbData;
    int nError = ERROR_SUCCESS;

    // Sanity check
    assert(pBlob->pbData != NULL);
    assert(pBlob->cbData != 0);

    // Until we find an end of the line
    while(szLineBegin < szLineEnd && dwMaxBlobs > 0)
    {
        const char * szBlobEnd = szLineBegin;

        // Find the end of the text blob
        while(szBlobEnd < szLineEnd && IsValueSeparator(szBlobEnd) == false)
            szBlobEnd++;

        // Verify the length of the found blob
        if((szBlobEnd - szLineBegin) != MD5_STRING_SIZE)
            return ERROR_BAD_FORMAT;

        // Verify if there is enough space in the buffer
        if((pbBufferEnd - pbBuffer) < MD5_HASH_SIZE)
            return ERROR_NOT_ENOUGH_MEMORY;

        // Perform the conversion
        nError = ConvertStringToBinary(szLineBegin, MD5_STRING_SIZE, pbBuffer);
        if(nError != ERROR_SUCCESS)
            return nError;

        // Move pointers
        pbBuffer += MD5_HASH_SIZE;
        dwMaxBlobs--;

        // Skip the separator
        while(szBlobEnd < szLineEnd && IsValueSeparator(szBlobEnd))
            szBlobEnd++;
        szLineBegin = szBlobEnd;
    }

    return nError;
}
Example #5
0
static bool IsFileDataIdName(const char * szFileName)
{
    BYTE BinaryValue[4];

    // File name must begin with "File", case insensitive
    if(AsciiToUpperTable_BkSlash[szFileName[0]] == 'F' &&
       AsciiToUpperTable_BkSlash[szFileName[1]] == 'I' &&
       AsciiToUpperTable_BkSlash[szFileName[2]] == 'L' &&
       AsciiToUpperTable_BkSlash[szFileName[3]] == 'E')
    {
        // Then, 8 hexadecimal digits must follow
        if(ConvertStringToBinary(szFileName + 4, 8, BinaryValue) == ERROR_SUCCESS)
        {
            // Must be followed by an extension or end-of-string
            return (szFileName[0x0C] == 0 || szFileName[0x0C] == '.');
        }
    }

    return false;
}
Example #6
0
// Parses single line from Overwatch.
int ParseRootFileLine(const char * szLinePtr, const char * szLineEnd, int nFileNameIndex, PQUERY_KEY PtrEncodingKey, char * szFileName, size_t nMaxChars)
{
    int nIndex = 0;
    int nError;

    // Extract the MD5 (aka encoding key)
    if(szLinePtr[MD5_STRING_SIZE] != '|')
        return ERROR_BAD_FORMAT;

    // Convert the encoding key to binary
    PtrEncodingKey->cbData = MD5_HASH_SIZE;
    nError = ConvertStringToBinary(szLinePtr, MD5_STRING_SIZE, PtrEncodingKey->pbData);
    if(nError != ERROR_SUCCESS)
        return nError;

    // Skip the variable
    szLinePtr += MD5_STRING_SIZE + 1;
    nIndex = 1;

    // Skip the variables until we find the file name
    while(szLinePtr < szLineEnd && nIndex < nFileNameIndex)
    {
        if(szLinePtr[0] == '|')
            nIndex++;
        szLinePtr++;
    }

    // Extract the file name
    while(szLinePtr < szLineEnd && szLinePtr[0] != '|' && nMaxChars > 1)
    {
        *szFileName++ = *szLinePtr++;
        nMaxChars--;
    }

    *szFileName = 0;
    return ERROR_SUCCESS;
}
Example #7
0
static LPBYTE WowHandler_GetKey(TRootHandler_WoW6 * pRootHandler, const char * szFileName)
{
    PCASC_FILE_ENTRY pFileEntry;
    DWORD FileDataId;
    BYTE FileDataIdLE[4];

    // Open by FileDataId. The file name must be as following:
    // File########.xxx, where '#' are hexa-decimal numbers (case insensitive).
    // Extension is ignored in that case
    if(IsFileDataIdName(szFileName))
    {
        ConvertStringToBinary(szFileName + 4, 8, FileDataIdLE);
        FileDataId = ConvertBytesToInteger_4(FileDataIdLE);

        pFileEntry = FindRootEntry(pRootHandler->FileTable, FileDataId);
    }
    else
    {
        // Find by the file name hash
        pFileEntry = FindRootEntry(pRootHandler->pRootMap, szFileName, NULL);
    }

    return (pFileEntry != NULL) ? pFileEntry->EncodingKey.Value : NULL;
}