You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
6.1 KiB
214 lines
6.1 KiB
/* ClassBundle Copyright (C) 1998-1999 Jochen Hoenicke.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
package jode.obfuscator;
|
|
import jode.GlobalOptions;
|
|
import jode.bytecode.ClassInfo;
|
|
import jode.bytecode.Reference;
|
|
import java.io.*;
|
|
import java.util.zip.ZipOutputStream;
|
|
|
|
///#ifdef JDK12
|
|
///import java.util.Collection;
|
|
///import java.util.Iterator;
|
|
///import java.util.Set;
|
|
///import java.util.HashSet;
|
|
///import java.util.Map;
|
|
///import java.util.TreeMap;
|
|
///import java.util.WeakHashMap;
|
|
///#else
|
|
import jode.util.Collection;
|
|
import jode.util.Iterator;
|
|
import jode.util.Set;
|
|
import jode.util.HashSet;
|
|
import jode.util.Map;
|
|
import jode.util.TreeMap;
|
|
import jode.util.HashMap;
|
|
///#endif
|
|
|
|
public class ClassBundle {
|
|
|
|
ModifierMatcher preserveRule = null;
|
|
PackageIdentifier basePackage;
|
|
/**
|
|
* the identifiers that must be analyzed.
|
|
*/
|
|
Set toAnalyze = new HashSet();
|
|
|
|
public ClassBundle() {
|
|
basePackage = new PackageIdentifier(this, null, "", false);
|
|
basePackage.setReachable();
|
|
basePackage.setPreserved();
|
|
}
|
|
|
|
///#ifdef JDK12
|
|
/// private static final Map aliasesHash = new WeakHashMap();
|
|
///#else
|
|
private static final Map aliasesHash = new HashMap();
|
|
///#endif
|
|
|
|
public Reference getReferenceAlias(Reference ref) {
|
|
Reference alias = (Reference) aliasesHash.get(ref);
|
|
if (alias == null) {
|
|
Identifier ident = getIdentifier(ref);
|
|
String newType = getTypeAlias(ref.getType());
|
|
if (ident == null)
|
|
alias = Reference.getReference
|
|
(ref.getClazz(), ref.getName(), newType);
|
|
else
|
|
alias = Reference.getReference
|
|
("L"+ident.getParent().getFullAlias().replace('.','/')+';',
|
|
ident.getAlias(), newType);
|
|
aliasesHash.put(ref, alias);
|
|
}
|
|
return alias;
|
|
}
|
|
|
|
public String getTypeAlias(String typeSig) {
|
|
String alias = (String) aliasesHash.get(typeSig);
|
|
if (alias == null) {
|
|
StringBuffer newSig = new StringBuffer();
|
|
int index = 0, nextindex;
|
|
while ((nextindex = typeSig.indexOf('L', index)) != -1) {
|
|
newSig.append(typeSig.substring(index, nextindex+1));
|
|
index = typeSig.indexOf(';', nextindex);
|
|
String typeAlias = basePackage.findAlias
|
|
(typeSig.substring(nextindex+1, index).replace('/','.'));
|
|
newSig.append(typeAlias.replace('.', '/'));
|
|
}
|
|
alias = newSig.append(typeSig.substring(index))
|
|
.toString().intern();
|
|
aliasesHash.put(typeSig, alias);
|
|
}
|
|
return alias;
|
|
}
|
|
|
|
public ClassIdentifier getClassIdentifier(String name) {
|
|
ClassIdentifier ident
|
|
= (ClassIdentifier) basePackage.getIdentifier(name);
|
|
return ident;
|
|
}
|
|
|
|
public Identifier getIdentifier(Reference ref) {
|
|
String clName = ref.getClazz();
|
|
if (clName.charAt(0) == '[')
|
|
/* Can't represent arrays */
|
|
return null;
|
|
ClassIdentifier ident =
|
|
getClassIdentifier(clName.substring(1, clName.length()-1)
|
|
.replace('/','.'));
|
|
if (ident == null)
|
|
return null;
|
|
return ident.getIdentifier(ref.getName(), ref.getType());
|
|
}
|
|
|
|
public void loadClasses(String wildcard) {
|
|
System.err.println("Loading: "+wildcard);
|
|
basePackage.loadMatchingClasses(new WildCard(wildcard));
|
|
}
|
|
|
|
public void reachableIdentifier(String fqn, boolean isVirtual) {
|
|
basePackage.reachableIdentifier(fqn, isVirtual);
|
|
}
|
|
|
|
public void setPreserved(ModifierMatcher preserveRule,
|
|
Collection fullqualifiednames) {
|
|
this.preserveRule = preserveRule;
|
|
|
|
basePackage.applyPreserveRule(preserveRule);
|
|
for (Iterator i = fullqualifiednames.iterator(); i.hasNext(); ) {
|
|
basePackage.preserveMatchingIdentifier
|
|
(new WildCard((String) i.next()));
|
|
}
|
|
analyze();
|
|
}
|
|
|
|
public void analyzeIdentifier(Identifier ident) {
|
|
if (ident == null)
|
|
throw new NullPointerException();
|
|
toAnalyze.add(ident);
|
|
}
|
|
|
|
public void analyze() {
|
|
while(!toAnalyze.isEmpty()) {
|
|
Identifier ident = (Identifier) toAnalyze.iterator().next();
|
|
toAnalyze.remove(ident);
|
|
ident.analyze();
|
|
}
|
|
}
|
|
|
|
public void buildTable(Renamer renameRule) {
|
|
basePackage.buildTable(renameRule);
|
|
}
|
|
|
|
public void readTable(String filename) {
|
|
try {
|
|
TranslationTable table = new TranslationTable();
|
|
InputStream input = new FileInputStream(filename);
|
|
table.load(input);
|
|
input.close();
|
|
basePackage.readTable(table);
|
|
} catch (java.io.IOException ex) {
|
|
GlobalOptions.err.println("Can't read rename table "+filename);
|
|
ex.printStackTrace(GlobalOptions.err);
|
|
}
|
|
}
|
|
|
|
public void writeTable(String filename) {
|
|
TranslationTable table = new TranslationTable();
|
|
basePackage.writeTable(table);
|
|
try {
|
|
OutputStream out = new FileOutputStream(filename);
|
|
table.store(out);
|
|
out.close();
|
|
} catch (java.io.IOException ex) {
|
|
GlobalOptions.err.println("Can't write rename table "+filename);
|
|
ex.printStackTrace(GlobalOptions.err);
|
|
}
|
|
}
|
|
|
|
public void doTransformations() {
|
|
basePackage.doTransformations();
|
|
}
|
|
|
|
public void storeClasses(String destination) {
|
|
if (destination.endsWith(".jar") ||
|
|
destination.endsWith(".zip")) {
|
|
try {
|
|
ZipOutputStream zip = new ZipOutputStream
|
|
(new FileOutputStream(destination));
|
|
basePackage.storeClasses(zip);
|
|
zip.close();
|
|
} catch (IOException ex) {
|
|
GlobalOptions.err.println
|
|
("Can't write zip file: "+destination);
|
|
ex.printStackTrace(GlobalOptions.err);
|
|
}
|
|
} else {
|
|
File directory = new File(destination);
|
|
if (!directory.exists()) {
|
|
GlobalOptions.err.println("Destination directory "
|
|
+directory.getPath()
|
|
+" doesn't exists.");
|
|
return;
|
|
}
|
|
basePackage.storeClasses(new File(destination));
|
|
}
|
|
}
|
|
}
|
|
|