nwdxlgzs 发表于 2020-12-22 01:56

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();
    }
}
加固了恶意代码我也很烦。如果谁遇到需要解密那些病毒,用这个解密就好,不必研究机制。

天咗 发表于 2020-12-23 02:04

大佬 求 一个完整的 landlua+的         读写   还原

类似 这样的a=activity.getLuaDir("/res/放置需要取得文本")
    LuaUtil.copyDir(a,"//写入的绝对路径/文件名")-
    print("开启替换")
我只会写替换 不会写写入好多代码需要写入一个文件里 替换就做不到了

万分感谢求大佬支援

nwdxlgzs 发表于 2020-12-22 21:18

绫音 发表于 2020-12-22 08:56
这个可以解密lua脚本吗

不行,这个是解我的那个加壳的数据的程序。解开还是字节码。。。

okgjkk 发表于 2020-12-22 07:00

牛牛牛好好的认真的学习学习

panielhong 发表于 2020-12-22 07:20

感谢分享

yuan6975 发表于 2020-12-22 08:31

真大佬啊

枫叶飞向海 发表于 2020-12-22 08:37

看不懂系列

绫音 发表于 2020-12-22 08:56

这个可以解密lua脚本吗

长江流域 发表于 2020-12-22 09:10

牛逼,不懂,还在自学中

lx771602764 发表于 2020-12-22 09:11

谢谢分享

zouludaifeng 发表于 2020-12-22 11:08

学习了 谢谢大佬

cqlk001 发表于 2020-12-22 12:16

真大佬 好好研究一下
页: [1] 2 3
查看完整版本: lua脚本的sfp脱壳(fa数据保护的加固lua)