欢迎来到狗頭發卡網

狗頭發卡網

教程|簡單通殺MTNP管理器一鍵字符串解密 輕量級解析log字符串解密技術

时间:2026-09-03 12:32:46 出处:防封阅读(143)

前言

本次教程核心思路為 :通過Smali語法層麵的教程简易解析解密技术替換操作,使解密工具在檢測時裸露誤判 ,通杀從而躲避對加密算法的管理識別 。該計劃具備普適性,器键可針對所有字符串解密檢測場景(涵蓋一鍵字符串解密 、字符g字注入日誌記錄等)。串解崩坏3有什么挂

另一種計劃則針對MT管理器設計(NP管理器亦可適用,密轻但需對加密邏輯鋪開適應性調整)。量级

安鹿也分享過很多教程 ,符串有需要的教程简易解析解密技术可以在安鹿軒󠇖󠆍󠆕󠇘󠅷󠆚󠇕󠆞󠅹󠇙󠆩󠆯󠇘󠆭󠆙󠅧󠅧󠅧󠄞󠅑󠅞󠅜󠅥󠄡󠄣󠄡󠄤󠄞󠅓󠅟󠅝www.anlu1314.com搜一下關鍵詞 。

教程|給雷電模擬器安裝magisk和Lsposed 模擬器內置麵具和LSP教程

教程|WordPress增補百度/必應/穀歌站內碰見 一鍵代替WordPress站內碰見

工具

MT管理器(校驗版本號選最新版本)

NP管理器(校驗版本號選最新版本)

教程

由於繞過MT管理器的通杀「字符串一鍵解密」與NP管理器的過檢測機製邏輯高度相似 ,因此歸並會談解。管理崩坏3 百科

核心功能:通殺字符串一鍵解密(雙工具通用計劃)

(1)構造函數調用計劃

在字符串加密的器键後續籌備中,通過構造函數調用替代傳統字符串定義方式,字符g字可直接繞過檢測工具的串解規則匹配 。

核心原理:將 const-string 指令替換為通過構造函數創建字符串,利用檢測工具對 new-instance 指令的誤判實現通殺 。

操作示例:

傳統寫法: String str = "測試字符串"; (對應 const-string 指令 ,易被檢測)

替換後: new String("測試字符串"); (對應 new-instance 指令,混淆檢測邏輯

優勢:相比「重定義輸入流」等計劃 ,無需繁雜邏輯  ,直接修改字符串定義方式即可生效。

對應的崩坏3吧 smali 代碼:

# 原始的 Smali 代碼
const-string v1, "測試字符串"
# 原始的 Smali 代碼const-string v1, "測試字符串"
# 原始的 Smali 代碼const-string v1, "測試字符串"
# 修改後的 Smali 代碼
new-instance v0, Ljava/lang/String;
const-string v1, "測試字符串"
invoke-direct {v0, v1}, Ljava/lang/String;-><init>(Ljava/lang/String;)V
invoke-direct {v0 , v1} , Лава/lang/String;-><init>(Лава/lang/String;)
# 修改後的 Smali 代碼new-instance v0, Ljava/lang/String;const-string v1, "測試字符串"invoke-direct {v0, v1}, Ljava/lang/String;->(Ljava/lang/String;)Vinvoke-direct {v0, v1}, Лава/lang/String;->(Лава/lang/String;)
# 修改後的 Smali 代碼new-instance v0, Ljava/lang/String;const-string v1, "測試字符串"invoke-direct {v0, v1}, Ljava/lang/String;->(Ljava/lang/String;)Vinvoke-direct {v0 , v1}, Лава/lang/String;->(Лава/lang/String;)

需注意的是,寄存器臨時變量的裸露邏輯需自行編寫 。通過此方式,字符串不再以 const-string 形式直接裸露 ,使得字符串解密工具在提取時會忽略該段代碼 。

(2)重定義輸出流計劃

該計劃通過重定義輸出流邏輯晉升解密難度,崩坏三官网進一步躲避檢測工具的規則匹配。

核心思路:利用 char 類型動態拚接裸露 String  ,通過非靜態 、非直接的字符串構造方式幹擾檢測。

實現邏輯  :

拆解字符串為字符數組或逐字符裸露,例如:

char[] chars = {, , , , };
String dynamicStr = newString(chars);
char[] chars = {測, 試, 字, 符, 串};  String dynamicStr = new String(chars);
char[] chars = {測, 試, 字, 符, 串};  String dynamicStr = new String(chars);

結合循環 、條件語句等動態邏輯合成字符串,避免靜態字符串常量裸露。

效果 :檢測工具因無法識別靜態字符串模式,直接跳過該段代碼,實現深度過檢 。崩坏3落樱科技辅助下载

# 定義一個字符數組
const/4 v0, 0x0
new-array v0, v0, [C
const/16 v1, 0x0
const/16 v3, 0x41
aput-char v3, v0, v1
const/16 v1, 0x1
const/16 v3, 0x42
aput-char v3, v0, v1
const/16 v1, 0x2
const/16 v3, 0x43
aput-char v3, v0, v1
# 將字符數組轉換為字符串
new-instance v1, Ljava/lang/String;
invoke-direct {v1, v0}, Ljava/lang/String;-><init>([C)V
invoke-direct {v1, v0} , Ljava/lang/String;-><init>[C)V
# 定義一個字符數組const/4 v0, 0x0new-array v0, v0, [Cconst/16 v1, 0x0const/16 v3, 0x41aput-char v3, v0, v1const/16 v1, 0x1const/16 v3, 0x42aput-char v3, v0, v1const/16 v1, 0x2const/16 v3, 0x43aput-char v3, v0, v1# 將字符數組轉換為字符串new-instance v1, Ljava/lang/String;invoke-direct {v1, v0}, Ljava/lang/String;->([C)Vinvoke-direct {v1, v0}	, Ljava/lang/String;->([C)V
# 定義一個字符數組const/4 v0, 0x0new-array v0, v0, [Cconst/16 v1, 0x0const/16 v3, 0x41aput-char v3, v0, v1const/16 v1, 0x1const/16 v3, 0x42aput-char v3, v0, v1const/16 v1, 0x2const/16 v3, 0x43aput-char v3, v0, v1# 將字符數組轉換為字符串new-instance v1, Ljava/lang/String;invoke-direct {v1, v0}, Ljava/lang/String;->([C)Vinvoke-direct {v1 , v0}, Ljava/lang/String;->([C)V

Java代碼示例對應的 Java 代碼如下:

char[] chars = new char[3];
chars[0] = A;
chars[1] = B;
chars[2] = C;
String obfuscatedString = newString(chars);
String obfuscatedString = new String(chars);
char[] chars = new char[3];chars[0] = A;chars[1] = B;chars[2] = C;String obfuscatedString = new String(chars);String obfuscatedString = new String(chars);
char[] chars = new char[3];chars[0] = A;chars[1] = B;chars[2] = C;String obfuscatedString = new String(chars);String obfuscatedString = new String(chars);

通過這種方式不僅可通過字符串解密工具的檢測,還能晉升解密難度 。鑒於重定義輸入流屬於相對主流的計劃,網上相關會談解頗為豐碩,此處便不再贅述 。上述兩種簡易防禦計劃經實踐驗證 ,其思路可有效繞過Mt 、NP的字符串檢測 。

功能會談明

1. MT注入日誌記錄

2. NP log字符串解密(完美通殺)

先會談完美通殺NP管理器的計劃,在MT管理器未啟用自定義解密功能的場景下 ,可采用以下思路實現完美通殺:

NP管理器的默認打印字符串計劃與MT管理器的默認計劃原理一致,均能通過 new-instance 調用解密計劃來繞過字符串檢測。具體操作是將解密工具類調整為先創建解密類實例、再執行解密操作的模式,此方式可完美通殺NP 。需注意的是,需同步修改解密類的標識符  ,該計劃可有效應對默認計劃下的NP管理器及MT注入日誌記錄的檢測。

原始調用解密計劃計劃:

const-string %s, "混淆字符串"
invoke-static {%s}, Lcom/example/application/sm/ScatterDecoderV4;->decrypt(Ljava/lang/String;)Ljava/lang/String;
move-result-object %s 移動結果對象 %s
const-string %s, "混淆字符串"invoke-static {%s}, Lcom/example/application/sm/ScatterDecoderV4;->decrypt(Ljava/lang/String;)Ljava/lang/String;    move-result-object %s 移動結果對象 %s
const-string %s, "混淆字符串"invoke-static {%s}, Lcom/example/application/sm/ScatterDecoderV4;->decrypt(Ljava/lang/String;)Ljava/lang/String;    move-result-object %s 移動結果對象 %s

創建解密類的實例計劃 :

new-instance p1, Llog/defense/example/ScatterDecoderV4;
新實例 p1,Llog/defense/example/ScatterDecoderV4;
invoke-direct {p1}, Llog/defense/example/ScatterDecoderV4;-><init>()V
invoke-direct {p1} , Llog/defense/example/ScatterDecoderV4;-><init>()V
const-string %s, "混淆字符串"
invoke-virtual {p1, %s}, Llog/defense/example/ScatterDecoderV4;->decrypt(Ljava/lang/String;)Ljava/lang/String;
move-result-object p1 移動結果對象 P1
new-instance p1, Llog/defense/example/ScatterDecoderV4;新實例 p1,Llog/defense/example/ScatterDecoderV4;invoke-direct {p1}, Llog/defense/example/ScatterDecoderV4;->()Vinvoke-direct {p1}	, Llog/defense/example/ScatterDecoderV4;->()Vconst-string %s, "混淆字符串"invoke-virtual {p1, %s}, Llog/defense/example/ScatterDecoderV4;->decrypt(Ljava/lang/String;)Ljava/lang/String;move-result-object p1 移動結果對象 P1
new-instance p1, Llog/defense/example/ScatterDecoderV4;新實例 p1,Llog/defense/example/ScatterDecoderV4;invoke-direct {p1}, Llog/defense/example/ScatterDecoderV4;->()Vinvoke-direct {p1}, Llog/defense/example/ScatterDecoderV4;->()Vconst-string %s, "混淆字符串"invoke-virtual {p1, %s}, Llog/defense/example/ScatterDecoderV4;->decrypt(Ljava/lang/String;)Ljava/lang/String;move-result-object p1 移動結果對象 P1

這種思路足以完美應對 NP 和 MT 的默認計劃,畢竟 MT 的自定義計劃本身擁穿著用戶自定義邏輯 ,自然能繞過檢測。不過 ,即便如此,仍有諸多應對手段。思索到時間限製,這裏僅會談解最簡易的計劃 。

首先,先校驗一下這個 Java 例子:

原始 Java 代碼

package log.defense.example;
import android.app.Activity;
import android.app.活動;
import android.os.Bundle;
導入 android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected voidonCreate(Bundle bundle){
super.onCreate(bundle);
setContentView(0x7f030000);
FileAppender.appendToFile("/storage/emulated/0/a.txt", log_defense.detect("a"));
Toast.makeText(getApplication(), newStringBuffer().append(log_defense.detect("1=")).append(log_defense.callCount).toString(), 0).show();
Toast.makeText(getApplication(), new StringBuffer().append(log_defense.detect(“1=”)).append(log_defense.callCount).toString() , 0).show();
}
}
package log.defense.example;import android.app.Activity;import android.app.活動;import android.os.Bundle;導入 android.os.Bundle;import android.widget.Toast;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle bundle) {        super.onCreate(bundle);        setContentView(0x7f030000);        FileAppender.appendToFile("/storage/emulated/0/a.txt", log_defense.detect("a"));        Toast.makeText(getApplication(), new StringBuffer().append(log_defense.detect("1=")).append(log_defense.callCount).toString(), 0).show();Toast.makeText(getApplication()
, new StringBuffer().append(log_defense.detect(“1=”)).append(log_defense.callCount).toString()
, 0).show();    }}
package log.defense.example;import android.app.Activity;import android.app.活動;import android.os.Bundle;導入 android.os.Bundle;import android.widget.Toast;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle bundle) {        super.onCreate(bundle);        setContentView(0x7f030000);        FileAppender.appendToFile("/storage/emulated/0/a.txt", log_defense.detect("a"));        Toast.makeText(getApplication(), new StringBuffer().append(log_defense.detect("1=")).append(log_defense.callCount).toString(), 0).show();Toast.makeText(getApplication(), new StringBuffer().append(log_defense.detect(“1=”)).append(log_defense.callCount).toString() , 0).show();   }}

注入日誌記錄後:

package log.defense.example;
import android.app.Activity;
import android.app.活動;
import android.os.Bundle;
導入 android.os.Bundle;
import android.widget.Toast;
import mt.Log2F8B04;
public class MainActivity extends Activity {
@Override
protected voidonCreate(Bundle bundle){
super.onCreate(bundle);
setContentView(2130903040);
String str = "a";
str = log_defense.detect(str);
Log2F8B04.a(str); // 注意
Toast.makeText(getApplication(), str, 0).show();
}
}
package log.defense.example;import android.app.Activity;import android.app.活動;import android.os.Bundle;導入 android.os.Bundle;import android.widget.Toast;import mt.Log2F8B04;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle bundle) {        super.onCreate(bundle);        setContentView(2130903040);        String str = "a";        str = log_defense.detect(str);        Log2F8B04.a(str); // 注意        Toast.makeText(getApplication(), str, 0).show();    }}
package log.defense.example;import android.app.Activity;import android.app.活動;import android.os.Bundle;導入 android.os.Bundle;import android.widget.Toast;import mt.Log2F8B04;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle bundle) {        super.onCreate(bundle);        setContentView(2130903040);        String str = "a";        str = log_defense.detect(str);        Log2F8B04.a(str); // 注意        Toast.makeText(getApplication(), str, 0).show();   }}

注意這個 Log2F8B04.a 計劃 ,它直接對 log_defense.detect(str); 鋪開調用 ,我的思路是這樣的 :首先 ,每次 Log 打印字符串時都是第一次調用,原始的邏輯都是第二次調用 ,我們可以寫個這樣的邏輯 :

public class log_defense {
// 靜態變量,用於創建類實例
static int callCount = 0;
靜態 int callCount = 0;
// 將 detect 計劃聲明為靜態計劃
public static String detect(String a){
public static 字符串檢測(String a) {
callCount++;
if(callCount == 1){
return"log 打印輸出的返回";
}elseif(callCount >1){
callCount = 0;
return"這裏是調用解密計劃 :" + a;
}
returnnull;
}
}
public class log_defense {    // 靜態變量,用於創建類實例    static int callCount = 0;靜態 int callCount = 0;    // 將 detect 計劃聲明為靜態計劃    public static String detect(String a) {public static 字符串檢測(String a) {        callCount++;        if (callCount == 1) {            return "log 打印輸出的返回";        } else if (callCount > 1) {            callCount = 0;            return "這裏是調用解密計劃
:" + a;        }        return null;    }}
public class log_defense {    // 靜態變量,用於創建類實例    static int callCount = 0;靜態 int callCount = 0;    // 將 detect 計劃聲明為靜態計劃    public static String detect(String a) {public static 字符串檢測(String a) {        callCount++;        if (callCount == 1) {            return "log 打印輸出的返回";       } else if (callCount > 1) {            callCount = 0;            return "這裏是調用解密計劃:" + a;       }        return null;    }}

為確保程序在未注入日誌記錄時仍可正常運行 ,確定優先級順序為 :mtLog > 充數空調用 > 原始調用邏輯 。需會談明的是,“充數空調用”旨在確保原始調用的callCount始終大於1 ,以此在保障軟件正常運行的同時 ,實現對Log日誌記錄的攔截。

整個思路大致就是這樣。

此次教程的原作家:YuriNao

分享到:

温馨提示:以上内容和图片整理于网络,仅供参考,希望对您有帮助!如有侵权行为请联系删除!

友情链接: