断点调试 Android 原生共享库

逆向工程 安卓 共享对象
2021-06-30 13:02:53

我正在尝试使用动态分析方法解决 FLARE-on 2015 挑战 #06 ( http://www.flare-on.com/files/2015_FLAREOn_Challenges.zip )。这是一个加载共享库 (libval​​idate.so) 的 Android APK。我已经能够打破这个库的加载位置,但是,我似乎无法在这个库中设置其他断点,这对于解决这个挑战至关重要。

到目前为止,这是我能够做的:

*PID: 1278在我的 Android 虚拟设备 (AVD) 上启动 FLAREON android 应用程序 ( ) 并输入错误的密码以强制 libval​​idate.so 出现在加载的共享库中

*转发端口:

mobisec $ adb forward tcp:1234 tcp:1234
mobisec $ adb shell
avd # cd /data/
avd # ./gdbserver :1234 --attach 1278
Attached; pid = 1278
Listening on port 1234

*在 Mobisec 上,在另一个终端中:

mobisec # cd /opt/mobisec/Android/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/
mobisec # ./arm-linux-androideabi-gdb
(gdb) target remote :1234
Remote debugging using :1234
0xb6eca5cc in ?? ()
(gdb) set solib-search-path /data/flareon/system_lib/
[...removed...]
Reading symbols from /data/flareon/system_lib/libvalidate.so...(no debugging symbols found)...done.
Loaded symbols for /data/flareon/system_lib/libvalidate.so
[...removed...]

(gdb) info sharedlibrary 
Error reading attached process's symbol file.
com.flare_on.flare: No such file or directory.
From        To          Syms Read   Shared Object Library
[...removed...]
0xab137e20  0xab139038  Yes (*)     /data/flareon/system_lib/libvalidate.so
(gdb) 
(gdb) x/50i 0xab137e20
   0xab137e20:  ldr     r0, [pc, #4]    ; 0xab137e2c
   0xab137e24:  add     r0, pc, r0
   0xab137e28:  b       0xab137da8
   0xab137e2c:  ldrdeq  r4, [r0], -r4   ; <UNPREDICTABLE>
   0xab137e30:  cmp     r0, #0
   0xab137e34:  push    {r3, lr}
   0xab137e38:  popeq   {r3, pc}
   0xab137e3c:  blx     r0
   0xab137e40:  pop     {r3, pc}
   0xab137e44:  mov     r1, r0
   0xab137e48:  ldr     r2, [pc, #12]   ; 0xab137e5c
   0xab137e4c:  ldr     r0, [pc, #12]   ; 0xab137e60
   0xab137e50:  add     r2, pc, r2
   0xab137e54:  add     r0, pc, r0
   0xab137e58:  b       0xab137d9c
   0xab137e5c:  andeq   r4, r0, r8, lsr #3
   0xab137e60:                  ; <UNDEFINED> instruction: 0xffffffd4
   0xab137e64 <Java_com_flareon_flare_ValidateActivity_validate>:       push    {r4, r5, r6, r7, lr}
   0xab137e66 <Java_com_flareon_flare_ValidateActivity_validate+2>:
    ldr r4, [pc, #320]  ; (0xab137fa8 <Java_com_flareon_flare_ValidateActivity_validate+324>)
   0xab137e68 <Java_com_flareon_flare_ValidateActivity_validate+4>:     adds    r5, r0, #0
   0xab137e6a <Java_com_flareon_flare_ValidateActivity_validate+6>:     movs    r1, #0
   0xab137e6c <Java_com_flareon_flare_ValidateActivity_validate+8>:     add     sp, r4
   0xab137e6e <Java_com_flareon_flare_ValidateActivity_validate+10>:    str     r2, [sp, #8]
   0xab137e70 <Java_com_flareon_flare_ValidateActivity_validate+12>:    add     r0, sp, #120    ; 0x78
   0xab137e72 <Java_com_flareon_flare_ValidateActivity_validate+14>:
[...removed...]
(gdb) b Java_com_flareon_flare_ValidateActivity_validate
Breakpoint 1 at 0xab137e74
(gdb) c
Continuing.

在这个阶段,android 应用程序在我的模拟器中运行,我可以在文本字段中提供一个字符串。当我单击“验证”按钮时,应用程序冻结,因为达到了 BP:

Breakpoint 1, 0xab137e74 in Java_com_flareon_flare_ValidateActivity_validate () from /data/flareon/system_lib/libvalidate.so

但是从这里开始,我还没有找到如何继续调试,因为我所有的尝试都失败了:

(gdb) x/10i $pc
=> 0xab137e74 <Java_com_flareon_flare_ValidateActivity_validate+16>:    bl      0xab138f08
   0xab137e78 <Java_com_flareon_flare_ValidateActivity_validate+20>:
    ldr r1, [pc, #308]  ; (0xab137fb0 <Java_com_flareon_flare_ValidateActivity_validate+332>)
   0xab137e7a <Java_com_flareon_flare_ValidateActivity_validate+22>:    movs    r2, #92 ; 0x5c
   0xab137e7c <Java_com_flareon_flare_ValidateActivity_validate+24>:    add     r0, sp, #28
   0xab137e7e <Java_com_flareon_flare_ValidateActivity_validate+26>:    add     r1, pc
   0xab137e80 <Java_com_flareon_flare_ValidateActivity_validate+28>:    bl      0xab138f18
   0xab137e84 <Java_com_flareon_flare_ValidateActivity_validate+32>:    ldr     r1, [r5, #0]
   0xab137e86 <Java_com_flareon_flare_ValidateActivity_validate+34>:    movs    r3, #169        ; 0xa9
   0xab137e88 <Java_com_flareon_flare_ValidateActivity_validate+36>:    lsls    r3, r3, #2
   0xab137e8a <Java_com_flareon_flare_ValidateActivity_validate+38>:    ldr     r3, [r1, r3]
(gdb) step
Single stepping until exit from function Java_com_flareon_flare_ValidateActivity_validate,
which has no line number information.

你能帮忙吗?非常感谢您的反馈。

发表评论编辑:

感谢您对step(step out) 与si(step in) 命令的澄清,确实非常有用。也许最初的帖子不够清晰。我想要做的实际上是在代码的后面创建另一个断点,但它似乎失败了,如下所示:

(gdb) b Java_com_flareon_flare_ValidateActivity_validate
Breakpoint 1 at 0xab143e74
(gdb) c
Continuing.

Breakpoint 1, 0xab143e74 in Java_com_flareon_flare_ValidateActivity_validate () from /data/flareon/system_lib/libvalidate.so
(gdb) x/20i $pc
=> 0xab143e74 <Java_com_flareon_flare_ValidateActivity_validate+16>:    bl      0xab144f08
   0xab143e78 <Java_com_flareon_flare_ValidateActivity_validate+20>:
    ldr r1, [pc, #308]  ; (0xab143fb0 <Java_com_flareon_flare_ValidateActivity_validate+332>)
   0xab143e7a <Java_com_flareon_flare_ValidateActivity_validate+22>:    movs    r2, #92 ; 0x5c
   0xab143e7c <Java_com_flareon_flare_ValidateActivity_validate+24>:    add     r0, sp, #28
   0xab143e7e <Java_com_flareon_flare_ValidateActivity_validate+26>:    add     r1, pc
   0xab143e80 <Java_com_flareon_flare_ValidateActivity_validate+28>:    bl      0xab144f18
   0xab143e84 <Java_com_flareon_flare_ValidateActivity_validate+32>:    ldr     r1, [r5, #0]
   0xab143e86 <Java_com_flareon_flare_ValidateActivity_validate+34>:    movs    r3, #169        ; 0xa9
   0xab143e88 <Java_com_flareon_flare_ValidateActivity_validate+36>:    lsls    r3, r3, #2
   0xab143e8a <Java_com_flareon_flare_ValidateActivity_validate+38>:    ldr     r3, [r1, r3]
   0xab143e8c <Java_com_flareon_flare_ValidateActivity_validate+40>:    adds    r0, r5, #0
   0xab143e8e <Java_com_flareon_flare_ValidateActivity_validate+42>:    ldr     r1, [sp, #8]
   0xab143e90 <Java_com_flareon_flare_ValidateActivity_validate+44>:    movs    r2, #0
   0xab143e92 <Java_com_flareon_flare_ValidateActivity_validate+46>:    blx     r3
   0xab143e94 <Java_com_flareon_flare_ValidateActivity_validate+48>:    subs    r6, r0, #0
   0xab143e96 <Java_com_flareon_flare_ValidateActivity_validate+50>:
    beq.n       0xab143eac <Java_com_flareon_flare_ValidateActivity_validate+72>
   0xab143e98 <Java_com_flareon_flare_ValidateActivity_validate+52>:    bl      0xab144f28
   0xab143e9c <Java_com_flareon_flare_ValidateActivity_validate+56>:    cmp     r0, #46 ; 0x2e
   0xab143e9e <Java_com_flareon_flare_ValidateActivity_validate+58>:
    bhi.n       0xab143eac <Java_com_flareon_flare_ValidateActivity_validate+72>
   0xab143ea0 <Java_com_flareon_flare_ValidateActivity_validate+60>:    movs    r2, #0
(gdb) b 0xab143e80
Function "0xab143e80" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 2 (0xab143e80) pending.

如您所见,当我尝试在 处设置第二个 BP 时0xab143e80,它表示该函数未定义。即使我强制创建这个 BP,它也永远不会达到。

我的问题是:一旦我处于第一个断点,我该如何设置另一个断点(例如在0xab143e80)?

1个回答

回答你的第一个问题

谷歌搜索gdb step产生https://sourceware.org/gdb/onlinedocs/gdb/Continuing-and-Stepping.html作为第一个结果。从该页面:

警告:如果您step在控制位于没有调试信息的情况下编译的函数内时使用该命令,则执行将继续进行,直到控制到达具有调试信息的函数。同样,它不会进入没有调试信息编译的函数。要在没有调试信息的情况下单步执行函数,请使用如下所述的stepi命令。

由于二进制文件可能没有使用调试信息编译,因此您需要使用stepi代替step,正如@guntram-blohm 在他上面的评论中所建议的那样。

回答你的第二个问题

b 0xab143e80不是在地址上设置断点的正确语法;你需要使用b *0xab143e80.

有关用法和命令语法的更多问题,请参阅https://sourceware.org/gdb/onlinedocs/gdb/gdb