jeb安装教程_JEB2插件教程之一
JEB2发布有段时间了,相比于JEB1来说功能强大了很多,但是API也发生了巨大的变化,不仅是定义上也包括架构上,这给我们移植或者是新编写插件带来了一定不便, 目前也还没看到详细一些的API分析教程。本文以一个具体的应用分析为例,解释如何编写一个JEB2中处理混淆应用的插件,来实现自动识别和重命名。
案例
我们的样例APK是一个采用了比较剑走偏锋混淆的东西,其中绝大部分类名、函数名、field名都被替换成了包含lIi的字符串,如下截图所示:
这种给人工分析时追踪函数调用带来了不便,因为这些字符串字母长的都比较像,所以我们需要写一个JEB脚本来自动化重命名这些item。我们的逻辑如下:
对于类:递归寻找它的父类和实现的接口。如果父类和接口包含了有意义的名字:例如SDK类Activity、不能混淆的类名MainActivity,以此为基础进行重命名
对于Field:根据该Field的类型,重命名其名字
对于函数:根据该函数的参数类型,重命名其名字
JEB2的API架构
由于JEB2试图成为像IDA那样的universal disassembler,其架构多了很多包装层。对于APK分析来说,关键的部分关系如下所示:
IProjectUnit -> ICodeUnit -> IJavaSourceUnit
IProjectUnit代表了整个workspace,一般我们只会使用project[0]
>>> engctx.getProjects()
[Project:{/xxx/xxx.apk.jdb2}]
ICodeUnit则代表了一个project中所有的可解析部分,如下面我们提到的,因为JEB2为各种架构都提供了统一包装层,ICodeUnit不再仅仅是dex或者jar,而还会包括了libraries中的各种native Library。
>>> units = RuntimeProjectUtil.findUnitsByType(prj, ICodeUnit, False)
>>> map(lambda x: print(x.name), units)
[u'Bytecode', u'arm64 image', u'arm image', u'arm image', u'mips image', u'x86 image', u'x86_64 image']
其中Bytecode项是对应的dex体. 其对应的ICodeUnit代表了整个dex, 已经提供了基本的类型信息,例如Class, Type, Method, Field, Package 使用者可以通过ICodeUnit.getClass/getMethod/getField获取到对应的ICodeClass/ICodeMethod/ICodeField. 但是这个层级的unit并没有提供class hierchy信息和具体的源代码AST信息,故我们还需要IJavaSourceUnit.
IJavaSourceUnit代表的是执行过反编译之后生成的Java源代码体,提供了更加丰富和细节的Java代码信息供使用. 其对应的AST元素为IJavaClass/IJavaMethod等等. 通过decompiler.decompile(icodeclass.getAddress())获取IJavaSourceUnit, 通过IJavaSourceUnit.getClassElement获取IJavaClass.
需要强调的是, ICodeUnit对应的是整个dex, 而IJavaSourceUnit对应的是单个反编译出的类.
自订操作
在JEB2中,用户操作(自定义操作)被统一包装在ActionContext类之下,类似于transaction的形势.API使用者提交各种ActionContext,并检查返回值是否成功.一个典型的重命名操作如下:
>>> actCntx = ActionContext(self.targetUnit, Actions.RENAME, clz.getItemId(), clz.getAddress())
actData = ActionRenameData()
actData.setNewName(newName)
if codeUnit.prepareExecution(actCntx, actData):
codeUnit.executeAction(actCntx, actData)
值的注意的是,这里的clz对象均为ICodeUnit调用getClass所查询出的ICodeClass类,而不是IJavaSourceUnit对应的IJavaClass. ActionContext作用的对象也是代表整个dex的ICodeUnit.
除了重命名操作之外, ActionContext还包括了COMMENT, CONVERT, CREATE_PACKAGE, DELETE, MOVE_TO_PACKAGE, QUERY_OVERRIDES, QUERY_TYPE_HIER, QUERY_XREFS, RENAME等操作, 其实就是我们在UI中右键所能执行的操作. 读者可能要问, 像QUEYR_TYPE_HIER这种操作, 通过IJavaSource解析AST不是也可以做? 我认为确实是这样, 这里可能还是为了给不同语言提供一个统一的抽象接口. 当然QUERY_XREFS顾名思义是获取到对应的引用, 这方便我们做一些callgraph的查询.
案例解析
如文章开头所示, 我们的目的是根据被混淆item的基类信息和类型信息/参数信息对其重命名. 主要逻辑如下:
for clz in codeunit.getClasses():
if isObfuscated(clz):
name = determineNameFromHierchy(clz) --->1
rename(clz, name)
for field in codeUnit.getFields():
if isObfuscated(field):
name = determineNameByFieldType(field)
rename(field, name)
for mtd in codeUnit.getMethods():
if isObfuscated(mtd):
name = determineNameByArgsType(field)
rename(field, name)
例如, class IiIiIiIi是继承于class iIiIiIiI, 而iIiIiIiI又继承于Activity/实现了onClickListener, 那么我们就可以使用Activity/onClickListener作为基准重命名两个被混淆的类. 这里的关键在于一个递归获取基类的函数, 如下所示:
'''
clzElement is ICodeClass retrieved from ICodeUnit.getClass()
'''
def tryDetermineGodeName(self, clzElement):
javaunit = self.decomp.decompile(clzElement.getAddress())
clzElement = javaunit.getClassElement()
#now clzElement is a IJavaClass
if not isFuckingName(clzElement.getName()):
#this is a non-obfuscated name, just return it
return clzElement.getName()
ssupers = clzElement.getImplementedInterfaces()
supers = []
supers.extend(ssupers)
# do not directly append on returned list!
superSig = clzElement.getSupertype().getSignature()
supers.append(clzElement.getSupertype())
for superItem in supers:
sig = superItem.getSignature()
if sig == "Ljava/lang/Object;":
#extend from java/lang/Object gives us zero info
#so try next
continue
if not isFuckingName(sig):
#return first non-obfuscated name
return sig
resolvedType = self.targetUnit.getClass(sig)
if resolvedType:
#this is a concret class
guessedName = self.tryDetermineGoodName(resolvedType)
if guessedName:
return guessedName
else:
#this is a SDK class
return sig
#cannot determine name from its supers, return None
return None
相对来讲, method和field的重命名就简单了很多, 如附代码所示, 在此不再赘述.
这里还有一个小细节, 因为需要操作的类比较多, 我们将插件定义为后台运行, 这样可以不阻塞UI, 同时获得更好的log效果.
重命名后的效果如下:
可以看到我们恢复出了较多可读信息. 完整代码: https://gist.github.com/flankerhqd/ca92b42f1f796763e5d1f8cd73247a30
总结
JEB2的API相对于JEB1组织层次更多, 也就没那么直观. 但有了初步了解之后, 也可以很快掌握使用方法. 测试版本: JEB2 2.3.4
Ref:
http://blog.csdn.net/weixin_37556843/article/details/66476295
https://www.pnfsoftware.com/jeb2/apidoc/reference/packages.html
https://groups.google.com/forum/#!topic/jeb-decompiler
jeb安装教程_JEB2插件教程之一相关推荐
- Visual Studio Code安装(软件及插件)教程
官网下载地址https://code.visualstudio.com/Download 百度网盘下载链接分享 链接:https://pan.baidu.com/s/1fTb4aG91N_Z-3VGk ...
- Pycharm2020.1安装中文语言插件教程,不需要汉化
方法一(在专业版和社区版都搜索不到插件): 1.安装好Pycharm并打开Pycharm 2.打开File,找到Settings并打开 3.打开Settings中的Pulgins,选择Marketpl ...
- thinkcmf搭建教程_ThinkCMF插件教程之写个HelloWorld插件
前言 趁着有时间,学习一波插件,插件是个好东西,希望人人都会写. 环境 语言:php5.6 框架:ThinkCMF 教程开始 1. 编写插件 创建插件配置文件:创建插件主类文件:在根目录的plugin ...
- Activiti6.0教程 Eclipse安装Activiti Diagram插件(一)
最近这段时间打算出一个Activiti6.0的详细教程,Activiti作为一个流行的开源工作流引擎,正在不断发展,其6.0版本以API形式提供服务,而之前版本基本都是要求我们的应用以JDK方式与其交 ...
- notepad++安装NPPJSONViewer插件教程
首先,下载notepad++并安装. notepad++官网我们一般是进不去的,无法从官网下载: 但是github上有release版本可以免费下载:Notepad++ release下载 很多安装j ...
- IDEA 2022 常用 插件 安装 与 全局配置 教程 大全
IDEA 2022 常用 插件 安装 与 全局配置 教程 大全 文章目录 IDEA 2022 常用 插件 安装 与 全局配置 教程 大全 一. 安装必备插件 1. Codota 代码智能提示插件 2. ...
- Chrome安装油猴插件详细教程
Chrome安装油猴插件详细教程 一.油猴安装方法 方法一:Google官方商店安装(推荐,需要科学上网) 方法二:本地安装(无需科学上网,不会科学上网的适用) 二.安装油猴插件 方法一:Google ...
- IDEA安装教程及插件推荐
目录 使用Jetbrains Toolbox安装(推荐) Windows版手动安装教程 Ubuntu版手动安装教程 推荐插件 中文语言包 CodeGlance Pro Rainbow Brackets ...
- vsCode安装使用教程和插件安装
vsCode安装使用教程 vsCode是什么 vsCode安装 vsCode汉化 vsCode常用命令说明 vsCode左边图标说明 vsCode基本使用 前端常用插件 在vosCode中显示html ...
- 【Ubuntu 16.04中为Chromium、Chrome、Firefox安装Flash播放器插件教程】
Ubuntu 16.04中为Chromium.Chrome.Firefox安装Flash播放器插件教程: Ubuntu 16.04中安装Chromium浏览器 http://www.linuxidc ...
最新文章
- IP BASE对OSPF的支持版本
- 神经网络的反向传导到底是在干什么?
- html5赛车小游戏,html5公路赛车小游戏
- Web API 实现JSONP或者安装配置Cors跨域
- 如何比较 Java 的字符串
- 真的没办法一心一意麽? php 文件操作
- python根据字典绘制条形图_使用 Bokeh 为你的 Python 绘图添加交互性 | Linux 中国
- 想换行做 5G 的开发者到底该咋办?
- v8:: fatalProcessOutOfMemory
- 【生信进阶练习1000days】day11day12-GEO data mining
- Ubuntu源码安装gcc-10
- 台式计算机时间跳动,电脑时间总是自动跳
- 云计算发展趋势-华为HCIA云计算学习笔记六
- 【coq】函数语言设计 笔记 07 - indProp
- smith 图中Q值和阻抗匹配
- PlatformIO使用Arduino[Ticker]库(ESP8266)
- 周志华 《机器学习初步》 绪论
- Substance Painter里 AO贴图 烘焙黑图 原因
- 域名批量查询 到期未续费域名查询
- c语言int x=3,C语言 设有 int x=11,则表示式((x++)*1/3)的值是几,为啥子