格式化用jad反编译混淆过的代码,能去大部分错误

在此特别声明,这只是学习使用,不得用于任何非法活动,否则,所有责任自负,与本人无关。


要用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;
		}
	}
}



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值