PerlRob has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I'm running Perl 5.10 on Windows XP, and I'm writing a program that must decrypt data using Microsoft's CryptUnprotectData() function.

If I use Luigino Masarati's Win32::CryptData module, the data is successfully decrypted and returned, but Perl crashes when my program exits--sometimes with an "Out of memory!" error. Apparently others have seen the same problem.

I've reduced the frequency of the crashes by copying the CryptUnprotectData() subroutine from Win32::CryptData and hacking around with it (using Win32::API and simply making the call to CryptUnprotectData() myself), but the crash still occurs 7 out of 10 times.

Could anyone help me determine what I'm doing wrong, or how best to debug? I'm not very good with pack() and unpack() even after reading the perldoc page, and the perldoc tutorial, and another tutorial. In particular I'm wondering whether this code properly creates all the data structures that must be passed to CryptUnprotectData():

sub decryptData { my $encryptedData = shift; my $pDataIn = pack('LL', length($encryptedData)+1, unpack('L!', pack('P', $encryptedData))); my $pszDataDescr = pack('L', undef); my $OptionalEntropy = undef; my $pOptionalEntropy = pack('LL', length($OptionalEntropy)+1, unpack('L!', pack('P', $OptionalEntropy))); my $pvReserved = pack('L', undef); my %PromptStruct = (); my $dwFlags = 0; my $DataOut; my $pDataOut = pack('LL', 0, 0); my $szPrompt = _ToUnicodeSz($PromptStruct{'Prompt'}); my $pPromptStruct = pack('L4', 16, $PromptStruct{'PromptFlags'} || 0, $PromptStruct{'hwndApp'} || 0, unpack('L!', pack('P', $szPrompt)) ); my $CryptUnprotectData = new Win32::API ('Crypt32', 'CryptUnprotectData', ['P', 'P', 'P', 'P', 'P', 'N', 'P'], 'N'); if($CryptUnprotectData->Call($pDataIn, $pszDataDescr, $pOptionalEntropy, $pvReserved, $pPromptStruct, $dwFlags, $pDataOut)) { my($len, $ptr) = unpack('LL', $pDataOut); $DataOut = unpack('P'.$len, pack('L!', $ptr)); return $DataOut; } else { return undef; } } sub _ToUnicodeChar { my $string = shift or return(undef); $string =~ s/(.)/$1\x00/sg; return $string; } sub _ToUnicodeSz { my $string = shift or return(undef); return _ToUnicodeChar($string."\x00"); }

Replies are listed 'Best First'.
Re: CryptUnprotectData crashes Perl
by Anonymous Monk on Jul 01, 2009 at 16:10 UTC