--- nfo/perl/scripts/fluscate/bin/fluscate.pl 2004/07/26 16:11:58 1.5 +++ nfo/perl/scripts/fluscate/bin/fluscate.pl 2004/08/03 00:24:15 1.6 @@ -1,9 +1,14 @@ #!/usr/bin/perl -# fluscate.pl 0.04 - The Flash Obfuscator +# fluscate - The Flash Obfuscator -# $Id: fluscate.pl,v 1.5 2004/07/26 16:11:58 joko Exp $ +# $Id: fluscate.pl,v 1.6 2004/08/03 00:24:15 joko Exp $ # $Log: fluscate.pl,v $ +# Revision 1.6 2004/08/03 00:24:15 joko +# restructured code (procedures) +# command-line arguments +# new feature: pollute +# # Revision 1.5 2004/07/26 16:11:58 joko # updated pod # included more complete list of flash event-handlers @@ -24,8 +29,10 @@ =pod + fluscate - The Flash Obfuscator + This software is Copyright (C) 2004 Andreas Motl - Ideas and future AppleScript integration by Holger Marseille. + Ideas and MacOS X Application by Holger Marseille This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -58,13 +65,24 @@ fluscate handles two different styles of function declarations: - 1. "Normal" ones + 1. "Normal" ones, e.g. function mp3Player ('arg1', 'arg2') - 2. There may be "stacked" function declarations + 2. There may be "stacked" function declarations, e.g. push 'mp3Player' function () +=head2 Pollute + + Some flash-disassemblers might croak when inserting the following code + after a/each "constants"-declaration: + + push 0 + ls: + dup + trace + branchIfTrue ls" + =head1 Dependencies @@ -74,6 +92,10 @@ =head1 Usage +=head2 General + + Please type "fluscate --help" to get more information about command-line parameters. + =head2 win32 #> flasm.exe -d puzzle.swf > puzzle.flm @@ -99,12 +121,6 @@ zufallsprinip (-21,-3,-89)? (->random) - evtl. constants nach abfrage ersetzen ? leider sehr aufwendig, bei vielen constants (->ask) - rausgeben des arrays mit den "neuen" werten um evtl die obfuscation rückgängig zu machen (->undo) - - " push 0 - ls: - dup - trace - branchIfTrue ls" - ... after each "constants" declaration (->pollute) - what about other symbols beside "function"s? (e.g. variables) (->mode) - include list of ->keywords from: http://www.macromedia.com/support/flash/action_scripts/actionscript_dictionary/ @@ -157,13 +173,25 @@ Password Busting / SWF Protections: http://www.searchlores.org/cinix_fla.htm =head2 Off-Topic - + +=head3 XML + XPath for Actionscript and other stuff: http://www.xfactorstudio.com/Actionscript/ + XMLRPC Flash Libraries for ActionScript 2.0: http://xmlrpcflash.sourceforge.net/ + +=head3 Marshalling / AMF (Flash Remoting protocol) + + AMFPHP - Flash Remoting for PHP: http://www.amfphp.org/ + AMF::Perl - Flash Remoting in Perl and Python: http://simonf.com/amfperl/ SerializerClass: http://sourceforge.net/projects/serializerclass/ - AMF::Perl - Flash Remoting in Perl and Python - using Flash Remoting protocol (AMF): - http://simonf.com/amfperl/ + +=head3 Misc + PEAR::SWF - Read and write SWF head tag: http://www.sephiroth.it/test/php/SWF/ - AMFPHP - Flash Remoting for PHP: http://www.amfphp.org/ + Convert videos to flv: + http://ffmpeg.sourceforge.net/ + http://www.videohelp.com/tools?tool=263 + Flash-CMS: http://www.lachoseinteractive.net/fr/produits/alahup/ =cut @@ -171,6 +199,12 @@ use strict; use warnings; +use Getopt::Long; +use Storable; +use Data::Dumper; + +my $VERSION = "0.10"; + my $regex = { 'function' => 'function(?:2|)\s(.+?)\s\(.*?\)', 'constants' => 'constants', @@ -178,104 +212,165 @@ 'function_stacked' => 'function(?:2|)\s\s\(.*?\)', 'push' => 'push\s\'(.+?)\'', }; -my @symbols_events = qw( - onDragOut - onDragOver - onKeyUp - onKeyDown - onKillFocus - onPress - onRelease - onReleaseOutside - onRollOut - onRollOver - onSetFocus - onActivity - onStatus - onSelect - onData - onLoad - allowDomain - allowInsecureDomain - onMouseDown - onMouseMove - onMouseUp - onMouseWheel - onEnterFrame - onUnload - onLoadComplete - onLoadError - onLoadInit - onLoadProgress - onLoadStart - onID3 - onSoundComplete - onResize - onChanged - onScroller -); my @symbols; +my @lines; +my $options; -# 1. read flasm code from STDIN -my @lines = ; +sub read_options { + GetOptions( + "pollute" => \$options->{pollute}, + "help" => \$options->{help}, + "version" => \$options->{version} + ); +} -my $counter = 0; -foreach (@lines) { - - # trim newlines - #chomp; - my $symbol; +sub scan_symbols { + my @symbols_events = qw( + onDragOut + onDragOver + onKeyUp + onKeyDown + onKillFocus + onPress + onRelease + onReleaseOutside + onRollOut + onRollOver + onSetFocus + onActivity + onStatus + onSelect + onData + onLoad + allowDomain + allowInsecureDomain + onMouseDown + onMouseMove + onMouseUp + onMouseWheel + onEnterFrame + onUnload + onLoadComplete + onLoadError + onLoadInit + onLoadProgress + onLoadStart + onID3 + onSoundComplete + onResize + onChanged + onScroller + ); - # check for all "function" / "function2" symbols and ... - if (m/$regex->{function}/) { - # ... remember them - $symbol = $1; - - - } elsif (m/$regex->{function_stacked}/) { - if ($lines[$counter - 1] =~ m/$regex->{push}/) { + my $counter = 0; + foreach (@lines) { + + # trim newlines + #chomp; + my $symbol; + + # check for all "function" / "function2" symbols and ... + if (m/$regex->{function}/) { + # ... remember them $symbol = $1; + + + } elsif (m/$regex->{function_stacked}/) { + if ($lines[$counter - 1] =~ m/$regex->{push}/) { + $symbol = $1; + } } + + if ($symbol and not grep(/$symbol/, @symbols_events)) { + push @symbols, $symbol; + } + + $counter++; + } - if ($symbol and not grep(/$symbol/, @symbols_events)) { - push @symbols, $symbol; - } - - $counter++; - } #print join("\n", @symbols); exit; # 2. step through all symbols found and replace them -my $symbol_counter = -1; -foreach my $symbol (@symbols) { - my $line_counter = 0; - foreach (@lines) { - - # function declarations; single quotes might not be there! - if (m/$regex->{function}/) { - s/\s'*$symbol'*\s/ '$symbol_counter' /i; - - # "constants"-line at begin of each block; single quotes should already be there - } elsif (m/$regex->{constants}/) { - s/'$symbol'/'$symbol_counter'/i; - - # function calls; replace inside predecessor line of calling-lines - } elsif (m/$regex->{call}/) { - $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_counter'/i; +sub obfuscate { - # function declarations; name of function is pushed on stack one line before! - } elsif (m/$regex->{function_stacked}/) { - $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_counter'/i; + # 1st stage: symbol replacement + my $symbol_counter = -1; + foreach my $symbol (@symbols) { + my $line_counter = 0; + foreach (@lines) { + + # function declarations; single quotes might not be there! + if (m/$regex->{function}/) { + s/\s'*$symbol'*\s/ '$symbol_counter' /i; + + # "constants"-line at begin of each block; single quotes should already be there + } elsif (m/$regex->{constants}/) { + s/'$symbol'/'$symbol_counter'/i; + + # function calls; replace inside predecessor line of calling-lines + } elsif (m/$regex->{call}/) { + $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_counter'/i; + + # function declarations; name of function is pushed on stack one line before! + } elsif (m/$regex->{function_stacked}/) { + $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_counter'/i; + } + + $line_counter++; + } + $symbol_counter--; + } - $line_counter++; - + # 2nd stage: pollute & Co. + if ($options->{pollute}) { + foreach (@lines) { + if (m/$regex->{constants}/) { + my $inject = qq( + push 0 + ls: + dup + trace + branchIfTrue ls + +); + $_ .= $inject; + } + } } - $symbol_counter--; + +} + +sub usage { + print "fluscate - The Flash Obfuscator (v$VERSION)", "\n"; + if (not $options->{version}) { + print <{help} || $options->{version}) { + usage(); + exit; + } + # read flasm code from STDIN + @lines = ; + scan_symbols(); + obfuscate(); + # write all stuff to STDOUT + print STDOUT @lines; +} + +main(); + +1; +__END__