Skip to content

Android

CCint3 edited this page Mar 7, 2020 · 15 revisions

Andorid 打开 Url Scheme协议链接

adb shell am start -a android.intent.action.VIEW -d "snssdk1128://user/profile/3733569708763603"

Android将用户安装证书改为系统证书

mount -o remount,rw /system
ls -al /data/misc/user/0/cacerts-added/
cp /data/misc/user/0/cacerts-added/* /etc/security/cacerts/
rm /data/misc/user/0/cacerts-added/*

使Android设备通过USB联网

使用开源项目 gnirehtet

该项目的通讯方式:

  1. 手机安装该项目配套的APK,该APK会在手机上创建VPN代理,将手机发出的数据包发送到指定端口上。(有些数据包没有实现,例如ICMP,这将导致在手机上执行ping命令总是失败的)
  2. 电脑端运行该项目配套的服务,监听指定端口,等待手机VPN发送数据包过来。
  3. 电脑端服务接收请求包后再向目标IP发送请求包以获得响应。
  4. 电脑端收到目标IP的响应后再将响应发送回手机

部署步骤:

  1. 安装配套的APK

-s 84B7N16620000115:s选项允许指定一个设备序列号,在多设备同时连接时非常有用。可以通过adb devices来查看当前有哪些可用的设备。

adb -s 84B7N16620000115 install gnirehtet.apk
  1. 启动配套的APK

该命令会使用adb向指定设备发送Android Intent请求以启动APK来创建VPN代理,配套的APK是不提供界面的,只是以一个后台服务的形式运行于手机上。

并且gnirehtet start会检查手机是否安装配套APK,如果没有则调用adb install

./gnirehtet start 84B7N16620000115 -d 114.114.114.114
  1. 启动gnirehtet 服务

服务会占用一个命令行终端,使用sudo nohup xxx &的方式使它运行在后台。

服务启动后,手机即可通过USB上网。

sudo nohup ./gnirehtet relay &

通过端口转发的形式向外部提供服务

使用场景:

因各种原因导致手机WIFI无法进行网络连接或WIFI连接不稳定,导致手机无法持久的向外部提供服务。

例如:手机A原本以WIFI的形式连接到局域网,并且手机A8082端口启动了一个HTTP服务供局域网内的其他设备使用。但是手机AWIFI不稳定,不能提供持久的可靠的HTTP服务;那么通过该方法可以让手机A通过USB的方式向外部继续提供持久的可靠的HTTP服务

应用:

  1. 使手机通过USB方式联网

使用gnirehtet让手机通过USB的方式上网

  1. adb转发端口

使用adb forward --list查看已经转发的端口列表

假定手机设备在8082端口向外提供HTTP服务,并且将计算机从18082端口接收的数据转发到手机的8082端口。

执行以下命令后adb会监听18082端口,请确保18082端口是空闲状态;

adb -s 84B7N16620000115 forward tcp:18082 tcp:8082
  1. 安装rinetd端口转发工具

因为无法通过局域网直接访问adb -s 84B7N16620000115 forward tcp:18082 tcp:8082之后的18082端口,所以需要端口转发工具再转发一次

sudo apt-get install rinetd
  1. 配置rinetd
sudo vim /etc/rinetd.conf

// 在最后一行添加以下内容
0.0.0.0 10082 127.0.0.1 18082   // 将本机从10082端口接收的数据转发到本机的18082端口
  1. 启动rinetd
sudo rinetd -c /etc/rinetd.conf
  1. 关闭防火墙或添加防火墙规则

关闭防火墙,使防火墙失效,即允许所有外部连接

sudo ufw reset

添加防火墙规则,将本地端口10082暴露出去

  1. 测试端口转发是否正确

在本机执行以下命令,假定本机局域网IP地址为192.168.14.30

telnet 127.0.0.1 18082 // 测试本机18082端口是否能正常向手机的8082端口发送数据
telnet 127.0.0.1 10082 // 测试本机10082端口是否能正常向本机的18082端口发送数据
telnet 192.168.14.30 18082 // 该命令将失败,因为无法通过局域网直接访问adb转发的端口
telnet 192.168.14.30 10082 // 测试本机10082端口是否能正常向本机的18082端口发送数据

在同一局域网的其他PC中执行以下命令:

telnet 192.168.14.30 10082 // 如果该命令失败,请检查以上步骤

查找端口

  1. 通过端口号查找占用该端口号的uid

查找8081端口,对应的16进制为:0x1f91

cat /proc/net/tcp6 | grep -i 1f91
# 或者
cat /proc/net/tcp | grep -i 1f91

结果如下:

  53: 00000000000000000000000000000000:1F91 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 10080        0 300399 1 0000000000000000 99 0 0 10 -1
  1. 通过uid查找该uid对应的进程号

其中10080uidUID(10080) - 10000 = u0_a80

ps | grep u0_a80

结果如下:

结果有多个进程都是u0_a80用户创建的进程,那么8081端口就在其中一个进程中

u0_a80    9732  530   1828844 114996 SyS_epoll_ 00f734acb8 S com.ss.android.ugc.aweme:push
u0_a80    9907  530   2520916 507228 SyS_epoll_ 00f734acb8 S com.ss.android.ugc.aweme
u0_a80    10029 530   1831376 118660 SyS_epoll_ 00f734acb8 S com.ss.android.ugc.aweme:pushservice
u0_a80    10956 530   1799376 102028 SyS_epoll_ 00f734acb8 S com.ss.android.ugc.aweme:downloader
u0_a80    10968 530   1989384 173844 SyS_epoll_ 00f734acb8 S com.ss.android.ugc.aweme:miniapp0
  1. 确认uid
cat /proc/9907/cgroup

结果如下:

3:cpuset:/foreground
2:cpu:/
1:cpuacct:/uid_10080/pid_9907

dumpsys

adb shell dumpsys > dumpsys.log

打开dumpsys.log搜索(dumpsys 可用的命令如下:

ACCESSIBILITY MANAGER (dumpsys accessibility)
ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)
ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)
ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)
ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)
ACTIVITY MANAGER SERVICES (dumpsys activity services)
ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)
DISPLAY MANAGER (dumpsys display)
DREAM MANAGER (dumpsys dreams)
INPUT MANAGER (dumpsys input)
MEDIA PROJECTION MANAGER (dumpsys media_projection)
MEDIA ROUTER SERVICE (dumpsys media_router)
MEDIA SESSION SERVICE (dumpsys media_session)
POWER MANAGER (dumpsys power)
PRINT MANAGER STATE (dumpsys print)
VOICE INTERACTION MANAGER (dumpsys voiceinteraction)
WINDOW MANAGER LAST ANR (dumpsys window lastanr)
WINDOW MANAGER POLICY STATE (dumpsys window policy)
WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)
WINDOW MANAGER SESSIONS (dumpsys window sessions)
WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)
WINDOW MANAGER TOKENS (dumpsys window tokens)
WINDOW MANAGER WINDOWS (dumpsys window windows)

查找顶级Activity

adb shell dumpsys activity activities > activity_activities.log

输出格式如下:其中每个Hist代表一个Activity

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)

Display #0 (activities from top to bottom):

  Stack #4:

    Task id #144

    * TaskRecord{e98d78a #144 A=com.tencent.karaoke U=0 sz=4}
    ...
      * Hist #3: ActivityRecord{6da6fab u0 com.tencent.karaoke/.module.detail.ui.GiftBillboardActivity t144}
      ...

      * Hist #2: ActivityRecord{cea57ec u0 com.tencent.karaoke/.module.live.ui.LiveActivity t144}
      ...

      * Hist #1: ActivityRecord{840f95 u0 com.tencent.karaoke/.module.webview.ui.WebViewContainerActivity t144}
      ...

      * Hist #0: ActivityRecord{ea80b18 u0 com.tencent.karaoke/.module.main.ui.MainTabActivity t144}
      ...

关闭SELinux

project system/core/
diff --git a/init/init.cpp b/init/init.cpp
index 93fe944..acbcf66 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -913,6 +913,7 @@ static bool selinux_is_disabled(void)
 
 static bool selinux_is_enforcing(void)
 {
+    return false;
     if (ALLOW_DISABLE_SELINUX) {
         return selinux_status_from_cmdline() == SELINUX_ENFORCING;
     }

adbd 取消授权

ALLOW_ADBD_NO_AUTHro.adb.secure是且的关系,编译release版时ALLOW_ADBD_NO_AUTH被置为0;这将导致release版的ro.adb.secure无论置1还是0都是不起作用的;

diff --git a/adb/adb_main.cpp b/adb/adb_main.cpp
index 45a2158..b526c1b 100644
--- a/adb/adb_main.cpp
+++ b/adb/adb_main.cpp
@@ -239,9 +239,9 @@ int adb_main(int is_daemon, int server_port)
     // descriptor will always be open.
     adbd_cloexec_auth_socket();
 
-    if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) {
+
         auth_required = false;
-    }
+

adbd ROOT

project system/core/
diff --git a/adb/adb_main.cpp b/adb/adb_main.cpp
index 45a2158..99050db 100644
--- a/adb/adb_main.cpp
+++ b/adb/adb_main.cpp
@@ -109,6 +109,7 @@ static void drop_capabilities_bounding_set_if_needed() {
 }
 
 static bool should_drop_privileges() {
+    return false;
 #if defined(ALLOW_ADBD_ROOT)
     char value[PROPERTY_VALUE_MAX];
 
@@ -287,12 +288,12 @@ int adb_main(int is_daemon, int server_port)
 
         D("Local port disabled\n");
     } else {
-        if ((root_seclabel != NULL) && (is_selinux_enabled() > 0)) {
-            // b/12587913: fix setcon to allow const pointers
-            if (setcon((char *)root_seclabel) < 0) {
-                exit(1);
-            }
-        }
+
+
+
+
+
+
         std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
         if (install_listener(local_name, "*smartsocket*", NULL, 0)) {
             exit(1);

更改adbd的监听端口

setprop service.adb.tcp.port 5555
stop adbd
start adbd

启用/关闭开发者选项 - USB debugging

启用:setprop persist.sys.usb.config mtp,adb

关闭:setprop persist.sys.usb.config mtp

相关代码:

https://developer.android.com/reference/android/provider/Settings.Global.html#ADB_ENABLED

https://android.googlesource.com/platform/frameworks/base/+/android-4.4_r1.2/services/java/com/android/server/usb/UsbDeviceManager.java

调试启动APK

:: Example:
::   run_dbg.bat org.github.testsignal .MainActivity
@ECHO OFF
CALL :DeQuote %1
SET PACKAGE_NAME=%return%

CALL :DeQuote %2
SET ACTIVITY_NAME=%return%

adb shell am start -D %PACKAGE_NAME%/%ACTIVITY_NAME%
adb shell ps | FINDSTR %PACKAGE_NAME%
ECHO please input process id:
SET /P PID=
adb forward tcp:12346 jdwp:%PID%
jdb -connect com.sun.jdi.SocketAttach:port=12346

PAUSE
GOTO :EOF

:DeQuote
  SET return=%~1
  GOTO :EOF

logcat

android的Log.d系列日志是写在/dev/log_xxx文件中的;而/dev是挂载在tmpfs文件系统上,所以重启之后日志就消失了。参考:system/core/liblog/logd_write.csystem/core/liblog/logd_write_kern.c

logd_write

# adb shell su -c mount | grep /dev
tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,size=1424720k,nr_inodes=356180,mode=755 0 0

TWRP

TWRP模式下挂载指定分区

adb shell make /test
adb shell ls -la /dev/block/platform/soc.0/f9824900.sdhci/by-name/boot
adb shell mount /dev/block/mmcblk0p43 /test

向进程发送信号

kill()
raise(int signum)

SIGTRAP 信号的默认处理函数

linker/debugger.cpp debuggerd_signal_handler
linker.__dl__ZL24debuggerd_signal_handleriP7siginfoPv

Native

静态注册或动态注册的Native函数,第二个参数总是一个jobject,标识了调用者的信息;例如:

private native String TestNative(int arg1, int arg2, String arg3);

在frida hook时:

const nativeHook_TestNative = {
  onEnter: function (args) {
    this.env = args[0];
    //this.caller = args[1]; // jobject of the caller.
    this.arg1 = args[2];
    this.arg2 = args[3];
    this.arg3 = args[4];
    this.tag = "nativeHook_TestNative";
    this.log = "";
    const tid = gettid();
    this.log += "> - - - - tid:[" + tid + "] - - - - <\n";
    this.log += this.tag + " Enter.\n";
    this.log += "  env: " + this.env + "\n";
    this.log += "  arg1: " + this.arg1 + "\n";
    this.log += "  arg2: " + this.arg2 + "\n";
    this.log += "  arg3: " + this.arg3 + ", " + GetStringUTFChars(this.env, this.arg3, NULL).readCString() + "\n";
    console.log(this.log);
  },
  onLeave: function (ret) {
    const tid = gettid();
    this.log = this.tag + " Leave.\n";
    this.log += "  ret: " + ret + ", str:" + GetStringUTFChars(this.env, ret, NULL).readCString() + "\n";
    this.log += "^ - - - - tid:[" + tid + "] - - - - ^\n";
    console.log(this.log);
  }
};

Ubuntu 上使用 Android-SDK

  • 安装platforms时需要注意引号

    root@github:/opt/android_sdk# ./tools/bin/sdkmanager --install "platforms;android-23"
    [=======================================] 100% Unzipping... android-6.0/source.p

Hide all methods with CMAKE

在 CMAKE 中设置隐藏所有方法(不显示他们的符号);

Hide all methods without add "__attribute__(visibility("default"))" for everyone of them:

set_target_properties(YOUR_TARGET_NAME PROPERTIES CXX_VISIBILITY_PRESET hidden)
set_target_properties(YOUR_TARGET_NAME PROPERTIES C_VISIBILITY_PRESET hidden)

Fucking knack of use ollvm edition clang to compile so on Android Studio

在 Android Studio 中使用 ollvm 版本的 clang 编译 so;

​ As you know, if you just overwrite the compiler executable file with ollvm edition, then you will get "'xxx.h' file not found" error, actually I am not understand this error explicitly, because the file exactly is there, and it will perform like you want when execute that compile command on shell, so here is my approach to avoid that:

​ Open "YOUT_PROJECT_PATH\app.externalNativeBuild\cmake\debug\TARGET_ABI\rules.ninja", find the line of "rule C_COMPILER__TARGET"(TARGET mean the target name you specified by "add_library" on "CMakeLists.txt"), and you will find the path of clang executable file under it, modify it with your ollvm edition clang, then build your project as normal, you will get the ollvm compiled file.

​ 如果简单的使用 ollvm 版本的 clang.exe 等可执行文件替换掉原版 ndk toolchain 中的 exe,那么将会报一些头文件查找不到的错误,网上说的原因似乎是不同版本的 clang 将会使用的头文件有差异,然而如果在控制台中直接使用 ollvm 版本 clang 去手动执行编译命令,是可以正常编译成功得到 .o 文件的,以下是我避免该坑的方法:

​ 打开 "YOUT_PROJECT_PATH\app.externalNativeBuild\cmake\debug\TARGET_ABI\rules.ninja",找到 "rule C_COMPILER__TARGET" 这一行(TARGET 指你在 CMakeLists.txt 中使用 add_library 指定的库名),然后你会在下面几行找到编译使用的 clang 路径,把它替换为你 ollvm 版本 clang 的路径,然后正常编译即可得到你想要的 so。