硕士生
 
- 金币
- 3642
- 好评
- 15
- 信誉
- 100
|
发表于
2024-10-25 09:59:26
来自手机
|
显示全部楼层
| 阅读模式
来自 重庆
本帖最后由 挽 于 2024-10-25 09:59 编辑
某些加固比较难脱修,手机机没root也用不了模块,最近发现小x分身搭配lspatch可以免root使用模块,但是小x好像要会员,而且有时候还有广告,然后就试着改了一下会员的判断逻辑在so层,直接内置模块改掉返回值就行
但是又发现使用独立分身时闪退,应该是分身有签名校验,使用去签工具一键去签后还是闪退,找了个破解版的小x研究了下去签思路,原来分身启动时校验的是小x的签名
,所以把需要过掉的签名改为小x的签名进行了,不过这样太麻烦了,每次制作分身都需要过一次签,如果能在创建分身的时候完成过签就好了,通过字符串定位到一个方法
- File file2 = new File(this.c.getCacheDir(), "temp");
- if (!file2.exists()) {
- file2.mkdirs();
- }
- if (b.e(this.c.getApplicationContext(), this.c.d)) {
- CreatingNewActivity creatingNewActivity2 = this.c;
- int i4 = creatingNewActivity2.k;
- if (i4 == n0.b.n) {
- e = creatingNewActivity2.getAssets().open("res");
- } else {
- e = m.e(i4, false);
- }
- Log.e("制作", "使用32位的分身 " + this.c.d + "," + this.a + "," + this.c.k);
- } else {
- CreatingNewActivity creatingNewActivity3 = this.c;
- int i5 = creatingNewActivity3.k;
- if (i5 == n0.b.n) {
- e = creatingNewActivity3.getAssets().open("res64");
- } else {
- e = m.e(i5, true);
- }
- Log.e("制作", "使用64位的分身 " + this.c.d + "," + this.a + "," + this.c.k);
- }
- if (e == null) {
- this.c.n.post(new d(this));
- this.c.n.postDelayed(new e(this), 2000L);
- return;
- }
- try {
- a.f(e, e.available(), this.c.n, UserCache.get().getYzDec(), file2.getAbsolutePath());
- } catch (IOException e4) {
- e4.printStackTrace();
- }
复制代码
应该就是制作分身的相关代码了,其中判断了所制作分身的位数,而且用到了assets中的相关资源文件res和res64,然后调用一些方法将返回值作为参数传给f方法,跳转到f方法看一下
- public static String f(InputStream inputStream, int i, Handler handler, String str, String str2) {
- FileOutputStream fileOutputStream;
- c cVar = new c(inputStream, str);
- FileOutputStream fileOutputStream2 = null;
- String str3 = null;
- while (true) {
- b e = cVar.e();
- if (e != null) {
- if (e.getName().equals("resource")) {
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- byte[] bArr = new byte[1024];
- int i2 = 0;
- while (true) {
- int read = cVar.read(bArr);
- if (read <= 0) {
- break;
- }
- byteArrayOutputStream.write(bArr, 0, read);
- i2 += read;
- int i3 = (int) ((i2 / i) * 40.0f);
- if (i3 > 40) {
- i3 = 40;
- }
- Message message = new Message();
- message.what = 888;
- message.arg1 = i3;
- handler.sendMessage(message);
- }
- byte[] byteArray = byteArrayOutputStream.toByteArray();
- byteArrayOutputStream.close();
- StringBuilder a = d.a.a(str2);
- a.append(File.separator);
- a.append(e.getName());
复制代码
大致流程就是将之前的资源数据做了一些处理,然后输出数据,这两个文件应该就是分身模板了,对这两个文件提前处理一下就应该可以了,去assets目录看一下,发现这两个文件居然有密码
记得传给f方法的数据又与第四个形参传到了,c类的构造函数,然后调用e方法,去e方法看一下
看不太懂,但看到了password显然与密码有关,hook一下f方法
第四个参数是一个字符串,试试对不对
成功打开,显然是个apk文件,解压,现在只需要去签处理一下就行了,但是原包没有签名不能直接去签,先用mt对小x去签,在导出去签所需的代码(在classes4.dex中)
然后打开之前解压的resource文件,导入去签的dex文件,然后搜索代码.super Landroid/app/Application;点开第三个将- .super Landroid/app/Application;
复制代码 改为- .super Lbin/mt/signature/KillerApplication;
复制代码 之后保存退出,压缩文件名为res64(32位的文件名为res)
用这个res64(res)替换原来的
但是由于替换掉了原来的文件导致原来的代码运行不了,所以要改一下它的f方法,先搜索
- invoke-static {v0, v8, v9, v10, v11}, Lo0/a;->f(Ljava/io/InputStream;ILandroid/os/Handler;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
复制代码
改成
- invoke-static {v0,v11}, Lo0/a;->f(Ljava/io/InputStream;Ljava/lang/String;)Ljava/lang/String;
复制代码
然后把f方法的代码重写一下
- .method public static f(Ljava/io/InputStream;Ljava/lang/String;)Ljava/lang/String;
- .registers 10
- .param p0, "i" # Ljava/io/InputStream;
- .param p1, "s" # Ljava/lang/String;
- .annotation system Ldalvik/annotation/Throws;
- value = {
- Ljava/io/IOException;
- }
- .end annotation
- .line 14
- new-instance v0, Ljava/util/zip/ZipInputStream;
- invoke-direct {v0, p0}, Ljava/util/zip/ZipInputStream;-><init>(Ljava/io/InputStream;)V
- .line 15
- .local v0, "zipIn":Ljava/util/zip/ZipInputStream;
- invoke-virtual {v0}, Ljava/util/zip/ZipInputStream;->getNextEntry()Ljava/util/zip/ZipEntry;
- move-result-object v1
- .line 16
- .local v1, "entry":Ljava/util/zip/ZipEntry;
- const-string v2, ""
- .line 17
- .local v2, "filePath":Ljava/lang/String;
- :goto_b
- if-eqz v1, :cond_61
- .line 18
- invoke-virtual {v1}, Ljava/util/zip/ZipEntry;->getName()Ljava/lang/String;
- move-result-object v3
- const-string v4, "resource"
- invoke-virtual {v3, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
- move-result v3
- if-eqz v3, :cond_59
- .line 19
- new-instance v3, Ljava/lang/StringBuilder;
- invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V
- invoke-virtual {v3, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- move-result-object v3
- sget-object v5, Ljava/io/File;->separator:Ljava/lang/String;
- invoke-virtual {v3, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- move-result-object v3
- invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- move-result-object v3
- invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
- move-result-object v2
- .line 20
- new-instance v3, Ljava/io/BufferedOutputStream;
- new-instance v4, Ljava/io/FileOutputStream;
- invoke-direct {v4, v2}, Ljava/io/FileOutputStream;-><init>(Ljava/lang/String;)V
- invoke-direct {v3, v4}, Ljava/io/BufferedOutputStream;-><init>(Ljava/io/OutputStream;)V
- .line 21
- .local v3, "bos":Ljava/io/BufferedOutputStream;
- const/16 v4, 0x1000
- :try_start_3c
- new-array v4, v4, [B
- .line 23
- .local v4, "bytesIn":[B
- :goto_3e
- invoke-virtual {v0, v4}, Ljava/util/zip/ZipInputStream;->read([B)I
- move-result v5
- move v6, v5
- .local v6, "read":I
- const/4 v7, -0x1
- if-eq v5, v7, :cond_4b
- .line 24
- const/4 v5, 0x0
- invoke-virtual {v3, v4, v5, v6}, Ljava/io/BufferedOutputStream;->write([BII)V
- :try_end_4a
- .catchall {:try_start_3c .. :try_end_4a} :catchall_4f
- goto :goto_3e
- .line 26
- .end local v4 # "bytesIn":[B
- .end local v6 # "read":I
- :cond_4b
- invoke-virtual {v3}, Ljava/io/BufferedOutputStream;->close()V
- goto :goto_59
- .line 20
- :catchall_4f
- move-exception v4
- :try_start_50
- invoke-virtual {v3}, Ljava/io/BufferedOutputStream;->close()V
- :try_end_53
- .catchall {:try_start_50 .. :try_end_53} :catchall_54
- goto :goto_58
- :catchall_54
- move-exception v5
- invoke-virtual {v4, v5}, Ljava/lang/Throwable;->addSuppressed(Ljava/lang/Throwable;)V
- :goto_58
- throw v4
- .line 28
- .end local v3 # "bos":Ljava/io/BufferedOutputStream;
- :cond_59
- :goto_59
- invoke-virtual {v0}, Ljava/util/zip/ZipInputStream;->closeEntry()V
- .line 29
- invoke-virtual {v0}, Ljava/util/zip/ZipInputStream;->getNextEntry()Ljava/util/zip/ZipEntry;
- move-result-object v1
- goto :goto_b
- .line 31
- :cond_61
- invoke-virtual {v0}, Ljava/util/zip/ZipInputStream;->closeEntry()V
- .line 32
- invoke-virtual {v0}, Ljava/util/zip/ZipInputStream;->close()V
- .line 33
- return-object v2
- .end method
复制代码
最后用lspatch对小x去签和内置模块
成功
模块 提取码:kkOX |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
-
查看全部评分
总评分:好评 +3
金币 +3
|