├── JEB2DeobscureClass.py └── README.md /JEB2DeobscureClass.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Deobscure class name(use debug directives as source name) for PNF Software's JEB2. 4 | """ 5 | __author__ = 'Ericli' 6 | 7 | from com.pnfsoftware.jeb.client.api import IScript 8 | from com.pnfsoftware.jeb.core import RuntimeProjectUtil 9 | from com.pnfsoftware.jeb.core.units.code import ICodeUnit, ICodeItem 10 | from com.pnfsoftware.jeb.core.units.code.android import IDexUnit 11 | from com.pnfsoftware.jeb.core.actions import Actions, ActionContext, ActionCommentData, ActionRenameData 12 | from java.lang import Runnable 13 | 14 | 15 | class JEB2DeobscureClass(IScript): 16 | def run(self, ctx): 17 | ctx.executeAsync("Running deobscure class ...", JEB2AutoRename(ctx)) 18 | print('Done') 19 | 20 | 21 | class JEB2AutoRename(Runnable): 22 | def __init__(self, ctx): 23 | self.ctx = ctx 24 | 25 | def run(self): 26 | ctx = self.ctx 27 | engctx = ctx.getEnginesContext() 28 | if not engctx: 29 | print('Back-end engines not initialized') 30 | return 31 | 32 | projects = engctx.getProjects() 33 | if not projects: 34 | print('There is no opened project') 35 | return 36 | 37 | prj = projects[0] 38 | 39 | units = RuntimeProjectUtil.findUnitsByType(prj, IDexUnit, False) 40 | 41 | for unit in units: 42 | classes = unit.getClasses() 43 | if classes: 44 | for clazz in classes: 45 | # print(clazz.getName(True), clazz) 46 | sourceIndex = clazz.getSourceStringIndex() 47 | clazzAddress = clazz.getAddress() 48 | if sourceIndex == -1 or '$' in clazzAddress:# Do not rename inner class 49 | # print('without have source field', clazz.getName(True)) 50 | continue 51 | 52 | sourceStr = str(unit.getString(sourceIndex)) 53 | if '.java' in sourceStr: 54 | sourceStr = sourceStr[:-5] 55 | 56 | # print(clazz.getName(True), sourceIndex, sourceStr, clazz) 57 | if clazz.getName(True) != sourceStr: 58 | self.comment_class(unit, clazz, clazz.getName(True)) # Backup origin clazz name to comment 59 | self.rename_class(unit, clazz, sourceStr, True) # Rename to source name 60 | 61 | def rename_class(self, unit, originClazz, sourceName, isBackup): 62 | actCtx = ActionContext(unit, Actions.RENAME, originClazz.getItemId(), originClazz.getAddress()) 63 | actData = ActionRenameData() 64 | actData.setNewName(sourceName) 65 | 66 | if unit.prepareExecution(actCtx, actData): 67 | try: 68 | result = unit.executeAction(actCtx, actData) 69 | if result: 70 | print('rename to %s success!' % sourceName) 71 | else: 72 | print('rename to %s failed!' % sourceName) 73 | except Exception, e: 74 | print (Exception, e) 75 | 76 | def comment_class(self, unit, originClazz, commentStr): 77 | actCtx = ActionContext(unit, Actions.COMMENT, originClazz.getItemId(), originClazz.getAddress()) 78 | actData = ActionCommentData() 79 | actData.setNewComment(commentStr) 80 | 81 | if unit.prepareExecution(actCtx, actData): 82 | try: 83 | result = unit.executeAction(actCtx, actData) 84 | if result: 85 | print('comment to %s success!' % commentStr) 86 | else: 87 | print('comment to %s failed!' % commentStr) 88 | except Exception, e: 89 | print (Exception, e) 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JebScripts 2 | 3 | * JEB2DeobscureClass.py 4 | 5 | 使用Smali中`.source`字段(`JEB中称为Debug Directives`)作为源文件名进行反混淆. 6 | 7 | > 1)不会反混淆内部类. 8 | > 9 | > 2)字段值为空时不起作用. 10 | > 11 | > 3)只有Smali中保留了源代码信息时脚本才能使用(`proguar-rules.pro`中设置 `-keepattributes SourceFile`) 12 | 13 | --------------------------------------------------------------------------------