1. 程式人生 > >Android 中 vector 反彙編示例

Android 中 vector 反彙編示例

前言

最近遇到一個 native crash 問題,如下所示:(Android 8.1)

Revision: '0'
ABI: 'arm64'
pid: 1863, tid: 3348, name: Binder:1863_F  >>> system_server <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8
Cause: null pointer dereference
    x0   c200007682ae00c0  x1   0000000070556938  x2   0000000000000001  x3   000000761afa89d8
    x4   00000000137
c0248 x5 0000000000000010 x6 0000000000000001 x7 0000000000000008 x8 0000000000000000 x9 238e9a517469cba9 x10 000000761afa89d4 x11 000000764e6e47b8 x12 0000000000000006 x13 0000000000000019 x14 0000000000000229 x15 0000000000000007 x16 000000761afa89d8 x17 0000000000000020 x18 0000000000000008 x19 0000000070556938 x20 0000000000000001 x21 000000761afa9588 x22 000000764eaa9300 x23 000000764eaa93f8 x24 000000764e623e73 x25 000000764e623e7b x26 0000000000000043 x27 000000761afa9588 x28 0000000000000059
x29 000000761afa88a0 x30 000000764e2dde4c sp 000000761afa8860 pc 000000764e2cae80 pstate 0000000080000000 v0 0000000000000000ffffffffffffffff v1 000000761afa90a0000000761afa9110 v2 000000000000000075636553636e7953 v3 00000000000000000000000000000000 v4 00000000000000000000000000000000 v5 00000000000000004000000000000000 v6 00000000000000000000000000000000 v7 00000000000000008020080280200802 v8 00000000000000000000000000000000 v9 00000000000000000000000000000000 v10 00000000000000000000000000000000 v11 00000000000000000000000000000000 v12 00000000000000000000000000000000 v13 00000000000000000000000000000000 v14 00000000000000000000000000000000 v15 00000000000000000000000000000000 v16 40100401401004014010040140100401 v17 80080000000000008800000000404000
v18 80000800000000000000000000000000 v19 0000000000000000d362ff28f3dabbdf v20 000000000000000000000000ebad8084 v21 000000000000000000000000ebad8085 v22 000000000000000000000000ebad8086 v23 000000000000000000000000ebad8087 v24 000000000000000000000000ebad8088 v25 000000000000000000000000ebad8089 v26 000000000000000000000000ebad808a v27 000000000000000000000000ebad808b v28 000000000000000000000000ebad808c v29 000000000000000000000000ebad808d v30 000000000000000000000000ebad808e v31 000000000000000000000000133c7810 fpsr 00000013 fpcr 00000000 backtrace: #00 pc 0000000000215e80 /system/lib64/libart.so (art::gc::Heap::FindContinuousSpaceFromObject(art::ObjPtr<art::mirror::Object>, bool) const+68) #01 pc 0000000000228e48 /system/lib64/libart.so (art::gc::Heap::IsMovableObject(art::ObjPtr<art::mirror::Object>) const+12) #02 pc 0000000000382f04 /system/lib64/libart.so (art::JNI::GetStringCritical(_JNIEnv*, _jstring*, unsigned char*)+596) #03 pc 000000000011342c /system/lib64/libandroid_runtime.so (android::android_os_Parcel_enforceInterface(_JNIEnv*, _jclass*, long, _jstring*)+76) #04 pc 0000000000cc9254 /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.app.admin.SecurityLog.readEventsOnWrapping [DEDUPED]+180) #05 pc 000000000177afc8 /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.os.Parcel.enforceInterface+56) #06 pc 00000000014f05ec /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.net.IConnectivityManager$Stub.onTransact+17724) #07 pc 00000000009c017c /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.os.Binder.execTransact+524) #08 pc 0000000000549588 /system/lib64/libart.so (art_quick_invoke_stub+584) #09 pc 00000000000dd178 /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) #10 pc 000000000046d290 /system/lib64/libart.so (art::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::ArgArray*, art::JValue*, char const*)+100) #11 pc 000000000046e718 /system/lib64/libart.so (art::InvokeVirtualOrInterfaceWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+440) #12 pc 0000000000347ed8 /system/lib64/libart.so (art::JNI::CallBooleanMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+624) #13 pc 00000000000bba88 /system/lib64/libandroid_runtime.so (_JNIEnv::CallBooleanMethod(_jobject*, _jmethodID*, ...)+120) #14 pc 000000000011f2cc /system/lib64/libandroid_runtime.so (JavaBBinder::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+156) #15 pc 000000000004ae38 /system/lib64/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+136) #16 pc 0000000000054e04 /system/lib64/libbinder.so (android::IPCThreadState::executeCommand(int)+532) #17 pc 0000000000054b40 /system/lib64/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+156) #18 pc 0000000000055178 /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+60) #19 pc 00000000000761f8 /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24) #20 pc 0000000000011460 /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+280) #21 pc 00000000000ab6a0 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140) #22 pc 0000000000067e3c /system/lib64/libc.so (__pthread_start(void*)+36) #23 pc 000000000001f280 /system/lib64/libc.so (__start_thread+68)

在反彙編 FindContinuousSpaceFromObject 方法的時候,始終理解的不太清楚,因此,使用 gdb 來輔助理解一下。因為 gdb 除錯過程當中,使用了一些 gdb 分析的常用技巧,並且新瞭解到了一些彙編知識,因此,將自己的一些收穫總結下來。(注:因為手頭的機器恰好是 Android 7.0 的,所以 gdb 除錯分析過程基於 Android 7.0,與上面的 log 略有不同)

一、FindContinuousSpaceFromObject

首先看一下 FindContinuousSpaceFromObject 方法的實現,基於 Android 7.0:
art/runtime/gc/heap.cc

space::ContinuousSpace* Heap::FindContinuousSpaceFromObject(const mirror::Object* obj,
                                                            bool fail_ok) const {
  for (const auto& space : continuous_spaces_) {
    if (space->Contains(obj)) {
      return space;
    }
  }
  if (!fail_ok) {
    LOG(FATAL) << "object " << reinterpret_cast<const void*>(obj) << " not inside any spaces!";
  }
  return nullptr;
}

二、gdb 分析過程

首先,我們需要將斷點設定在 FindContinuousSpaceFromObject 方法處,通過:

nm libart.so | grep -i FindContinuousSpaceFromObject

我們可以知道 FindContinuousSpaceFromObject 對應的 symbol 為:

_ZNK3art2gc4Heap29FindContinuousSpaceFromObjectEPKNS_6mirror6ObjectEb

通過 b 來設定斷點,continue 使程式繼續執行:
在這裡插入圖片描述
通過 disass 檢視其對應的彙編程式碼:

Dump of assembler code for function art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const:
   0x0000007fa15dd42c <+0>:	stp	x24, x23, [sp,#-64]!
   0x0000007fa15dd430 <+4>:	stp	x22, x21, [sp,#16]
   0x0000007fa15dd434 <+8>:	stp	x20, x19, [sp,#32]
   0x0000007fa15dd438 <+12>:	stp	x29, x30, [sp,#48]
   0x0000007fa15dd43c <+16>:	add	x29, sp, #0x30
   0x0000007fa15dd440 <+20>:	sub	sp, sp, #0x10
   0x0000007fa15dd444 <+24>:	adrp	x22, 0x7fa19f8000 <_ZTVN3art5arm6412Arm64ContextE+32>
   0x0000007fa15dd448 <+28>:	ldr	x22, [x22,#1368]
   0x0000007fa15dd44c <+32>:	mov	w20, w2
   0x0000007fa15dd450 <+36>:	mov	x19, x1
   0x0000007fa15dd454 <+40>:	ldr	x22, [x22]
   0x0000007fa15dd458 <+44>:	str	x22, [sp,#8]
=> 0x0000007fa15dd45c <+48>:	ldp	x23, x21, [x0]
   0x0000007fa15dd460 <+52>:	cmp	x23, x21
   0x0000007fa15dd464 <+56>:	b.eq	0x7fa15dd494 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+104>
   0x0000007fa15dd468 <+60>:	mov	x24, x23
   0x0000007fa15dd46c <+64>:	ldr	x0, [x24],#8
   0x0000007fa15dd470 <+68>:	mov	x1, x19
   0x0000007fa15dd474 <+72>:	ldr	x8, [x0]
   0x0000007fa15dd478 <+76>:	ldr	x8, [x8,#8]
   0x0000007fa15dd47c <+80>:	blr	x8
   0x0000007fa15dd480 <+84>:	and	w8, w0, #0x1
   0x0000007fa15dd484 <+88>:	tbnz	w8, #0, 0x7fa15dd530 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+260>
   0x0000007fa15dd488 <+92>:	cmp	x21, x24
   0x0000007fa15dd48c <+96>:	mov	x23, x24
   0x0000007fa15dd490 <+100>:	b.ne	0x7fa15dd468 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+60>
   0x0000007fa15dd494 <+104>:	and	w8, w20, #0x1
   0x0000007fa15dd498 <+108>:	tbz	w8, #0, 0x7fa15dd4a4 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+120>
   0x0000007fa15dd49c <+112>:	mov	x0, xzr
   0x0000007fa15dd4a0 <+116>:	b	0x7fa15dd534 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+264>
   0x0000007fa15dd4a4 <+120>:	adrp	x1, 0x7fa195e000
   0x0000007fa15dd4a8 <+124>:	add	x1, x1, #0xb83
   0x0000007fa15dd4ac <+128>:	mov	x0, sp
   0x0000007fa15dd4b0 <+132>:	mov	w2, #0x515                 	// #1301
   0x0000007fa15dd4b4 <+136>:	orr	w3, wzr, #0x6
   0x0000007fa15dd4b8 <+140>:	mov	w4, #0xffffffff            	// #-1
   0x0000007fa15dd4bc <+144>:	bl	0x7fa14be818 <art::LogMessage::LogMessage(char const*, unsigned int, art::LogSeverity, int)>
   0x0000007fa15dd4c0 <+148>:	mov	x0, sp
   0x0000007fa15dd4c4 <+152>:	bl	0x7fa14be810 <art::LogMessage::stream()>
   0x0000007fa15dd4c8 <+156>:	adrp	x21, 0x7fa195f000
   0x0000007fa15dd4cc <+160>:	add	x21, x21, #0x806
   0x0000007fa15dd4d0 <+164>:	mov	x20, x0
   0x0000007fa15dd4d4 <+168>:	orr	w1, wzr, #0x8
   0x0000007fa15dd4d8 <+172>:	mov	x0, x21
   0x0000007fa15dd4dc <+176>:	bl	0x7fa1497b00 <[email protected]>
   0x0000007fa15dd4e0 <+180>:	mov	x2, x0
   0x0000007fa15dd4e4 <+184>:	mov	x0, x20
   0x0000007fa15dd4e8 <+188>:	mov	x1, x21
   0x0000007fa15dd4ec <+192>:	bl	0x7fa14b5c74 <std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long)>
   0x0000007fa15dd4f0 <+196>:	mov	x1, x19
   0x0000007fa15dd4f4 <+200>:	bl	0x7fa14b5abc <std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(void const*)>
   0x0000007fa15dd4f8 <+204>:	adrp	x20, 0x7fa195f000
   0x0000007fa15dd4fc <+208>:	add	x20, x20, #0x80e
   0x0000007fa15dd500 <+212>:	mov	x19, x0
   0x0000007fa15dd504 <+216>:	orr	w1, wzr, #0x18
   0x0000007fa15dd508 <+220>:	mov	x0, x20
   0x0000007fa15dd50c <+224>:	bl	0x7fa1497b00 <[email protected]>
   0x0000007fa15dd510 <+228>:	mov	x2, x0
   0x0000007fa15dd514 <+232>:	mov	x0, x19
   0x0000007fa15dd518 <+236>:	mov	x1, x20
   0x0000007fa15dd51c <+240>:	bl	0x7fa14b5c74 <std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std