編輯:關於Android編程
以下以adb shell下通過gdb工具調試/system/bin/ping舉例:
# /data/local/tmp/gdb --args /system/bin/ping
GNU gdb (GDB) 7.3.1-gg2
...
(gdb) info target
Symbols from "/system/bin/ping".
Local exec file:
`/system/bin/ping', file type elf32-littlearm.
Entry point: 0x1078
0x00000134 - 0x00000147 is .interp
0x00000148 - 0x00000598 is .dynsym
0x00000598 - 0x0000081e is .dynstr
0x00000820 - 0x00000a48 is .hash
0x00000a48 - 0x00000bf0 is .rel.dyn
0x00000bf0 - 0x00000db8 is .rel.plt
0x00000db8 - 0x00001078 is .plt
0x00001078 - 0x0000436c is .text
0x0000436c - 0x00004384 is .note.android.ident
0x00004384 - 0x00004454 is .ARM.exidx
0x00004454 - 0x0000446c is .ARM.extab
0x0000446c - 0x00005466 is .rodata
0x00006d40 - 0x00006d48 is .preinit_array
0x00006d48 - 0x00006d50 is .init_array
0x00006d50 - 0x00006d58 is .fini_array
0x00006d58 - 0x00006e50 is .dynamic
0x00006e50 - 0x00007000 is .got
0x00007000 - 0x000070c0 is .data
0x000070c0 - 0x0001a1ee is .bss
(gdb) b *0x1078 // 設置斷點到text段首地址
Breakpoint 1 at 0x1078
(gdb) r
Starting program: /system/bin/ping
warning: Breakpoint address adjusted from 0x40003ca5 to 0x40003ca4.
Warning:
Cannot insert breakpoint 1.
Error accessing memory address 0x1078: Input/output error.
(gdb) d 1 // 在開啟了內存布局隨機化的kernel中,必然出現上述異常,無視,直接刪掉斷點1
(gdb) info target
Symbols from "/system/bin/ping".
Unix child process:
Using the running image of child process 9782.
While running this, GDB does not access memory from...
Local exec file:
`/system/bin/ping', file type elf32-littlearm.
Entry point: 0x2a001078
0x2a000134 - 0x2a000147 is .interp
0x2a000148 - 0x2a000598 is .dynsym
0x2a000598 - 0x2a00081e is .dynstr
0x2a000820 - 0x2a000a48 is .hash
0x2a000a48 - 0x2a000bf0 is .rel.dyn
0x2a000bf0 - 0x2a000db8 is .rel.plt
0x2a000db8 - 0x2a001078 is .plt
0x2a001078 - 0x2a00436c is .text
0x2a00436c - 0x2a004384 is .note.android.ident
0x2a004384 - 0x2a004454 is .ARM.exidx
0x2a004454 - 0x2a00446c is .ARM.extab
0x2a00446c - 0x2a005466 is .rodata
0x2a006d40 - 0x2a006d48 is .preinit_array
0x2a006d48 - 0x2a006d50 is .init_array
0x2a006d50 - 0x2a006d58 is .fini_array
0x2a006d58 - 0x2a006e50 is .dynamic
0x2a006e50 - 0x2a007000 is .got
0x2a007000 - 0x2a0070c0 is .data
0x2a0070c0 - 0x2a01a1ee is .bss
........
(gdb) x/32i 0x2a001078 // 查看新text段匯編指令,尋找libc_init調用
0x2a001078: push {r11, lr}
0x2a00107c: add r11, sp, #4
0x2a001080: sub sp, sp, #16
0x2a001084: ldr r3, [pc, #80] ; 0x2a0010dc
0x2a001088: add r3, pc, r3
0x2a00108c: ldr r2, [pc, #76] ; 0x2a0010e0
0x2a001090: ldr r2, [r3, r2]
0x2a001094: str r2, [r11, #-20]
0x2a001098: ldr r2, [pc, #68] ; 0x2a0010e4
0x2a00109c: ldr r2, [r3, r2]
0x2a0010a0: str r2, [r11, #-16]
0x2a0010a4: ldr r2, [pc, #60] ; 0x2a0010e8
0x2a0010a8: ldr r2, [r3, r2]
0x2a0010ac: str r2, [r11, #-12]
0x2a0010b0: mov r2, r11
0x2a0010b4: add r2, r2, #4
0x2a0010b8: str r2, [r11, #-8]
0x2a0010bc: sub r12, r11, #20
0x2a0010c0: ldr r0, [r11, #-8]
0x2a0010c4: mov r1, #0
0x2a0010c8: ldr r2, [pc, #28] ; 0x2a0010ec
0x2a0010cc: ldr r3, [r3, r2]
0x2a0010d0: mov r2, r3
0x2a0010d4: mov r3, r12
0x2a0010d8: bl 0x2a000dcc (參見附注,r2即為main函數)
0x2a0010dc: andeq r5, r0, r0, lsl #29
0x2a0010e0: ;
0x2a0010e4: ;
0x2a0010e8: ;
0x2a0010ec: ;
0x2a0010f0: push {r11, lr}
0x2a0010f4: add r11, sp, #4
(gdb) b *0x2a0010d8
Breakpoint 2 at 0x2a0010d8
(gdb) c
Continuing.
Breakpoint 2, 0x2a0010d8 in ?? ()
(gdb) p/x $r2 // 查看main函數地址
$1 = 0x2a0017c9
(gdb) b *0x2a0017c9 //
main函數上下斷點,此時libc.so已加載,還可以b open/fputs/exit ...
warning: Breakpoint address adjusted from 0x2a0017c9 to 0x2a0017c8.
Breakpoint 3 at 0x2a0017c8
(gdb) c
Continuing.
warning: Breakpoint 3 address previously adjusted from 0x2a0017c9 to 0x2a0017c8.
Breakpoint 3, 0x2a0017c8 in ?? ()
(gdb) display /4i $pc
1: x/4i $pc
=> 0x2a0017c8: stmdb sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
0x2a0017cc: ldr.w r4, [pc, #2600] ; 0x2a0021f8
0x2a0017d0: ldr.w r3, [pc, #2600] ; 0x2a0021fc
0x2a0017d4: add r4, pc
(gdb) ni
0x2a0017cc in ?? ()
1: x/4i $pc
=> 0x2a0017cc: ldr.w r4, [pc, #2600] ; 0x2a0021f8
0x2a0017d0: ldr.w r3, [pc, #2600] ; 0x2a0021fc
0x2a0017d4: add r4, pc
0x2a0017d6: mov r6, r0
(gdb)
0x2a0017d0 in ?? ()
1: x/4i $pc
=> 0x2a0017d0: ldr.w r3, [pc, #2600] ; 0x2a0021fc
0x2a0017d4: add r4, pc
0x2a0017d6: mov r6, r0
0x2a0017d8: ldr r0, [r4, r3]
(gdb)
....
附注:
ELF可執行文件入口,__libc_init第3個參數即為main:
bionic\libc\arch-arm\bionic\crtbegin.c
__LIBC_HIDDEN__ void _start() {
......
void* raw_args = (void*) ((uintptr_t) __builtin_frame_address(0) + sizeof(void*));
__libc_init(raw_args, NULL, &main, &array);
}
gdb采用的是Android toolchain中的gdb7.3.1-gg2源碼編譯生成,編譯工具使用codesourcery的arm-none-linux-gnueabi。
首先讓大家有個全局的認識,直接上個項目,看看僅僅通過這幾行代碼,竟然就能完成如此強悍的功能。下篇再仔細講講為什麼要這麼寫。效果圖:實現了三個view間的相互滑動第一個VI
Android設置鬧鐘並不像IOS那樣這麼簡單,做過Android設置鬧鐘的開發者都知道裡面的坑有多深。下面記錄一下,我解決Android鬧鐘設置的解決方案。主要問題1、
在Android開發中,我們經常會遇到這樣一種情況:在UI界面上進行某項操作後要執行一段很耗時的代碼,比如我們在界面上點擊了一個”下載“按鈕,那麼
記錄一下微信第三方實現登錄的方法。還是比較簡單。一、必要的准備工作1.首先需要注冊並被審核通過的微信開放平台帳號,然後創建一個移動應用,也需要被審核;2.然後到資源中心下