登录后更精彩...O(∩_∩)O...
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一个简单的jeb字符串解密脚本
闲着没事学了一下2.*的jeb 脚本,大概1-2年前,大家都还是1.*的版本,但是现在2.*的api都变了好多,但是原理其实还是不变的(AST),所以就现学现卖,找了一个字符串加密的app做了实验,效果还是可以的。关于怎么学习这些api,其实跟着示例的几个script走一遍,稍微看一些文档,基本上就会用了。
这份代码主要针对的是解密函数唯一的加密方式,其中 methodname里可以自己定义解密的类的名字,decryptstring函数是对应的解密函数,这个脚本可能还不完善,但是我用着没问题了,大家可以多提提意见 [Python] 纯文本查看 复制代码 from com.pnfsoftware.jeb.client.api import IScript, IconType, ButtonGroupType
from com.pnfsoftware.jeb.core import RuntimeProjectUtil
from com.pnfsoftware.jeb.core.units.code.java import IJavaSourceUnit
from com.pnfsoftware.jeb.core.units.code import ICodeUnit, ICodeItem
from com.pnfsoftware.jeb.core.output.text import ITextDocument
from com.pnfsoftware.jeb.core.units.code.java import IJavaSourceUnit, IJavaStaticField, IJavaNewArray, IJavaConstant, IJavaCall, IJavaField, IJavaMethod, IJavaClass
from com.pnfsoftware.jeb.core.events import JebEvent, J
from com.pnfsoftware.jeb.core.util import DecompilerHelper
import base64
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
stringfilter=['aes error',]
methodname=['La/auu/a;','c']
class ReString(IScript):
def run(self, ctx):
print('start deal with strings')
self.ctx = ctx
engctx = ctx.getEnginesContext()
if not engctx:
print('Back-end engines not initialized')
return
projects = engctx.getProjects()
if not projects:
print('There is no opened project')
return
# means this is current project
prj=projects[0]
self.codeunits=RuntimeProjectUtil.findUnitsByType(prj , ICodeUnit,False)
for codeUnit in self.codeunits:
self.decompileForCodeUnit(codeUnit)
units = RuntimeProjectUtil.findUnitsByType(prj, IJavaSourceUnit, False)
for unit in units:
javaClass = unit.getClassElement()
print('[+] decrypt:'+javaClass.getName())
self.cstbuilder = unit.getFactories().getConstantFactory()
self.processClass(javaClass)
unit.notifyListeners(JebEvent(J.UnitChange))
print('Done.')
def decompileForCodeUnit(self, codeUnit):
decomp = DecompilerHelper.getDecompiler(codeUnit)
allClasses = codeUnit.getClasses()
if allClasses == None:
return
for c in allClasses:
# do not decompile inner classes
if (c.getGenericFlags() & ICodeItem.FLAG_INNER) == 0:
a = c.getAddress()
srcUnit = decomp.decompile(a)
def processClass(self ,javaClass):
if javaClass.getName() == methodname[0]:
print("find auu")
return
for method in javaClass.getMethods():
block=method.getBody()
i = 0 ;
while i < block.size():
stm = block.get(i)
self.checkElement(block ,stm)
i += 1
def checkElement(self,parent,e):
if isinstance(e,IJavaCall):
mmethod = e.getMethod()
mname = mmethod.getName()
msig = mmethod.getSignature()
if mname == methodname[1] and methodname[0] in msig :
v=[]
for arg in e.getArguments():
if isinstance(arg , IJavaConstant):
v.append(arg.getString())
if len(v) == 1 :
decstr = self.decryptstring(v[0])
parent.replaceSubElement(e, self.cstbuilder.createString(decstr))
for subelt in e.getSubElements():
if isinstance(subelt, IJavaClass) or isinstance(subelt, IJavaField) or isinstance(subelt, IJavaMethod):
continue
self.checkElement(e,subelt)
def decryptstring(self,string):
src = []
key = [69, 110, 99, 114, 121, 112, 116]
keylen = len(key)
data = base64.decodestring(string)
for index , char in enumerate(data):
src.append( chr(ord(char) ^ key[index % keylen ]))
return ''.join(src)
###############################################
###
### just for test
###
################################################
def processSourceTree(self, e):
if e:
self.analyzeNode(e)
elts = e.getSubElements()
for e in elts:
self.processSourceTree(e)
def getTextDocument(self, srcUnit):
formatter = srcUnit.getFormatter()
if formatter and formatter.getDocumentPresentations():
doc = formatter.getDocumentPresentations()[0].getDocument()
if isinstance(doc, ITextDocument):
return doc
return None
def formatTextDocument(self, doc):
javaCode, formattedMarks = '', ''
# retrieve the entire document -it's a source file,
# no need to buffer individual parts. 10 MLoC is enough
alldoc = doc.getDocumentPart(0, 10000000)
for lineIndex, line in enumerate(alldoc.getLines()):
javaCode += line.getText().toString() + '\n'
for mark in line.getMarks():
# 0-based line and column indexes
formattedMarks += '%d:%d - %s (%s)\n' % (lineIndex, mark.getOffset(), mark.getName(), mark.getObject())
return javaCode, formattedMarks
我这里找的app是*易的,大家可以自行下载他们家app, 他们的字符串方案很简单,就是采用了github上开源的stringforg ,然后自己改了一下密钥,实际就是一个base64 和抑或操作, 对于这些解密函数唯一的加密方式,其实很弱的,也可以用hook的方式改。但是比较蛋疼的是,我尝试用frida去hook好像失败了,可能是我姿势不大对。另外,有的加密可能会采用多种方式进行加密,这种其实也比较好破,基本上改一下我的代码,加入自定义的解密函数即可。 对于字符串这方面,个人还是倾向于dexguard那种,一个类一个解密函数,当然,那样其实也是可以通过jeb进行解密的。 github上有一个项目叫simplify,不知道并对没有,感觉这个挺厉害的,采用了虚拟执行的方式去解决字符串加密和一些混淆,但是目前应该还不算完善。
from: https://bbs.kanxue.com/thread-219449.htm
|