首页
社区
课程
招聘
[分享] 安卓逆向课题之5, mobile spider get started. 两天高度集中学习, 承上启下的流程,a明白,b上手练.(5th完结)
2023-11-7 04:18 2817

[分享] 安卓逆向课题之5, mobile spider get started. 两天高度集中学习, 承上启下的流程,a明白,b上手练.(5th完结)

2023-11-7 04:18
2817

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

[原创] 肉丝的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


源码,以及Jeb,jadx 反编译的源码对比

Jeb 给出了 editText 资源的位置.对象的位置

picture 0

jadx 相同的对象, editText 资源的位置, 只是分离显示,一个商业软件, 一个免费软件的差异.

picture 1

picture 2

ID资源会放在 Resources.arsc 里面 ( 上图 )

app-debug.apk source code in Android Studio

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
package com.example.myapplication1105;
 
import androidx.appcompat.app.AppCompatActivity;
 
import android.os.Bundle;
import android.util.Base64;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
 
public class MainActivity extends AppCompatActivity {
 
    EditText username_et;
    EditText password_et;
    TextView message_tv;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        password_et = (EditText) this.findViewById(R.id.editText2);
        username_et = (EditText) this.findViewById(R.id.editText);
        message_tv = ((TextView) findViewById(R.id.textView));
        this.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (username_et.getText().toString().compareTo("admin") == 0) {
                    message_tv.setText("You cannot login as admin");
                    return;
                }
                //hook target
                message_tv.setText("Sending to the server :" + Base64.encodeToString((username_et.getText().toString() + ":" + password_et.getText().toString()).getBytes(), Base64.DEFAULT));
 
            }
        });
    }
}

app-debug.apk Decompile code in JEB

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
package com.example.myapplication1105;
 
import android.os.Bundle;
import android.util.Base64;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
 
public class MainActivity extends AppCompatActivity {
    TextView message_tv;
    EditText password_et;
    EditText username_et;
 
    @Override  // androidx.fragment.app.FragmentActivity
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(0x7F0B001C);  // layout:activity_main
        this.password_et = (EditText)this.findViewById(0x7F080098);  // id:editText2
        this.username_et = (EditText)this.findViewById(0x7F080097);  // id:editText
        this.message_tv = (TextView)this.findViewById(0x7F080181);  // id:textView
        this.findViewById(0x7F080058).setOnClickListener(new View.OnClickListener() {  // id:button
            @Override  // android.view.View$OnClickListener
            public void onClick(View v) {
                if(MainActivity.this.username_et.getText().toString().compareTo("admin") == 0) {
                    MainActivity.this.message_tv.setText("You cannot login as admin");
                    return;
                }
 
                MainActivity.this.message_tv.setText("Sending to the server :" + Base64.encodeToString(MainActivity.this.username_et.getText().toString() + ":" + MainActivity.this.password_et.getText().toString().getBytes(), 0));
            }
        });
    }
}

通过对比, Jeb编译代码和source code 接近90%相同


病毒代码对比

GDA 4.10 的对比,

picture 3

在app入口的 代码的解释

picture 4

对比, jeb/jadx/jda class name 命名差别不大

picture 5
picture 6
picture 8

kali must install chinese font. font will display currect.

use jeb , decompile, MainActivity(). the key comment after code per line.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MainActivity extends Activity {
    // 定义名为 MainActivity 的 Java 类,继承自 Android 的 Activity 类
 
    @Override
    // 标注,表示该方法是对父类方法的重写
    protected void onCreate(Bundle arg14) {
        // 在 Android 活动的生命周期方法 onCreate 中,当活动被创建时调用
        LogCatBroadcaster.start(this); // 调用 LogCatBroadcaster 类的 start 方法,可能用于日志记录
        super.onCreate(arg14); // 调用父类的 onCreate 方法,执行一些默认初始化
        this.startService(new Intent(this, MyServiceOne.class));
        // 启动名为 MyServiceOne 的服务,使用 Intent 对象标识要启动的服务
    }
}

所有核心逻辑全部都在--com.shimeng.qq2693533893 的-- MyServiceOne(class) 这个类里面.

picture 9

picture 10

恶意代码中找到,修改系统的配置,太黑了.

picture 11
picture 12
picture 13

又是上述3项对比

静态, 动态,要一起看.

手工脱壳,基本不可用, win时代可以, 现在基本都是 自动脱壳机,修改ART的源码.
vmp 确实是手脱.

调试病毒

APP启动后,usb 被强制断开

picture 14

管理 android虚拟机的快照功能.

picture 15
picture 16
picture 17

如果需要还原,
点击关闭窗口,即可恢复快照.
picture 18

picture 19

运行如下命令即可 启动恢复好的环境.

picture 21

1
"C:\Program Files\Genymobile\Genymotion\player.exe" --vm-name 706eac57-e1eb-4541-9a75-242d5a7ae25e --resume

picture 20

函数解析 USBLock( )函数

picture 22

代码解释如下

picture 23

目前的分析状态就是在有source code 基础上的分析.

picture 24

在royuse的课程分析中, 变量 v8, intent 2, intent12,没有一个是对的, 在 3年后的今天, 在 jeb 2022版本中,改进了, 课程中出现的 问题, 解析明确. 上图中,已经明显没了课程中的错误.

反编译

picture 25

问题依旧, 只能作为参考.

使用Frida 打印 Intent 内容

picture 26

决定都是hook, 看他有没有经过这里, 动态hook时候, 的参数,调用栈,返回值, print 出来, 才是真的结果.

通过注册自己的启动信号到系统的广播事件, 功能如下.

picture 27

你掌握的技能,(目前知道这个软件源代码的情况下,你需要能够开发出这个勒索软件)你才能真正掌握他的构成.

首先,你能开发一个恶意app ,你才能开发他的hook.
你能开发他的hook ,你就能控制他的所有行为了.

本地安装termux su root, 下 执行 frida-server. 通过ip链接.不会收到病毒影响. 绕过adb

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
vbox86p:/data/local/tmp # ./frida-server-15.2.2-android-x86  --help
Usage:
  frida [OPTION?]
 
Help Options:
帮助选项:
  -h, --help                            Show help options 显示帮助选项
 
Application Options:
应用程序选项:
  --version                             Output version information and exit
  显示版本信息并退出
 
  -l, --listen=ADDRESS                  Listen on ADDRESS
  在 ADDRESS 上监听
  --certificate=CERTIFICATE             Enable TLS using CERTIFICATE
  使用 CERTIFICATE 启用 TLS
  --origin=ORIGIN                       Only accept requests with ?Origin? header matching ORIGIN (by default any origin will be accepted)
  仅接受具有匹配 ORIGIN 的 "Origin" 标头的请求(默认情况下,将接受任何来源)
  --token=TOKEN                         Require authentication using TOKEN
  要求使用 TOKEN 进行身份验证
  --asset-root=ROOT                     Serve static files inside ROOT (by default no files are served)
  提供 ROOT 内的静态文件(默认情况下不提供文件)
  -d, --directory=DIRECTORY             Store binaries in DIRECTORY
  将二进制文件存储在 DIRECTORY 中
  -D, --daemonize                       Detach and become a daemon 
  分离并成为守护进程
  --policy-softener=system|internal     Select policy softener 
  选择策略软化器
  -P, --disable-preload                 Disable preload optimization
  禁用预加载优化
  -C, --ignore-crashes                  Disable native crash reporter integration
  禁用本地崩溃报告程序集成
  -v, --verbose                         Be verbose
  显示详细信息
1
2
./frida-server-15.2.2-android-x86 -l 0.0.0.0:8888 //代表监听所有地址本地和公网的8888端口
//服务端操作
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
└─# objection --help
Usage: objection [OPTIONS] COMMAND [ARGS]...
 
       _   _         _   _
   ___| |_|_|___ ___| |_|_|___ ___
  | . | . | | -_|  _|  _| | . |   |
  |___|___| |___|___|_| |_|___|_|_|
        |___|(object)inject(ion)
   
       Runtime Mobile Exploration
          by: @leonjza from @sensepost
 
  By default, communications will happen over USB, unless the --network option
  is provided.
 
Options:
  -N, --network            Connect using a network connection instead of USB.
  -h, --host TEXT          [default: 127.0.0.1]
  -p, --port INTEGER       [default: 27042]
  -ah, --api-host TEXT     [default: 127.0.0.1]
  -ap, --api-port INTEGER  [default: 8888]
  -g, --gadget TEXT        Name of the Frida Gadget/Process to connect to.
                           [default: Gadget]
  -S, --serial TEXT        A device serial to connect to.
  -d, --debug              Enable debug mode with verbose output. (Includes
                           agent source map in stack traces)
  --help                   Show this message and exit.
 
Commands:
  api          Start the objection API server in headless mode.
  device-type  Get information about an attached device.
  explore      Start the objection exploration REPL.
  patchapk     Patch an APK with the frida-gadget.so.
  patchipa     Patch an IPA with the FridaGadget dylib.
  run          Run a single objection command.
  signapk      Zipalign and sign an APK with the objection key.
  version      Prints the current version and exists.

objection 的链接方法

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
objection -N -h 192.168.31.35 -p 8888 -g com.android.settings explore
 
adb connect 192.168.31.35
 
vbox86p:/ # ps -e | grep -i frid
root          8014  2644   64896  46392 poll_schedule_timeout f17dabb9 S frida-server-15.2.2-android-x86
 
vbox86p:/ # netstat -tunlp | grep -i frida
tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      8014/frida-server-15.2.2-android-x86
tcp        0      0 192.168.31.35:8888      192.168.31.81:44284     ESTABLISHED 8014/frida-server-15.2.2-android-x86
 
vbox86p:/ # netstat -aple | grep frida
tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      root       67365       8014/frida-server-15.2.2-android-x86
tcp        0      0 192.168.31.35:8888      192.168.31.81:44284     ESTABLISHED root       66512       8014/frida-server-15.2.2-android-x86
unix  3      [ ]         STREAM     CONNECTED        67377 8014/frida-server-1@/data/local/tmp/re.frida.server/pipe-094e09da4080d0b09b2dd8a9f89d22a7
unix  3      [ ]         STREAM     CONNECTED        67419 8014/frida-server-1
unix  3      [ ]         STREAM     CONNECTED        67375 8014/frida-server-1@/data/local/tmp/re.frida.server/pipe-c46232b81779e52cfde9e28c56dfb8f1
 
vbox86p:/ # lsof -p 8014  | grep 8888                                                                                                                 
frida-ser  8014       root    7u     IPv4                          0t0      67365 TCP :8888->:0 (LISTEN)
frida-ser  8014       root    8u     IPv4                          0t0      66512 TCP :8888->:44284 (ESTABLISHED)
 
vbox86p:/ # netstat -tulp | grep frida                                                                                                                
tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      8014/frida-server-15.2.2-android-x86
tcp        0      0 192.168.31.35:8888      192.168.31.81:44284     ESTABLISHED 8014/frida-server-15.2.2-android-x86

picture 28

反向查找开放的端口(特定的APP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
./frida-server-15.2.2-android-x86 -l 0.0.0.0 //代表监听所有地址本地和公网的默认端口
//服务端操作
 
vbox86p:/ # netstat -tulp | grep frida                                                                                                                
tcp        0      0 0.0.0.0:27042           0.0.0.0:*               LISTEN      12098/frida-server-15.2.2-android-x86
// find the listenning port is 27042
 
vbox86p:/ # ps -e | grep -i frida
root         12098  2644   56588  44860 poll_schedule_timeout f6cbbbb9 S frida-server-15.2.2-android-x86 // find the process ID
 
vbox86p:/ # netstat -tunlp | grep frida
tcp        0      0 0.0.0.0:27042           0.0.0.0:*               LISTEN      12098/frida-server-15.2.2-android-x86 // find the process port
 
vbox86p:/ # lsof -p 12098 | grep TCP                                                                                                                  
frida-ser 12098       root    7u     IPv4                          0t0      73142 TCP :27042->:0 (LISTEN) // Filter the port of Frida-server.
 
未知的app得到它监听的端口, 通过这样的方法.

启动恶意 app 后 USB被强制断开

picture 29

picture 30

Package Name: com.shimeng.qq2693533893

根据进程名开始hook

晕, 怎么没有进程名?
picture 32

恶意app 还在跑呀.
picture 31

picture 33
picture 34
跑起来了.

picture 35

1
2
3
┌──(root㉿r0env)-[~]
└─# objection -N -h 192.168.31.202  -g  com.shimeng.qq2693533893  explore -P ~/.objection/plugins
// load hluwa"s plugins for Frida.

picture 36

picture 37

picture 38

trace特定的class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
com.shimeng.qq2693533893 on (Google: 8.1.0) [net] # plugin wallbreaker classdump com.shimeng.qq2693533893.MyBroadcast --fullname
 
package com.shimeng.qq2693533893
 
class MyBroadcast {
 
    /* static fields */静态字段   注册了一个启动完成之后, [需要开发经验]
    static java.lang.String ACTION; => android.intent.action.BOOT_COMPLETED
 
    /* instance fields */ 实例字段
 
    /* constructor methods */ 构造函数方法
    com.shimeng.qq2693533893.MyBroadcast();
 
    /* static methods */ 静态方法
 
    /* instance methods */ 实例方法
    void onReceive(android.content.Context, android.content.Intent);
 
}

重点关注 onReceive 方法

依然和 MyServices 方法关联
picture 39

1
com.shimeng.qq2693533893 on (Google: 8.1.0) [net] # plugin wallbreaker classdump com.shimeng.qq2693533893.MyServiceOne --fullname

picture 40

Tracer功能就是 跟踪按钮 点击后, 调用了哪些 function.
Trace 他的执行路径. 通过静态和动态分析确定他的主要逻辑在哪里?

最后还需要验证,
就是将这个类给hook上, 主要功能就在 MyServicesOne里面.

picture 41

于是将此类的所有方法都 hook 上了.

picture 42

hook 大意, 在函数上挂了个钩子, 只要函数执行一次, 就会有个记录.
钩子可以把 参数替换掉, 返回值可以替换掉, 钩子也可以把调用栈打映出来.
从哪里到这里的 调用栈 print 出来.

如果不懂,加上调用栈,

1
android hooking watch class com.shimeng.qq2693533893.MyServiceOne --dump-backtrace

picture 43

探测这个类是从哪里过来被调用的.

1
2
android hooking watch class com.shimeng.qq2693533893.MyServiceOne.access$L1000018 --dump-
backtrace

picture 44

修改如下

1
2
android hooking watch class_method  com.shimeng.qq2693533893.MyServiceOne.access$L1000018
 --dump-backtrace

picture 45

擦找 100018 是什么?

1
2
3
4
5
6
7
8
9
10
11
(agent) [415183] Called com.shimeng.qq2693533893.MyServiceOne.access$L1000018(com.shimeng.qq2693533893.MyServiceOne)
(agent) [415183] Backtrace:
    com.shimeng.qq2693533893.MyServiceOne.access$L1000018(Native Method)
    com.shimeng.qq2693533893.MyServiceOne$100000007.run(MyServiceOne.java:309)
    android.os.Handler.handleCallback(Handler.java:790)
    android.os.Handler.dispatchMessage(Handler.java:99)
    android.os.Looper.loop(Looper.java:164)
    android.app.ActivityThread.main(ActivityThread.java:6494)
    java.lang.reflect.Method.invoke(Native Method)
    com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

第一个可疑函数 com.shimeng.qq2693533893.MyServiceOne.access$L1000018**
第二个可疑函数com.shimeng.qq2693533893.MyServiceOne$100000007

picture 46

一下是代码解读

1
2
3
4
5
6
7
8
9
MyServiceOne.this.hand2.postDelayed(this, 1800L);:在 MyServiceOne 实例的 hand2 上使用 postDelayed 方法,定时执行当前的 Runnable 实例(即自身),间隔为 1800 毫秒。
 
AudioManager v1 = (AudioManager)MyServiceOne.this.getSystemService("audio");:获取应用程序的音频管理器。
 
v1.setStreamVolume(3, v1.getStreamMaxVolume(3), 4);:设置第 3 个音频流的音量为最大值。
 
v1.getStreamMaxVolume(0); 和 v1.getStreamVolume(0);:获取第 0 个音频流的最大音量和当前音量。
 
((Vibrator)MyServiceOne.this.getApplication().getSystemService("vibrator")).vibrate(new long[]{100L, 1500L, 100L, 1500L}, -1);:使用应用程序的振动器服务(Vibrator)执行振动,传递了振动模式和振动重复次数。

这里就找到了嫌疑.

picture 47

picture 48

picture 49

下一步确认解密的地方.

继续hook 该类下 ,所有的方法.

1
com.shimeng.qq2693533893 on (Google: 8.1.0) [net] # android hooking watch class com.shimeng.qq2693533893.MyServiceOne

picture 50

以便于 点击按钮,监控调用栈

通过调用栈知道是音量的+ 号.

picture 51

picture 52

显示的调用栈,
picture 53

代表了调用两次流程.

经过了这类的方法体,他的执行流程,

picture 54

picture 55

通过过滤得到

picture 56

picture 57

在 Jadx-gui 中 执行流程基本一致

picture 58

判断第一个函数 ”颜如玉“ 是从哪里调用过来的.

从新开一个 objection 进程,探测一个类的名字.

1
2
3
4
objection -N -h 192.168.31.202  -g  com.shimeng.qq2693533893  explore -P ~/.objection/plugins
 
android hooking watch class_method com.shimeng.qq2693533893.MyServiceOne.颜如玉 --dump-ar
gs --dump-backtrace --dump-return

picture 59

验证猜想

输入 2009 , 再次点击, 出现了调用栈

picture 60

难道从 100000xxx 0002过来的?

picture 61

picture 62

其实就是一个匿名的内部类.
New onClick. 就是一个内部类.

picture 63

100000002代码的定义

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
class 100000002 implements View.OnClickListener {
    // 私有成员变量
    private final MyServiceOne this$0// 引用 MyServiceOne 类的实例
    private final TextView val$a00;
    private final TextView val$b00;
    private final Button val$button;
    private final TextView val$c00;
    private final TextView val$d00;
    private final EditText val$editText;
    private final TextView val$lpo;
    private final TextView val$textView2;
    private final int val$诗梦;
 
    // 构造函数,用于初始化成员变量
    100000002(EditText arg16, int arg17, TextView arg18, Button arg19, TextView arg20, TextView arg21, TextView arg22, TextView arg23, TextView arg24) {
        this.val$editText = arg16;
        this.val$诗梦 = arg17;
        this.val$lpo = arg18;
        this.val$button = arg19;
        this.val$textView2 = arg20;
        this.val$a00 = arg21;
        this.val$b00 = arg22;
        this.val$c00 = arg23;
        this.val$d00 = arg24;
    }
 
    // 静态方法,用于获取 MyServiceOne 实例
    //关键的参数还是冲这里传递过来的.
    //关键的参数还是冲这里传递过来的.
    static MyServiceOne access$0(100000002 arg4) {
        return MyServiceOne.this;   // 通过此方法获取 MyServiceOne 实例
    }
    //关键的参数还是冲这里传递过来的.
    //关键的参数还是冲这里传递过来的.
 
    @Override
    public void onClick(View arg15) {
        // 获取输入框文本并进行处理
        String v2 = this.val$editText.getText().toString();
        if (v2.length() >= 3) {
            // 调用颜如玉方法进行处理, //从这里调用的颜如玉的方法//从这里调用的颜如玉的方法
            String v3 = MyServiceOne.颜如玉(颜如玉QQ2693533893.getSaltMD5("" + this.val$诗梦/*初始化函数*/)).replaceAll("\\D+", "");//从这里调用的颜如玉的方法
 
            // 若满足条件,执行以下操作
            if (v3.length() > 9 && v3.length() > 3) {
                StringBuffer v6 = new StringBuffer();
                StringBuffer v7 = new StringBuffer().append("9DDEB743E935CE399F1DFAF080775366");
                // 比较字符串, 如果success, 解除锁定.
                if (v6.append(颜如玉QQ2693533893.getSaltMD5(MyServiceOne.颜如玉(v2.substring(0, 3))))
                        .append(v2.substring(3, v2.length())).toString()
                        .equals(v7.append(v3.substring(0, 9)).toString())) {
                    // 调用 MyServiceOne 实例的方法
                    MyServiceOne.this.util.removeView();
                    MyServiceOne.this.sm2(); //识别码
                    return;
                }
 
                --MyServiceOne.this.L;
                ++MyServiceOne.this.B;
                // 设置文本内容
                this.val$lpo.setText("很抱歉!密码错误解锁请加QQ群:437732815联系管理员购买正确的密码解锁...密码以错"
                        + MyServiceOne.this.B + "次!" + "还剩" + MyServiceOne.this.L + "次输入错误密码的机会");
                if (MyServiceOne.this.L <= 0) {
                    this.val$lpo.setText("本次输入密码错误次数累计以达10次,请重启手机后获取输入密码机会!");
                    this.val$button.setVisibility(8);
                    this.val$textView2.setVisibility(8);
                    this.val$editText.setVisibility(8);
                    this.val$a00.setVisibility(8);
                    this.val$b00.setVisibility(8);
                    this.val$c00.setVisibility(8);
                    this.val$d00.setVisibility(8);
                    return;
                }
            }
        }
    }
}

picture 64

搜索字符串是纯粹碰运气

"解除锁定" 搜索不到
“识别码” 搜索到

picture 65

搜索字符串是纯粹碰运气,
以上的流程才是科学的方法. 你经过哪个class ,从这个class print BackTrace. 一步一步来,往上搜索. 搜到真正调用的地方. 这才是真正科学的方法.

内存是不会骗人的.

可以看到每个反编译, Decompile Application, 都有自己的想法.

病毒,其实把所有的逻辑都写在了services里面.

总结

Xpose 可以hook系统启动的一些的函数, 可以随着ART一起启动.
Frida 做不到. 必须手动启动.

Xpose 天生和系统集成的.
静态分析是辅助.
动态分析是主力.

Jar 包的概念.
编写插件时候,需要引入一个依赖.
会有一个 XposedBridge 的 jar 包.

app 开发时候,总是需要引入第三方 动态库, 本质是一个jar包.

你开发的所有组件不可能自己去写, 而是寻找有些的框架,节省开发时间.

Jar包是有 source code 的.

一定要懂开发, 否则后面寸步难行.

图片动态加载, 一致加载, 就不用看了.

source code is open source. 那就不用看了.

com.google.android.exoplayer2.source这样的包名的组件就不用看了.

开发的高度决定逆向的高度

《android软件安全权威指南》


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-1-19 23:03 被calleng编辑 ,原因: 编辑 样式, 修改标题和结构
收藏
点赞0
打赏
分享
最新回复 (2)
雪    币: 19410
活跃值: (29069)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-11-7 17:38
2
1
感谢分享
雪    币: 80
活跃值: (2516)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
calleng 2023-11-7 22:45
3
0

更新完毕, 学习可以博大精深.体验相当好.不亚于, 交钱3万的课程. 

# 参考  AD 附上 , (抄自肉丝的课)


狗皮膏药       




最后于 2023-11-7 23:35 被calleng编辑 ,原因:
游客
登录 | 注册 方可回帖
返回