在此特别声明,这只是学习使用,不得用于任何非法活动,否则,所有责任自负,与本人无关。
要用jad如下,-safe:所有类都带包名
jad -o -r -f -safe -ff -sjava -d com_src2 src/**/*.class
pause
package jad.chruan;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.chruan.util.DirUtil;
/**
* 格式化
* 用jad反编译混淆过的代码,能去大部分错误,当然逻辑的错误还是要自己修改。
* @author chruan
*
*/
public class JadFormat {
private String returnStr = null;
/**
*
*/
private Integer lineNum;
private List<ClassName> clsList;
public static void main(String[] args) {
JadFormat jadFormat = new JadFormat();
jadFormat.doWork();
System.out.println("end");
}
public void doWork() {
String path = "D:\\CHRUAN\\android\\mypj\\com_src";
String newsrc = "D:\\CHRUAN\\android\\mypj\\new_com_src";
int pathLen = path.length();
List<String> list = new ArrayList<String>();
// 取得所有文件路径
DirUtil.dir(path, list);
// 找到所有类,把文件名作为类名,并把文件 夹作为包,格式化类包
clsList = listClass(list, pathLen);
System.out.println(list.size());
// 遍历所有文件,修改所有错误。如,把一位字母类包修改为三位一样的。
for (int idx = 0, size = list.size(); idx < size; idx++) {
String fp = list.get(idx);
if (fp.endsWith(".java")) {
List<String> aticle = new ArrayList<String>();// 存放类文件
List<LineBean> returnLines = new ArrayList<LineBean>();// 用来把return语句放在方法最后
List<LineBean> superLines = new ArrayList<LineBean>();// 用来把super语句放在方法最前
lineNum = new Integer(-1);
File file = new File(fp);// 类文件
BufferedReader reader = null;
BufferedWriter writer = null;
try {
String newPath = fp.substring(pathLen);
newPath = newsrc + getNewSrcPath(newPath);
writer = new BufferedWriter(new FileWriter(
new File(newPath)));
reader = new BufferedReader(new FileReader(file));
// 按行处理
String line = null;
while ((line = reader.readLine()) != null) {
processModify(line, aticle, returnLines, superLines);
lineNum++;
aticle.add("\r\n");
}
preWrite(writer, aticle, returnLines, superLines);
processWrite(writer, aticle);
System.out.println(newPath);
// if (idx > 50)
// break;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (writer != null)
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
/**
* 找到所有类,把文件名作为类名,并把文件 夹作为包,格式化类包
*
* @param list
* @param pathLen
* @return
*/
private List<ClassName> listClass(List<String> list, int pathLen) {
// TODO Auto-generated method stub
List<ClassName> clsList = new ArrayList<JadFormat.ClassName>();
int pLen = pathLen;
for (int idxx = 0, size = list.size(); idxx < size; idxx++) {
String path = list.get(idxx);
if (path.endsWith(".java")) {
boolean needReplace = false;
String newPath = path.substring(pLen);
// String newPath = path;
ClassName cls = new ClassName();
cls.orgClass = newPath.substring(1, newPath.length() - 5)
.replace('\\', '.');
int len = newPath.length();
int idx = 0;
char c = newPath.charAt(idx);
StringBuilder sb = new StringBuilder();
int dogCount = -1;
while (idx < len) {
char lastc = c;
int count = 0;
while (idx < len && (c = newPath.charAt(idx)) != '\\') {
sb.append(c);
count++;
lastc = c;
idx++;
}
if (count == 1) {
sb.append(lastc).append(lastc);
needReplace = true;
}
if (idx >= len)
break;
else {
sb.append(c);
idx++;
dogCount++;
}
}
if (needReplace) {
newPath = sb.deleteCharAt(0).toString();
newPath = newPath.replace('\\', '.');
cls.count = dogCount;
cls.regClass = "(^| |\\)|\\(|\\[|=|!)"
+ cls.orgClass.replace(".", "\\.")
+ "(;| |\\)|,|\\.|\\[|$)";
cls.length = newPath.length() - 5;
cls.packegedClass = newPath.substring(0, cls.length);
clsList.add(cls);
}
}
}
Collections.sort(clsList);
return clsList;
}
/**
* 把文件路径换成新的文件路径 按修改的类包名
*
* @param newPath
* @return
*/
private String getNewSrcPath(String newPath) {
// TODO Auto-generated method stub
int len = newPath.length();
int idx = 0;
char c = newPath.charAt(idx);
StringBuilder sb = new StringBuilder();
// sb.append(c);
while (idx < len) {
char lastc = c;
int count = 0;
while (idx < len && (c = newPath.charAt(idx)) != '\\') {
sb.append(c);
count++;
lastc = c;
idx++;
}
if (count == 1)
sb.append(lastc).append(lastc);
if (idx >= len)
break;
else {
sb.append(c);
idx++;
}
}
return sb.toString();
}
/**
* 就是把一些要注释的注释的注释掉,把包名中有一个字母包名的变成三个同字母
* @param line
* @param aticle
* @param returnLines
* @param superLines
* @throws IOException
*/
private void processModify(String line, List<String> aticle,
List<LineBean> returnLines, List<LineBean> superLines)
throws IOException {
Pattern pattern;
Matcher m = null;
String lineTrim = line.trim();
// ######## 注释的
if (lineTrim.startsWith("//")) {
lineNum++;
aticle.add(line);
return;
}
// ######## 要注释的
if (line.equals(" return;") || lineTrim.startsWith("JVM INSTR")
|| lineTrim.equals("exception;") || lineTrim.equals("i;")
|| lineTrim.startsWith("throw exception")) {
lineNum++;
aticle.add("//" + line);
return;
}
// ######## 导入的
if (line.startsWith("import ")) {
boolean find = false;
pattern = Pattern.compile("(\\.[a-z]\\.)|( [a-z]\\.)");
do {
m = pattern.matcher(line);
find = m.find();
if (find) {
String s = m.group();
String aaa = s.substring(1, 2);
aaa = s.substring(0, 1) + aaa + aaa + aaa + ".";
line = m.replaceFirst(aaa);
}
} while (find);
lineNum++;
aticle.add(line);
return;
}
// ######## package
if (line.startsWith("package ")) {
boolean find = false;
pattern = Pattern.compile("(\\.[a-z](\\.|;))|( [a-z]\\.)");
do {
m = pattern.matcher(line);
find = m.find();
if (find) {
String s = m.group();
String aaa = s.substring(1, 2);
aaa = s.substring(0, 1) + aaa + aaa + aaa
+ s.substring(2, 3);
;
line = m.replaceFirst(aaa);
}
} while (find);
lineNum++;
aticle.add(line);
return;
}
// ######## 加逗号的
// || lineTrim.startsWith("break;")
// lineTrim.startsWith("continue;")
if (lineTrim.startsWith("break MISSING_BLOCK")
|| lineTrim.startsWith("break ")
|| lineTrim.startsWith("continue; ")
|| lineTrim.startsWith("break; /* Loop/switch")) {
lineNum++;
aticle.add("//" + line);
lineNum++;
aticle.add("\r\n");
lineNum++;
aticle.add(";");
return;
}
// ######## 跳到的
if (line.startsWith("_")) {
pattern = Pattern.compile("^\\_[a-zA-Z0-9]+\\d+\\:$");
m = pattern.matcher(line);
if (m.find()) {
lineNum++;
aticle.add("//" + line);
return;
}
}
// ########### 把类包修改
line = modifyPkg(line, aticle);
// ######## if goto的
if (lineTrim.startsWith("if")) {
pattern = Pattern
.compile("if\\(true\\) goto \\_[a-zA-Z0-9]+\\d+; else goto \\_[a-zA-Z0-9]+\\d+");
m = pattern.matcher(line);
if (m.find()) {
lineNum++;
aticle.add("//" + line);
return;
}
}
// ######## goto else 的
pattern = Pattern
.compile("goto \\_[a-zA-Z0-9]+\\d+; else goto \\_[a-zA-Z0-9]+\\d+");
m = pattern.matcher(line);
if (m.find()) {
lineNum++;
aticle.add(line.substring(0, m.start()));
lineNum++;
aticle.add("\r\n");
lineNum++;
aticle.add("//" + m.group());
lineNum++;
aticle.add("\r\n");
lineNum++;
aticle.add(";");
return;
}
// ######## goto 的
pattern = null;
m = null;
pattern = Pattern.compile("goto( \\_[a-zA-Z0-9]+\\d+)+");
m = pattern.matcher(lineTrim);
if (m.find()) {
lineNum++;
aticle.add("//" + line);
return;
}
// ### exception
pattern = null;
m = null;
pattern = Pattern.compile("^exception\\d*;$");
m = pattern.matcher(lineTrim);
if (m.find()) {
lineNum++;
aticle.add("//" + line);
return;
}
// ######## 一个变量放一行的。
pattern = null;
m = null;
pattern = Pattern.compile("^[a-zA-Z0-9]+;$");
m = pattern.matcher(lineTrim);
if (m.find()) {
if (lineTrim.indexOf("continue") != -1
|| lineTrim.indexOf("break") != -1)
;
else {
lineNum++;
aticle.add("//" + line);
return;
}
}
// ####### a/a/a/a/a/a/dd.getName()
pattern = null;
m = null;
pattern = Pattern.compile("\\b([a-z]+/){2,}[a-zA-Z]+\\b");
m = pattern.matcher(line);
if (m.find()) {
boolean find = false;
String oldLine = line;
String region = m.group();
line = region;
pattern = Pattern.compile("(/[a-z]/)|(\\b[a-z]/)");
int start = 0;
boolean found = false;
do {
m = pattern.matcher(line);
find = m.find(start);
if (find) {
found = true;
String s = m.group();
String aaa = "";
if (s.length() > 2) {
aaa = s.substring(1, 2);
aaa = s.substring(0, 1) + aaa + aaa + aaa + ".";
} else {
aaa = s.substring(0, 1);
aaa = aaa + aaa + aaa + ".";
}
line = m.replaceFirst(aaa);
start = m.end();
}
} while (find);
// if (found) {
lineNum++;
aticle.add("//" + oldLine);
lineNum++;
aticle.add("\r\n");
if (line.indexOf("java") != -1)
line = line.replace('/', '.');
line = oldLine.replace(region, line + ".class");
lineNum++;
aticle.add(line);
return;
// } else
// line = oldLine;
}
// ######## return
if (lineTrim.startsWith("return ")) {
lineNum++;
aticle.add("//" + line);
// System.out.println(aticle.get(aticle.size()-1));
LineBean lineBean = new LineBean();
lineBean.content = line;
lineBean.number = lineNum;
returnLines.add(lineBean);
return;
}
// ######## super
if (lineTrim.equals("super();")) {
lineNum++;
aticle.add("//" + line);
LineBean lineBean = new LineBean();
lineBean.content = line;
lineBean.number = lineNum;
superLines.add(lineBean);
return;
}
lineNum++;
aticle.add(line);
}
/**
* 把局部变量移到最前,return移动最后,super()移动到最前。
* @param writer
* @param aticle
* @param returnLines
* @param superLines
* @throws IOException
*/
private void preWrite(BufferedWriter writer, List<String> aticle,
List<LineBean> returnLines, List<LineBean> superLines)
throws IOException {
int rtSize = returnLines.size();
int atsize = aticle.size();
int lastNum = atsize;
// ####### 上是个变量的
for (int idx = 0; idx < atsize; idx++) {
String line = aticle.get(idx);
if (line.indexOf("JVM INSTR ") != -1) {
aticle.set(idx - 2, "//" + aticle.get(idx - 2));
}
}
// ############# return
for (int idx = rtSize - 1; idx >= 0; idx--) {
LineBean rt = returnLines.get(idx);
int last = rt.number;
int bigCount = 0;
aticle.get(rt.number);
boolean find = false;
for (int num = last + 1; num < lastNum; num++) {
String line = aticle.get(num).trim();
if (!line.startsWith("//"))
for (int i = 0, len = line.length(); i < len; i++) {
char c = line.charAt(i);
if (c == '{')
bigCount++;
else if (c == '}')
bigCount--;
}
if (bigCount < 0) {
aticle.set(num, rt.content + "\r\n" + aticle.get(num));
find = true;
break;
}
}
lastNum = rt.number;
if (!find)
System.out.println(rt.content);
}
// 往上找super()
int spSize = superLines.size();
for (int idx = 0; idx < spSize; idx++) {
LineBean rt = superLines.get(idx);
int bigCount = 0;
boolean find = false;
for (int num = rt.number - 1; num > 0; num--) {
String line = aticle.get(num).trim();
if (!line.startsWith("//"))
for (int i = 0, len = line.length(); i < len; i++) {
char c = line.charAt(i);
if (c == '{')
bigCount--;
else if (c == '}')
bigCount++;
}
if (bigCount < 0) {
aticle.set(num, aticle.get(num) + "\r\n" + rt.content);
find = true;
break;
}
}
if (!find)
System.out.println(rt.content);
}
// #######局部变量移到最前
moveArgs(aticle, atsize);
// System.out.println(atsize);
atsize = aticle.size();
// System.out.println(atsize+" ==============");
}
/**
* 重新写到文件
* @param writer
* @param aticle
* @throws IOException
*/
private void processWrite(BufferedWriter writer, List<String> aticle)
throws IOException {
// TODO Auto-generated method stub
int atsize = aticle.size();
StringBuilder sb = new StringBuilder();
for (int idx = 0; idx < atsize; idx++) {
String line = aticle.get(idx);
sb.append(line);
}
writer.write(sb.toString());
}
/**
* 修改类包名
*
* @param line
* @param aticle
* @return
*/
private String modifyPkg(String line, List<String> aticle) {
// TODO Auto-generated method stub
int clsCount = 0;
String oldLine = line;
for (int clsIdx = this.clsList.size() - 1; clsIdx >= 0; clsIdx--) {
int start = 0;
ClassName cls = clsList.get(clsIdx);
Pattern pattern = Pattern.compile(cls.regClass);
while (true) {
Matcher m = pattern.matcher(line);
if (m.find(start)) {
start = m.end();
String region = m.group();
String newRegion = region.replace(cls.orgClass,
cls.packegedClass);
// System.out.println(Matcher.quoteReplacement(region));
// line = line.replaceFirst(region,
// Matcher.quoteReplacement(newRegion));
line = m.replaceFirst(newRegion);
clsCount++;
} else
break;
}
if (clsCount > 5)
break;
}
if (clsCount > 0) {
lineNum++;
aticle.add("//" + oldLine);
lineNum++;
aticle.add("\r\n");
}
return line;
}
/**
* 局部变量移到最前
* @param aticle
* @param atsize
*/
private void moveArgs(List<String> aticle, int atsize) {
// TODO Auto-generated method stub
List<ArgsList> argsSet = new ArrayList<ArgsList>();
// #######局部变量移到最前
int pos = 0;
boolean start = false;
Pattern pattern = Pattern
.compile("^(((public)|(protected)|(private))( [a-zA-Z\\.]+)? [a-zA-Z]+\\(.+\\))");
Pattern patternArgs = Pattern
.compile("^[a-zA-Z\\.]{1,25} [a-zA-Z0-9]{1,15};$");
int bigCount = 0;
ArgsList argsList = null;
for (int idx = 0; idx < atsize; idx++) {
String line = aticle.get(idx);
String lineTrim = line.trim();
if (!lineTrim.startsWith("//")) {
Matcher m = pattern.matcher(lineTrim);
// 找到方法开头
if (m.find()) {
if (lineTrim.indexOf(" class") != -1
|| lineTrim.indexOf(" interface") != -1
|| lineTrim.indexOf(";") != -1)
continue;
// System.out.println(line);
// 找到 {
boolean f = false;
while (true) {
if (lineTrim.startsWith("//")) {
idx++;
line = aticle.get(idx);
lineTrim = line.trim();
continue;
}
for (int idxx = 0, len = lineTrim.length(); idxx < len; idxx++) {
char c = lineTrim.charAt(idxx);
if (c == '{') {
bigCount++;
f = true;
} else if (c == '}')
bigCount--;
}
if (f && bigCount != 1)
throw new RuntimeException("bad code start!");
if (bigCount == 1) {
pos = idx;
start = true;
argsList = new ArgsList();
argsList.pos = pos;
argsSet.add(argsList);
break;
}
idx++;
line = aticle.get(idx);
lineTrim = line.trim();
}
} else if (start) {
// 找局部变量定义
boolean f = false;
while (true) {
if (lineTrim.startsWith("//")) {
idx++;
line = aticle.get(idx);
lineTrim = line.trim();
continue;
}
for (int idxx = 0, len = lineTrim.length(); idxx < len; idxx++) {
char c = lineTrim.charAt(idxx);
if (c == '{') {
bigCount++;
} else if (c == '}') {
bigCount--;
f = true;
}
}
if (f && bigCount < 0)
throw new RuntimeException("bad code end!");
// 到}了
if (bigCount == 0) {
pos = idx;
start = false;
break;
}
// 找局部变量定义
m = patternArgs.matcher(lineTrim);
if (m.find()) {
// list.add line;
// System.out.println(pos + " " + line);
aticle.set(idx, "//" + line);
argsList.argsList.add("\r\n" + line);
}
idx++;
line = aticle.get(idx);
lineTrim = line.trim();
}
}
}
}
// 把找的加到列表中
List<String> newAticle = new ArrayList<String>();
int setSize = argsSet.size();
int count = 0;
for (int idx = 0; idx < setSize; idx++) {
ArgsList argsList2 = argsList = argsSet.get(idx);
if (argsList2 != null) {
while (count <= argsList2.pos) {
newAticle.add(aticle.get(count));
count++;
}
newAticle.addAll(argsList2.argsList);
// count = newAticle.size();
}
}
while (count < atsize) {
newAticle.add(aticle.get(count));
count++;
}
aticle.clear();
aticle.addAll(newAticle);
}
/**
* 变量声明列表,用来把变量放在方法内的前面。
* @author Administrator
*
*/
class ArgsList {
int pos;
List<String> argsList = new ArrayList<String>();
}
/**
* java文件的行
* @author Administrator
*
*/
class LineBean {
int number;
String content = null;
}
/**
* java文件名
* @author Administrator
*
*/
class ClassName implements Comparable {
int count = 0;
int length = 0;
String packegedClass;
String orgClass;
String regClass;
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
ClassName odj = (ClassName) o;
if (this.count > odj.count)
return 1;
else if (this.count < odj.count)
return -1;
else if (this.length > odj.length)
return 1;
else
return -1;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return packegedClass + " " + count + " " + length + " " + regClass;
}
}
}