环境

  1. sudo apt install curl
  2. sudo apt-get install openjdk-8-jdk
  3. sudo apt-get install python
  4. sudo apt-get install git
  5. sudo apt install net-tools
  6. libncurses.so.5
  7. sudo apt install libncurses*
  8. sudo apt-get install g++-multilib gcc-multilib lib32ncurses5-dev lib32z1-dev
  9. sudo apt-get install libxml2-utils

ss客户端

  1. ss客户端:
  2. https://caijinbo.tech/2020/05/07/ubuntu20.04-%E5%AE%89%E8%A3%85shadowsocks-qt5/
  3. 👆报错:
  4. ss-qt5: error while loading shared libraries: libQtShadowsocks.so.2: cannot open shared object file: No such file or directory
  5. apt install botan*
  6. 再运行即可
  7. PATH=~/bin:$PATH
  8. export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
  9. repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-8.0.0_r1

编译

  1. source build/envsetup.sh
  2. lunch 23
  3. lunch aosp_sailfish-user
  4. export LC_ALL=C
  5. vim prebuilts/sdk/tools/jack-admin
  1. vim /etc/java-8-openjdk/security/java.security
  2. 找到TLSv1这行,把TLSv1, TLSv1.1,删除后保存
  3. jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
  1. 487c487
  2. < JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME"
  3. ---
  4. > JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4096m -cp $LAUNCHER_JAR $LAUNCHER_NAME"
  1. make -j8

ubuntu adb devices 没有列表:

  1. > ls usb -> { Bus 001 Device 008: ID 18d1:4ee7 Google Inc. VMware Virtual USB Mouse }
  2. > 写入: `sudo gedit /etc/udev/rules.d/51-android.rules`
  3. SUBSYSTEM=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="4ee7", MODE="0666", GROUP="plugdev"
  4. > sudo service udev restart
  5. > sudo adb kill-server
  6. > sudo adb start-server

clion

https://android.googlesource.com/platform/build/soong/+/HEAD/docs/clion.md

  1. // 打开开关,编译时生成CMakeLists.txt
  2. export SOONG_GEN_CMAKEFILES=1
  3. export SOONG_GEN_CMAKEFILES_DEBUG=1
  4. // 全编译
  5. make -j32
  6. // 或者编译单独模块
  7. make frameworks/native/service/libs/ui
  8. // CMakeLists.txt会生成在
  9. out/development/ide/clion/frameworks/native/libs/ui/libui-arm64-android/CMakeLists.txt

https://www.jianshu.com/p/9450806f38be (生成imr,ipr)

  1. source build/envsetup.sh
  2. lunch
  3. mmm development/tools/idegen/
  4. [报错的话:] make idegen
  5. sh ./development/tools/idegen/idegen.sh

https://github.com/fashare2015/AOSP_Indexer (clion 打开android.ipr索引)

cMakeList.txt

  1. (out/development/ide/clion/cMakeList.txt)
  2. # THIS FILE WAS AUTOMATICALY GENERATED!
  3. # ANY MODIFICATION WILL BE OVERWRITTEN!
  4. # To improve project view in Clion :
  5. # Tools > CMake > Change Project Root
  6. cmake_minimum_required(VERSION 3.5)
  7. project(AOSP-Natives)
  8. # add_subdirectory(frameworks/native)
  9. add_subdirectory(art/runtime/libartd-arm64-android)
  10. # 查看是属于哪个cmakelist下面的
  11. # cd aosp/out/development/ide/clion
  12. # grep -ril interpreter
  13. # art/runtime/libartd-arm64-android/CMakeLists.txt
  14. # 就添加哪个目录同步即可

android studio


trace smali

在解释模式下,java函数的调用关系InvokeWithArgArrayjni的调用关系

  1. art/runtime/jni_internal.cc
  2. @CallObjectMethod
  3. @CallObjectMethodV
  4. @CallObjectMethodA
  5. @CallBooleanMethod
  6. @......
  7. 指向 @InvokeVirtualOrInterfaceWithVarArgs
  8. /home/zp/android/aosp/art/runtime/reflection.cc
  9. @InvokeVirtualOrInterfaceWithVarArgs
  10. @InvokeWithArgArray

static void InvokeWithArgArray(const ScopedObjectAccessAlreadyRunnable& soa, ArtMethod method, ArgArray argarray, JValue result, const char shorty) REQUIRES_SHARED(Locks::mutator_lock) { uint32_t args = arg_array->GetArray(); if (UNLIKELY(soa.Env()->check_jni)) { CheckMethodArguments(soa.Vm(), method->GetInterfaceMethodIfProxy(kRuntimePointerSize), args); } // add ArtMethod artMethod = nullptr; Thread self = Thread::Current(); const ManagedStack managedStack = self->GetManagedStack(); if( managedStack != nullptr ){ ArtMethod* tmpartmethod = managedStack->GetTopQuickFrame(); if( tmpartmethod != nullptr ){ artMethod = tmpartmethod; } } if( artMethod != nullptr ){ std::ostringstream oss; oss << “[InvokeWithArgArray]beforecall caller:” << artMethod->PrettyMethod() << “—-called:” << method->PrettyMethod(); if(strstr(oss.str().c_str(), “InvokeWithArgArrayBefore”)){ LOG(ERROR) << oss.str(); } } // add method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, shorty); // add if( artMethod != nullptr ){ std::ostringstream oss; oss << “[InvokeWithArgArray]aftercall caller:” << artMethod->PrettyMethod() << “—-called:” << method->PrettyMethod(); if(strstr(oss.str().c_str(), “InvokeWithArrayAfter”)){ LOG(ERROR) << oss.str(); } } // add }

  1. /home/zp/aosp/222/art/runtime/art_method.cc
  2. @ArtMethod::Invoke

jni 执行前,与执行结束 #jnitrace #jni的调用关系

  1. # jni 执行前
  2. art/runtime/entrypoints/quick/quick_jni_entrypoints.cc
  3. @JniMethodStart
  4. extern uint32_t JniMethodStart(Thread* self) {
  5. JNIEnvExt* env = self->GetJniEnv();
  6. DCHECK(env != nullptr);
  7. uint32_t saved_local_ref_cookie = bit_cast<uint32_t>(env->local_ref_cookie);
  8. env->local_ref_cookie = env->locals.GetSegmentState();
  9. ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
  10. // add
  11. std::ostringstream oss;
  12. oss << "[JniMethodStart]name:" << native_method->PrettyMethod().c_str() << ", addr:" << native_method->GetEntryPointFromJni();
  13. if(strstr(oss.str().c_str(), "JniMethodStartflag") != nullptr){
  14. LOG(WARNING) << oss.str();
  15. }
  16. // add
  17. if (!native_method->IsFastNative()) {
  18. // When not fast JNI we transition out of runnable.
  19. self->TransitionFromRunnableToSuspended(kNative);
  20. }
  21. return saved_local_ref_cookie;
  22. }
  23. # 执行结束
  24. art/runtime/entrypoints/quick/quick_jni_entrypoints.cc
  25. @PopLocalReferences
  26. static void PopLocalReferences(uint32_t saved_local_ref_cookie, Thread* self)
  27. REQUIRES_SHARED(Locks::mutator_lock_) {
  28. // add
  29. // jni函数执行结束以后要对局部引用删掉, 就会调用 PopLocalReferences
  30. ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
  31. std::ostringstream oss;
  32. oss << "[JniMethodEnd->PopLocalReferences]name:" << native_method->PrettyMethod().c_str() << ",addr:" << native_method->GetEntryPointFromJni();
  33. if( strstr(oss.str().c_str(), "JniMethodEndflag") != nullptr ){
  34. LOG(WARNING) << oss.str();
  35. }
  36. // add
  37. JNIEnvExt* env = self->GetJniEnv();
  38. if (UNLIKELY(env->check_jni)) {
  39. env->CheckNoHeldMonitors();
  40. }
  41. env->locals.SetSegmentState(env->local_ref_cookie);
  42. env->local_ref_cookie = bit_cast<IRTSegmentState>(saved_local_ref_cookie);
  43. self->PopHandleScope();
  44. }

registerNative 日志开启

  1. /home/zp/aosp/222/art/runtime/art_method.cc
  2. @ArtMethod::RegisterNative

const void ArtMethod::RegisterNative(const void native_method, bool is_fast) { CHECK(IsNative()) << PrettyMethod(); CHECK(!IsFastNative()) << PrettyMethod(); CHECK(native_method != nullptr) << PrettyMethod(); if (is_fast) { AddAccessFlags(kAccFastNative); } // add std::ostringstream oss; oss << “[ArtMethod::RegisterNative]” << this->PrettyMethod() << “—addr:” << native_method; if( strstr(oss.str().c_str(), “RegisterNativeflag”) != nullptr ){ LOG(ERROR)<PrettyMethod() << “—addr:” << native_method; sleep(60); } // add void new_native_method = nullptr; Runtime::Current()->GetRuntimeCallbacks()->RegisterNativeMethod(this, native_method, /out*/&new_native_method); SetEntryPointFromJni(new_native_method); return new_native_method; }

  1. ```
  2. <a name="iVlBX"></a>
  3. ### 只对感兴趣的app开启switch模式
  4. ```powershell
  5. /home/zp/aosp/222/art/runtime/interpreter/interpreter.cc
  6. @export

namespace art { // 强制开启switch模式 extern “C” void forceinterpreter(){ Runtime* runtime = Runtime::Current(); runtime->GetInstrumentation()->ForceInterpretOnly(); LOG(WARNING)<<”forceinterpreter is called”; }

  1. ```
  2. <a name="kBYfK"></a>
  3. ## 刷机
  4. ```powershell
  5. 第一次:
  6. fastboot flashing unlock
  7. fastboot flash boot boot.img
  8. fastboot flash ramdisk ramdisk.img
  9. fastboot flash ramdisk-recovery ramdisk-recovery.img
  10. fastboot flash system system.img
  11. fastboot flash userdata userdata.img
  12. fastboot flash vendor vendor.img
  13. fastboot flash system_other system_other.img
  14. fastboot reboot
  15. 第二次及以后:
  16. system.img
  17. system_other.img
  18. fastboot flash system system.img
  19. magisk root 刷机:
  20. fastboot flash boot magisk_patched-22100_eHmmC.img

fastboot devices 找不到: https://blog.csdn.net/qq_33529867/article/details/113665717

frida 脚本配合使用

  1. ///<reference path='F:\rf-android\frida\test3\u\frida-gum.d.ts'/>
  2. /*
  3. adb -s FA7130303354 root
  4. adb -s FA7130303354 shell /data/local/tmp/fri
  5. adb shell dumpsys window | findstr mCurrentFocus
  6. adb shell input text asdf & adb shell input tap 879 1671
  7. logcat -G 256m
  8. ip.tool.lu
  9. */
  10. // frida -U -F com.whatsapp.w4b -l trace.js --no-pause
  11. // frida -U -f com.whatsapp.w4b -l trace.js --no-pause
  12. // frida -U -f com.p1.mobile.putong -l trace.js --no-pause
  13. /*
  14. # 加载插件 (Wallbreaker)
  15. objection -g com.whatsapp.w4b:push explore -P E:\objplu
  16. plugin wallbreaker objectsearch com.tencent.mars.stn.StnLogic
  17. plugin wallbreaker objectdump 0x2d46
  18. objection -g com.whatsapp.w4b explore
  19. objection -g com.whatsapp.w4b explore -c xxxx.js
  20. objection -g com.whatsapp.w4b explore --startup-command 'android hooking watch xxx'
  21. android hooking search classes Interceptor
  22. android hooking watch class com.one.tomato.thirdpart.csdc.CsdcSdkUtil
  23. android hooking watch class_method okhttp3.logging.HttpLoggingInterceptor.intercept --dump-args --dump-backtrace --dump-return
  24. */
  25. function forceinterpreter()
  26. {
  27. var libartmodule = Process.getModuleByName("libart.so");
  28. var forceinterpreter_addr = libartmodule.getExportByName("forceinterpreter");
  29. console.log("forceinterpreter_addr: "+forceinterpreter_addr);
  30. var forceinterpreter = new NativeFunction(forceinterpreter_addr, "void", []);
  31. Interceptor.attach(forceinterpreter_addr, {
  32. onEnter: function(){
  33. console.log("go into forceinterpreter");
  34. },onLeave: function(){
  35. console.log("leave forceinterpreter");
  36. }
  37. })
  38. }
  39. function hookStrstr(){
  40. var libcmodule = Process.getModuleByName("libc.so");
  41. var strstr_addr = libcmodule.getExportByName("strstr");
  42. Interceptor.attach(strstr_addr, {
  43. onEnter: function(args){
  44. this.btn = false;
  45. // console.log("go into forceinterpreter");
  46. this.arg0 = ptr(args[0]).readUtf8String();
  47. this.arg1 = ptr(args[1]).readUtf8String();
  48. if( this.arg1.indexOf("InvokeWithArgArray") != -1 ){
  49. console.log("["+Process.getCurrentThreadId()+"]"+this.arg1 + "--" + this.arg0);
  50. this.btn = true;
  51. }
  52. if( this.arg1.indexOf("RegisterNative") != -1 ){
  53. console.log("["+Process.getCurrentThreadId()+"]"+this.arg1 + "--" + this.arg0);
  54. this.btn = true;
  55. }
  56. if( this.arg1.indexOf("PerformCall") != -1 ){
  57. console.log("["+Process.getCurrentThreadId()+"]"+this.arg1 + "--" + this.arg0);
  58. this.btn = true;
  59. }
  60. if( this.arg1.indexOf("JniMethodStart") != -1 ){
  61. console.log("["+Process.getCurrentThreadId()+"]"+this.arg1 + "--" + this.arg0);
  62. this.btn = true;
  63. }
  64. if( this.arg1.indexOf("JniMethodEnd") != -1 ){
  65. console.log("["+Process.getCurrentThreadId()+"]"+this.arg1 + "--" + this.arg0);
  66. this.btn = true;
  67. }
  68. },onLeave: function(retVal){
  69. if( this.btn == true ){
  70. this.context.r0 = 0x111;
  71. }
  72. // console.log("leave forceinterpreter");
  73. }
  74. })
  75. Java.perform(function(){
  76. var aaa = Java.use("java.lang.System");
  77. aaa.loadLibrary.overload('java.lang.String').implementation = function(a1){
  78. var Log = Java.use("android.util.Log")
  79. Log.e("[loadLibrary]", "re loadLibrary --------------> : " + a1);
  80. console.error("re loadLibrary --------------> : " + a1);
  81. var ret = this.loadLibrary(a1)
  82. console.log("re loadLibrary : " + ret);
  83. return ret;
  84. }
  85. })
  86. }
  87. function main(){
  88. // forceinterpreter()
  89. forceinterpreter()
  90. hookStrstr()
  91. }
  92. function print_stack(){
  93. Java.perform(function() {
  94. var Exception = Java.use("java.lang.Exception")
  95. var instance = Exception.$new("print_stack")
  96. var stack = instance.getStackTrace();
  97. console.log(stack)
  98. instance.$dispose();
  99. })
  100. }
  101. function thread_stack(This){
  102. // Module.findBaseAddress("libwhatsapp.so")
  103. console.log('thread called from:\n' +
  104. Thread.backtrace(This.context, Backtracer.ACCURATE)
  105. .map(DebugSymbol.fromAddress).join('\n') + '\n');
  106. }
  107. // dword显示
  108. function showDword(address, num, dump){
  109. if(dump) console.error( hexdump(address, {length:num*4}) );
  110. for(var i=0;i<num;i++){
  111. var ui = (i*4).toString(16);
  112. console.log("\t", "(0x"+ui+")"+"["+address.add(i*4)+"]:"+address.add(i*4).readPointer());
  113. }
  114. }
  115. function clear(){
  116. // adb shell pm clear com.whatsapp.w4b
  117. Interceptor.detachAll()
  118. }
  119. function thread_stack(This){
  120. // Module.findBaseAddress("libwhatsapp.so")
  121. console.log('thread called from:\n' +
  122. Thread.backtrace(This.context, Backtracer.ACCURATE)
  123. .map(DebugSymbol.fromAddress).join('\n') + '\n');
  124. }
  125. setTimeout(main, 1)