/[cvs]/nfo/perl/scripts/fluscate/bin/fluscate.pl
ViewVC logotype

Diff of /nfo/perl/scripts/fluscate/bin/fluscate.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by joko, Fri Jul 23 12:13:14 2004 UTC revision 1.6 by joko, Tue Aug 3 00:24:15 2004 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl  #!/usr/bin/perl
2    
3  # fluscate.pl 0.03 - The Flash Obfuscator  # fluscate - The Flash Obfuscator
4    
5  # $Id$  # $Id$
6  # $Log$  # $Log$
7    # Revision 1.6  2004/08/03 00:24:15  joko
8    # restructured code (procedures)
9    # command-line arguments
10    # new feature: pollute
11    #
12    # Revision 1.5  2004/07/26 16:11:58  joko
13    # updated pod
14    # included more complete list of flash event-handlers
15    # fixed substitution regex #1: now using spaces around function names
16    #
17    # Revision 1.4  2004/07/26 13:51:54  joko
18    # updated pod
19    #
20    # Revision 1.3  2004/07/23 12:56:07  joko
21    # updated pod
22    #
23    # Revision 1.2  2004/07/23 12:24:52  joko
24    # pod
25    #
26  # Revision 1.1  2004/07/23 12:13:14  joko  # Revision 1.1  2004/07/23 12:13:14  joko
27  # initial commit  # initial commit
28  #  #
29    
30  =pod  =pod
 This software is Copyright (C) 2004 Andreas Motl  
 Ideas and future AppleScript integration by Holger Marseille.  
31    
32  This program is free software; you can redistribute it and/or    fluscate - The Flash Obfuscator
33  modify it under the terms of the GNU General Public License  
34  as published by the Free Software Foundation; either version 2    This software is Copyright (C) 2004 Andreas Motl
35  of the License, or (at your option) any later version.    Ideas and MacOS X Application by Holger Marseille
36      
37  This program is distributed in the hope that it will be useful,    This program is free software; you can redistribute it and/or
38  but WITHOUT ANY WARRANTY; without even the implied warranty of    modify it under the terms of the GNU General Public License
39  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    as published by the Free Software Foundation; either version 2
40  GNU General Public License for more details.    of the License, or (at your option) any later version.
41      
42  You should have received a copy of the GNU General Public License    This program is distributed in the hope that it will be useful,
43  along with this program; if not, write to the Free Software    but WITHOUT ANY WARRANTY; without even the implied warranty of
44  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45      GNU General Public License for more details.
46      
47      You should have received a copy of the GNU General Public License
48      along with this program; if not, write to the Free Software
49      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
50    
51  =cut  =cut
52    
53    
# Line 32  Foundation, Inc., 59 Temple Place - Suit Line 55  Foundation, Inc., 59 Temple Place - Suit
55    
56  =head1 Features  =head1 Features
57    
58  =head2 Requests  
59    - komplexere verschlüsselung als "-1, -2 ..." z-b nicht in der numerischen reihenfolge sondern nach  =head2 Obfuscation
60      zufallsprinip (-21,-3,-89)? (->random)  
61    - evtl. constants nach abfrage ersetzen ? leider sehr aufwendig, bei vielen constants (->ask)    See ASO Pro: http://www.genable.com/aso/preview.html
62    - 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)  
63    
64  =head2 Functions  =head2 Functions
 fluscate handles two different styles of function declarations:  
65    
66    1. "Normal" ones    fluscate handles two different styles of function declarations:
67    
68      1. "Normal" ones, e.g.
69        function mp3Player ('arg1', 'arg2')        function mp3Player ('arg1', 'arg2')
70    
71    2. There may be "stacked" function declarations    2. There may be "stacked" function declarations, e.g.
72        push 'mp3Player'        push 'mp3Player'
73        function  ()        function  ()
74    
75    =head2 Pollute
76    
77      Some flash-disassemblers might croak when inserting the following code
78      after a/each "constants"-declaration:
79    
80        push 0
81        ls:
82          dup
83          trace
84          branchIfTrue ls"
85    
86    
87    =head1 Dependencies
88    
89      "flasm" is required to disassemble swf files, see http://www.nowrap.de/flasm.html
90      ACKs go to Igor Kogan.
91    
92    
93    =head1 Usage
94    
95    =head2 General
96    
97      Please type "fluscate --help" to get more information about command-line parameters.
98    
99    =head2 win32
100    
101      #> flasm.exe -d puzzle.swf > puzzle.flm
102      #> cat puzzle.flm | perl fluscate.pl > puzzle_fusc.flm
103      #> flasm.exe -a puzzle_fusc.flm
104    
105    =head2 *nix
106    
107      #> ./flasm -d puzzle.swf > puzzle.flm
108      #> cat puzzle.flm | ./fluscate.pl > puzzle_fusc.flm
109      #> ./flasm -a puzzle_fusc.flm
110    
111    
112    =head1 Development
113    
114    =head2 Todo
115    
116      - provide list of flash event handler names to exclude from symbol replacement
117    
118    =head2 Wishlist
119    
120      - komplexere verschlüsselung als "-1, -2 ..." z-b nicht in der numerischen reihenfolge sondern nach
121        zufallsprinip (-21,-3,-89)? (->random)
122      - evtl. constants nach abfrage ersetzen ? leider sehr aufwendig, bei vielen constants (->ask)
123      - rausgeben des arrays mit den "neuen" werten um evtl die obfuscation rückgängig zu machen (->undo)
124      - what about other symbols beside "function"s? (e.g. variables) (->mode)
125      - include list of ->keywords from:
126        http://www.macromedia.com/support/flash/action_scripts/actionscript_dictionary/
127      - replace symbols in multiple files (->multifile)
128    
129    =head2 Notes
130    
 =head1 Notes  
131    - no function may be called "Initialize", rename it to (e.g.) "Initialize2", reassembling will not work otherwise    - no function may be called "Initialize", rename it to (e.g.) "Initialize2", reassembling will not work otherwise
132      (doesn't matter when obfuscating since function names will be replaced of course)      (doesn't matter when obfuscating since function names will be replaced of course)
133    - function names seem to be/work case insensitive (shuffle <-> Shuffle)    - function names seem to be/work case insensitive (shuffle <-> Shuffle)
# Line 66  fluscate handles two different styles of Line 137  fluscate handles two different styles of
137    - "getMember" and "getVariable" also do function calls!    - "getMember" and "getVariable" also do function calls!
138    - there are reserved function names which must not be replaced! (-> event handlers, e.g. "onPress")    - there are reserved function names which must not be replaced! (-> event handlers, e.g. "onPress")
139    
 =head1 Todo / Review  
   - what about other symbols beside "function"s?  
140    
141  =head1 Usage  =head1 Links
142    
143  =head2 Usage (win32):  =head2 ActionScript Decompilers / Disassemblers
144    #> flasm.exe -d puzzle.swf > puzzle.flm  
145    #> cat puzzle.flm | perl fluscate.pl > puzzle_fusc.flm    Flasm:
146    #> flasm.exe -a puzzle_fusc.flm      http://www.nowrap.de/flasm.html
147        http://www.opaque.net/~dave/flasm/
148      Flare: http://www.nowrap.de/flare.html
149      Sothink SWF Decompiler: http://www.srctec.com/flashdecompiler/
150      Imperator FLA: http://www.ave-imperator.com/
151      SWF Decompiler: http://www.19.5degs.com/swfdecompiler.php
152      Gordon: http://www.futurecandy.com/
153    
154    =head2 ActionScript Editors & Co.
155    
156  =head2 Usage (*nix):    URL Action Editor and Actionscript Viewer:
157    #> flasm -d puzzle.swf > puzzle.flm      http://www.buraks.com/
158    #> cat puzzle.flm | fluscate.pl > puzzle_fusc.flm      http://voisen.org/archives/2003/02/uae_303_and_asv_309.php
159    #> flasm -a puzzle_fusc.flm    SE|PY ActionScript Editor: http://www.sephiroth.it/python/sepy.php
160    
161    =head2 Obfuscators
162    
163      ASO Pro (ActionScript Obfuscator Pro): http://www.genable.com/aso/preview.html
164      SWOB (swf obfuscator): http://home.byu.net/jtb64/Swob.htm
165      OBFU - A Flash Actionscript obfuscator: http://opaque.net/~dave/obfu/
166    
167    =head2 Misc
168    
169      ActionScript Protection:
170        http://www.as-protect.com/
171        http://www.quasimondo.com/archives/000377.php
172      Developer's SWF Guardian: http://anyrd.anyorganization.com/
173      Password Busting / SWF Protections: http://www.searchlores.org/cinix_fla.htm
174    
175    =head2 Off-Topic
176    
177    =head3 XML
178    
179      XPath for Actionscript and other stuff: http://www.xfactorstudio.com/Actionscript/
180      XMLRPC Flash Libraries for ActionScript 2.0: http://xmlrpcflash.sourceforge.net/
181    
182    =head3 Marshalling / AMF (Flash Remoting protocol)
183    
184      AMFPHP - Flash Remoting for PHP: http://www.amfphp.org/
185      AMF::Perl - Flash Remoting in Perl and Python: http://simonf.com/amfperl/
186      SerializerClass: http://sourceforge.net/projects/serializerclass/
187    
188    =head3 Misc
189    
190      PEAR::SWF - Read and write SWF head tag: http://www.sephiroth.it/test/php/SWF/
191      Convert videos to flv:
192        http://ffmpeg.sourceforge.net/
193        http://www.videohelp.com/tools?tool=263
194      Flash-CMS: http://www.lachoseinteractive.net/fr/produits/alahup/
195    
196  =cut  =cut
197    
# Line 87  fluscate handles two different styles of Line 199  fluscate handles two different styles of
199  use strict;  use strict;
200  use warnings;  use warnings;
201    
202    use Getopt::Long;
203    use Storable;
204    use Data::Dumper;
205    
206    my $VERSION = "0.10";
207    
208  my $regex = {  my $regex = {
209    'function' => 'function(?:2|)\s(.+?)\s\(.*?\)',    'function' => 'function(?:2|)\s(.+?)\s\(.*?\)',
210    'constants' => 'constants',    'constants' => 'constants',
# Line 94  my $regex = { Line 212  my $regex = {
212    'function_stacked' => 'function(?:2|)\s\s\(.*?\)',    'function_stacked' => 'function(?:2|)\s\s\(.*?\)',
213    'push' => 'push\s\'(.+?)\'',    'push' => 'push\s\'(.+?)\'',
214  };  };
 my @symbols_events = qw( onPress onReleaseOutside onRelease onMouseDown onEnterFrame );  
215  my @symbols;  my @symbols;
216    my @lines;
217    my $options;
218    
219  # 1. read flasm code from STDIN  sub read_options {
220  my @lines = <STDIN>;    GetOptions(
221        "pollute" => \$options->{pollute},
222        "help" => \$options->{help},
223        "version" => \$options->{version}
224      );
225    }
226    
227  my $counter = 0;  sub scan_symbols {
228  foreach (@lines) {    my @symbols_events = qw(
229          onDragOut
230    # trim newlines      onDragOver
231    #chomp;      onKeyUp
232    my $symbol;      onKeyDown
233          onKillFocus
234    # check for all "function" / "function2" symbols and ...      onPress
235    if (m/$regex->{function}/) {      onRelease
236      # ... remember them      onReleaseOutside
237      $symbol = $1;      onRollOut
238        onRollOver
239        onSetFocus
240        onActivity
241        onStatus
242        onSelect
243        onData
244        onLoad
245        allowDomain
246        allowInsecureDomain
247        onMouseDown
248        onMouseMove
249        onMouseUp
250        onMouseWheel
251        onEnterFrame
252        onUnload
253        onLoadComplete
254        onLoadError
255        onLoadInit
256        onLoadProgress
257        onLoadStart
258        onID3
259        onSoundComplete
260        onResize
261        onChanged
262        onScroller
263      );
264        
265        my $counter = 0;
266    } elsif (m/$regex->{function_stacked}/) {    foreach (@lines) {
267      if ($lines[$counter - 1] =~ m/$regex->{push}/) {      
268        # trim newlines
269        #chomp;
270        my $symbol;
271        
272        # check for all "function" / "function2" symbols and ...
273        if (m/$regex->{function}/) {
274          # ... remember them
275        $symbol = $1;        $symbol = $1;
276        
277        
278        } elsif (m/$regex->{function_stacked}/) {
279          if ($lines[$counter - 1] =~ m/$regex->{push}/) {
280            $symbol = $1;
281          }
282      }      }
283        
284        if ($symbol and not grep(/$symbol/, @symbols_events)) {
285          push @symbols, $symbol;
286        }
287        
288        $counter++;
289        
290    }    }
291        
   if ($symbol and not grep(/$symbol/, @symbols_events)) {  
     push @symbols, $symbol;  
   }  
     
   $counter++;  
     
292  }  }
293    
294  #print join("\n", @symbols); exit;  #print join("\n", @symbols); exit;
295    
296  # 2. step through all symbols found and replace them  # 2. step through all symbols found and replace them
297  my $symbol_counter = -1;  sub obfuscate {
 foreach my $symbol (@symbols) {  
   my $line_counter = 0;  
   foreach (@lines) {  
       
     # function declarations; single quotes might not be there!  
     if (m/$regex->{function}/) {  
       s/'*$symbol'*/'$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;  
298    
299      # function declarations; name of function is pushed on stack one line before!    # 1st stage: symbol replacement
300      } elsif (m/$regex->{function_stacked}/) {    my $symbol_counter = -1;
301        $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_counter'/i;    foreach my $symbol (@symbols) {
302        my $line_counter = 0;
303        foreach (@lines) {
304          
305          # function declarations; single quotes might not be there!
306          if (m/$regex->{function}/) {
307            s/\s'*$symbol'*\s/ '$symbol_counter' /i;
308          
309          # "constants"-line at begin of each block; single quotes should already be there
310          } elsif (m/$regex->{constants}/) {
311            s/'$symbol'/'$symbol_counter'/i;
312          
313          # function calls; replace inside predecessor line of calling-lines
314          } elsif (m/$regex->{call}/) {
315            $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_counter'/i;
316      
317          # function declarations; name of function is pushed on stack one line before!
318          } elsif (m/$regex->{function_stacked}/) {
319            $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_counter'/i;
320          }
321    
322          $line_counter++;
323          
324      }      }
325        $symbol_counter--;
326      }
327    
328      $line_counter++;    # 2nd stage: pollute & Co.
329          if ($options->{pollute}) {
330        foreach (@lines) {
331          if (m/$regex->{constants}/) {
332            my $inject = qq(
333          push 0
334          ls:
335            dup
336            trace
337            branchIfTrue ls
338      
339    );
340            $_ .= $inject;
341          }
342        }
343      }
344    
345    }
346    
347    sub usage {
348      print "fluscate - The Flash Obfuscator (v$VERSION)", "\n";
349      if (not $options->{version}) {
350      print <<USAGE;
351        [-p|--pollute]      Pollute code by inserting snippet making life harder for disassemblers
352        [-h|--help]         This text
353        [-v|--version]      Show version information only
354    USAGE
355      };
356    }
357    
358    sub main {
359      read_options();
360      #print Dumper($options);
361      if ($options->{help} || $options->{version}) {
362        usage();
363        exit;
364    }    }
365    $symbol_counter--;    # read flasm code from STDIN
366      @lines = <STDIN>;
367      scan_symbols();
368      obfuscate();
369      # write all stuff to STDOUT
370      print STDOUT @lines;
371  }  }
372    
373  # write all stuff to STDOUT  main();
374  print STDOUT @lines;  
375    1;
376    __END__

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.6

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed