예제 #1
0
void EncryptData_model(BYTE * inData, size_t len, const BYTE* key1, const BYTE* key2, const BYTE* key3, t_DES_SPtrans * sp)
{
	assert((len & 0x7) == 0);
#ifdef _DEBUG
	BYTE * oldData = new BYTE[len];
	memcpy(oldData, inData, len);
#endif
	DES_key_schedule sKey[3];

	DES_set_key((const_DES_cblock*)key1, &sKey[0]);
	DES_set_key((const_DES_cblock*)key2, &sKey[1]);
	DES_set_key((const_DES_cblock*)key3, &sKey[2]);

	for (size_t i = 0; i < len; i += 8)
	{
		DES_encrypt3((DWORD*)(inData + i), &sKey[0], &sKey[1], &sKey[2], sp);
	}
#ifdef _DEBUG
	BYTE* newData = new BYTE[len];
	memcpy(newData, inData, len);
	DecryptData(newData, len, key1, key2, key3);
	int cmp = memcmp(newData, oldData, len);
	assert(cmp == 0);
	CC_SAFE_DELETE_ARRAY(newData);
	CC_SAFE_DELETE_ARRAY(oldData);
#endif
}
int main(int argc, char *argv[])
{
	//
	// Algorytm szyfrujacy jest staly i nie bedzie zmieniany
	// w przyszlosci, wiec mozna bez obaw szyfrowac wszelkiego
	// rodzaju dane aplikacji jak pliki konfiguracyjne, bazy danych etc.
	//

	printf("Testowanie funkcji EncryptData() i DecryptData()\n");
	printf("------------------------------------------------\n");
	print_plaintext();

	// szyfruj dane
	EncryptData(szKey, sizeof(szKey), szSecretData, sizeof(szSecretData));
	print_encrypted();

	// odszyfruj dane
	DecryptData(szKey, sizeof(szKey), szSecretData, sizeof(szSecretData));
	print_decrypted();

	//
	// Szyfruj i deszyfruj pamiec w tym samym procesie. Aplikacja
	// uruchomiona w innym procesie nie bedzie w stanie odszyfrowac
	// danych.
	//

	printf("\n\nTestowanie funkcji EncryptMemory() i DecryptMemory() (bez klucza)\n");
	printf("-----------------------------------------------------------------\n");
	print_plaintext();

	// szyfruj dane
	EncryptMemory(szSecretData, sizeof(szSecretData));
	print_encrypted();

	// odszyfruj dane
	DecryptMemory(szSecretData, sizeof(szSecretData));
	print_decrypted();

	printf("\n\nNacisnij dowolny klawisz, aby kontynuowac . . .");

	getch();

	return 0;
}
예제 #3
0
BOOL ProtectedStorage::EnumProtectedStorage(void)
{
    IPStorePtr pStore;
    IEnumPStoreTypesPtr EnumPStoreTypes;
    IEnumPStoreTypesPtr EnumSubTypes;
    IEnumPStoreItemsPtr spEnumItems;
    PSTORECREATEINSTANCE pPStoreCreateInstance;

    HMODULE hpsDLL = LoadLibrary("pstorec.dll");
    HRESULT hr;
    GUID TypeGUID, subTypeGUID;
    LPWSTR itemName;
    unsigned long psDataLen = 0;
    unsigned char *psData = NULL;
    int i = 0;
    char szItemName[512];
    char szItemData[512];
    char szResName[512];
    char szResData[512];
    char szItemGUID[50];
    char szTemp[256];

    pPStoreCreateInstance = (PSTORECREATEINSTANCE)GetProcAddress(hpsDLL, "PStoreCreateInstance");
    if (pPStoreCreateInstance == NULL)
    {
        printf("Unable to obtain handle to PStoreCreateInstance in pstorec.dll\n");
        return FALSE;
    }

    hr = pPStoreCreateInstance(&pStore, 0, 0, 0);
    if (FAILED(hr))
    {
        printf("Unable to create protected storage instance (error code %X)\n", hr);
        return FALSE;
    }

    hr = pStore->EnumTypes(0, 0, &EnumPStoreTypes);
    if (FAILED(hr))
    {
        printf("Unable to enumerate protected storage types (error code %X)\n", hr);
        return FALSE;
    }

    while(EnumPStoreTypes->raw_Next(1, &TypeGUID, 0) == S_OK)
    {
        wsprintf(szItemGUID, "%x", TypeGUID);
        hr = pStore->EnumSubtypes(0, &TypeGUID, 0, &EnumSubTypes);
        if (FAILED(hr))
        {
            printf("Unable to enumerate protected storage subtypes for GUID %S (error code %X)\n", szItemGUID, hr);
            continue;
        }

        while(EnumSubTypes->raw_Next(1, &subTypeGUID, 0) == S_OK)
        {
            hr = pStore->EnumItems(0, &TypeGUID, &subTypeGUID, 0, &spEnumItems);
            if (FAILED(hr))
            {
                printf("Unable to enumerate protected storage items for GUID %S (error code %X)\n", szItemGUID, hr);
                continue;
            }

            while(spEnumItems->raw_Next(1,&itemName,0) == S_OK)
            {
                _PST_PROMPTINFO *pstiinfo = NULL;
                psDataLen = 0;
                psData = NULL;

                wsprintf(szItemName, "%ws", itemName);
                hr = pStore->ReadItem(0, &TypeGUID, &subTypeGUID, itemName, &psDataLen, &psData, pstiinfo, 0);
                if (FAILED(hr))
                {
                    printf("Unable to read protected storage item %S (error code %X)\n", szItemName, hr);
                    continue;
                }

                if(strlen((char*)psData) < (psDataLen - 1))
                {
                    i = 0;
                    for(DWORD m = 0; m < psDataLen; m += 2)
                    {
                        if(psData[m] == 0)
                            szItemData[i] = ',';
                        else
                            szItemData[i] = psData[m];

                        i++;
                    }

                    if (i > 0)
                        szItemData[i - 1] = 0;
                    else
                        szItemData[0] = 0;
                }
                else
                {
                    wsprintf(szItemData, "%s", psData);
                }

                strcpy_s(szResName, 512, "");
                strcpy_s(szResData, 512, "");

                if(_stricmp(szItemGUID, "220d5cc1") == 0)
                {
                    // GUIDs beginning with "220d5cc1" are Outlook Express
                    BOOL bDeletedOEAccount = TRUE;
                    for(i = 0; i < m_nOutlookCount; i++)
                    {
                        if(strcmp(m_pOutlookDataHead[i].POPpass, szItemName) == 0)
                        {
                            bDeletedOEAccount = FALSE;
                            printf(OUTPUT_FORMAT, m_pOutlookDataHead[i].POPserver, "Outlook Express Account", m_pOutlookDataHead[i].POPuser, szItemData);
                            break;
                        }
                    }

                    if(bDeletedOEAccount)
                        printf(OUTPUT_FORMAT, szItemName, "Deleted Outlook Express Account", m_pOutlookDataHead[i].POPuser, szItemData);
                }
                else if(_stricmp(szItemGUID, "5e7e8100") == 0)
                {
                    // GUIDs beginning with 5e7e8100 are IE password-protected sites

                    strcpy_s(szTemp, 512, "");

                    // If the item begins with DPAPI, it has been protected using the CryptProtectData call.
                    // Decrypt it using the opposite call. This is a HUGE assumption on my part, but so far
                    // appears to be the case
                    if (strncmp(szItemName, "DPAPI:", 6) == 0)
                    {
                        char* szDecryptedPassword = DecryptData(psDataLen, psData);

                        if (szDecryptedPassword != NULL)
                        {
                            char szUser[200];
                            memset(szUser, 0, 200);

                            // Also have to figure out the user name. This section may need some work
                            if (strncmp(szItemName + 7, "ftp://", 6) == 0)
                            {
                                size_t nPos = strcspn(szItemName + 13, "@");
                                if (nPos > 0 && nPos < strlen(szItemName + 13))
                                {
                                    // Found the @ sign - copy everything between ftp:// and the @ sign
                                    strncpy_s(szUser, 200, szItemName + 13, nPos);
                                }
                                else
                                {
                                    strcpy_s(szUser, 200, szItemName + 13);
                                }
                            }
                            else
                            {
                                // Just copy user name verbatim I guess
                                strcpy_s(szUser, 200, szItemName);
                            }

                            printf(OUTPUT_FORMAT, szItemName, "IE Password-Protected Site", szUser, szDecryptedPassword);
                            free(szDecryptedPassword);
                        }
                        else
                        {
                            printf(OUTPUT_FORMAT, szItemName, "IE Password-Protected Site", szItemName, "ERROR DECRYPTING");
                            //printf("Decryption error for item %s: error %d\n", szItemName, GetLastError());
                        }
                    }
                    else if(strstr(szItemData, ":") != 0)
                    {
                        strcpy_s(szTemp, 512, strstr(szItemData, ":") + 1);
                        *(strstr(szItemData, ":")) = 0;
                        printf(OUTPUT_FORMAT, szItemName, "IE Password-Protected Site", szItemData, szTemp);
                    }

                }
                else if(_stricmp(szItemGUID, "b9819c52") == 0)
                {
                    // GUIDs beginning with b9819c52 are MSN Explorer Signup
                    char msnid[100];
                    char msnpass[100];
                    BOOL first = TRUE;
                    char *p;

                    for(DWORD m = 0; m < psDataLen; m += 2)
                    {
                        if(psData[m] == 0)
                        {
                            szItemData[i] = ',';
                            i++;
                        }
                        else
                        {
                            if(IsCharAlphaNumeric(psData[m])||(psData[m]=='@')||(psData[m]=='.')||(psData[m]=='_'))
                            {
                                szItemData[i] = psData[m];
                                i++;
                            }
                        }
                    }

                    szItemData[i - 1] = 0;
                    p = szItemData + 2;

                    //psData[4] - number of msn accounts
                    for(int ii = 0; ii < psData[4]; ii++)
                    {
                        strcpy_s(msnid, 100, p + 1);

                        if(strstr(msnid,",") != 0)
                            *strstr(msnid,",") = 0;

                        if(strstr(p + 1, ",") != 0)
                            strcpy_s(msnpass, 100, strstr(p + 1, ",") + 2);

                        if(strstr(msnpass, ",") != 0)
                            *strstr(msnpass, ",") = 0;

                        p = strstr(p + 1, ",") + 2 + strlen(msnpass) + 7;

                        printf(OUTPUT_FORMAT, msnid, "MSN Explorer Signup", msnid, msnpass);
                    }
                }
                else if(_stricmp(szItemGUID, "e161255a") == 0)
                {
                    // GUIDs beginning with e161255a are other stored IE credentials
                    if(strstr(szItemName, "StringIndex") == 0)
                    {
                        if(strstr(szItemName, ":String") != 0)
                            *strstr(szItemName, ":String") = 0;

                        strncpy_s(szTemp, 512, szItemName, 8);
                        if((strstr(szTemp, "http:/") == 0) && (strstr(szTemp, "https:/") == 0))
                            printf(OUTPUT_FORMAT, szItemName, "IE Auto Complete Fields", szItemData, "");
                        else
                        {
                            strcpy_s(szTemp, 512, "");
                            if(strstr(szItemData, ",") != 0)
                            {
                                strcpy_s(szTemp, 512, strstr(szItemData, ",") + 1);
                                *(strstr(szItemData, ",")) = 0;
                            }

                            printf(OUTPUT_FORMAT, szItemName, "AutoComplete Passwords", szItemData, szTemp);
                        }
                    }
                }
                else if(_stricmp(szItemGUID, "89c39569") == 0)
                {
                    // IdentitiesPass info. It's already been displayed, so just supress these
                }
                else
                {
                    // Catch-all for miscellaneous data
                    strcpy_s(szTemp, 512, "");
                    if(strstr(szItemData, ":") != 0)
                    {
                        strcpy_s(szTemp, 512, strstr(szItemData, ":") + 1);
                        *(strstr(szItemData, ":")) = 0;
                    }

                    printf(OUTPUT_FORMAT, szItemName, "Unknown", szItemData, szTemp);
                }
                ZeroMemory(szItemName, sizeof(szItemName));
                ZeroMemory(szItemData, sizeof(szItemData));
            }
        }
    }

    return TRUE;
}
/*
 * Unwrap key function. Used for:
 *
 * -- Given key of BlobType CSSM_KEYBLOB_WRAPPED, decode and decrypt
 *    it, yielding a key in either raw or reference format. Unwrapping
 *    key may be either raw or reference. The context must match
 *    the unwrapping key (ALGCLASS_SYMMETRIC  or ALGCLASS_ASYMMETRIC).
 *
 *	  Private keys are assumed to be PKCS8 encoded; session keys  
 *    are assumed to be PKCS7 encoded. 
 *
 * -- Convert a Raw key to a reference key (with no decrypting).
 *    This is called a NULL unwrap; no unwrapping key need be present in
 *    the context, but the context must be of class 
 *    ALGCLASS_SYMMETRIC and algorithm ALGID_NONE.
 */ 
void AppleCSPSession::UnwrapKey(
		CSSM_CC_HANDLE CCHandle,
		const Context &Context,
		const CssmKey *PublicKey,
		const CssmKey &WrappedKey,
		uint32 KeyUsage,
		uint32 KeyAttr,
		const CssmData *KeyLabel,
		const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
		CssmKey &UnwrappedKey,
		CssmData &DescriptiveData,
		CSSM_PRIVILEGE Privilege)
{
	bool 					isNullUnwrap = false;
	CssmKey					*unwrappingKey = NULL;
	cspKeyType				keyType;				// CKT_Public, etc. 
	CSSM_KEYBLOB_FORMAT		wrapFormat = WrappedKey.blobFormat();
	
	/* obtain unwrapping key if present */
	unwrappingKey = Context.get<CssmKey>(CSSM_ATTRIBUTE_KEY);
	if(unwrappingKey == NULL) {
		if((Context.algorithm() == CSSM_ALGID_NONE) &&
		   (Context.type() == CSSM_ALGCLASS_SYMMETRIC)) {
				// NULL unwrap, OK
				isNullUnwrap = true;
		}
		else {
			errorLog0("UnwrapKey: missing wrapping key\n");
			CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_KEY);
		}
	}

	/* 
	 * validate unwrappingKey 
	 */
	if(!isNullUnwrap) {
		/* make sure unwrapping key type matches context */
		CSSM_CONTEXT_TYPE unwrapType;
		switch(unwrappingKey->KeyHeader.KeyClass) {
			case CSSM_KEYCLASS_PUBLIC_KEY:
			case CSSM_KEYCLASS_PRIVATE_KEY:
				unwrapType = CSSM_ALGCLASS_ASYMMETRIC;
				break;
			case CSSM_KEYCLASS_SESSION_KEY:
				unwrapType = CSSM_ALGCLASS_SYMMETRIC;
				break;
			default:
				errorLog0("UnwrapKey: bad class of wrappingKey\n");
				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
		}
		if(unwrapType != Context.type()) {
			errorLog0("UnwrapKey: mismatch unwrappingKey/contextType\n");
			CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
		}
		if(Context.algorithm() == CSSM_ALGID_NONE) {
			errorLog0("UnwrapKey: null wrap alg, non-null key\n");
			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
		}
		cspValidateIntendedKeyUsage(&unwrappingKey->KeyHeader, CSSM_KEYUSE_UNWRAP);
		cspVerifyKeyTimes(unwrappingKey->KeyHeader);
	}

	/* validate WrappedKey */
	switch(WrappedKey.keyClass()) {
		case CSSM_KEYCLASS_PUBLIC_KEY:
			#if 	!ALLOW_PUB_KEY_WRAP
			if(!isNullUnwrap) {
				errorLog0("UnwrapKey: unwrap of public key illegal\n");
				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
			}
			#endif	/* ALLOW_PUB_KEY_WRAP */
			keyType = CKT_Public;
			break;
		case CSSM_KEYCLASS_PRIVATE_KEY:
			keyType = CKT_Private;
			break;
		case CSSM_KEYCLASS_SESSION_KEY:
			keyType = CKT_Session;
			break;
		default:
			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
	}
	if(isNullUnwrap) {
		if(WrappedKey.blobType() != CSSM_KEYBLOB_RAW) {
			errorLog0("UnwrapKey: expected raw blobType\n");
			CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
		}
	}
	else {
		if(WrappedKey.blobType() != CSSM_KEYBLOB_WRAPPED) {
			errorLog0("UnwrapKey: expected wrapped blobType\n");
			CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
		}
	}

	/* validate requested storage and usage */
	cspKeyStorage keyStorage = cspParseKeyAttr(keyType, KeyAttr);
	switch(keyStorage) {
		case CKS_Ref:
		case CKS_Data:
			break;		// OK
		default:
			CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
	}
	cspValidateKeyUsageBits(keyType,  KeyUsage);

	/* prepare outgoing header */
	CssmKey::Header &unwrappedHdr = UnwrappedKey.header();
	const CssmKey::Header &wrappedHdr   = WrappedKey.header();
	setKeyHeader(unwrappedHdr,
		plugin.myGuid(),
		wrappedHdr.algorithm(),		// same as incoming 
		wrappedHdr.keyClass(),		// same as incoming
		KeyAttr & ~KEY_ATTR_RETURN_MASK,
		KeyUsage);
	unwrappedHdr.LogicalKeySizeInBits = wrappedHdr.LogicalKeySizeInBits;
	unwrappedHdr.StartDate = wrappedHdr.StartDate;
	unwrappedHdr.EndDate = wrappedHdr.EndDate;
	UnwrappedKey.KeyData.Data = NULL;	// ignore possible incoming KeyData
	UnwrappedKey.KeyData.Length = 0;
	
	/* validate wrappedKey format */
	if(!isNullUnwrap) {
		switch(wrapFormat) {
			case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7:
				if(WrappedKey.keyClass() != CSSM_KEYCLASS_SESSION_KEY) {
					/* this unwrapping style only for symmetric keys */
					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
				}
				break;
			case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8:
			case CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSL:
				if(WrappedKey.keyClass() != CSSM_KEYCLASS_PRIVATE_KEY) {
					/* these unwrapping styles only for private keys */
					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
				}
				break;
			case CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM:
				UnwrapKeyCms(CCHandle,
						Context,
						WrappedKey,
						CredAndAclEntry,
						UnwrappedKey,
						DescriptiveData,
						Privilege,
						keyStorage);
				return;
			case CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSH1:
				/* RSA private key, unwrap to ref key only */
				if(WrappedKey.keyClass() != CSSM_KEYCLASS_PRIVATE_KEY) {
					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
				}
				if(WrappedKey.algorithm() != CSSM_ALGID_RSA) {
					CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
				}
				if(keyStorage != CKS_Ref) {
					errorLog0("UNwrapKey: OPENSSH1 only wraps to reference key\n");
					CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
				}
				UnwrapKeyOpenSSH1(CCHandle,
						Context,
						WrappedKey,
						CredAndAclEntry,
						UnwrappedKey,
						DescriptiveData,
						Privilege,
						keyStorage);
				return;
			default:
				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT);
		}
	}

	/* Get key blob, decoding and decrypting if necessary */
	CssmData decodedBlob;
	CssmData remData;
	try {
		if(isNullUnwrap) {
			/* simple copy of raw blob */
			copyData(WrappedKey.KeyData, 
				UnwrappedKey.KeyData, 
				normAllocator);
			unwrappedHdr.BlobType = CSSM_KEYBLOB_RAW;
			unwrappedHdr.Format   = wrapFormat; 
		}
		else {
			decodedBlob = CssmData::overlay(WrappedKey.KeyData);
			CSSM_SIZE bytesDecrypted;		
			CssmData *unwrapData = 
				CssmData::overlay(&UnwrappedKey.KeyData);
				
			DecryptData(CCHandle,
				Context,
				&decodedBlob,		// CipherBufs[],
				1,					// CipherBufCount,
				unwrapData,			// ClearBufs[]
				1,					// ClearBufCount
				bytesDecrypted,
				remData,
				Privilege);
	
			// I'm not 100% sure about this....
			assert(remData.Length == 0);
			UnwrappedKey.KeyData.Length = bytesDecrypted;
			unwrappedHdr.BlobType = CSSM_KEYBLOB_RAW;
			
			/* 
			 * Figure out various header fields from resulting blob
			 */
			switch(wrapFormat) {
				case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7:
					unwrappedHdr.Format = 
						CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
					if(unwrappedHdr.LogicalKeySizeInBits == 0) {
						unwrappedHdr.LogicalKeySizeInBits =
							(unsigned)(bytesDecrypted * 8);
					}
					/* app has to infer/know algorithm */
					break;
				case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8:
					pkcs8InferKeyHeader(UnwrappedKey);
					break;
				case CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSL:
					/* 
					 * App told us key algorithm (in WrappedKey).
					 * Infer format and key size. 
					 */
					opensslInferKeyHeader(UnwrappedKey);
					break;
			}
		}
	}
	catch (...) {
		errorLog0("UnwrapKey: DecryptData() threw exception\n");
		freeCssmData(remData, normAllocator);
		throw;
	}
	freeCssmData(remData, normAllocator);

	/* 
	 * One more thing: cook up a BinaryKey if caller wants a 
	 * reference key.
	 */
	if(keyStorage == CKS_Ref) {
		/*
		 * We have a key in raw format; convert to BinaryKey.
		 */
		BinaryKey *binKey = NULL;
		CSPKeyInfoProvider *provider = infoProvider(UnwrappedKey);
		/* optional parameter-bearing key */
		CssmKey *paramKey = Context.get<CssmKey>(CSSM_ATTRIBUTE_PARAM_KEY);
		provider->CssmKeyToBinary(paramKey, UnwrappedKey.KeyHeader.KeyAttr, &binKey);
		addRefKey(*binKey, UnwrappedKey);
		delete provider;
	}
}
예제 #5
0
UPK_STATUS
NitroPlus::
GetFileData(
    UNPACKER_FILE_INFO         *FileInfo,
    UNPACKER_FILE_ENTRY_BASE   *BaseEntry,
    ULONG                       Flags /* = 0 */
)
{
    PBYTE               Buffer;
    ULONG               Size;
    NTSTATUS            Status;
    NITRO_PLUS_ENTRY   *Entry;

    Entry = (NITRO_PLUS_ENTRY *)BaseEntry;

    if (FLAG_ON(Entry->Attributes, FILE_ATTRIBUTE_DIRECTORY))
        return STATUS_UNSUCCESSFUL;

    Status = m_File.Seek(Entry->Offset, FILE_BEGIN);
    FAIL_RETURN(Status);

    Size   = Entry->CompressedSize.LowPart;
    Buffer = (PBYTE)AllocateMemory(Size);
    if (Buffer == NULL)
        return STATUS_INSUFFICIENT_RESOURCES;

    FileInfo->FileType                  = UnpackerFileBinary;
    FileInfo->BinaryData.Buffer         = Buffer;
    FileInfo->BinaryData.Size.QuadPart  = Size;

    Status = m_File.Read(Buffer, Size);
    FAIL_RETURN(Status);

    if (FLAG_ON(Flags, UNPACKER_SAVE_RAW_DATA))
        return STATUS_SUCCESS;

    if (FLAG_ON(Entry->Flags, UNPACKER_ENTRY_ENCRYPTED))
    {
        DecryptData(Buffer, Entry->DecryptLength, Entry->Seed);
//        EncryptData(Buffer, Entry->DecryptLength, Entry->Seed);
//        DecryptData(Buffer, Entry->DecryptLength, Entry->Seed);
    }

    if (FLAG_ON(Entry->Flags, UNPACKER_ENTRY_COMPRESSED))
    {
        Size = Entry->Size.LowPart;
        Buffer = (PBYTE)AllocateMemory(Size);
        if (Buffer == NULL)
            return STATUS_INSUFFICIENT_RESOURCES;

        Status = uncompress(Buffer, &Size, FileInfo->BinaryData.Buffer, FileInfo->BinaryData.Size.LowPart);
        FreeMemory(FileInfo->BinaryData.Buffer);

        FileInfo->BinaryData.Buffer         = Buffer;
        FileInfo->BinaryData.Size.QuadPart  = Size;

        if (Status != Z_OK)
        {
            return STATUS_UNSUCCESSFUL;
        }
    }

    return STATUS_SUCCESS;
}