lua脚本的sfp脱壳(fa数据保护的加固lua)
本帖最后由 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);
write(new File(out, String.valueOf(i) + ".signature"), (String)result);
} 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);
write(new File(out, String.valueOf(i) + ".signature"), (String)result);
} 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);
write(new File(out, String.valueOf(i) + ".signature"), (String)result);
} 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;
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);
}
publicObject[] 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;
for (reviSrcIdx = byteData.length; reviSrcIdx - 1 > 0 && byteData == '='; reviSrcIdx--) {;}
if (reviSrcIdx - 1 == 0) { return null;}
byte byteDest[] = new byte[((reviSrcIdx * 3) / 4)];
for (iSrcIdx = 0; iSrcIdx < reviSrcIdx; iSrcIdx++) {
if (byteData == '+')
byteTemp = 62;
else if (byteData == '/')
byteTemp = 63;
else if (byteData < 2 + 10)
byteTemp = (byte) (byteData + 52 - 2);//0
else if (byteData < (12 + 26))
byteTemp = (byte) (byteData - 12);//A
else if (byteData < (100 + 26))
byteTemp = (byte) (byteData + 26 - 100);//a
}
for (iSrcIdx = 0, iDestIdx = 0; iSrcIdx < reviSrcIdx
&& iDestIdx < ((byteDest.length / 3) * 3); iSrcIdx += 4) {
byteDest = (byte) ((byteTemp << 2) & 0xFC | (byteTemp >>> 4) & 0x03);
byteDest = (byte) ((byteTemp << 4) & 0xF0 | (byteTemp >>> 2) & 0x0F);
byteDest = (byte) ((byteTemp << 6) & 0xC0 | byteTemp & 0x3F);
}
if (iSrcIdx < reviSrcIdx) {
if (iSrcIdx < reviSrcIdx - 2) {
byteDest = (byte) ((byteTemp << 2) & 0xFC | (byteTemp >>> 4) & 0x03);
byteDest = (byte) ((byteTemp << 4) & 0xF0 | (byteTemp >>> 2) & 0x0F);
} else if (iSrcIdx < reviSrcIdx - 1) {
byteDest = (byte) ((byteTemp << 2) & 0xFC | (byteTemp >>> 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();
}
}
加固了恶意代码我也很烦。如果谁遇到需要解密那些病毒,用这个解密就好,不必研究机制。 大佬 求 一个完整的 landlua+的 读写 还原
类似 这样的a=activity.getLuaDir("/res/放置需要取得文本")
LuaUtil.copyDir(a,"//写入的绝对路径/文件名")-
print("开启替换")
我只会写替换 不会写写入好多代码需要写入一个文件里 替换就做不到了
万分感谢求大佬支援 绫音 发表于 2020-12-22 08:56
这个可以解密lua脚本吗
不行,这个是解我的那个加壳的数据的程序。解开还是字节码。。。 牛牛牛好好的认真的学习学习 感谢分享 真大佬啊 看不懂系列 这个可以解密lua脚本吗 牛逼,不懂,还在自学中 谢谢分享 学习了 谢谢大佬 真大佬 好好研究一下