/[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.3 by joko, Fri Jul 23 12:56:07 2004 UTC revision 1.7 by joko, Tue Aug 3 02:36:05 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.7  2004/08/03 02:36:05  joko
8    # new features: Random, Undo, Interactive mode
9    #
10    # Revision 1.6  2004/08/03 00:24:15  joko
11    # restructured code (procedures)
12    # command-line arguments
13    # new feature: pollute
14    #
15    # Revision 1.5  2004/07/26 16:11:58  joko
16    # updated pod
17    # included more complete list of flash event-handlers
18    # fixed substitution regex #1: now using spaces around function names
19    #
20    # Revision 1.4  2004/07/26 13:51:54  joko
21    # updated pod
22    #
23  # Revision 1.3  2004/07/23 12:56:07  joko  # Revision 1.3  2004/07/23 12:56:07  joko
24  # updated pod  # updated pod
25  #  #
# Line 16  Line 32 
32    
33  =pod  =pod
34    
35      fluscate - The Flash Obfuscator
36    
37    This software is Copyright (C) 2004 Andreas Motl    This software is Copyright (C) 2004 Andreas Motl
38    Ideas and future AppleScript integration by Holger Marseille.    Ideas and MacOS X Application by Holger Marseille
39        
40    This program is free software; you can redistribute it and/or    This program is free software; you can redistribute it and/or
41    modify it under the terms of the GNU General Public License    modify it under the terms of the GNU General Public License
# Line 40  Line 58 
58    
59  =head1 Features  =head1 Features
60    
61  =head2 Functions  
62    =head2 Obfuscation
63    
64      See ASO Pro: http://www.genable.com/aso/preview.html
65      fluscate implements a subset of these features plus some others.
66    
67    =head2 Symbols
68    
69    =head3 Functions
70    
71    fluscate handles two different styles of function declarations:    fluscate handles two different styles of function declarations:
72    
73    1. "Normal" ones    1. "Normal" ones, e.g.
74        function mp3Player ('arg1', 'arg2')        function mp3Player ('arg1', 'arg2')
75    
76    2. There may be "stacked" function declarations    2. There may be "stacked" function declarations, e.g.
77        push 'mp3Player'        push 'mp3Player'
78        function  ()        function  ()
79    
80    =head2 Pollute
81    
82      Some flash-disassemblers might croak when inserting the following code
83      after a/each "constants"-declaration:
84    
85        push 0
86        ls:
87          dup
88          trace
89          branchIfTrue ls
90      
91      Needs testing!
92    
93    =head2 Random
94    
95      Instead of using '-1', '-2', '-3', etc., this option creates randomized numbers
96      as symbol replacements.
97    
98    =head2 Undo
99      
100      fluscate now has "undo"-functionality which can revert symbol replacements.
101      First, use "fluscate -m -s" (memorize+save switches) to store your metadata and
102      "fluscate -m -l -u" (memorize+load+undo switches) to make things undone.
103    
104    =head2 Interactive mode
105    
106      Can ask you about each symbol whether to replace it. Use "-i -f file.flm".
107    
108    
109  =head1 Dependencies  =head1 Dependencies
110    
# Line 60  Line 114 
114    
115  =head1 Usage  =head1 Usage
116    
117  =head2 win32  =head2 General
118    
119      Please type "fluscate --help" to get more information about command-line parameters.
120    
121    =head2 Semantic use:
122    
123    =head3 win32
124    
125    #> flasm.exe -d puzzle.swf > puzzle.flm    #> flasm.exe -d puzzle.swf > puzzle.flm
126    #> cat puzzle.flm | perl fluscate.pl > puzzle_fusc.flm    #> cat puzzle.flm | perl fluscate.pl > puzzle_fusc.flm
127    #> flasm.exe -a puzzle_fusc.flm    #> flasm.exe -a puzzle_fusc.flm
128    
129  =head2 *nix  =head3 *nix
130    
131    #> ./flasm -d puzzle.swf > puzzle.flm    #> ./flasm -d puzzle.swf > puzzle.flm
132    #> cat puzzle.flm | ./fluscate.pl > puzzle_fusc.flm    #> cat puzzle.flm | ./fluscate.pl > puzzle_fusc.flm
# Line 78  Line 138 
138  =head2 Todo  =head2 Todo
139    
140    - provide list of flash event handler names to exclude from symbol replacement    - provide list of flash event handler names to exclude from symbol replacement
141      - include list of ->keywords from:
142        http://www.macromedia.com/support/flash/action_scripts/actionscript_dictionary/
143    
144  =head2 Wishlist  =head2 Wishlist
145    
   - komplexere verschlüsselung als "-1, -2 ..." z-b nicht in der numerischen reihenfolge sondern nach  
     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)  
146    - what about other symbols beside "function"s? (e.g. variables) (->mode)    - what about other symbols beside "function"s? (e.g. variables) (->mode)
147      - replace symbols in multiple files (->multifile)
148      - more symbol-replacement-modes:
149          normal, random, random-alphanumeric (e.g. ahjit, twobc, plodf), wordlist, etc.
150    
151  =head2 Notes  =head2 Notes
152    
# Line 104  Line 159 
159    - "getMember" and "getVariable" also do function calls!    - "getMember" and "getVariable" also do function calls!
160    - 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")
161    
162    
163    =head1 Links
164    
165    =head2 ActionScript Decompilers / Disassemblers
166    
167      Flasm:
168        http://www.nowrap.de/flasm.html
169        http://www.opaque.net/~dave/flasm/
170      Flare: http://www.nowrap.de/flare.html
171      Sothink SWF Decompiler: http://www.srctec.com/flashdecompiler/
172      Imperator FLA: http://www.ave-imperator.com/
173      SWF Decompiler: http://www.19.5degs.com/swfdecompiler.php
174      Gordon: http://www.futurecandy.com/
175    
176    =head2 ActionScript Editors & Co.
177    
178      URL Action Editor and Actionscript Viewer:
179        http://www.buraks.com/
180        http://voisen.org/archives/2003/02/uae_303_and_asv_309.php
181      SE|PY ActionScript Editor: http://www.sephiroth.it/python/sepy.php
182    
183    =head2 Obfuscators
184    
185      ASO Pro (ActionScript Obfuscator Pro): http://www.genable.com/aso/preview.html
186      SWOB (swf obfuscator): http://home.byu.net/jtb64/Swob.htm
187      OBFU - A Flash Actionscript obfuscator: http://opaque.net/~dave/obfu/
188    
189    =head2 Misc
190    
191      ActionScript Protection:
192        http://www.as-protect.com/
193        http://www.quasimondo.com/archives/000377.php
194      Developer's SWF Guardian: http://anyrd.anyorganization.com/
195      Password Busting / SWF Protections: http://www.searchlores.org/cinix_fla.htm
196    
197    =head2 Off-Topic
198    
199    =head3 XML
200    
201      XPath for Actionscript and other stuff: http://www.xfactorstudio.com/Actionscript/
202      XMLRPC Flash Libraries for ActionScript 2.0: http://xmlrpcflash.sourceforge.net/
203    
204    =head3 Marshalling / AMF (Flash Remoting protocol)
205    
206      AMFPHP - Flash Remoting for PHP: http://www.amfphp.org/
207      AMF::Perl - Flash Remoting in Perl and Python: http://simonf.com/amfperl/
208      SerializerClass: http://sourceforge.net/projects/serializerclass/
209    
210    =head3 Misc
211    
212      PEAR::SWF - Read and write SWF head tag: http://www.sephiroth.it/test/php/SWF/
213      Convert videos to flv:
214        http://ffmpeg.sourceforge.net/
215        http://www.videohelp.com/tools?tool=263
216      Flash-CMS: http://www.lachoseinteractive.net/fr/produits/alahup/
217    
218  =cut  =cut
219    
220    
221  use strict;  use strict;
222  use warnings;  use warnings;
223    
224    use Getopt::Long;
225    use Storable;
226    use Data::Dumper;
227    use Term::ReadKey;
228    
229    my $VERSION = "0.10";
230    
231  my $regex = {  my $regex = {
232    'function' => 'function(?:2|)\s(.+?)\s\(.*?\)',    'function' => 'function(?:2|)\s(.+?)\s\(.*?\)',
233    'constants' => 'constants',    'constants' => 'constants',
# Line 117  my $regex = { Line 235  my $regex = {
235    'function_stacked' => 'function(?:2|)\s\s\(.*?\)',    'function_stacked' => 'function(?:2|)\s\s\(.*?\)',
236    'push' => 'push\s\'(.+?)\'',    'push' => 'push\s\'(.+?)\'',
237  };  };
 my @symbols_events = qw( onPress onReleaseOutside onRelease onMouseDown onEnterFrame );  
238  my @symbols;  my @symbols;
239    my $symbols_table;
240    my @lines;
241    my $options;
242    
243    sub read_options {
244      GetOptions(
245        "pollute" => \$options->{pollute},
246        "help" => \$options->{help},
247        "version" => \$options->{version},
248        "random" => \$options->{random},
249        "memorize" => \$options->{memorize},
250        "load" => \$options->{load},
251        "save" => \$options->{save},
252        "undo" => \$options->{undo},
253        "interactive" => \$options->{interactive},
254        "file=s" => \$options->{file},
255      );
256    }
257    
258  # 1. read flasm code from STDIN  sub scan_symbols {
259  my @lines = <STDIN>;    my @symbols_events = qw(
260        onDragOut
261  my $counter = 0;      onDragOver
262  foreach (@lines) {      onKeyUp
263          onKeyDown
264    # trim newlines      onKillFocus
265    #chomp;      onPress
266    my $symbol;      onRelease
267        onReleaseOutside
268        onRollOut
269        onRollOver
270        onSetFocus
271        onActivity
272        onStatus
273        onSelect
274        onData
275        onLoad
276        allowDomain
277        allowInsecureDomain
278        onMouseDown
279        onMouseMove
280        onMouseUp
281        onMouseWheel
282        onEnterFrame
283        onUnload
284        onLoadComplete
285        onLoadError
286        onLoadInit
287        onLoadProgress
288        onLoadStart
289        onID3
290        onSoundComplete
291        onResize
292        onChanged
293        onScroller
294      );
295        
296    # check for all "function" / "function2" symbols and ...    my $counter = 0;
297    if (m/$regex->{function}/) {    foreach (@lines) {
298      # ... remember them      
299      $symbol = $1;      # trim newlines
300          #chomp;
301          my $symbol;
302    } elsif (m/$regex->{function_stacked}/) {      
303      if ($lines[$counter - 1] =~ m/$regex->{push}/) {      # check for all "function" / "function2" symbols and ...
304        if (m/$regex->{function}/) {
305          # ... remember them
306        $symbol = $1;        $symbol = $1;
307        
308        } elsif (m/$regex->{function_stacked}/) {
309          if ($lines[$counter - 1] =~ m/$regex->{push}/) {
310            $symbol = $1;
311          }
312        }
313        
314        if ($symbol and not grep(/$symbol/, @symbols_events)) {
315          push @symbols, $symbol;
316      }      }
317        
318        $counter++;
319        
320    }    }
321        
322    if ($symbol and not grep(/$symbol/, @symbols_events)) {  }
323      push @symbols, $symbol;  
324    sub scramble_symbols {
325      if ($options->{random}) {
326        #my $range = $#symbols;
327        #my $range = 7;
328        my $range = 10000;
329        my $rndmem = {};
330        foreach (@symbols) {
331          shuffle:
332          my $rnd = -int(rand($range) + 1);
333          goto shuffle if ($rndmem->{$rnd});
334          $symbols_table->{$_} = $rnd;
335          $rndmem->{$rnd}++;
336        }
337      } else {
338        my $symbol_counter = -1;
339        foreach (@symbols) {
340          $symbols_table->{$_} = $symbol_counter;
341          $symbol_counter--;
342        }
343    }    }
     
   $counter++;  
     
344  }  }
345    
346  #print join("\n", @symbols); exit;  sub select_symbols {
347      print STDERR "Please answer with y/n to select symbols for replacement:", "\n";
348      ReadMode 3;
349      foreach (keys %$symbols_table) {
350        print STDERR $_, ": ";
351        getkey:
352        my $key = ReadKey(0) || "";
353        goto getkey if ($key !~ m/[yn]/i);
354        print STDERR $key, "\n";
355        delete $symbols_table->{$_} if ($key =~ m/n/i);
356      }
357      ReadMode 0;
358    }
359    
360  # 2. step through all symbols found and replace them  # 2. step through all symbols found and replace them
361  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;  
362    
363      # function declarations; name of function is pushed on stack one line before!    # 1st stage: symbol replacement
364      } elsif (m/$regex->{function_stacked}/) {    foreach my $symbol (keys %{$symbols_table}) {
365        $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_counter'/i;      my $symbol_new = $symbols_table->{$symbol};
366        my $line_counter = 0;
367        foreach (@lines) {
368          
369          # function declarations; single quotes might not be there!
370          if (m/$regex->{function}/) {
371            s/\s'*$symbol'*\s/ '$symbol_new' /i;
372          
373          # "constants"-line at begin of each block; single quotes should already be there
374          } elsif (m/$regex->{constants}/) {
375            s/'$symbol'/'$symbol_new'/i;
376          
377          # function calls; replace inside predecessor line of calling-lines
378          } elsif (m/$regex->{call}/) {
379            $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_new'/i;
380      
381          # function declarations; name of function is pushed on stack one line before!
382          } elsif (m/$regex->{function_stacked}/) {
383            $lines[$line_counter - 1] =~ s/'$symbol'/'$symbol_new'/i;
384          }
385    
386          $line_counter++;
387          
388      }      }
389      }
390    
391      $line_counter++;    # 2nd stage: pollute & Co.
392          if ($options->{pollute}) {
393        foreach (@lines) {
394          if (m/$regex->{constants}/) {
395            my $inject = qq(
396          push 0
397          ls:
398            dup
399            trace
400            branchIfTrue ls
401      
402    );
403            $_ .= $inject;
404          }
405        }
406      }
407    
408    }
409    
410    sub usage {
411      print "fluscate - The Flash Obfuscator (v$VERSION)", "\n";
412      if (not $options->{version}) {
413      print <<USAGE;
414        [-p|--pollute]      Pollute code by inserting snippet making life harder for disassemblers
415        [-h|--help]         This text
416        [-v|--version]      Show version information only
417        [-m|--memorize]     Enable "memorize"-mode: can load and save symbol replacement metadata
418        [-l|--load]         Load symbol replacement table from file
419        [-s|--save]         Save symbol replacement table to file
420        [-u|--undo]         Replaces obfuscated symbols with original ones; valid only with "memorize" and "load"
421        [-f|--file]         Specify path to file for interactive mode
422    USAGE
423      };
424    }
425    
426    sub main {
427      
428      # basic option handling
429      read_options();
430      #print Dumper($options);
431      if ($options->{help} || $options->{version}) {
432        usage();
433        exit;
434    }    }
435    $symbol_counter--;    if ($options->{interactive} and not -z STDIN) {
436        print "Can not switch to interactive mode while reading from STDIN, please specify file with '-f'.", "\n";
437        exit;
438      }
439      
440      if ($options->{file}) {
441        # read flasm code from file
442        if (!open(FH, $options->{file})) {
443          print "Could not open file '$options->{file}'!", "\n";
444          exit;
445        }
446        @lines = <FH>;
447        close(FH);
448      } else {
449        # read flasm code from STDIN
450        @lines = <STDIN>;
451        close(STDIN);
452      }
453    
454      # symbol stuff (build/load/save)
455      my $file = "fluscate.syms";
456      if ($options->{memorize} and $options->{load}) {
457        # load
458        $symbols_table = retrieve($file);
459        if ($options->{undo}) {
460          %$symbols_table = reverse %$symbols_table;
461        }
462      } else {
463        # build
464        scan_symbols();
465        scramble_symbols();
466        # save
467        if ($options->{memorize} and $options->{save}) {
468          store($symbols_table, $file);
469        }
470      }
471      
472      if ($options->{interactive}) {
473        select_symbols();
474      }
475      #print Dumper($symbols_table); exit;
476      
477      # replacements
478      obfuscate();
479      # write all stuff to STDOUT
480      print STDOUT @lines;
481  }  }
482    
483  # write all stuff to STDOUT  main();
484  print STDOUT @lines;  
485    1;
486    __END__

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.7

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