编写脚本批量还愿JEB 加密字符串

解密完后效果如下:
脚本源码:
https://github.com/bingghost/JebPlugins
思路:
下面的该封装的基本都封装了,过程如下:
1.先遍历类定位到指定的类,
2.然后遍历该类的所有方法定位到解密函数,对其做交叉引用
得到所有引用该解密函数的地方
3. 对每一个引用函数做语法解析AST,拿到所有的语法元素信息,同时得到加密的byte数组信息
4. 调用解密函数解密得到字符串
5. 调用jebview接口,使用解密后的字符串替换byte数组,同时刷新界面
编写代码如下:
import java.io.*;
import java.util.List;
import jeb.api.IScript;
import jeb.api.JebInstance;
import jeb.api.ui.*;
import jeb.api.ast.*;
import jeb.api.dex.Dex;
import jeb.api.dex.DexClass;
import jeb.api.dex.DexClassData;
import jeb.api.dex.DexMethod;
import jeb.api.dex.DexMethodData;
public class Hello implements IScript {
private final static String DecodeMethodSignature = "Lcom/pnfsoftware/jebglobal/Si;->ob([BII)Ljava/lang/String;";
private final static String DecodeClassSignature = "Lcom/pnfsoftware/jebglobal/Si;";
private JebInstance mJebInstance = null;
private Constant.Builder mBuilder = null;
private static File logFile;
private static BufferedWriter writer;
/**
* 功能: 遍历所有的类 找到指定的类
* @return 指定类的dex索引, 没有找到返回-1
*/
@SuppressWarnings("unchecked")
private int findClass(Dex dex, String findClassSignature) {
List<String> listClassSignatures = dex.getClassSignatures(false);
int index = 0;
for (String classSignatures : listClassSignatures) {
if (classSignatures.equals(findClassSignature)) {
mJebInstance.print("find:" + classSignatures);
return index;
}
index++;
}
return -1;
}
private int findMethod(Dex dex, int classIndex, String findMethodSignature) {
DexClass dexClass = dex.getClass(classIndex);
DexClassData dexClassData = dexClass.getData();
DexMethodData[] dexMethods = dexClassData.getDirectMethods();
for (int i = 0; i < dexMethods.length; i++) {
int methodIndex = dexMethods[i].getMethodIndex();
DexMethod dexMethod = dex.getMethod(methodIndex);
String methodSignature = dexMethod.getSignature(true);
if (methodSignature.equals(findMethodSignature)) {
mJebInstance.print("find:" + methodSignature);
return methodIndex;
}
}
return -1;
}
/***
* 功能: 遍历指定函数的应用方法
* @param dex
* @param methodIndex
*/
@SuppressWarnings("unchecked")
private void traverseReferences(Dex dex,int methodIndex) {
List<Integer> methodReferences = dex.getMethodReferences(methodIndex);
mJebInstance.print("引用数量:" + methodReferences.size());
for (Integer refIndex : methodReferences) {
DexMethod refDexMethod = dex.getMethod(refIndex);
mJebInstance.print("引用的方法:" + refDexMethod.getSignature(true));
// 找到AST中对应的Method
mJebInstance.decompileMethod(refDexMethod.getSignature(true));
Method decompileMethodTree = mJebInstance.getDecompiledMethodTree(refDexMethod.getSignature(true));
// 拿到语句块,遍历所有语句
List<IElement> subElements = decompileMethodTree.getSubElements();
replaceDecodeMethod(subElements, decompileMethodTree);
}
}
@SuppressWarnings("unchecked")
@Override
public void run(JebInstance jebInstance) {
// 初始化相关信息
jebInstance.print("start decode strings plugin");
init(jebInstance, "D:\\log.txt");
mBuilder = new Constant.Builder(jebInstance);
JebUI ui = jebInstance.getUI();
JavaView javaView = (JavaView) ui.getView(View.Type.JAVA);
Dex dex = jebInstance.getDex();
while (true) {
int classIndex = findClass(dex, DecodeClassSignature);
if (classIndex == -1) {
break;
}
int methodIndex = findMethod(dex, classIndex, DecodeMethodSignature);
if (methodIndex == -1) {
break;
}
traverseReferences(dex,methodIndex);
// 刷新UI
javaView.refresh();
break;
}
// 关闭文件
close();
}
private void replaceDecodeMethod(List<IElement> elements, IElement parentEle) {
for (IElement element : elements) {
if (!(element instanceof Call)) {
// 不是方法
List<IElement> subElements = element.getSubElements();
replaceDecodeMethod(subElements, element);
continue;
}
Call call = (Call) element;
Method method = call.getMethod();
if (!method.getSignature().equals(DecodeMethodSignature)) {
// 不是指定函数签名
List<IElement> subElements = element.getSubElements();
replaceDecodeMethod(subElements, element);
continue;
}
analyzeArguments(call,parentEle,element);
}
}
// 解析引用函数的参数
private void analyzeArguments(Call call,IElement parentEle,IElement element) {
try {
// 拿到函数的参数
List<IExpression> arguments = call.getArguments();
// 获取第一个参数元素
NewArray arg1 = (NewArray) arguments.get(0);
List encBL = arg1.getInitialValues();
if (encBL == null) {
return;
}
int size = encBL.size();
byte[] enStrBytes = new byte[size];
int decFlag;
int encode;
int i = 0;
// 设置Flags 有的地方可能是变量形式的参数
if (arguments.get(1) instanceof Constant) {
decFlag = ((Constant) (arguments.get(1))).getInt();
} else {
decFlag = 4;
}
// 初始化加密字节数组
for (i = 0; i < size; i++) {
enStrBytes[i] = ((Constant) encBL.get(i)).getByte();
}
// 设置encode
encode = ((Constant) (arguments.get(2))).getInt();
String decString = do_dec(enStrBytes,decFlag,encode);
logWrite("解密后字符串: " + decString);
// mJebInstance.print("解密后字符串: " + decString);
// 替换原来的表达式
parentEle.replaceSubElement(element, mBuilder.buildString(decString));
} catch (Exception e) {
mJebInstance.print(e.toString());
}
}
// 根据情况解密字符串
private String do_dec(byte[] enStrBytes, int decFlag, int encode) {
String dec = "";
while (true) {
if (decFlag != 4) {
dec = decString(enStrBytes, decFlag, encode);
break;
}                   
// 穷举可能存在的情况 0 1 2
dec = decString(enStrBytes, 2, encode);
if (!isStr(dec)) {
dec = decString(enStrBytes, 1, encode);
}
if (!isStr(dec)) {
dec = decString(enStrBytes, 0, encode);
}
break;
}
return dec;
}
// 判断字符串是否是一个合理的字符串
private boolean isStr(String s) {
int len = s.length() > 3 ? 3 : s.length();
String str = s.substring(0, len);
if (str.matches("[a-zA-Z0-9_\u4e00-\u9fa5]*")) {
return true;
}
return false;
}
private String setString(byte[] bytes_str) {
String new_str;
try {
new_str = new String(bytes_str, "UTF-8");
}
catch(Exception e) {
new_str = new String(bytes_str);
}
return new_str;
}
// 解密字符串
public String decString(byte[] enStrBytes, int decFlag, int encode) {
byte[] decstrArray;
int enstrLen;
if(enStrBytes == null) {
return "decode error";
}
if (decFlag == 0 || enStrBytes.length == 0) {
return setString(enStrBytes);
}
if(decFlag == 1) {
enstrLen = enStrBytes.length;
decstrArray = new byte[enstrLen];
byte bEncode = ((byte)encode);
for (int i = 0;i < enstrLen;i++) {
decstrArray[i] = ((byte)(bEncode ^ enStrBytes[i]));
bEncode = decstrArray[i];
}
return setString(decstrArray);
}
if(decFlag == 2) {
enstrLen = enStrBytes.length;
decstrArray = new byte[enstrLen];
String coprightString = "Copyright (c) 1993, 2015, Oracle and/or its affiliates. All rights reserved. ";
int index = 0;
for (int i = 0;i < enstrLen;i++) {
decstrArray[i] = ((byte)(enStrBytes[i] ^ (((byte)coprightString.charAt(index)))));
index = (index + 1) % coprightString.length();
}
return setString(decstrArray);
}
return "decode error";
}
public void logWrite(String log) {
try {
writer.write(log + "\r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
public void init(JebInstance jebInstance, String logPath) {
mJebInstance = jebInstance;
logFile = new File(logPath);
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(logFile), "utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void close() {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

来自为知笔记(Wiz)

转载于:https://www.cnblogs.com/bingghost/p/5819735.html

十二. 一步步破解JEB 2.0demo版二相关推荐

  1. 十一. 一步步破解JEB 2.0demo版一

    字符串解密算法还愿 jeb.jar为核心功能,所以主要分析这个 1. jar转dex在使用jeb分析 Android\sdk\build-tools\23.0.3 dx.bat --dex --out ...

  2. 二年级数学计算机教学教案,人教版二年级下册数学全册教案

    <人教版二年级下册数学全册教案>由会员分享,可在线阅读,更多相关<人教版二年级下册数学全册教案(10页珍藏版)>请在人人文库网上搜索. 1.2014 人教版二年级下册数学全册教 ...

  3. 二年级数学计算机教学教案,人教版二年级数学备课教案

    小学数学备课教案教学内容:三年级下册P109例2,练习二十四第3.4题,小学数学备课教案.教学目标:1.让学生通过观察.猜测.操作.验证等活动,初步体会等量代换的思想方法.2.培养学生有序地.全面地思 ...

  4. # 2017-2018-1 20155336《信息安全技术》实验二——Windows口令破解

    2017-2018-1 20155336<信息安全技术>实验二--Windows口令破解 实验原理 口令破解方法 口令破解主要有两种方法:字典破解和暴力破解. 字典破解是指通过破解者对管理 ...

  5. 雷军:《我十年的程序员生涯》系列之二(我赚的第一桶金)

    // 转载自雷军2008年11月5日写的博客.以下内容为博客原文: <我十年的程序员生涯>系列之二:我写BITLOK的这七年 1989年8月,大二暑假,我和王全国合作写了我的第一个正式作品 ...

  6. 2017-2018-1 20155308《信息安全技术》实验二——Windows口令破解

    2017-2018-1 20155308<信息安全技术>实验二--Windows口令破解 实验原理 口令破解主要有两种方法:字典破解和暴力破解. 字典破解是指通过破解者对管理员的了解,猜测 ...

  7. # 2017-2018-1 20155232《信息安全技术》实验二——Windows口令破解

    2017-2018-1 20155232<信息安全技术>实验二--Windows口令破解 [实验目的] 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破解 ...

  8. # 2017-2018-1 20155312《信息安全技术》实验二——Windows口令破解实验报告

    2017-2018-1 20155312<信息安全技术>实验二--Windows口令破解实验报告 实验目的 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破 ...

  9. 读后感: 波、波、波---走出软件作坊:三五个人十来条枪 如何成为开发正规军(二十二)

    波.波.波---走出软件作坊:三五个人十来条枪 如何成为开发正规军(二十二) http://blog.csdn.net/david_lv/archive/2008/06/26/2589809.aspx ...

最新文章

  1. dx9 lock unlock效率太低_synchronized的缺陷,Lock的诞生
  2. shell中条件判断if中的-z到-d的意思
  3. python代码执行过程记录_[原创]IDAPython+OdbgScript动态获取程序执行流程
  4. verilog HDL 编码风格
  5. Dapr Meetup 3.22【周六】
  6. wpf 文件上传到服务器_07-文件上传到阿里云OSS实战(一)
  7. oracle运维工作中每天巡检的必要性--job的相关问题
  8. weblogic domain creation
  9. android 切换主题介绍一
  10. 【丁丁历险记】ESP8266/ESP32做微信遥控语音识别
  11. 华为机试真题 C++ 实现【数字涂色】
  12. 庄子·内篇·逍遥游第一(郭象注)
  13. Sony WH-1000XM3降级到2.00
  14. 【求职】关于简历制作的心得
  15. CC00056.bigdatajava——|Java分支结构.V06|——|Java.v06|ifelseifelse.v02|个人所得税计算方式一|
  16. 工业42、57、86、110步进电机
  17. PHP7常用新特性介绍
  18. JVM G1 源码分析(七)- Full GC
  19. C++--顺时针打印矩阵
  20. Kubernetes服务发现:Service、Kube-Proxy(Netfilter)

热门文章

  1. python3安装pip3-Python3中安装pip3
  2. python精通书籍-清华学霸整理,Python入门到精通这几本书帮你快速入行
  3. python小项目案例-拯救Python新手的几个项目实战
  4. python利器手机版-将安卓手机打造成你的python全栈开发利器
  5. python在中小学教学中的应用-中小学Python编程语言教学
  6. php和python哪个工资高-学python和php哪个前景好
  7. python2好还是python3好-新手入门选择Python2还是Python3
  8. python 是什么类型的语言-python到底是什么类型的语言
  9. python 是什么类型的语言-python是一种什么类型的语言
  10. python爬虫代码1000行-几行Python代码爬取3000+上市公司的信息