Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

A real challenge

by tachyon (Chancellor)
on Jul 16, 2001 at 16:59 UTC ( #97005=perlquestion: print w/ replies, xml ) Need Help??
tachyon has asked for the wisdom of the Perl Monks concerning the following question:

At this node PerlApp decompile? a fellow monk chinman has asked for the help of the perl monks. He has compiled a script usiing PerlApp from Active State. His problem is that he has lost the source code. Decompiling the app is trivial and generates 4 source code files (amingst others) that chinman wishes to retrieve. Having established to my satisfaction that the afore mentioned monk did indeed generate this app (he correctly names all the component scripts, etc) the challenge is now to regenerate his original source. Now Active State has encoded the script data so that it is no longer simple ASCII so this is no gimmee.

But what is the encoding algorithm? To shed some light I asked him to encode this script:
#!"#$%&'()*+,-./0123456789:;<=>?@ #ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_` #abcdefghijklmnopqrstuvwxyz{|}~ #!"#$%&'()*+,-./0123456789:;<=>?@ #ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_` #abcdefghijklmnopqrstuvwxyz{|}~ #!"#$%&'()*+,-./0123456789:;<=>?@ #ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_` #abcdefghijklmnopqrstuvwxyz{|}~ print "Show me the encoding!\n";

The embedded encoded script is interesting. As it is binary encoded and unlikely to pass easily through PM i have used the following subto encode both the original and the embedded PerlApp script:

sub print_enc { my $file = shift; my $count = 0; open FILE, $file or die; binmode FILE; local $/; my $stuff = <FILE>; my @stuff = split //,$stuff; for (@stuff) { print ord($_),","; print "\n" unless ++$count %10; } print "\nCount $count\n"; }

Here is the unecoded and encoded data with a script to regenerate the original source data (note we are using WIN32 so we have CRLF -> chr 13 10. In the unencoded part you can easily see the ASCII series but in the embedded script it is gone. The ratio of 343:333 indicates that a simple 8:7 bitshift is not what has been done but what has? Nor does the pattern obviously repeat.

@unencoded = ( 35,33,34,35,36,37,38,39,40,41, 42,43,44,45,46,47,48,49,50,51, 52,53,54,55,56,57,58,59,60,61, 62,63,64,13,10,35,65,66,67,68, 69,70,71,72,73,74,75,76,77,78, 79,80,81,82,83,84,85,86,87,88, 89,90,91,92,93,94,95,96,13,10, 35,97,98,99,100,101,102,103,104,105, 106,107,108,109,110,111,112,113,114,115, 116,117,118,119,120,121,122,123,124,125, 126,13,10,35,33,34,35,36,37,38, 39,40,41,42,43,44,45,46,47,48, 49,50,51,52,53,54,55,56,57,58, 59,60,61,62,63,64,13,10,35,65, 66,67,68,69,70,71,72,73,74,75, 76,77,78,79,80,81,82,83,84,85, 86,87,88,89,90,91,92,93,94,95, 96,13,10,35,97,98,99,100,101,102, 103,104,105,106,107,108,109,110,111,112, 113,114,115,116,117,118,119,120,121,122, 123,124,125,126,13,10,35,33,34,35, 36,37,38,39,40,41,42,43,44,45, 46,47,48,49,50,51,52,53,54,55, 56,57,58,59,60,61,62,63,64,13, 10,35,65,66,67,68,69,70,71,72, 73,74,75,76,77,78,79,80,81,82, 83,84,85,86,87,88,89,90,91,92, 93,94,95,96,13,10,35,97,98,99, 100,101,102,103,104,105,106,107,108,109, 110,111,112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,13,10,112, 114,105,110,116,32,34,83,104,111,119, 32,109,101,32,116,104,101,32,101,110, 99,111,100,105,110,103,33,92,110,34, 59,13,10,); # Count 343 chars print chr($_) for @unencoded; print "\n###############\n"; @encoded = ( 96,78,82,90,86,76,65,79,92,9, 131,11,30,29,30,31,16,112,81,71, 93,67,83,100,76,88,78,94,28,105, 81,80,44,42,96,46,48,51,106,6, 41,55,49,59,35,44,36,57,110,230, 112,99,98,99,100,117,23,52,44,48, 44,62,15,41,63,43,5,42,119,14, 13,15,68,38,9,21,24,71,41,4, 28,20,28,6,23,25,6,83,221,85, 68,71,72,73,90,58,31,9,23,124, 70,114,86,66,80,64,6,115,71,70, 70,11,111,66,92,95,30,114,93,67, 77,71,95,80,80,77,26,146,28,15, 14,15,112,42,98,34,54,42,50,32, 21,51,41,61,47,107,24,34,33,35, 112,18,61,33,36,123,21,56,40,32, 40,50,59,53,42,127,201,42,17,81, 82,83,68,36,5,19,1,31,15,56, 24,12,26,10,80,37,29,28,24,85, 53,24,10,9,84,56,19,13,7,120, 74,70,74,87,4,140,6,21,24,25, 26,11,109,78,90,70,70,84,97,71, 85,65,83,23,108,86,85,87,28,126, 81,77,48,36,96,46,50,58,54,44, 33,47,60,105,227,107,126,125,126,127, 112,16,49,39,61,35,51,4,44,56, 46,62,124,9,49,48,12,42,96,14, 16,19,74,38,9,23,17,27,3,12, 4,25,78,198,80,67,66,67,68,85, 55,20,12,16,12,30,47,9,31,126, 21,82,61,1,27,76,2,16,7,29, 7,14,46,10,80,13,26,12,71,13, 26,67,198,68,91,94,87,17,124,47, 65,79,99,); # Count 333 chars print chr($_) for @encoded;

Can you crack the code and help chinman? Perhaps more data will be required. I have asked for a linear string to check for repeats but this is what we have to work with currently.

cheers

tachyon

s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Edit Masem 2001-07-16 - READMORE moved per request

Comment on A real challenge
Select or Download Code
Re: A real challenge
by larryk (Friar) on Jul 16, 2001 at 18:03 UTC
    How do you know you have got the right part of the "compiled" file to match the source? Also, 343:333 seems a bit strange -- I would guess the encoded version is derived from a single char for newlines (10 lines - reduces to 333:333)

    Update I reckon 11 (encoded) is a plus (+)

    "Argument is futile - you will be ignorralated!"

Re: A real challenge
by ariels (Curate) on Jul 16, 2001 at 18:06 UTC
    343-333==10, the number of lines in the original. Perhaps your CRLF assumptions need to be revisited? If this PerlApp thing is using just "\cJ" (or "\cM") to terminate lines, this length would drop out naturally.
Re: A real challenge
by c-era (Curate) on Jul 16, 2001 at 19:22 UTC
    I've got it figured out. The CR is removed. It is then encoded with an XOR. The XOR pattern is, 67,111,112,121,114,105,103,104,116,32,169,32,50,48,48,48,32,65,99,116,105,118,101,83,116,97,116,101,32,84,111,111,108,32,67,111,114,112,46 (which prints out to 'Copyright © 2000 ActiveState Tool Corp.'). Here is a how to use it:
    # Our decode string my @decode = ( 67,111,112,121,114,105,103,104,116,32,169,32,50,48,48,48,32,65,99,116, +105,118,101,83,116,97,116,101,32,84,111,111,108,32,67,111,114,112,46) +; # Our encoded string my @encoded = ( 96,78,82,90,86,76,65,79,92,9, 131,11,30,29,30,31,16,112,81,71, 93,67,83,100,76,88,78,94,28,105, 81,80,44,42,96,46,48,51,106,6, 41,55,49,59,35,44,36,57,110,230, 112,99,98,99,100,117,23,52,44,48, 44,62,15,41,63,43,5,42,119,14, 13,15,68,38,9,21,24,71,41,4, 28,20,28,6,23,25,6,83,221,85, 68,71,72,73,90,58,31,9,23,124, 70,114,86,66,80,64,6,115,71,70, 70,11,111,66,92,95,30,114,93,67, 77,71,95,80,80,77,26,146,28,15, 14,15,112,42,98,34,54,42,50,32, 21,51,41,61,47,107,24,34,33,35, 112,18,61,33,36,123,21,56,40,32, 40,50,59,53,42,127,201,42,17,81, 82,83,68,36,5,19,1,31,15,56, 24,12,26,10,80,37,29,28,24,85, 53,24,10,9,84,56,19,13,7,120, 74,70,74,87,4,140,6,21,24,25, 26,11,109,78,90,70,70,84,97,71, 85,65,83,23,108,86,85,87,28,126, 81,77,48,36,96,46,50,58,54,44, 33,47,60,105,227,107,126,125,126,127, 112,16,49,39,61,35,51,4,44,56, 46,62,124,9,49,48,12,42,96,14, 16,19,74,38,9,23,17,27,3,12, 4,25,78,198,80,67,66,67,68,85, 55,20,12,16,12,30,47,9,31,126, 21,82,61,1,27,76,2,16,7,29, 7,14,46,10,80,13,26,12,71,13, 26,67,198,68,91,94,87,17,124,47, 65,79,99,); # Our unecoded string my @unencoded; for my $char (@encoded){ # XOR the encoded string with the decode character push @unencoded, ($char ^ $decode[0]); # Rotate the decode string push @decode, shift @decode; } for my $char (@unencoded){ if ($char == 10){ # Print a newline if the charater is 10 print "\n"; } else { # Print out the unencoded string print chr($char); } }
    I hope you enjoy.
      or even
      #!perl -w use strict; sub encode_decode ($) { my $txt = shift; my $key = 'Copyright 2000 ActiveState Tool Corp.' x length $txt; my $enc = $txt ^ substr $key, 0, length $txt; return wantarray ? unpack "C*", $enc : $enc; } undef $/; my @encoded_ascii = encode_decode <DATA>; # one or other #my $encoded_string = ~~encode_decode <DATA>; # of these two __DATA__ #!"#$%&'()*+,-./0123456789:;<=>?@ #ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_` #abcdefghijklmnopqrstuvwxyz{|}~ #!"#$%&'()*+,-./0123456789:;<=>?@ #ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_` #abcdefghijklmnopqrstuvwxyz{|}~ #!"#$%&'()*+,-./0123456789:;<=>?@ #ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_` #abcdefghijklmnopqrstuvwxyz{|}~ print "Show me the encoding!\n";

      "Argument is futile - you will be ignorralated!"

        You're making $key too long by a factor of 39. You want something more like this (where @encoded is the given byte array):

        my $encodedString = pack('c*', @encoded); my $key = 'Copyright 2000 ActiveState Tool Corp.'; $key = $key x ( length($encodedString) / length($key) + 1); $key = substr($key, 0, length($encodedString)); print $key ^ $encodedString;
Re: A real challenge
by tachyon (Chancellor) on Jul 17, 2001 at 02:59 UTC

    Thanks guys ++ all round, it occured to me in my sleep that 333 + 10 "\r" is 343. How nice to wake up with the solution presented - with comments too! I have regenerated chinman's scripts and emailed them to him. We have saved having to rewrite 60kB+ of perl code so I hope he is pleased :-)

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Believe me, I am more than pleased! This saved me more than a few curse words. Thanks to all! You rock!

      chinman

      #!/usr/bin/perl -w $camel = $hump do { theHumpty($camel); }
      Wow! I had the same problem as chinman. I had developed a fairly involved script for my investment club and used PerlApp to send the package out to all the members. My computer crashed and I lost my code, but using your technique and a member's copy of the .exe I was able to restore my original script this evening!

      BTW, I hadn't heard of this forum until Google brought me here looking for a solution to this problem. I'll be back.

      Thanks to all of you!!

        Glad it helped. You have got to love Google. The impossible delivered yesterday, miracles take a little longer.....

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://97005]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2014-11-27 03:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (178 votes), past polls