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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations)
Tue Aug 3 02:36:05 2004 UTC (19 years, 11 months ago) by joko
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +137 -25 lines
File MIME type: text/plain
new features: Random, Undo, Interactive mode

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

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