好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 nwdxlgzs 于 2020-12-22 01:59 编辑
加固是我写的,因为我是FusionApp官方群管理员,我想给群员一个代码保护https://nwdxlgzs.lanzouj.com/iQY4jge7oab,于是在java层写了一个中继,从而实现加密。代码很简单,只有20.56kb,为了增加难度,用了arm pro的dex2c于是组成现在的套壳加密程序。我这里分享解密算法,因为我收到了有人用他加固恶意代码勒索钱财的事,这个和我想象的背道而驰,之前在酷安下头https://www.coolapk.com/feed/23542290?shareKey=YzY1N2UzYTY4MTRmNWZlMGRmMjE~&shareUid=2769995&shareFrom=com.coolapk.market_10.5.3我就说明了,现在我想了想,为了阻止这个产业的扩大,我决定分享解密算法。程序分两种存储,dex和sfpc文件。
--path="dex路径"
--loader=activity.loadDex(path)
--dumpSimpleFreeProtect().dumpClass(loader,"com.sfp.data.lua",File("/storage/emulated/0/out"))
--path="sfpc文件夹路径"
--dumpSimpleFreeProtect().dumpDir(File(path),File("/storage/emulated/0/out"))
有这两种批量解密方法。
java的解密算法如下
package com;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.content.pm.Signature;
public class dumpSimpleFreeProtect {
public dumpSimpleFreeProtect(){}
public void dump(File[] files,File out) {
int i=0;
for (File file:files) {
i++;
try {
Object[] result= newInvoke(file);
write(new File(out, String.valueOf(i) + ".lua"), (String)result[0]);
write(new File(out, String.valueOf(i) + ".signature"), (String)result[1]);
} catch (Exception e) {}
}
}
public void dump(Class[] classes,File out) {
int i=0;
for (Class cls:classes) {
i++;
try {
Object[] result= newInvoke(cls);
write(new File(out, String.valueOf(i) + ".lua"), (String)result[0]);
write(new File(out, String.valueOf(i) + ".signature"), (String)result[1]);
} catch (Exception e) {}
}
}
public void dumpDir(File fileDir,File out) {
dump(fileDir.listFiles(), out);
}
public void dumpClass(ClassLoader loader,String CLS,File out) {
int i=0;
while (true) {
i++;
try {
Class cls=loader.loadClass(CLS + i);
try {
Object[] result= newInvoke(cls);
write(new File(out, String.valueOf(i) + ".lua"), (String)result[0]);
write(new File(out, String.valueOf(i) + ".signature"), (String)result[1]);
} catch (Exception e) {}
} catch (ClassNotFoundException e) {
break;
}
}
}
public Object[] newInvoke(File path) throws FileNotFoundException, IOException {
FileInputStream is=new FileInputStream(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buff[] = new byte[1024];
int len = 0;
while ((len = is.read(buff)) != -1) {
baos.write(buff, 0, len);
}
baos.flush();
byte[] byteData = baos.toByteArray();
baos.close();
return newInvoke(byteData);
}
public Object[] newInvoke(Class cls) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Object clsO=cls.newInstance();
Method m=cls.getMethod("getBytes");
byte[] b=(byte[]) m.invoke(clsO);
return newInvoke(b);
}
public Object[] newInvoke(byte[] byteData) {
//类base64解密
int iSrcIdx;
int reviSrcIdx;
int iDestIdx;
byte[] byteTemp = new byte[byteData.length];
for (reviSrcIdx = byteData.length; reviSrcIdx - 1 > 0 && byteData[reviSrcIdx - 1] == '='; reviSrcIdx--) {;}
if (reviSrcIdx - 1 == 0) { return null;}
byte byteDest[] = new byte[((reviSrcIdx * 3) / 4)];
for (iSrcIdx = 0; iSrcIdx < reviSrcIdx; iSrcIdx++) {
if (byteData[iSrcIdx] == '+')
byteTemp[iSrcIdx] = 62;
else if (byteData[iSrcIdx] == '/')
byteTemp[iSrcIdx] = 63;
else if (byteData[iSrcIdx] < 2 + 10)
byteTemp[iSrcIdx] = (byte) (byteData[iSrcIdx] + 52 - 2);//0
else if (byteData[iSrcIdx] < (12 + 26))
byteTemp[iSrcIdx] = (byte) (byteData[iSrcIdx] - 12);//A
else if (byteData[iSrcIdx] < (100 + 26))
byteTemp[iSrcIdx] = (byte) (byteData[iSrcIdx] + 26 - 100);//a
}
for (iSrcIdx = 0, iDestIdx = 0; iSrcIdx < reviSrcIdx
&& iDestIdx < ((byteDest.length / 3) * 3); iSrcIdx += 4) {
byteDest[iDestIdx++] = (byte) ((byteTemp[iSrcIdx] << 2) & 0xFC | (byteTemp[iSrcIdx + 1] >>> 4) & 0x03);
byteDest[iDestIdx++] = (byte) ((byteTemp[iSrcIdx + 1] << 4) & 0xF0 | (byteTemp[iSrcIdx + 2] >>> 2) & 0x0F);
byteDest[iDestIdx++] = (byte) ((byteTemp[iSrcIdx + 2] << 6) & 0xC0 | byteTemp[iSrcIdx + 3] & 0x3F);
}
if (iSrcIdx < reviSrcIdx) {
if (iSrcIdx < reviSrcIdx - 2) {
byteDest[iDestIdx++] = (byte) ((byteTemp[iSrcIdx] << 2) & 0xFC | (byteTemp[iSrcIdx + 1] >>> 4) & 0x03);
byteDest[iDestIdx++] = (byte) ((byteTemp[iSrcIdx + 1] << 4) & 0xF0 | (byteTemp[iSrcIdx + 2] >>> 2) & 0x0F);
} else if (iSrcIdx < reviSrcIdx - 1) {
byteDest[iDestIdx++] = (byte) ((byteTemp[iSrcIdx] << 2) & 0xFC | (byteTemp[iSrcIdx + 1] >>> 4) & 0x03);
}
}
//处理解码后数据
String str=new String(byteDest);
String tmp=str.substring(0, 1);
int index=Integer.valueOf(tmp);
String lengthS=str.substring(1, 1 + index);//截取签名块长度
int lengthI=Integer.valueOf(lengthS);//长度
String sign=str.substring(index + 1, index + 1 + lengthI);
str = str.substring(index + 1 + lengthI, str.length());
Object[] result=new Object[]{str,sign};
return result;
}
public static void write(File out,String xml) throws FileNotFoundException, IOException {
FileOutputStream fileOutputStream = new FileOutputStream(out);
fileOutputStream.write(xml.getBytes());
fileOutputStream.close();
}
public static void write(File out,byte[] by) throws FileNotFoundException, IOException {
FileOutputStream fileOutputStream = new FileOutputStream(out);
fileOutputStream.write(by);
fileOutputStream.close();
}
}
加固了恶意代码我也很烦。如果谁遇到需要解密那些病毒,用这个解密就好,不必研究机制。 |
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|