lldb积累

lldb 真难用

# 运行

运行程序以及远程调试:

debugserver 127.0.0.1:1234 /var/containers/Bundle/Application/B1A257AC-7E38-4131-8A72-6DE17F9C2C61/Aweme.app

process connect connect://127.0.0.1:1234

# 基址相关

断点加载新 module:

breakpoint set --name _dyld_register_func_for_add_image

breakpoint set --name _dyld_image_count

查看基址:

image list -o -f|grep 'AwemeCore'

检查函数是否加载以及断点函数名:

image lookup -vn awemeMain
breakpoint set --name awemeMain

查看模块:

target modules lookup -a 0x10826ad98

# 调试操作

寄存器操作:

register read
register $x0
register write x0 0x12345678

读内存到文件:

memory read --outfile /Users/lixiangyu102/Desktop/douyin/douyin/secDump 0x0000000101e235a8 0x0000000101e23600 --force

按相关格式查看地址:

expr -l objc++ -- (id)$x0
po (id)$x0
po (Class)$x0

监视断点:

watchpoint set expression -w read -- 0x123456

watchpoint set expression -w write -- 0x123456

# 使用外部脚本

python 脚本,dump 内存

command script import /Users/lixiangyu102/Desktop/douyin/douyin/testDump.py
# 下面是 dump 内存的
import lldb
def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f read_strings.read_strings read_strings')
    print("[*started*]")
    start_address = 0x000000010826ad98
    end_address =   0x000000010862cc88
    output_file = '/Users/lixiangyu102/Desktop/douyin/douyin/testStrings.txt'
    process = debugger.GetSelectedTarget().GetProcess()
    try:
        with open(output_file, 'w') as f:
            address = start_address
            while address < end_address:
                error = lldb.SBError()
                pointer = process.ReadPointerFromMemory(address, error)
                if error.Success():
                    string = process.ReadCStringFromMemory(pointer, 256, error)
                    if error.Success():
                        f.write(f"0x{address:x} -> 0x{pointer:x}: {string}\n")
                    else:
                        f.write(f"0x{address:x} -> 0x{pointer:x}: [Failed to read string]\n")
                else:
                    f.write(f"Failed to read pointer at 0x{address:x}\n")
                address += 8  # Move to the next pointer (8 bytes for 64-bit)
    except IOError as e:
        result.SetError(f"Failed to open or write to file: {e}")

打印这个具体类具体方法的

(lldb) expr (IMP)class_getMethodImplementation((Class)objc_getMetaClass("internal_DeviceInfoZZZX"), (SEL)NSSelectorFromString(@"16923bf24c2b4257b579fcc6bffd0888720170518L"))
c
expr (IMP)class_getMethodImplementation((Class)[TTInstallIDManager class], @selector(_identifierFromFileForKey:))

获取所有已加载的类 class:

expr -- @import ObjectiveC
expr -- unsigned int outCount; Class *classes = objc_copyClassList(&outCount); for (unsigned int i = 0; i < outCount; i++) { printf("%s\n", class_getName(classes[i])); } free(classes);
expr -- @import ObjectiveC
expr -- unsigned int outCount; FILE * pFile;pFile = fopen("/tmp/test", "w"); Class *classes = objc_copyClassList(&outCount); for (unsigned int i = 0; i < outCount; i++) { fprintf(pFile,"%s\n", class_getName(classes[i])); } fflush(pFile);fclose(pFile);printf("1");free(classes);

从类名获取对象并打印结构体:

po [internal_DeviceInfoZZZX _methodDescription]
expr Class $class = objc_getClass("internal_DeviceInfoZZZX")
expr unsigned int $methodCount = 0
expr Method *$methods = class_copyMethodList($class, &$methodCount)
expr for (unsigned int $k1 = 0; $k1 < $methodCount; $k1++) { Method $method = $methods[$k1]; printf("Method address: %p\n", $method); printf("Method name: %s\n", sel_getName(method_getName($method))); printf("Method types: %s\n", method_getTypeEncoding($method)); printf("Method imp: %p\n", method_getImplementation($method)); }
expr -l objc++ -- @import ObjectiveC; {     Class cls = objc_getClass("internal_DeviceInfoZZZX");     unsigned int methodCount = 0;     Method *methods = class_copyMethodList(cls, &methodCount);     for (unsigned int i = 0; i < methodCount; i++) {         Method method = methods[i];         SEL sel = method_getName(method);         IMP imp = method_getImplementation(method);         const char *name = sel_getName(sel);         printf("Method name: %s\n", name);         printf("Method address: %p\n", (void *)imp);         printf("Method types: %s\n", method_getTypeEncoding(method));     }     free(methods); }
expr -l objc++ -- @import ObjectiveC; {     Class cls = (Class)objc_getClass("internal_DeviceInfoZZZX");     unsigned int methodCount = 0;     Method *methods = class_copyMethodList(cls, &methodCount);     for (unsigned int i = 0; i < methodCount; i++) {         Method method = methods[i];         SEL sel = method_getName(method);         IMP imp = method_getImplementation(method);         const char *name = sel_getName(sel);         printf("Method name: %s\n", name);         printf("Method address: %p\n", (void *)imp);         printf("Method types: %s\n", method_getTypeEncoding(method));     }     free(methods); }

# 批量拿方法名以及地址

import lldb
def __lldb_init_module(debugger, internal_dict):
    classnames = []
    with open('Class.txt', 'r') as f:
        for line in f:
            classnames.append(line.strip())
    output_file = "method_descriptions.txt"
    with open(output_file, "w") as f:
        pass
    # 获取命令解释器
    command_interpreter = debugger.GetCommandInterpreter()
    
    # 遍历类名并执行命令 po
    for classname in classnames:
        po_command = f'po [{classname} _methodDescription]'
        result = lldb.SBCommandReturnObject()
        command_interpreter.HandleCommand(po_command, result)
        with open(output_file, "a") as f:
            f.write(f"Class: {classname}\n")
            f.write(result.GetOutput())
            f.write("\n\n")
        if result.GetError():
            with open(output_file, "a") as f:
                f.write(f"Error for class {classname}:\n")
                f.write(result.GetError())
                f.write("\n\n")
    print(f"Results saved to {output_file}")
    print("The 'dump_methods' command has been installed. Use 'dump_methods' to run the script.")

# 初始化脚本

不会