首页
社区
课程
招聘
[原创]记一次中联X科的试岗实战项目
2023-4-4 15:09 27702

[原创]记一次中联X科的试岗实战项目

2023-4-4 15:09
27702

写在前面

因为笔者在此之前完全没有安卓逆向的工作经验,所以对方在面试结束后提出远程试岗七天,从而观察笔者的工作能力,结果因为笔者设备的问题无法达到对方的要求,只能说这大概就是有缘无份吧,这里做一份零基础的总结,会一步一步记录自己踩得每一个坑以及心路历程,希望能给后来的新人()一些指引,求加精。

试岗项目

项目名称 WhatsApp插件开发
作者 刘XX
时间 2023年3月27日
机器 Nexus5、小米6X

项目内容

开发一个 xposed 插件,可以在 whatsApp 中导入通讯录功能,输入是手机号,输出是这个手机号对应的id和个人信息,对方还跟贴心的给出了项目预览图,应该是对方近期接到的项目,也可以看出对方没有白嫖我的意思。

 

**上网

首先遇到的难题就是这是个国外的 APP,需要**上网,笔者电脑端目前使用的是付费代理配合 Clash,这里就说一下在电脑上开启代理后可以科学上网之后的设置,重点在于要开启允许局域网的选项和记录端口(记住7890这个端口之后有用)

 

打开cmd命令行输入ipconfig命令查看当前电脑的ip地址,笔者电脑当前的ip为 192.168.43.208

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
Microsoft Windows [Version 10.0.19044.1288]
(c) 2019 Microsoft Corporation. All rights reserved.
 
C:\Users\Administrator>ipconfig
 
Windows IP Configuration
 
 
Ethernet adapter 以太网:
 
   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :
 
Wireless LAN adapter 本地连接* 1:
 
   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :
 
Wireless LAN adapter 本地连接* 2:
 
   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :
 
Ethernet adapter VMware Network Adapter VMnet1:
 
   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::6842:f609:4368:dd6f%8
   IPv4 Address. . . . . . . . . . . : 192.168.241.1
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :
 
Ethernet adapter VMware Network Adapter VMnet8:
 
   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::fc33:c1cf:5ea9:f741%16
   IPv4 Address. . . . . . . . . . . : 192.168.139.1
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :
 
Wireless LAN adapter WLAN:
 
   Connection-specific DNS Suffix  . : lan
   IPv6 Address. . . . . . . . . . . : 240e:36c:d9c:d300:4c18:2120:55bd:c26f
   Temporary IPv6 Address. . . . . . : 240e:36c:d9c:d300:9b4:f4ee:7eb4:ce25
   Link-local IPv6 Address . . . . . : fe80::4c18:2120:55bd:c26f%18
   IPv4 Address. . . . . . . . . . . : 192.168.43.208
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : fe80::1%18
                                       192.168.43.1
 
Ethernet adapter 蓝牙网络连接 2:
 
   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :
 
C:\Users\Administrator>

在工作机 nexus 5 上连接wifi,要和电脑连接同一个wifi(确保ip的 C 段是一致的),连接成功后修改wifi的配置选项(长按或者点右侧的小箭头),将代理改为手动,主机名设置为电脑的 ip 地址,端口设置为 clash 的端口 7890,保存成功后这部手机就也可以走电脑的clash代理科学上网。

 

关键代码定位

点开APP随便浏览了一下功能,根据对方给出的预览图,可以知道首先是需要定位这个界面的 onCreat 界面,首先考虑的就是直接搜字符串,比如“邀请使用”这四个字,但是拖入 jadx 一番搜索后什么也没有。

 

 

这时我就想到,会不是因为是国外的app,默认是英文所以没搜到,于是我把软件调整为英文,观察到英文界面存在Contants Help 等字样,并逐一进行了搜索,但依然没有结果,这里推测可能是对字符串进行了加密处理

 

 

字符串走不通就换条路,既然是定位界面,那么显然通过 adb 命令查看最上层的界面是个好办法,这里得有点耐心,多翻一翻找到 whatsapp 相关的地方,可以看到当前界面为 ACTIVITY com.whatsapp/.contact.picker.ContactPicker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
C:\Users\Administrator>adb shell dumpsys activity top
........
TASK com.whatsapp id=167 userId=0
  ACTIVITY com.whatsapp/.contact.picker.ContactPicker 9264d37 pid=4208
    Local Activity 7762ff6 State:
      mResumed=true mStopped=false mFinished=false
      mChangingConfigurations=false
      mCurrentConfig={1.0 ?mcc?mnc [zh_CN] ldltr sw392dp w392dp h714dp 440dpi nrml long port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1080, 2030) mAppBounds=Rect(0, 0 - 1080, 2030) mWindowingMode=fullscreen mActivityType=standard} s.8 themeChanged=0 themeChangedFlags=0}
      mLoadersStarted=true
      Active Fragments in 59ae076:
        #0: 05m{499b677 #0 androidx.lifecycle.LifecycleDispatcher.report_fragment_tag}
          mFragmentId=#0 mContainerId=#0 mTag=androidx.lifecycle.LifecycleDispatcher.report_fragment_tag
          mState=5 mIndex=0 mWho=android:fragment:0 mBackStackNesting=0
          mAdded=true mRemoving=false mFromLayout=false mInLayout=false
          mHidden=false mDetached=false mMenuVisible=true mHasMenu=false
          mRetainInstance=false mRetaining=false mUserVisibleHint=true
          mFragmentManager=FragmentManager{59ae076 in HostCallbacks{21522e4}}
          mHost=android.app.Activity$HostCallbacks@21522e4
          Child FragmentManager{3f9834d in 05m{499b677}}:
            FragmentManager misc state:
              mHost=android.app.Activity$HostCallbacks@21522e4
              mContainer=android.app.Fragment$1@1cc8e02
              mParent=05m{499b677 #0 androidx.lifecycle.LifecycleDispatcher.report_fragment_tag}
              mCurState=5 mStateSaved=false mDestroyed=false

在 jadx 中找到 ContactPicker 的 onCreat 方法,接下来只要直接 HOOK onCreat 方法就成功一半了

 

XPosed插件安装

xposed的开发环境配置其实我在另一篇笔记里写过,这里为了大家方便()就粘贴过来一份

环境配置

环境配置较为繁琐,分为以下步骤

  • 复制 XposedBridgeApi-82.jar 到工程中供使用

    切换至 Project 模式,在app目录下新建文件夹lib,将 XposedBridgeApi-82.jar 复制到 app/lib 文件夹下

  • 配置依赖

    • 右键工程 — Open Module Setting — Dependencies — app — Declared Dependencies — 点击加号 — JAR/ARR Dependencies
    • Step 1: lib/XposedBridgeApi-82.jar
    • Step 2:compileOnly — OK
  • 新建 Empty Activity 并在 AndroidManifest.xml 中添加代码

    1
    2
    3
    <meta-data android:name = "xposedmodule" android:value="true"/>
    <meta-data android:name = "xposeddescription" android:value="Xposed模块示例"/>
    <meta-data android:name = "xposedminversion" android:value="54"/>
  • 新建入口类 Main.java 并实现 IXposedHookLoadPackage 接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package com.example.xposeddemo;
     
    import de.robv.android.xposed.IXposedHookLoadPackage;
    import de.robv.android.xposed.callbacks.XC_LoadPackage;
     
    public class Main implements IXposedHookLoadPackage {
     
        @Override
        public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
     
        }
    }
  • 复制入口类名

    右键入口类 Main — Copy Path/Reference — Copy Reference

  • 配置入口类名文件

    app/src/main 文件夹下新建文件夹 assets,app/src/main/assets 文件夹下新建文件 xposed_init,将复制的入口类名粘贴在文件中即可

Hook函数

这里就不讲过多的理论了,jadx中右键想要hook的方法可以直接生成xposed的代码片段,这样我们就有了现成的框架

 

Main.java

1
2
3
4
5
6
7
8
9
10
11
XposedHelpers.findAndHookMethod("com.whatsapp.contact.picker.ContactPicker", classLoader, "onCreate", android.os.Bundle.class, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
    }
    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
        Log.d("lxz","hook start");
    }
});

本以为简单的hook却成了噩梦的开始,因!为!有!反!调!试!

 

反调试对抗

最开始笔者是在nexus5中直接安装的xposed框架,应该是软件检测了这个框架,在jadx中可以看到是有一个Native层AbortHook方法的

 

 

正在笔者一筹莫展的时候,对方询问了一下我的进度,好嘛,打了瞌睡就有枕头,对方直接给了反调对抗思路,那就是用面具刷edxposed

 

 

Magisk Root

刷机

  1. 进入开发者模式,打开USB调试
  2. 执行 ./adb reboot bootloader 或关机状态同时按住“音量减”和“电源”直到手机开机,进入 bootloader。
  3. 按“音量减”,直到选项移至“Recovery mode”。
  4. 按“电源”启动恢复模式。此时屏幕上会显示带有红色感叹号的 Android 机器人。
  5. 按住“电源”,在按住电源的同时,按一次“音量加”按钮,然后马上松开“电源”。
  6. 按“音量减”,选中“Wipe data/factory reset”进行双清。
  7. 刷机压缩包后解压,解压后里面的压缩包还要再解压(system.img、boot.img、recovery.img 要看到这几个文件),注意,解压出来的文件要复制到上一层目录中,不然会提示找不到文件
  8. 修改 flash-all.bat 中的 fastboot -w update image-hammerhead-lmy48b.zip 为:
    1. fastboot flash recovery recovery.img
    2. fastboot flash boot boot.img
    3. fastboot flash system system.img
  9. 清除个人数据的(双WIPE),根据个人情况上添加在 flash-all.bat 中
    1. fastboot flash cache cache.img
    2. fastboot flash userdata userdata.img
  10. 双击 flash-all.bat

我觉着在MagiskRoot前最好先刷一下机,因为这样才能保证你提取的boot文件和手机的系统是对应的,其实刷机还是蛮简单的,谷歌的手机双击bat就可以,小米手机官网有现成的刷机工具,这里就说两个坑,一个是fastboot模式中遇到 wait for devices 的问题,这其实是你的电脑还缺少一个驱动,根据我的经验,下载驱动精灵,它会提示你再安装一个驱动就可以了,另一个坑就是小米的刷机工具右下角默认是刷机后lock,这tm就简直是坑爹,记得改成双清,不然又tm把bl给锁上了(lock再刷机会有0s问题,需要重新解锁)。

提取boot.img

在官网下载手机的刷机包,反复解压,直到找到其中的boot.img文件,把这个文件拷贝到手机中

修改boot.img

在手机中安装 magisk.apk,依次点击,安装 — 选项 — 下一步 — 方式 — 选择修补一个文件 — 选择刚刚存放在手机中的 boot.img 文件 — 开始,等待执行结束你会发现在 boot.img 所在的目录中多了一个文件(有时候这个文件在电脑中看不见,在手机中重命名后就能看见了,不知道为啥),将这个文件拷贝到刷机包 boot.img 所在的目录,将刷机包原本的boot.img 重命名为 boot.img.bak ,将magisk 生成的这个文件重命名为 boot.img,此时刷机包中的 boot.img 就被 magisk 生成的 boot.img 替换了

刷入boot.img

有两种方式刷入修改后的 boot.img ,我喜欢偷懒直接刷机,毕竟点击鼠标更简单哈

  • 因为已经将刷机包中的boot.img进行了替换,所以可以简单的再重新刷一下机就可以了
  • 使用 fastboot flash boot boot.img命令仅刷入boot.img

安装edxposed

nexus5

笔者最开始使用的设备是nexus5,笔者先后经历了

  • 安卓4.4系统无法安装新版magisk(安装旧版解决)
  • 安装 riru 提示sdk版本过低(手机升级安卓6.0解决)
  • 安装新版 riru 模块需要android 8.0(安装旧版riru)
  • 找不到旧版本的 edxposed (百度了一下午的帖子,找了资源)
  • edxposed 和 riru 的版本不匹配导致安装失败(又翻了一天的帖子,找了一大堆资源挨个试)
  • 好不容易edxposed和riru都安装上了,手机重启无法开机
  • 这个安装过程大概历时三天,此时我的心态已然崩溃(因为试岗七天已经过了4天,买设备也来不及),直接开始躺平,这种状态一直持续到试岗失败,退出群聊

小米6X

事情的转机来自于我老妈说她的小米6X电池不太行了,此时的我转念一想,换个手机我手里不就有个安卓9的手机了么,就这样,小米6X就变成了我的Android逆向工程机。

 

小米6X的edxposed安装依然遇到版本问题,这里我总结一下使用的版本:

  • Magisk-v23.0.apk

  • riru-v25.4.4-release.zip

  • EdXposed-v0.5.2.2_4683-master-release.zip

  • EdXposedManager-4.6.2-46200-org.meowcat.edxposed.manager-release.apk

安装xposed插件后,可以看到此时已经成功Hook(nexus5坑我不浅!!!)

 

Xposed插件开发

此时我们先考虑在改界面添加一个TextView,那么问题就变成了获取Context的问题,根据之前学习的经验,可以通过 findAndHookConstructor来解决,下面上代码

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
package com.example.xposeddemo;
 
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.content.ContentResolver;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
 
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
 
public class Main implements IXposedHookLoadPackage {
    private String packageName = "com.whatsapp";
    private String className = packageName + ".contact.picker.ContactPicker";
    Context context;
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        hookMainAcivityInit(loadPackageParam);
        XposedHelpers.findAndHookMethod(className,
                loadPackageParam.classLoader, "onCreate", android.os.Bundle.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                Log.d("lxz", "hook start");
                //获取界面
                final Activity mActivity = (Activity) param.thisObject;
                //创建一个 TextView
                TextView textView = new TextView(context);
                // 创建布局,设置参数
                FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                // 设置控件到底端的距离
                params.bottomMargin = 100;
                // 设置控件的位置
                params.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
                // 设置控件文本
                textView.setText("hook text");
                // 添加 TextView 到 Activity 中
                mActivity.addContentView(textView,params);
            }
        });
    }
 
    private void hookMainAcivityInit(XC_LoadPackage.LoadPackageParam loadPackageParam)
    {
        String packageName = loadPackageParam.packageName;
        if(!packageName.equals(packageName))
            return;
 
        Class hookClass = XposedHelpers.findClass(
                className,loadPackageParam.classLoader);
 
        XposedHelpers.findAndHookConstructor(
                hookClass,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        super.beforeHookedMethod(param);
                        context = (Context) param.thisObject;
                    }
                }
        );
    }
}

重启手机后也如预期般的,显示了 hook text 字样

 

 

接下来我们只要遍历通讯录后把内容设置到 textView 上就可以了,这部分的内容在之前的 Android 安全笔记中也有提过,读写系统应用通讯录的ContentProvider,其重点在于以下几点:

  • 读写系统应用通讯录的ContentProvider需要权限,分别为

    android.permission.READ_CONTACTS 和 android.permission.READ_CONTACTS

  • 数据库中直接看到的 mimetype_id 项并不存在,该项为多表查询,真实字段为 mimetype,可以通过在代码中遍历列名观察到

  • mimetype 是 String类型,而不是在数据库中看到的 int 类型

  • 添加联系人时,应先在 raw_contacts 中添加一个空项,然后再在 data 中添加各种数据

  • 注意:虽然添加了读写通讯录的权限,但依然要在手机中手动配置应用读写通讯录的权限,这里我踩过坑!!!

如果不会的话请移步我之前的笔记中 ContentProvider 部分,这里我们就不啰嗦了,直接上完整代码

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package com.example.xposeddemo;
 
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.content.ContentResolver;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
 
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
 
public class Main implements IXposedHookLoadPackage {
    private String packageName = "com.whatsapp";
    private String className = packageName + ".contact.picker.ContactPicker";
    Context context;
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        hookMainAcivityInit(loadPackageParam);
        hookAnonymousInternalClass(loadPackageParam);
    }
 
    private void hookMainAcivityInit(XC_LoadPackage.LoadPackageParam loadPackageParam)
    {
        String packageName = loadPackageParam.packageName;
        if(!packageName.equals(packageName))
            return;
 
        Class hookClass = XposedHelpers.findClass(
                className,loadPackageParam.classLoader);
 
        XposedHelpers.findAndHookConstructor(
                hookClass,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        super.beforeHookedMethod(param);
                        context = (Context) param.thisObject;
                    }
                }
        );
    }
        private void hookAnonymousInternalClass(XC_LoadPackage.LoadPackageParam loadPackageParam) {
        if(loadPackageParam.packageName.equals(packageName)){
            Log.d("lxz","xposed loading");
 
            final Class<?> mMainActivity = XposedHelpers.findClass(className,loadPackageParam.classLoader);
 
            XposedHelpers.findAndHookMethod(mMainActivity, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
 
                    final Activity mActivity = (Activity) param.thisObject;
 
                    Log.d("lxz","onCreate已加载...");
 
                    // 创建一个 TextView
                    TextView textView = new TextView(context);
                    // 创建布局,设置参数
                    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                            ViewGroup.LayoutParams.WRAP_CONTENT,
                            ViewGroup.LayoutParams.WRAP_CONTENT);
                    // 设置控件到底端的距离
                    params.bottomMargin = 0;
                    // 设置控件的位置
                    params.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
 
                    List<PersonInfo> personInfoList = new ArrayList<>();
                    ContentResolver resolver = context.getContentResolver();
                    Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
                    Cursor cursor = resolver.query(uri,new String[]{"_id","display_name"},null,null,null,null);
 
                    if(cursor != null)
                    {
                        while (cursor.moveToNext())
                        {
                            int id = cursor.getInt(0);
                            String name = cursor.getString(1);
                            Log.d("lxz","id = " + id + "    name = " + name);
                            uri = Uri.parse("content://com.android.contacts/raw_contacts/"+id+"/data");
 
                            Cursor cursor2 = resolver.query(uri,new String[]{"mimetype","raw_contact_id","data1"},null,null,null,null);
                            PersonInfo personInfo = new PersonInfo();
                            while(cursor2.moveToNext())
                            {
                                String mimetype = cursor2.getString(0);
                                int raw_contact_id = cursor2.getInt(1);
                                String data1 = cursor2.getString(2);
                                Log.d("lxz", "minetype = " + mimetype + " address = " + data1);
                                personInfo.set_id(raw_contact_id);
 
                                if(mimetype.equals("vnd.android.cursor.item/phone_v2"))
                                {
                                    personInfo.setNumber(data1);
                                } else if (mimetype.equals("vnd.android.cursor.item/postal-address_v2")) {
                                    personInfo.setAddress(data1);
                                } else if (mimetype.equals("vnd.android.cursor.item/email_v2")) {
                                    personInfo.setEmail(data1);
                                } else if (mimetype.equals("vnd.android.cursor.item/name")) {
                                    personInfo.setName(data1);
                                }
                            }
                            personInfoList.add(personInfo);
                        }
                    }
 
                    String ss = new String();
                    for (PersonInfo personInfo : personInfoList)
                    {
                        Log.d("lxz",personInfo.toString());
                        ss = ss + personInfo.toString();
                    }
                    textView.setText(ss);
                    // 添加 TextView 到 Activity 中
                    mActivity.addContentView(textView,params);
                }
            });
 
        }
    }
}

重启后可以看到通讯录的详细信息已经出现在了 whatsapp 中,主体框架已经搭建完毕,剩下就是一些排版和琐碎的工作,这里就不继续演示了(毕竟已经退出群聊了,而且我发现我好像 hook 错界面了,尴尬ing…)

 

总结与收获

这次的试岗可以说收获颇丰,学习()并巩固了非常多的知识点,这都是之前逆向 creakme 不曾遇到的问题,最重要的是 whatsapp 也算是知名度较高的 app 了,今后的面试官问起来也算是有逆向分析过大型 app 的经验,而且我在这里也给新人们说一个事情,那就是面试官非常喜欢在看雪发表过优秀文章的人,就比如说我之前的帖子被加为优秀后被我写在了简历里,之后面试的每一个面试官都对这个事情非常的感兴趣,好吧,我承认是我的简历平平无奇没有别的看点,但在这里也还是希望和我一样的新人在看雪多发文章一起交流,一起进步。


阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

最后于 2023-4-7 15:04 被kanxue编辑 ,原因:
收藏
点赞9
打赏
分享
最新回复 (7)
雪    币: 500
活跃值: (1540)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
黑龙lilad 2023-4-6 04:39
2
0

最后于 2023-4-8 10:01 被黑龙lilad编辑 ,原因:
雪    币: 861
活跃值: (69)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_威郑天 2023-4-10 18:07
3
0
楼主能留联系方式吗,想和你沟通交流一下。
雪    币: 466
活跃值: (1989)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
熊趴趴来 2023-4-10 19:18
4
1
nexus系列在dalvik时代用的,现在都用pixel 系列
雪    币: 19803
活跃值: (29410)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-4-11 09:08
5
1
不强求自己
雪    币: 12142
活跃值: (15570)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
pureGavin 2 2023-4-11 09:31
6
0
感谢分享
雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
zx_958536 2023-4-12 09:39
7
0
雪    币: 2113
活跃值: (3842)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
st0ne 1 2023-4-14 07:58
8
0
感谢分享
游客
登录 | 注册 方可回帖
返回