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"); }

In reply to CryptUnprotectData crashes Perl by PerlRob

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.