首页
社区
课程
招聘
[讨论]Android Reverse Project No.9, "Types of App Security Protection, Identification and Handling Methods"
发表于: 2024-1-4 07:17 3528

[讨论]Android Reverse Project No.9, "Types of App Security Protection, Identification and Handling Methods"

2024-1-4 07:17
3528

入门学习逆向的个人笔记,预览(欢迎探讨)

[原创] 肉丝的r0env2022(kali linux)配置xrdp远程桌面,以及Genymotion安卓11的ssh登陆问题和11系统amr64转译问题.
[分享] (Android) 逆向入门记录 一篇杂文, 记录.
[分享] Adndroid逆向的基础环境准备 的一些记录 , 抄袭royuse的课 第3课
[分享] 安卓逆向课题之4, Activity,service,content provider,broadcast receiver和实例演示,完毕
[分享] 安卓逆向课题之5, mobile spider get started. 两天高度集中学习, 承上启下的流程,a明白,b上手练.(5th完结)
[分享] 安卓逆向课题之6, mobile spider get started. Object的自动化动态分析和快速定位(笔记完毕)
[分享] 安卓逆向课题之7, mobile spider get started. 看电视直播App(未加固)去广告升级 (笔记待完善)
[分享] 安卓逆向课题之8, 真实App实操带壳App重打包去强制升级(部分抄袭别人笔记)(一次不完美的实践)
[讨论] Android Reverse Project No.9, "Types of App Security Protection, Identification and Handling Methods"
[原创] Android Reverse Project No.9, "Types of App Protection“ ---- Video Course


Thanks

Thank you to all the people for the shared spirit, thank you to r0yuse, thank you to the wechat group of royuse fans, thanks for KanXUE.

What is native, the closer to the CPU definition.
dex file, in fact, is explained in java. Native program, natively interpreted by Android.

1
2
3
4
5
6
7
ps -e | grep  -i frida
adb push /root/Downloads/20200815/frida-server-15.2.2-android-arm64 /data/local/tmp/
chmod +x frida-server-15.2.2-android-arm64
./frida-server-15.2.2-android-arm64  &
objection -g com.android.chrome
memory list modules
dex file with libart.so interpretation and execution

libart.so written by CPP , and run at CPU.

1
libart.so   0xf3189000  4562944 (4.4 MiB)    /system/lib/libart.so

This is android system architecture.

IMG_20240101_012503

IMG_20240101_014114

Too easy

When Android first started, around 2010, not to mention the security of APPs, even the security of the Android system itself was not taken seriously.

After all, the protagonists of the world are still PC and WEB.

However, the world is relatively fair. Although there are no security measures, there is no need for cracking. It would be good if a new platform could perform the functions that a mobile operating system should have. As for other third-party applications, there were very few paid applications. The mobile network environment at that time was completely different from today.

In the beginning

The people who are most concerned about Android security should be hackers and blackmailers.

After all, the meal still needs to be ate, and the virus still needs to be written. .

In 2009, smali/baksmali turned out. This should be the first public DEX assembler/disassembler. Most people’s Android cracking road, Android reverse road, Android virus analysis road, and Android ** road , also starts from here.

So in 2010, Kaspersky intercepted the first Android virus...

In the same year, various technical papers on Android virus analysis and Android security began to appear, such as smali-based static analysis, sandbox-based dynamic analysis, etc.

In the same year, excellent Android reverse analysis tools such as dex2jar and apktool began to be developed and open sourced. In the following years, the black industry based on these two tools became increasingly prosperous...

Taishi

2010 can be said to be the beginning of the rapid development of Android security.

If you want to crack a software without protection, you only need to use apktool, dex2jar and other tools to clearly and completely see the original code logic of a product. Coupled with perseverance and a certain amount of reverse thinking, you can It can be done.

Although there was no one-click APP reinforcement service like today, code protection technology was not new, and the routines could be copied and used.

One of the most commonly used protection methods is: code obfuscation

For example, Google comes with the obfuscator ProGuard. The only function of ProGuard is to modify class names, method names, and field names. There are two main benefits. One is symbol obfuscation. Changing the original XXXActivity to a makes it difficult for you to guess the purpose of this class. Another benefit is the compressed file size. After all, there are tens of thousands of types, and the byte ratio of symbol strings in the dex file is not small.

1
2
3
If you want to analyze a hardening/protection application,
you should first implement this hardening/protection,
which requires looking at the problem from a development perspective.

IMG_20240101_033740

IMG_20240101_033939

IMG_20240101_034410

Another representative one is DexGuard, another product from the same developer as ProGuard. The difference is that it has richer functions and is a commercial software sold for money, while ProGuard is a free software for all developers to use for free. Dexguard's obfuscation function is more powerful and supports functions such as string encryption, flower instructions, and resource encryption. With development now, DexGuard has richer functions and even some runtime protections. It is no longer a simple obfuscator.

Commonly used protection methods include: dynamic loading

Compile the code that needs to be protected separately, encrypt it and decrypt it while the program is running, and use ClassLoader to load it dynamically. This is a common way to protect code on PC, and it was also the basis for the first generation of shells.


Please Check the artcile blow.
https://github.com/xiaokanghub/Android

IMG_20240101_045309

Dynamic Loading Method 1: Android Reinforcement Application Hook Method-Frida

I apologize for the obfuscation. Here's the explanation of the provided code using a copyable Markdown source format:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Use Java.perform to execute the following code in the context of the running Android application.
Java.perform(function () {
 
    // Obtain a reference to the 'android.app.Application' class using Java.use.
    var application = Java.use('android.app.Application');
 
    // Hook the 'attach' method of the 'android.app.Application' class with a specific parameter type.
    application.attach.overload('android.content.Context').implementation = function(context){
 
        // Call the original 'attach' method with the provided context and store its result.
        var result = this.attach(context);
 
        // Obtain the class loader from the provided context.
        var classloader = context.getClassLoader();
 
        // Set the obtained class loader as the loader for the Java class factory in Frida.
        Java.classFactory.loader = classloader;
 
        // Use the Java class factory to load the 'com.zcm.MainWindow' class.
        var yeyoulogin = Java.classFactory.use('com.zcm.MainWindow');
 
        // Output information about the loaded class to the console.
        console.log("yeyoulogin:" + yeyoulogin);
 
        // Hook the 'Button_UserLogin$ByClick' method of the 'com.zcm.MainWindow' class.
        yeyoulogin.Button_UserLogin$ByClick.implementation = function (arg) {
            // Output the value of the 'ReturnValueAAAA' property of 'this' object to the console.
            console.log("retval:" + this.ReturnValueAAAA);
        }
    }
});

Explanation:

  1. The code uses Java.perform to execute the provided code in the context of the running Android application.

  2. It obtains a reference to the android.app.Application class.

  3. It hooks the attach method of the android.app.Application class, specifically targeting the overload that takes a parameter of type android.content.Context.

  4. The original attach method is called with the provided context, and its result is stored.

  5. The class loader from the provided context is obtained.

  6. The obtained class loader is set as the loader for the Java class factory in Frida.

  7. The com.zcm.MainWindow class is loaded using the Java class factory.

  8. Information about the loaded class is output to the console.

  9. The Button_UserLogin$ByClick method of the com.zcm.MainWindow class is hooked, allowing the interception and modification of its behavior when called.

  10. The value of the ReturnValueAAAA property of the this object (which represents the instance of the hooked method) is output to the console.

Dynamic Loading Method 2 : List loaded classes

1
2
3
4
5
6
7
8
9
Java.enumerateLoadedClasses({
    "onMatch": function(className) {
        // Callback function called for each matched class name
        console.log(className);
    },
    "onComplete": function() {
        // Callback function called when the enumeration is complete
    }
});

Explanation:

  • Java.enumerateLoadedClasses: This function is provided by Frida and is used to enumerate all currently loaded Java classes in the application.

  • "onMatch": function(className) { console.log(className) }: This is a callback function that will be invoked for each matched class name during the enumeration. It simply logs each class name to the console.

  • "onComplete": function() { }: This is another callback function that will be invoked when the enumeration is complete. In this case, it is an empty function, meaning it does not perform any specific action.

Overall, this code is designed to log the names of all loaded Java classes in the application, providing insights into the class structure and loaded components during runtime.

Certainly! Here's the explanation of the provided code using Markdown source format:

Dynamic Loading Method 3 : Hook dynamically loaded classes ----》 Get the parameters of the constructor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Use Java.perform to execute the following code in the context of the running Android application.
Java.perform(function(){
     
    // Create a wrapper for the DexClassLoader.
    var dexclassLoader = Java.use("dalvik.system.DexClassLoader");
     
    // Hook its constructor $init and print its four parameters.
    dexclassLoader.$init.implementation = function(dexPath, optimizedDirectory, librarySearchPath, parent){
        console.log("dexPath:" + dexPath);
        console.log("optimizedDirectory:" + optimizedDirectory);
        console.log("librarySearchPath:" + librarySearchPath);
        console.log("parent:" + parent);
         
        // Do not disrupt its original logic; call its original constructor.
        this.$init(dexPath, optimizedDirectory, librarySearchPath, parent);
    }
     
    // Log a message indicating that the hooking is completed.
    console.log("down!");
});

Explanation:

  1. The code uses Java.perform to execute the provided code in the context of the running Android application.

  2. It creates a wrapper for the DexClassLoader class.

  3. It hooks the constructor $init of the DexClassLoader class and prints its four parameters: dexPath, optimizedDirectory, librarySearchPath, and parent.

  4. The original logic of the constructor is not disrupted; it calls the original constructor.

  5. It logs a message indicating that the hooking process is completed.

IMG_20240101_054758

if you wanted the known where is the function from, You can search the keywords "dalvik.system.DexClassLoader" , you may get the new page to understood , how it is implemented?

IMG_20240101_055259

IMG_20240101_061541

Positive development ideas Android dynamically loading dex,

Please refer to the following web links.
https://blog.csdn.net/lx768863620/article/details/79414010

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       start();
    }
    public void start(){
        File dexOutputDir = getDir("dex", 0);
        //Dex 文件存放位置
        String dexPath ="/storage/emulated/0/output.jar";// Environment.getExternalStorageDirectory().toString() + File.separator + "output.jar";
        DexClassLoader loader = new DexClassLoader(dexPath,
                dexOutputDir.getAbsolutePath(),
                null, ClassLoader.getSystemClassLoader().getParent());
        try {
            Class clz = loader.loadClass("com.youbo.switchsky.LogUtils");
            Object instance= clz.newInstance();
            Method method = clz.getMethod("show", Context.class);
            method.invoke(instance,this);
        } catch (Exception e) {
            Log.d("TEST111", "error happened", e);
        }
    }
 
}

so the most important problem is to realize and write on by yourself.

The most hard-core protection: Native development

Use NDK to write applications and directly generate native code

IMG_20240101_064136

They are using NDK developmented. by C++ or C .

Because he writes the key logic in the so file, which makes it difficult for you to analyze.

Java-level protectino is almost abandoned now.

Well, this is the basis of today's java2cpp technology. . .

The most modern protection: core data and functions are cloud-based.

Put all important functions and data into cloud computing, and the client can be used only for display. Well, this is barely the basis of current risk control. . .

Therefore, most of the current code protection methods on the mobile terminal are constantly upgraded and adapted based on the predecessors.

Taisu

If protection is standing on the shoulders of giants, then cracking is standing on the shoulders of God.

Since static analysis is not possible, the attacker can also perform dynamic analysis from a God's perspective.

Regarding dynamic analysis, I wrote a special article "Summary of Android Dynamic Analysis Attack and Defense" and talked about some routines. You can check the historical information on the official account.

In the face of dynamic analysis, dynamic loading, which was originally the most direct, effective and low-cost method, has become the most fragile protection method.

Usually you only need to attach a process to do a memory roaming search for dex.035 or even look directly at the Segment name to find the dynamically loaded dex file in the memory and dump it. As of 2020, this method is still effective for most hardened generation protections. .

Of course, there's a lot of manual work, such as dvmDexFileOpenPartial and other function break points about loading code, and you can easily find the decrypted dex file by doing Hook.

This is the unpacking method of Android hardened No. 1 machine.

Because simple dynamic loading alone cannot stop people at all, there are probably several other development routes for application protection at this time:

Fight against debuggers

This part has been discussed a lot in the article "Android Dynamic Analysis Offense and Defense Summary" published by the public account (Hu Ke Laoshiji), you can refer to it.

Of course, there are not many methods at the beginning, but they are obtained through continuous exploration, competitive product analysis, and community sharing by all parties.

Fight against decompilers

By looking for vulnerabilities and BUGs in various decompilers and disassemblers, the payload is inserted into the DEX or resource files that need to be protected, causing the tool to crash and prevent it from running normally.

However, this road is obviously a dead end. With the continuous maintenance of various tools, compatibility becomes stronger and stronger. It is not easy to find such bugs that can be bypassed directly. Even if there are any, they will be quickly fixed.

Typical examples are Black Hat USA 2012 - Dex Education: Practicing Safe Dex, and 360 hardening which also had some such protection before.

Against people: disgusting flow

The code protects millions of roads, but only disgusting people are the king.

So the responsibility of this road is to carry forward the essence of obfuscation: "disgusting".

for example:

1. Symbol obfuscation upgraded version:

Previously, the class name, method name, and field name were replaced by abcd. Later, I started to use a obfuscation dictionary, which includes various small language symbols and invisible symbols. Just use the symbols in these dictionaries to generate new class names, method names, and field names. The final effect is that it looks garbled or blank.

Of course, there are many countermeasures. For example, the anti-obfuscation function of the open source decompiler Jadx supports automatic renaming of symbols into meaningless names like abcd;

Another example is another anti-obfuscation function, which reads the sourcefile attribute from the DEX file to restore the real class name. However, this is just debugging information, so many obfuscators will directly remove this field.

More advanced, such as blank obfuscation.

IMG_20240101_071017

The effect shown by the code

IMG_20240101_071119

So the most effective tool to combat this kind of obfuscation is: people

2. String encryption enhanced version:

Many of the initial string encryptions were relatively monotonous. Generally, there was a decryption method that accepted an encrypted string or byte[] and then returned a string. This is of course easy to target. As long as you first use dex2jar and then dynamically load the Jar package and call the decryption method through reflection, you can get the plaintext string.

So many mutation methods appeared later, probably the following:

1. Guerrilla play method, group strings and use multiple algorithms to encrypt them. Instead of relying on only one method to decrypt, each decryption method corresponds to a different algorithm, so you can't catch them all at once.
2. The Self-Defense Force’s approach is to check the running environment when initializing the decryption algorithm, or rely on the context environment to increase the difficulty of calling.
3. Use native decryption and SO protection.
*

3. Native protection

For Native's disgusting flow protection, the most popular and most effective one is OLLVM. OLLVM is something that only appeared since 2013, and may have a lot of content. I will talk about this later.

As for other Native protection, there are basically only two methods at the beginning:

1. Destroy the ELF file structure and even customize the linker to load customized SO.
2. Encrypt the code segment and decrypt it at runtime, which is similar to Dex dynamic loading. Or directly apply a traditional ELF shell such as UPX.

While dynamic DUMPing of memory can result in real code, not being able to repair the complete file structure leaves a lot missing that can aid in analysis.

4. Other obfuscations:

I have seen before that there is no normal file in the APK package except the necessary manifest. The assert, lib, dex, and res are all protected (including some of the methods mentioned above), let alone compatibility. Or how about the performance, anyway, it’s really disgusting...

Tai Chi

2010 was the year of creation of Android application security. By about 2013, various code protection technologies for Android applications had basically taken shape, and most of the above technologies had been stably implemented.

It can be said that the period from 2009 to 2012 was a period when Android application security went from Wuji to Tai Chi and ushered in a new era.

During this time, Android has captured most of the mobile phone market.

In 2013, the global market share of Android mobile phones was as high as 80%, and a large number of users and developers poured in.

Google’s Android empire is unstoppable.

At the same time, the spring of the Android application security market is also coming.

To predict what will happen in the future, please press and hold the QR code below to follow Hu Ke Lao Shi Ji and listen to the next chapter's breakdown...

Here function was not encrypted. read directly.

IMG_20240102_030947

Here, you can look directly at his logic without any obfuscation.

IMG_20240102_031241

earch for the main dex file of 学而思

1
2
3
4
5
/root/Downloads/anzhuo-yingyong-rumen2/20200822/com.xes.jazhanghui.activity/
 
cd /root/Downloads/anzhuo-yingyong-rumen2/20200822/com.xes.jazhanghui.activity/
 
grep -ril "okhttp3"

// check the dumped file size

1
du -sh `ls`

IMG_20240102_031431

There are too many files, and it is confusing to look directly.

IMG_20240102_031931

The goal is to use frida -- interceptors of this goal


The specific location of the error, the core requirements, and the okhttp3hook .js of the restore system (the course and the steps to detail how to build a js file)

why the script report error.

IMG_20240102_040946

There are two ways for Frida to load scripts

objection -g com.xes.jazhanghui.activity explore -P /root/.objection/plugin

a, solve the problem of envirment configuration .

// Here is Spanwan Mode ---->

1
frida -U -l /root/Downloads/anzhuo-yingyong-rumen2/AndroidFridaBeginnersBook/hookOkhttp3.js -f com.singleman.freevideo --no-pause

// Here is Attach Mode ---->

1
frida -U -l /root/Downloads/anzhuo-yingyong-rumen2/AndroidFridaBeginnersBook/hookOkhttp3.js com.singleman.freevideo --no-pause

// system envirmoment configuration only for Jul 28, 2020

1
2
3
4
5
pyenv local 3.8.3
frida version 12.11.6
frida-tools version 8.1.0
objection version 1.9.5
Jul 28, 2020  //date

// installing step
// The installation order here should not be messed up, and the frida must be in front of the frida-tools first

1
2
3
4
proxychains  pyenv install 3.8.3
pip install frida==12.11.6
pip install frida-tools==8.1.0
pip install objection==1.9.5

// debug the App called com.xes.jazhanghui.activity

1
objection -g com.xes.jazhanghui.activity explore

IMG_20240102_062119

IMG_20240102_062135

dumped path is

1
/root/com.xes.jazhanghui.activity/

Author dumped path of Course is

1
/root/desktop20200820/com.xes.jazhanghui.activity

I didn't have a problem with my operation,But I have these files included in my script.

1
2
/data/local/tmp/myok2curl.dex
/data/local/tmp/okhttplogging.dex

The following 3 package names should exist in the system and have been installed.

1
2
3
com.moczul.ok2curl.CurlInterceptor
com.moczul.ok2curl.logger.Loggable
com.r0ysue.learnokhttp.okhttp3Logging

Problems mentioned in the script

IMG_20240102_064046


As you can see from the lesson, my phone doesn't have these two files, so the error is reported.
The solution is to comment out all the useless code blocks and manually load them into Frida

IMG_20240102_030947

As you can see from the screenshot above, there is no obfuscation.
We can go directly to the target class name okhttp3 by way of script.

Follow the final Video Requirements toggle

1
2
pyenv lcoal 3.8.3
frida version  12.11.6

Modified js script (maybe it was correct )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function searchClient(){
    Java.perform(function(){
        // //Java.openClassFile("/data/local/tmp/r0gson.dex").load();
        // //const gson = Java.use('com.r0ysue.gson.Gson');
        // var gson2 = Java.use('com.google.gson.Gson');
 
        // // 加载包含CurlInterceptor拦截器的DEX
        // Java.openClassFile("/data/local/tmp/myok2curl.dex").load();
        // console.log("loading dex successful!")
        // const curlInterceptor =  Java.use("com.moczul.ok2curl.CurlInterceptor");
        // const loggable = Java.use("com.moczul.ok2curl.logger.Loggable");
        // var Log = Java.use("android.util.Log");
        // var TAG = "okhttpGETcurl";
        // //注册类————一个实现了所需接口的类
        // var MyLogClass = Java.registerClass({
        //     name: "okhttp3.MyLogClass",
        //     implements: [loggable],
        //     methods: {
        //         log: function (MyMessage) {
        //             Log.v(TAG, MyMessage);
        //         }}
        // });       
        // const mylog = MyLogClass.$new();
        // // 得到所需拦截器对象
        // var curlInter = curlInterceptor.$new(mylog);
 
 
        // // 加载包含logging-interceptor拦截器的DEX
        // Java.openClassFile("/data/local/tmp/okhttplogging.dex").load();
        // var MyInterceptor = Java.use("com.r0ysue.learnokhttp.okhttp3Logging");
        // var MyInterceptorObj = MyInterceptor.$new();       
 
        Java.choose("okhttp3.OkHttpClient",{
            onMatch:function(instance){
                console.log("1. found instance:",instance)
                console.log("2. instance.interceptors():",instance.interceptors().$className)
                console.log("3. instance._interceptors:",instance._interceptors.value.$className)
                //console.log("4. interceptors:",gson2.$new().toJson(instance.interceptors()))
                console.log("5. interceptors:",Java.use("java.util.Arrays").toString(instance.interceptors().toArray()))
                var newInter = Java.use("java.util.ArrayList").$new();
                newInter.addAll(instance.interceptors());
                console.log("6. interceptors:",Java.use("java.util.Arrays").toString(newInter.toArray()));
                console.log("7. interceptors:",newInter.$className);
                newInter.add(MyInterceptorObj);
                newInter.add(curlInter);
                instance._interceptors.value = newInter;
                 
            },onComplete:function(){
                console.log("Search complete!")
            }
        })
         
    })
 
}
 
setImmediate(searchClient)

b, Troubleshoot issues and execute them successfully

execute following Script.

1
frida -UF -/root/Downloads/anzhuo-yingyong-rumen2/20240104/2024.01.04.testfor_xueersi_education.js.js    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──(root㉿r0env)-[~]
└─# frida -UF -l  /root/Downloads/anzhuo-yingyong-rumen2/20240104/2024.01.04.testfor_xueersi_education.js.js                                                                                                                               
     ____
    / _  |   Frida 12.11.6 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://www.frida.re/docs/home/
1. found instance: okhttp3.OkHttpClient@6046fbb
2. instance.interceptors(): java.util.Collections$UnmodifiableRandomAccessList
3. instance._interceptors: java.util.Collections$UnmodifiableRandomAccessList
5. interceptors: [com.networkbench.agent.impl.h.b@13a6831, com.tal.xes.app.net.interceptor.LocalCacheInterceptor@8837b16, com.tal.xes.app.net.interceptor.HttpLoggingInterceptor@8804c97, com.xes.cloudlearning.bcmpt.net.CommonHeaderIntercept@9c0ce84, com.tal.xes.app.netbusiness.interceptor.ServerStatusInterceptor@41c566d, com.tal.xes.app.netbusiness.interceptor.AppHeadersInterceptor@7b432a2, com.tal.xes.app.netbusiness.interceptor.AppParamsInterceptor@a731b33, com.tal.xes.app.netbusiness.interceptor.SaveServerTimeInterceptor@1be4ef0, com.tal.xes.app.net.interceptor.ParamsInterceptor@7b4ec69, com.tal.xes.app.netbusiness.interceptor.SignInterceptor@a46d6ee, com.tal.xes.app.netbusiness.interceptor.NetResponseErrorInterceptor@fba378f, com.tal.xes.app.net.retrofit_url.RetrofitUrlManager$1@326e625]
6. interceptors: [com.networkbench.agent.impl.h.b@13a6831, com.tal.xes.app.net.interceptor.LocalCacheInterceptor@8837b16, com.tal.xes.app.net.interceptor.HttpLoggingInterceptor@8804c97, com.xes.cloudlearning.bcmpt.net.CommonHeaderIntercept@9c0ce84, com.tal.xes.app.netbusiness.interceptor.ServerStatusInterceptor@41c566d, com.tal.xes.app.netbusiness.interceptor.AppHeadersInterceptor@7b432a2, com.tal.xes.app.netbusiness.interceptor.AppParamsInterceptor@a731b33, com.tal.xes.app.netbusiness.interceptor.SaveServerTimeInterceptor@1be4ef0, com.tal.xes.app.net.interceptor.ParamsInterceptor@7b4ec69, com.tal.xes.app.netbusiness.interceptor.SignInterceptor@a46d6ee, com.tal.xes.app.netbusiness.interceptor.NetResponseErrorInterceptor@fba378f, com.tal.xes.app.net.retrofit_url.RetrofitUrlManager$1@326e625]
7. interceptors: java.util.ArrayList
ReferenceError: identifier 'MyInterceptorObj' undefined
    at [anon] (../../../frida-gum/bindings/gumjs/duktape.c:83728)                                                                                                                                                                          
    at /2024.01.04.testfor_xueersi_education.js.js:44                                                                                                                                                                                      
    at frida/node_modules/frida-java-bridge/lib/class-factory.js:310                                                                                                                                                                       
    at frida/node_modules/frida-java-bridge/lib/class-factory.js:264                                                                                                                                                                       
    at tt (frida/node_modules/frida-java-bridge/lib/android.js:462)                                                                                                                                                                        
[Nexus 5X::学而思培优]->   

There are several practical examples of obfuscation

examples of no obfuscation XueErSi APP

IMG_20240103_002541

IMG_20240103_002443

This is an obvious certificate binding class

IMG_20240103_002830

Only one we care about that is the operation of the OkHttp3 sub class interceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package  okhttp3
 
class OkHttpClient {
                                                                                                                                                                                                                                             
        /* static fields */                                                                                                                                                                                                                
        static java.util.List DEFAULT_PROTOCOLS; => [0x6912]: [h2, http/1.1]
        static java.util.List DEFAULT_CONNECTION_SPECS; => [0x690a]: [ConnectionSpec(cipherSuites=[TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_CCM_SHA256, TLS_AES_256_CCM_8_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA], tlsVersions=[TLS_1_3, TLS_1_2, TLS_1_1, TLS_1_0], supportsTlsExtensions=true), ConnectionSpec()]                                                                                                                                          
 
        /* instance fields */
        int shadow$_monitor_; => -1916673143
        java.lang.Class shadow$_klass_; => [0x6862]: class okhttp3.OkHttpClient
        java.util.List _connectionSpecs; => [0x6856]: [ConnectionSpec(cipherSuites=[TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_CCM_SHA256, TLS_AES_256_CCM_8_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA], tlsVersions=[TLS_1_3, TLS_1_2, TLS_1_1, TLS_1_0], supportsTlsExtensions=true), ConnectionSpec()]                                                                                                                                                         
        okhttp3.CookieJar _cookieJar; => [0x681a]: okhttp3.CookieJar$1@35c2f45
        okhttp3.Authenticator _proxyAuthenticator; => [0x65ba]: okhttp3.Authenticator$1@ad59d9f
        java.net.Proxy _proxy; => null
        okhttp3.CertificatePinner _certificatePinner; => [0x6586]: okhttp3.CertificatePinner@0
        javax.net.SocketFactory _socketFactory; => [0x6556]: javax.net.DefaultSocketFactory@905569a
        javax.net.ssl.HostnameVerifier _hostnameVerifier; => [0x6536]: com.tal.xes.app.net.-$$Lambda$NetHelper$6BAsjZ5QKjp5NoLA82QXE-fjgFI@3c98f4d
        int pingInterval; => 0
        int callTimeout; => 0
        int connectTimeout; => 30000
        okhttp3.Dns _dns; => [0x6516]: okhttp3.Dns$1@456cb3e
        javax.net.ssl.SSLSocketFactory _sslSocketFactory; => [0x64f6]: com.android.org.conscrypt.OpenSSLSocketFactoryImpl@62ddee4
        okhttp3.ConnectionPool _connectionPool; => [0x64d6]: okhttp3.ConnectionPool@cc4fbcb
        okhttp3.Cache _cache; => [0x64b6]: okhttp3.Cache@e993fa8
        okhttp3.Dispatcher _dispatcher; => [0x6496]: okhttp3.Dispatcher@c957ac1
        int readTimeout; => 30000
        okhttp3.internal.tls.CertificateChainCleaner certificateChainCleaner; => [0x6476]: okhttp3.internal.tls.BasicCertificateChainCleaner@0
        java.net.ProxySelector _proxySelector; => [0x6456]: sun.net.spi.DefaultProxySelector@4c5e03e
        java.util.List _protocols; => [0x6542]: [h2, http/1.1]
        java.util.List _networkInterceptors; => [0x6432]: [com.tal.xes.app.net.interceptor.NetCacheInterceptor@9524266]
        okhttp3.EventListener$Factory _eventListenerFactory; => [0x6416]: okhttp3.EventListener$2@92589a7
        boolean _retryOnConnectionFailure; => true
        okhttp3.internal.cache.InternalCache _internalCache; => null
        java.util.List _interceptors; => [0x6402]: [com.networkbench.agent.impl.h.b@316ae54, com.tal.xes.app.net.interceptor.LocalCacheInterceptor@2be01fd, com.tal.xes.app.net.interceptor.HttpLoggingInterceptor@6301ef2, com.xes.cloudlearning.bcmpt.net.CommonHeaderIntercept@d171943, com.tal.xes.app.netbusiness.interceptor.ServerStatusInterceptor@95a5bc0, com.tal.xes.app.netbusiness.interceptor.AppHeadersInterceptor@9edc0f9, com.tal.xes.app.netbusiness.interceptor.AppParamsInterceptor@49d383e, com.tal.xes.app.netbusiness.interceptor.SaveServerTimeInterceptor@c08069f, com.tal.xes.app.net.interceptor.ParamsInterceptor@f6973ec, com.tal.xes.app.netbusiness.interceptor.SignInterceptor@5c073b5, com.tal.xes.app.netbusiness.interceptor.NetResponseErrorInterceptor@9309a4a, com.tal.xes.app.net.retrofit_url.RetrofitUrlManager$1@7f06dbb]                                                                                                            
        boolean _followSslRedirects; => true
        int writeTimeout; => 30000
        okhttp3.Authenticator _authenticator; => [0x6506]: okhttp3.Authenticator$1@ad59d9f
        boolean _followRedirects; => true
 
        /* constructor methods */
        void OkHttpClient();
        void OkHttpClient(okhttp3.OkHttpClient$Builder);
 
        /* static methods */
        static int identityHashCodeNative(java.lang.Object);
        static int identityHashCode(java.lang.Object);
        static javax.net.ssl.SSLSocketFactory newSslSocketFactory(javax.net.ssl.X509TrustManager);
 
        /* instance methods */
        int hashCode();
        void wait();
        void wait(long);
        void wait(long, int);
        void notify();
        void notifyAll();
        boolean equals(java.lang.Object);
        java.lang.Object clone();
        void finalize();
        java.lang.Object internalClone();
        java.lang.String toString();
        java.lang.Class getClass();
        int readTimeoutMillis();
        javax.net.ssl.HostnameVerifier hostnameVerifier();
        boolean retryOnConnectionFailure();
        javax.net.ssl.SSLSocketFactory sslSocketFactory();
        okhttp3.Dispatcher dispatcher();
        boolean followRedirects();
        okhttp3.OkHttpClient$Builder newBuilder();
        okhttp3.Dns dns();
        okhttp3.CookieJar cookieJar();
        java.util.List connectionSpecs();
        javax.net.SocketFactory socketFactory();
        int pingIntervalMillis();
        int callTimeoutMillis();
        boolean followSslRedirects();
        java.util.List networkInterceptors();
        okhttp3.Call newCall(okhttp3.Request);
        java.net.Proxy proxy();
        okhttp3.CertificatePinner certificatePinner();
        java.net.ProxySelector proxySelector();
        okhttp3.EventListener$Factory eventListenerFactory();
        int writeTimeoutMillis();
        int connectTimeoutMillis();
        okhttp3.Authenticator proxyAuthenticator();
        okhttp3.Cache cache();
        java.util.List protocols();
        okhttp3.ConnectionPool connectionPool();
        okhttp3.WebSocket newWebSocket(okhttp3.Request, okhttp3.WebSocketListener);
        java.util.List interceptors();
        okhttp3.Authenticator authenticator();
        okhttp3.internal.cache.InternalCache internalCache();
 
}

<!-- IMG_20240103_063217 -->

<!-- IMG_20240103_063226 -->

<!-- IMG_20240103_063232 -->

IMG_20240103_065244

This is offcial API handbook of Interceptors. Its structure can be roughly guessed

IMG_20240103_065307

This is we wanted find the target of interceptor function of okhttp3.client class

IMG_20240103_065319

IMG_20240103_065326

examples of obfuscation Mooc

IMG_20240103_065710

IMG_20240103_065802

IMG_20240103_070016

IMG_20240103_070226

IMG_20240103_070431

Generally, it is cracked with a confusing mode.

you can using Frida Hook to print the Area's result.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Java.choose("okhttp3.OkHttpClient",{
    onMatch:function(instance){
        console.log("1. found instance:",instance)
        console.log("2. instance.interceptors():",instance.interceptors().$className)
        console.log("3. instance._interceptors:",instance._interceptors.value.$className)   //方法的是 interceptors
        //console.log("4. interceptors:",gson2.$new().toJson(instance.interceptors()))
        console.log("5. interceptors:",Java.use("java.util.Arrays").toString(instance.interceptors().toArray()))
        var newInter = Java.use("java.util.ArrayList").$new();
        newInter.addAll(instance.interceptors());
        console.log("6. interceptors:",Java.use("java.util.Arrays").toString(newInter.toArray()));
        console.log("7. interceptors:",newInter.$className);
        newInter.add(MyInterceptorObj);
        newInter.add(curlInter);
        instance._interceptors.value = newInter;
         
    },onComplete:function(){
        console.log("Search complete!")
    }
})

we can use this idea to replace the idea of the interceptor as a whole.

IMG_20240103_073734

we were dynamic position this class.

IMG_20240103_074441

IMG_20240103_075222

IMG_20240103_075255

IMG_20240103_075345

ok , this is correct .

How to judge ? it is based on his class name.

IMG_20240103_075558

IMG_20240103_075915

IMG_20240103_080442

examples of obfuscation Free cinema APP

IMG_20240103_081104

this App className alll was disappeard.

IMG_20240103_081321

IMG_20240103_082156

how to judge the class is correct or not.
watch them structure is correct.

IMG_20240103_091154

IMG_20240103_092420

1
2
3
4
smali/فمضﺝ/ﻙﺫتك$ﻝبـق.smali
smali/فمضﺝ/ﻙﺫتك$ﺯﺵتﻝ.smali
smali/فمضﺝ/ﻙﺫتك.smali  <---
smali/okhttp3/internal/platform/Platform.smali

this is for the obfs later charector.

IMG_20240103_232311

IMG_20240103_232715

IMG_20240103_232947

IMG_20240103_233133

IMG_20240103_234903

IMG_20240103_235344

IMG_20240104_000839
IMG_20240104_000911

IMG_20240104_001009

IMG_20240104_001342

Almost exactly the same as the normal function structure.

IMG_20240104_003508

IMG_20240104_004159

IMG_20240104_004500

IMG_20240104_005056

ok, finally, i will write the javascript to the loaded manually.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
function searchClient(){
    Java.perform(function(){
        // //Java.openClassFile("/data/local/tmp/r0gson.dex").load();
        // //const gson = Java.use('com.r0ysue.gson.Gson');
        // var gson2 = Java.use('com.google.gson.Gson');
 
        // // 加载包含CurlInterceptor拦截器的DEX
        // Java.openClassFile("/data/local/tmp/myok2curl.dex").load();
        // console.log("loading dex successful!")
        // const curlInterceptor =  Java.use("com.moczul.ok2curl.CurlInterceptor");
        // const loggable = Java.use("com.moczul.ok2curl.logger.Loggable");
        // var Log = Java.use("android.util.Log");
        // var TAG = "okhttpGETcurl"image.png;
        // //注册类————一image.png个实现了所需接口的类
        // var MyLogClass = Java.registerClass({
        //     name: "okhttp3.MyLogClass"image.png,
        //     impimage.pnglements: [loggable],
        //     methods: {
        //         log: function (MyMessage) {image.png
        //             Log.v(TAG, MyMessage);
        //         }}
        // });       
        // const mylog = MyLogClass.$new();
        // // 得到所需拦截器对象
        // var curlInter = curlInterceptor.$new(mylog);
 
 
        // 加载包含logging-interceptor拦截器的DEX
        // Java.openClassFile("/data/local/tmp/okhttplogging.dex").load();
        // var MyInterceptor = Java.use("com.singleman.freevideo.okhttp3Logging");
        // var MyInterceptorObj = MyInterceptor.$new();
         
        Java.choose("فمضﺝ.ﻙﺫتك",{
            onMatch:function(instance){
                console.log("1. found instance:",instance)
                //console.log("2. instance.interceptors():",instance.interceptors().$className)
                console.log("3. instance._interceptors:",instance.ﻭﻍﺫﻉ.value.$className)
                 
                //console.log("4. interceptors:",gson2.$new().toJson(instance.interceptors()))
                console.log("5. interceptors:",Java.use("java.util.Arrays").toString(instance.ﻭﻍﺫﻉ.value.toArray()))
                /*
                var newInter = Java.use("java.util.ArrayList").$new();
                newInter.addAll(instance.interceptors());
                console.log("6. interceptors:",Java.use("java.util.Arrays").toString(newInter.toArray()));
                console.log("7. interceptors:",newInter.$className);
                newInter.add(MyInterceptorObj);
                newInter.add(curlInter);
                instance._interceptors.value = newInter;
                */
                 
            },onComplete:function(){
                console.log("Search complete!")
            }
        })
         
 
        // Java.choose("okhttp3.OkHttpClient",{
        //     onMatch:function(instance){
        //         console.log("1. found instance:",instance)
        //         console.log("2. instance.interceptors():",instance.interceptors().$className)
        //         console.log("3. instance._interceptors:",instance._interceptors.value.$className)
        //         //console.log("4. interceptors:",gson2.$new().toJson(instance.interceptors()))
        //         console.log("5. interceptors:",Java.use("java.util.Arrays").toString(instance.interceptors().toArray()))
        //         var newInter = Java.use("java.util.ArrayList").$new();
        //         newInter.addAll(instance.interceptors());
        //         console.log("6. interceptors:",Java.use("java.util.Arrays").toString(newInter.toArray()));
        //         console.log("7. interceptors:",newInter.$className);
        //         newInter.add(MyInterceptorObj);
        //         newInter.add(curlInter);
        //         instance._interceptors.value = newInter;
                 
        //     },onComplete:function(){
        //         console.log("Search complete!")
        //     }
        // })
         
    })
 
}
 
// setImmediate(searchClient)
// I think using SetImmediate function can using at the SPan mode, will start at the app started before.! simply . Firda First. and App second.
// if there im comment , load Java script to Memory. and useing function name to call When using Frida in interactive mode
//  Here is  Spanwan Mode  ----> frida -U -l /root/Downloads/anzhuo-yingyong-rumen2/AndroidFridaBeginnersBook/hookOkhttp3.js -f com.singleman.freevideo --no-pause
//
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌──(root㉿r0env)-[~]
└─# frida -U -l /root/Downloads/anzhuo-yingyong-rumen2/AndroidFridaBeginnersBook/hookOkhttp3.js  com.singleman.freevideo --no-pause                                                                                                      
     ____
    / _  |   Frida 12.11.6 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://www.frida.re/docs/home/
                                                                                 
[Nexus 5X::com.singleman.freevideo]-> searchClient
function
[Nexus 5X::com.singleman.freevideo]-> searchClient()
1. found instance: فمضﺝ.ﻙﺫتك@1b76d08
2. instance._interceptors: java.util.Collections$UnmodifiableRandomAccessList
3. interceptors: [ﻝبـق.ﻍبﺯﺫ.ﻝبـق.ﻝبـق.بﺙذن.بﺙذن.ﻝبـق@a820ca1]
4. found instance: فمضﺝ.ﻙﺫتك@ebe9ec6
5. instance._interceptors: java.util.Collections$UnmodifiableRandomAccessList
6. interceptors: [ﻝبـق.ﻍبﺯﺫ.ﻝبـق.ﻝبـق.بﺙذن.بﺙذن.ﻝبـق@eae1e87]
7. found instance: فمضﺝ.ﻙﺫتك@da51b4
8. instance._interceptors: java.util.Collections$UnmodifiableRandomAccessList
9. interceptors: [ﻝبـق.ﻍبﺯﺫ.ﻝبـق.ﻝبـق.بﺙذن.بﺙذن.ﻝبـق@711d1dd]
10. found instance: فمضﺝ.ﻙﺫتك@e75e152
11. instance._interceptors: java.util.Collections$UnmodifiableRandomAccessList
12. interceptors: [ﻝبـق.ﻍبﺯﺫ.ﻝبـق.ﻝبـق.بﺙذن.بﺙذن.ﻝبـق@a441c23]
Search complete!
[Nexus 5X::com.singleman.freevideo]->

All reference links

nexus 5x brush machine pointing North
https://www.jianshu.com/p/f0dc69b75476

Flash magisk for nexus with ADB Sideload !
https://bbs.kanxue.com/thread-279435-1.htm#1759925

frida js script using methods
https://papayawd.github.io/2020/10/18/frida-js%E8%84%9A%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/

https://cmsblogs.cn/3706.html
Android Frida Reverse & Packet Grabbing Combat PDF Download

Android: Create a Screenshot with ADB
https://supportcommunity.zebra.com/s/article/000021675?language=en_US

OkHttpClient (OkHttp 3.7.0 API).
https://javadoc.io/static/com.squareup.okhttp3/okhttp/3.7.0/okhttp3/OkHttpClient.html#connectionSpecs--

Location analysis based on memory roaming
https://onejane.github.io/2021/02/12/%E5%9F%BA%E4%BA%8E%E5%86%85%E5%AD%98%E6%BC%AB%E6%B8%B8%E5%AE%9A%E4%BD%8D%E5%88%86%E6%9E%90/#%E6%A1%88%E4%BE%8B%E4%B8%80

Socket&Websocket&ProtobufSelf-spitting and killing Everything can be reversed
https://onejane.github.io/2021/03/14/Socket&Websocket&Protobuf%E8%87%AA%E5%90%90%E9%80%9A%E6%9D%80/#%E5%85%B3%E9%94%AE%E7%B1%BB%E5%AE%9A%E4%BD%8D

siyujie_OkHttpLogger-Frida Frida implements a script that intercepts okhttp
https://github.com/siyujie/OkHttpLogger-Frida

r0gson.dex
https://github.com/r0ysue/AndroidSecurityStudy/blob/master/FRIDA/r0gson.dex.zip

xiaokanghub_Android Android 加固应用Hook方式-Frida
https://github.com/xiaokanghub/Android

Basic Syntax Markdown Guide
https://www.markdownguide.org/basic-syntax/

Android App Protection (1)
https://mp.weixin.qq.com/s/tI89U6eht0F_KrMJXooo1A

siyujie_okhttp_find Search for okhttp3 based on features and use java reflection.
https://github.com/siyujie/okhttp_find/

adb - How to mount _system rewritable or read-only (RW_RO) - Android Enthusiasts Stack Exchange
https://android.stackexchange.com/questions/110927/how-to-mount-system-rewritable-or-read-only-rw-ro

How to connect Burp Suite to an Android Emulator by artx MII Cyber Security Consulting Services Medium
https://medium.com/mii-cybersec/how-to-connect-burp-suite-to-an-android-emulator-9da19b0ad2c3

[Original] null obfuscation - android security - see snow - security community _ security recruitment _ kanxue.com
https://bbs.kanxue.com/thread-247680.htm

Boutique Serial丨Android App Reverse Course No. 3 frida injected Okhttp Capture Packet Part I
https://mp.weixin.qq.com/s?__biz=Mzg3MjU3NzU1OA==&mid=2247496420&idx=1&sn=9a1460a6755524f3e22bf53878a4802c&source=41#wechat_redirect

GitHub - w296488320_NullProguard_ Blank Obfuscation source code
https://github.com/w296488320/NullProguard

https://blog.cxplay.org/works/vscode-to-markdown-editor/
将 VS Code 打造成一个体验舒适的 Markdown 编辑器 _ CXPLAY World

http://www.dtasecurity.cn:20080/androidjunior/readme.html
0822 class Course 9th : real app practice

1
2
3
4
5
6
7
8
9
10
11
12
Types, screening and treatment methods of reinforcement》
 
Confuse the development process of reinforcement technology
Identification of common obfuscation reinforcement techniques
The core principle of shelling (tooling).
Memory enumeration, trace, and visualization
Memory-based deobfuscation and feature localization
 
Example: Okhttp3 key class positioning after obfuscation
 
The so-called native is closer to the interpreter: Android native is libart.so to explain, and Linux native is CPU direct interpretation
If you want to analyze a reinforcement/protection method, you must first implement this reinforcement/protection. Look at the problem from a development perspective

Android App Protection (2)
https://mp.weixin.qq.com/s/DkpQ_71Gt-jkwOuRU1Mv0A?

DexClassLoader Android Developers
https://developer.android.com/reference/dalvik/system/DexClassLoader

Concerns about the cybersecurity industry in Japan

「onMatch function(instance){」の検索結果 - Yahoo!検索
https://
search.yahoo.co.jp/search?p=onMatch%3Afunction(instance)%7B&ei=UTF-8&ts=498&aq=-1&x=nl&rkf=1&fl=2

How many security industry researchers are there in Japan?
株式会社アクティブディフェンス研究所
http://blog.activedefense.co.jp/2021/12/fridaandroid-malwaremoqhao-xloader.html

事業概要 - 株式会社アクティブディフェンス研究所
https://www.activedefense.co.jp/consultingetc/

改竄とリバースエンジニアリング (Android)
https://github.com/coky-t/owasp-mastg-ja/blob/master/Document/0x05c-Reverse-Engineering-and-Tampering.md

Frida Tutorial 1 - HackTricks
https://book.hacktricks.xyz/v/jp/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1

Useful Words

1
2
3
4
5
Lexical Obfuscation 它们分别为符号混淆
object - code obfuscation 目标代码混淆
obfuscation tool 混淆工具
code obfuscation tool 工具
identifier renaming obfuscation 标识符重命名混淆

[注意]APP应用上架合规检测服务,协助应用顺利上架!

最后于 2024-1-19 23:02 被calleng编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
看了下,有丢失图片
2024-1-4 08:52
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3

2024-1-4 08:53
0
雪    币: 31
活跃值: (3269)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
mb_ldbucrik
这个是不要的,具体看上面代码,和下面的图片。 3 者一样, 去掉了中间。
2024-1-4 08:55
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
好的,感谢回答
2024-1-4 10:10
0
游客
登录 | 注册 方可回帖
返回
//