当前位置: 首页 > 工具软件 > LLDB > 使用案例 >

LLDB 从害怕到真香

司徒志强
2023-12-01

环境配置

  • 下载sdk
  • 下载ndk
  • lldb-server路径:sdk/lldb/3.1/android/{arch}/lldb-server
  • lldb路径:sdk\ndk\23.0.7599858\toolchains\llvm\prebuilt\windows-x86_64\bin\lldb.cmd

配置lldb-server

adb push lldb-server /data/local/tmp/
adb shell su -c 'chmod +x ./data/local/tmp/lldb-server'
adb shell su -c './data/local/tmp/lldb-server platform --listen "*:1234" --server'

方案二

adb push lldb-server /data/local/tmp/
adb shell su -c 'chmod +x ./data/local/tmp/lldb-server'
adb shell su -c './data/local/tmp/lldb-server platform --listen unix-abstract:///data/local/tmp/debug.sock --server'

配置lldb

adb forward tcp:124 tcp:1234
lldb.cmd
platform list
platform select remote-android
platform connect connect://:1234

方案二

lldb.cmd
platform list
platform select remote-android
platform connect unix-abstract-connect:///data/local/tmp/debug.sock

注入进程

platform process list
attach <pid>

获取进程pid: ps -A | grep <packageName>

具体调试

  • 常用命令:wa,image,info,br
  • 内存写入断点
watchpoint set expression -w write -- 0xe8583c00+32

其它

常用命令

  • help:查看所有帮助信息
  • apropos:查找和特定的词或主题相关的调试器命令列表
  • image list -o -f :查找所有模块基址

pycharm 导入lldb模块

ref:pycharm下设置PYTHONPATH
lldb模块路径:sdk\ndk\23.0.7599858\toolchains\llvm\prebuilt\windows-x86_64\lib\python3.9\site-packages

  • 直接在Window下python里import lldb会报找不到_lldb模块
  • 可以在msys2命令行里启动pycharm.exe,然后在pycharm里正常编写代码即可(前提需要在msys2里用pacman先安装lldb)(若是pacman报密钥错误,不要搜解决方案,解决不了的,直接删除原来msys2,再下载最新版msys2重新安装即可)(安装完成后再用pacman更新下)
  • 当然也可以再macOS里pycharm使用lldb,没什么坑

python api for lldb

ref:python-reference

pycharm 编写lldb调试代码

import os
import re
import sys
import lldb


def enter_console(command_interpreter: lldb.SBCommandInterpreter, ):
    while True:
        command = input("(lldb) ")
        if command == "q":
            return
        print(exec_lldb(command_interpreter, command))


def hexdump(command_interpreter: lldb.SBCommandInterpreter, pointer: int, size: int) -> str:
    return exec_lldb(command_interpreter, "memory read %s %s" % (pointer, pointer + size))


def get_so_base(command_interpreter: lldb.SBCommandInterpreter, so_name: str) -> int:
    result = exec_lldb(command_interpreter, "image list")
    return int(re.split(r" +", re.findall(r"\[.*?\\%s" % so_name, result)[0])[-2], 16)


def get_pointer_value(command_interpreter: lldb.SBCommandInterpreter, pointer: int) -> int:
    result = exec_lldb(command_interpreter, "memory read -fx -c1 %s" % pointer)
    print(result)
    return int(result.split(' ')[1], 16)


def exec_lldb(command_interpreter: lldb.SBCommandInterpreter, command: str) -> str:
    ci_result = lldb.SBCommandReturnObject()
    command_interpreter.HandleCommand(command, ci_result)
    process:lldb.SBProcess=command_interpreter.GetProcess()
    if not ci_result.Succeeded():
        print(ci_result)
        return ""
    return ci_result.GetOutput()


def exec_android_shell(platform: lldb.SBPlatform, command: str) -> str:
    command: lldb.SBPlatformShellCommand = lldb.SBPlatformShellCommand(command)  # (shell) android shell env
    error = platform.Run(command)
    if not error.Success():
        print(error)
        return ""
    return command.GetOutput()


def do_task(debugger: lldb.SBDebugger):
    # try:
    debugger.SetAsync(False)
    ci :lldb.SBCommandInterpreter= debugger.GetCommandInterpreter()
    plat:lldb.SBPlatform=debugger.GetSelectedPlatform()

    result = exec_android_shell(plat, "system/bin/ps -A | grep xxxxx | grep -v xxx")
    print(result)
    pid = re.split(' +', result)[1]
    exec_lldb(ci, "attach " + pid)

    base = get_so_base(ci, "libxxxxxx.so")
    print("base:", hex(base))

    # enter_console(ci)

    print(hexdump(ci,base+0xa5910,1024))

    exec_lldb(ci,"memory read %s %s -outfile ./test.bin --binary -force"%(base+0xa5910,base+0xa5910+47308*5))
    # exec_lldb(ci,"br set -a %s"%(base+0x2991c))

    # tmp=ci.GetProcess().ReadMemory(base,1000000,error)
    # print(error)
    # data=bytearray(tmp)
    # index=data.find(bytes({0x11,0x00,0x3D,0xC1}))
    # print(index)

    enter_console(ci)

    # except Exception as e:
    #     print(e)
    exec_lldb(ci, "detach")


if __name__ == '__main__':
    os.popen(
        r"D:\tool\AdbTool1.0.1\adb shell su -c './data/local/tmp/lldb-server p --server --listen unix-abstract:///data/local/tmp/debug.sock'")

    platform: lldb.SBPlatform = lldb.SBPlatform("remote-android")

    error = platform.ConnectRemote(lldb.SBPlatformConnectOptions("unix-abstract-connect:///data/local/tmp/debug.sock"))
    print(error)

    debugger: lldb.SBDebugger = lldb.SBDebugger.Create()
    debugger.SetSelectedPlatform(platform)

    do_task(debugger)

    platform.DisconnectRemote()
    platform.Clear()
    debugger.Clear()
    lldb.SBDebugger.Destroy(debugger)

lldb 调试时汇编显示错误问题

(lldb) dis -A thumb
cmd: dis -A thumb
->  0xc90701e6: mov    r6, r0
    0xc90701e8: ldr    r0, [pc, #0x3c]
    0xc90701ea: add    r0, pc
    0xc90701ec: ldr    r0, [r0]
    0xc90701ee: ldr    r0, [r0]
    0xc90701f0: cmp    r0, r6
    0xc90701f2: .short 0xbf04                    ; unknown opcode
    0xc90701f4: add    sp, #0x8
    0xc90701f6: pop    {r4, r5, r6, pc}
    0xc90701f8: movs   r0, #0x10
    0xc90701fa: .long  0xebeaf6db                ; unknown opcode
    0xc90701fe: ldr    r1, [r4, #0x4]
    0xc9070200: mov    r5, r0
    0xc9070202: mov    r2, r6
    0xc9070204: .long  0x0000f7ff                ; unknown opcode

LLDB调试尽量不要断在匿名函数上,否则容易出现异常

多个Thread被断下时如何切换线程

thread select <thread index>

image lookup 用法

(lldb) image lookup -n gaea::idl::BaseModel::Pack
cmd: image lookup -n gaea::idl::BaseModel::Pack
2 matches found in C:\Users\shlu\.lldb\module_cache\remote-android\.cache\88BCF618-38A8-E885-2B70-C424D3CDD73F-D4819735\libgaea.so:
        Address: libgaea.so[0x00191f40] (libgaea.so.PT_LOAD[0]..text + 120672)
        Summary: libgaea.so`gaea::idl::BaseModel::Pack(cmp_ctx_s*) const        Address: libgaea.so[0x00191fe4] (libgaea.so.PT_LOAD[0]..text + 120836)
        Summary: libgaea.so`gaea::idl::BaseModel::Pack(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >*) const

(lldb) image lookup -a 0xcfddd00a
cmd: image lookup -a 0xcfddd00a
      Address: libgaea.so[0x0019200a] (libgaea.so.PT_LOAD[0]..text + 120874)
      Summary: libgaea.so`gaea::idl::BaseModel::Pack(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >*) const + 38

更多

更多逆向技术交流:星球《逆向涉猎》。

参考

 类似资料: