Best Python code snippet using avocado_python
vmlinux.py
Source:vmlinux.py  
...76    # Cleanup? shouldn't be necessary77    jitter.vm.set_exception(0)78    jitter.vm.reset_memory_access()79    return True80def miasm_load_vmlinux(kallsyms, vmlinux):81    global g_machine82    global g_code_size83    global g_jitter84    global g_cpu85    if kallsyms['arch'] == 'arm':86        g_cpu = "arml"87    elif kallsyms['arch'] == 'arm64':88        g_cpu = "aarch64l"89    else:90        raise Exception('Invalid arch')91    g_machine = Machine(g_cpu)92    g_jitter = g_machine.jitter('gcc')93    start_addr = kallsyms['_start']94    g_code_size = ((len(vmlinux) + 0x1000) >> 12 << 12)95    g_code_size += 0x8000000    # bss96    end_addr = start_addr + g_code_size97    print_log("[+]mapping %s - %s" % (hex(start_addr), hex(end_addr)))98    g_jitter.vm.add_memory_page(start_addr, PAGE_READ|PAGE_WRITE, b"\x00"*g_code_size, "code page")99    g_jitter.vm.set_mem(kallsyms['_start'], vmlinux)100    # stack101    g_jitter.vm.add_memory_page(0xdead1000, PAGE_READ|PAGE_WRITE, b"\x00"*0x2000, "stack")102def miasm_set_mem(addr, body):103    global g_machine104    global g_jitter105    assert(len(body) <= 4096)106    all_mem = g_jitter.vm.get_all_memory()107    is_mapped = False108    for start in all_mem.keys():109        # print_log("%s: %d" % (hex(addr), all_mem[addr]['size']))110        if addr >= start and addr < (start + all_mem[start]['size']):111            is_mapped = True112            break113    if not is_mapped:114        g_jitter.vm.add_memory_page(addr, PAGE_READ|PAGE_WRITE, b"\x00"*0x1000, "data")115    print_log('[+]set memory content @ %s' % (hex(addr)))116    g_jitter.vm.set_mem(addr, body)117def get_mem_access(kallsyms, sym_name, args):118    global g_machine119    global g_code_size120    global g_jitter121    global g_cpu122    global g_mem_access123    # Assuming the symbol is there124    sym_idx = kallsyms['name'].index(sym_name)125    sym_addr = kallsyms['address'][sym_idx]126    sym_size = kallsyms['address'][sym_idx + 1] - sym_addr127    if sym_size <= 0:128        raise Exception('Invalid address table?')129    # Parsing args130    if g_cpu == 'arml':131        for reg, value in args.items():132            if reg == 'R0':133                g_jitter.cpu.R0 = value134            elif reg == 'R1':135                g_jitter.cpu.R1 = value136            elif reg == 'R2':137                g_jitter.cpu.R2 = value138            elif reg == 'R3':139                g_jitter.cpu.R3 = value140            elif reg == 'R4':141                g_jitter.cpu.R4 = value142            elif reg == 'R5':143                g_jitter.cpu.R5 = value144            elif reg == 'R6':145                g_jitter.cpu.R6 = value146            elif reg == 'R7':147                g_jitter.cpu.R7 = value148            g_jitter.cpu.SP = 0xdead2000149    elif g_cpu == 'aarch64l':150        for reg, value in args.items():151            if reg == 'X0':152                g_jitter.cpu.X0 = value153            elif reg == 'X1':154                g_jitter.cpu.X1 = value155            elif reg == 'X2':156                g_jitter.cpu.X2 = value157            elif reg == 'X3':158                g_jitter.cpu.X3 = value159            elif reg == 'X4':160                g_jitter.cpu.X4 = value161            elif reg == 'X5':162                g_jitter.cpu.X5 = value163            elif reg == 'X6':164                g_jitter.cpu.X6 = value165            elif reg == 'X7':166                g_jitter.cpu.X7 = value167            g_jitter.cpu.SP = 0xdead2000168    else:169        raise Exception('Invalid arch')170    bp_start = kallsyms['_start']171    bp_size = g_code_size172    g_jitter.exceptions_handler.callbacks[EXCEPT_BREAKPOINT_MEMORY] = []173    g_jitter.add_exception_handler(EXCEPT_BREAKPOINT_MEMORY, mem_breakpoint_handler)174    print_log('[+]setting up memory breakpoint in range [%s, %s]' % (hex(bp_start), hex(bp_start + bp_size)))175    g_jitter.vm.add_memory_breakpoint(bp_start, bp_size, PAGE_READ | PAGE_WRITE)176    # g_jitter.set_trace_log()177    if g_cpu == 'arml':178        g_jitter.cpu.LR = 0xdead0000179    elif g_cpu == 'aarch64l':180        g_jitter.cpu.LR = 0xdead0000181    g_mem_access = {}182    g_jitter.init_run(sym_addr)183    try:184        g_jitter.continue_run()185    except AssertionError:186        assert g_jitter.vm.get_exception() == EXCEPT_ACCESS_VIOL187    g_jitter.vm.remove_memory_breakpoint(bp_start, PAGE_READ | PAGE_WRITE)188    for pc in g_mem_access.keys():189        access = g_mem_access[pc]190        if pc > sym_addr and pc < (sym_addr + sym_size):    # we ignore the first instruction191            yield access192#//////SIMENG_MIASM END//////193kallsyms = {194            'arch'          :'',195            'ptr_size'      :0,196            '_start'        :0,197            'numsyms'        :0,198            'address'       :[],199            'type'          :[],200            'name'          :[],201            'address_table'     : 0,202            'name_table'        : 0,203            'type_table'        : 0,204            'token_table'       : 0,205            'table_index_table' : 0,206            'linux_banner' : "",207            }208def INT(offset, vmlinux):209    bytes = kallsyms['ptr_size'] // 8210    s = vmlinux[offset:offset+bytes]211    f = 'I' if bytes==4 else 'Q'212    (num,) = struct.unpack(f, s)213    return num214def INT32(offset, vmlinux):215    s = vmlinux[offset:offset+4]216    (num,) = struct.unpack('I', s)217    return num218def INT64(offset, vmlinux):219    s = vmlinux[offset:offset+8]220    (num,) = struct.unpack('Q', s)221    return num222def SHORT(offset, vmlinux):223    s = vmlinux[offset:offset+2]224    (num,) = struct.unpack('H', s)225    return num226def STRIPZERO(offset, vmlinux, step=4):227    NOTZERO = INT32 if step==4 else INT228    for i in range(offset,len(vmlinux),step):229        if NOTZERO(i, vmlinux):230            return i231def ord_compat(ch):232    try:233        value = ord(ch)234    except TypeError:235        value = ch236    return value237#//////////////////////238def do_token_index_table(kallsyms , offset, vmlinux):239    kallsyms['token_index_table'] = offset240    print_log('[+]kallsyms_token_index_table = ', hex(offset))241def do_token_table(kallsyms, offset, vmlinux):242    kallsyms['token_table'] = offset243    print_log('[+]kallsyms_token_table = ', hex(offset))244    for i in range(offset,len(vmlinux)):245        if SHORT(i,vmlinux) == 0:246            break247    for i in range(i, len(vmlinux)):248        if ord_compat(vmlinux[i]):249            break250    offset = i-2251    do_token_index_table(kallsyms , offset, vmlinux)252def do_marker_table(kallsyms, offset, vmlinux):253    kallsyms['marker_table'] = offset254    print_log('[+]kallsyms_marker_table = ', hex(offset))255    offset += (((kallsyms['numsyms']-1)>>8)+1)*(kallsyms['ptr_size'] // 8)256    offset = STRIPZERO(offset, vmlinux)257    do_token_table(kallsyms, offset, vmlinux)258def do_type_table(kallsyms, offset, vmlinux):259    flag = True260    for i in range(offset,offset+256*4,4):261        if INT(i, vmlinux) & ~0x20202020 != 0x54545454:262            flag = False263            break264    if flag:265        kallsyms['type_table'] = offset266        while INT(offset, vmlinux):267            offset += (kallsyms['ptr_size'] // 8)268        offset = STRIPZERO(offset, vmlinux)269    else:270        kallsyms['type_table'] = 0271    print_log('[+]kallsyms_type_table = ', hex(kallsyms['type_table']))272    offset -= (kallsyms['ptr_size'] // 8)273    do_marker_table(kallsyms, offset, vmlinux)274def do_name_table(kallsyms, offset, vmlinux):275    kallsyms['name_table'] = offset276    print_log('[+]kallsyms_name_table = ', hex(offset))277    for i in range(kallsyms['numsyms']):278        length = ord_compat(vmlinux[offset])279        offset += length+1280    while offset%4 != 0:281        offset += 1282    offset = STRIPZERO(offset, vmlinux)283    do_type_table(kallsyms, offset, vmlinux)284    # decompress name and type285    name_offset = 0286    for i in range(kallsyms['numsyms']):287        offset = kallsyms['name_table']+name_offset288        length = ord_compat(vmlinux[offset])289        offset += 1290        name_offset += length+1291        name = ''292        while length:293            token_index_table_offset = ord_compat(vmlinux[offset])294            xoffset = kallsyms['token_index_table']+token_index_table_offset*2295            token_table_offset = SHORT(xoffset, vmlinux)296            strptr = kallsyms['token_table']+token_table_offset297            while ord_compat(vmlinux[strptr]):298                name += '%c' % ord_compat(vmlinux[strptr])299                strptr += 1300            length -= 1301            offset += 1302        if kallsyms['type_table']:303            kallsyms['type'].append('X')304            kallsyms['name'].append(name)305        else:306            kallsyms['type'].append(name[0])307            kallsyms['name'].append(name[1:])308def do_guess_start_address(kallsyms, vmlinux):309    _startaddr_from_enable_mmu = 0310    _startaddr_from_xstext = 0311    _startaddr_from_banner = 0312    _startaddr_from_processor = 0313    for i in range(kallsyms['numsyms']):314        if kallsyms['name'][i] in ['_text', 'stext', '_stext', '_sinittext', '__init_begin']:315            if hex(kallsyms['address'][i]):316                if _startaddr_from_xstext==0 or kallsyms['address'][i]<_startaddr_from_xstext:317                    _startaddr_from_xstext = kallsyms['address'][i]318        elif kallsyms['name'][i] == '__enable_mmu':319            if kallsyms['arch'] == 'arm64':320                enable_mmu_addr = kallsyms['address'][i]321                '''322                msr ttbr0_el1, x25          // load TTBR0323                msr ttbr1_el1, x26          // load TTBR1324                '''325                enable_mmu_fileoffset = vmlinux.find(b'\x19\x20\x18\xd5\x3a\x20\x18\xd5')326                if enable_mmu_fileoffset != -1:327                    _startaddr_from_enable_mmu = enable_mmu_addr - enable_mmu_fileoffset + 0x40328                    _startaddr_from_enable_mmu = _startaddr_from_enable_mmu & 0xfffffffffffff000329                # print_log('_startaddr_from_enable_mmu = %s' % (hex(_startaddr_from_enable_mmu)))330        elif kallsyms['name'][i] == 'linux_banner':331            linux_banner_addr = kallsyms['address'][i]332            linux_banner_fileoffset = vmlinux.find(b'Linux version ')333            if linux_banner_fileoffset != -1:334                _startaddr_from_banner = linux_banner_addr - linux_banner_fileoffset335        elif kallsyms['name'][i] == '__lookup_processor_type_data':336            lookup_processor_addr = kallsyms['address'][i]337            step = kallsyms['ptr_size'] // 8338            if kallsyms['arch'] == 'arm':339                addr_base = 0xC0008000340            else:341                addr_base = 0xffffff8008080000342            for i in range(0,0x100000,step):343                _startaddr_from_processor = addr_base + i344                fileoffset = lookup_processor_addr - _startaddr_from_processor345                if fileoffset < 0:346                    break347                if fileoffset+step > len(vmlinux):348                    continue349                if lookup_processor_addr == INT(fileoffset, vmlinux):350                    break351            if _startaddr_from_processor == _startaddr_from_processor+0x100000:352                _startaddr_from_processor = 0353    start_addrs = [_startaddr_from_banner, _startaddr_from_enable_mmu, _startaddr_from_processor, _startaddr_from_xstext]354    if kallsyms['arch']==64 and _startaddr_from_banner!=_startaddr_from_xstext:355         start_addrs.append( 0xffffff8008000000 + INT(8, vmlinux) )356    for addr in start_addrs:357        if addr != 0 and addr % 0x1000 == 0:358            if kallsyms['arch'] == 'arm64' and addr < 0xffff000000000000:359                continue360            kallsyms['_start']= addr361            break362    else:363        assert False,"  [!]kernel start address error..."364    return kallsyms['_start']365def do_offset_table(kallsyms, start, vmlinux):366    step = 4    # this is fixed step367    kallsyms['address'] = []368    prev_offset = 0369    relative_base = 0   # We will determine this later370    # status371    #   0: looking for 1st 00 00 00 00372    #   1: looking for 2nd 00 00 00 00373    #   2: looking for non-zero ascending offset seq374    status = 0375    for i in range(start, len(vmlinux), step):376        offset = INT32(i, vmlinux)377        # print hex(i + 0xffffff8008080000), hex(offset)378        if status == 0:379            if offset == 0:380                kallsyms['address'].append(relative_base + offset)381                status = 1382            else:383                return 0384        elif status == 1:385            if offset == 0:386                kallsyms['address'].append(relative_base + offset)387                status = 2388            else:389                return 1390        elif status == 2:391            if (offset > 0) and (offset >= prev_offset) and (offset < 0x80000000) and \392            (prev_offset != 0 or offset - prev_offset < 0xf8000):   # For latest aarch32 kernels, since kallsyms_offsets start with 0xf8000393                kallsyms['address'].append(relative_base + offset)394                prev_offset = offset395            else:396                return (i - start) // step397    return 0398def do_offset_table_arm(kallsyms, start, vmlinux):399    step = 4    # this is fixed step400    kallsyms['address'] = []401    prev_offset = 0402    relative_base = 0   # We will determine this later403    # status404    #   0: looking for 1st 00 80 0f 00405    #   1: looking for 2nd 00 80 0f 00406    #   2: looking for non-zero ascending offset seq407    status = 0408    for i in range(start, len(vmlinux), step):409        offset = INT32(i, vmlinux)410        # print hex(i + 0xffffff8008080000), hex(offset)411        if status == 0:412            if offset == 0xf8000:413                kallsyms['address'].append(relative_base + offset)414                status = 1415            else:416                return 0417        elif status == 1:418            if offset == 0xf8000:419                kallsyms['address'].append(relative_base + offset)420                status = 2421                prev_offset = offset422            else:423                return 1424        elif status == 2:425            if (offset > 0) and (offset >= prev_offset) and (offset < 0x80000000):426                kallsyms['address'].append(relative_base + offset)427                prev_offset = offset428            else:429                return (i - start) // step430    return 0431def do_address_table(kallsyms, offset, vmlinux, addr_base_32 = 0xC0000000):432    step = kallsyms['ptr_size'] // 8433    if kallsyms['arch'] == 'arm':434        addr_base = addr_base_32435    else:436        addr_base = 0xffffff8008000000437    kallsyms['address'] = []438    prev_addr = 0439    for i in range(offset, len(vmlinux), step):440        addr = INT(i, vmlinux)441        if addr < addr_base:442            return (i-offset) // step443        elif addr < prev_addr:444            return (i-offset) // step445        else:446            kallsyms['address'].append(addr)447            prev_addr = addr448    return 0449def insert_symbol(name, addr, sym_type):450    idx = bisect.bisect_right(kallsyms['address'], addr)451    # Check if name is duplicate, assuming address is correct452    i = idx - 1453    if i < kallsyms['numsyms']:454        while i >= 0 and kallsyms['address'][i] == addr:455            if kallsyms['name'][i] == name:456                return457            i -= 1458    kallsyms['address'].insert(idx, addr)459    kallsyms['type'].insert(idx, sym_type)460    kallsyms['name'].insert(idx, name)461    kallsyms['numsyms'] += 1462def check_miasm_symbols(vmlinux):463    global args464    if args is None:465        # Most likely laoded in IDA or r2. For now just disable experimental features.466        return467    else:468        if (not miasm_installed) or (not args.miasm):469            return470    print_log('[+]miasm features (experimental) enabled')471    print_log('[+]init miasm engine...')472    miasm_load_vmlinux(kallsyms, vmlinux)473    # selinux_enforcing474    if 'selinux_enforcing' not in kallsyms['name']:475        print_log('[+]selinux_enforcing not found, using miasm to locate it')476        if 'enforcing_setup' not in kallsyms['name']:477            print_log('[!]enforcing setup not found')478        else:479            miasm_set_mem(0x10000000, b'1\x00')480            call_args = {}481            if kallsyms['arch'] == 'arm64':482                call_args['X0'] = 0x10000000483            elif kallsyms['arch'] == 'arm':484                call_args['R0'] = 0x10000000485            loc_selinux_enforcing = 0486            for access in get_mem_access(kallsyms, 'enforcing_setup', call_args):487                # print_log("%s , %s, %d" % (access['dir'], hex(access['addr']), access['len']))488                if access['dir'] == 'write' and access['len'] == 4:489                    loc_selinux_enforcing = access['addr']490                    break491            if loc_selinux_enforcing > 0:492                print_log("[+]found selinux_enforcing @ %s" % (hex(loc_selinux_enforcing)))493                if loc_selinux_enforcing > kallsyms['_start']:494                    insert_symbol('selinux_enforcing', loc_selinux_enforcing, 'B')495        pass496def find_sys_call_table(kallsyms, vmlinux):497    loc_sys_call_table = 0498    symbols = []499    if kallsyms['arch'] == 'arm':500        symbols.append('sys_restart_syscall')501        symbols.append('sys_exit')502        symbols.append('sys_fork')503        symbols.append('sys_read')504        pass505    elif kallsyms['arch'] == 'arm64':506        '''507        #define __NR_io_setup 0508        __SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)509        #define __NR_io_destroy 1510        __SYSCALL(__NR_io_destroy, sys_io_destroy)511        #define __NR_io_submit 2512        __SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)513        #define __NR_io_cancel 3514        __SYSCALL(__NR_io_cancel, sys_io_cancel)515        '''516        symbols.append('sys_io_setup')517        symbols.append('sys_io_destroy')518        symbols.append('sys_io_submit')519        symbols.append('sys_io_cancel')520        pass521    else:522        return523    print_log('[+]looking for symbols ', symbols)524    addr_string = b''525    for sym in symbols:526        if sym not in kallsyms['name']:527            print_log('[!]%s not found' % (sym))528            return529        idx = kallsyms['name'].index(sym)530        if kallsyms['ptr_size'] == 64:531            addr_string = addr_string + struct.pack('<Q', kallsyms['address'][idx])532        elif kallsyms['ptr_size'] == 32:533            addr_string = addr_string + struct.pack('<L', kallsyms['address'][idx])534        else:535            raise Exception('Invalid ptr_size')536    offset = vmlinux.find(addr_string)537    if offset == -1:538        print_log("[!]Can't find sys_call_table")539        return540    loc_sys_call_table = kallsyms['_start'] + offset541    print_log("[+]Found sys_call_table @ %s" % (hex(loc_sys_call_table)))542    insert_symbol('sys_call_table', loc_sys_call_table, 'R')543def do_kallsyms(kallsyms, vmlinux):544    step = kallsyms['ptr_size'] // 8545    min_numsyms = 20000546    offset = 0547    vmlen  = len(vmlinux)548    is_offset_table = 0549    kallsyms_relative_base = 0550    while offset+step < vmlen:551        num = do_address_table(kallsyms, offset, vmlinux)552        if num > min_numsyms:553            if (kallsyms['arch'] == 'arm') or \554            (kallsyms['address'][0] // 0x100000000 == 0xffffffc0 or \555            kallsyms['address'][0] // 0x100000000 == 0xffffff80):556                kallsyms['numsyms'] = num557                break558        offset += (num+1)*step559    # 2G/2G kernel560    if kallsyms['numsyms'] == 0 and kallsyms['arch'] == 'arm':561        print_log('[!]could be 2G/2G kernel...')562        offset = 0563        step = 4564        while offset+step < vmlen:565            num = do_address_table(kallsyms, offset, vmlinux, addr_base_32 = 0x80000000)566            if num > min_numsyms:567                kallsyms['numsyms'] = num568                break569            else:570                offset += (num+1)*step571    if kallsyms['numsyms'] == 0:572        print_log('[!]could be offset table...')573        is_offset_table = 1574        offset = 0575        step = 4576        while offset+step < vmlen:577            num = do_offset_table(kallsyms, offset, vmlinux)578            if num > min_numsyms:579                kallsyms['numsyms'] = num580                break581            else:582                if num > 2:583                    offset += (num) * step584                else:585                    offset += step586        # For some aarch32 kernels, kallsyms_offset beign with 0xf8000587        if kallsyms['numsyms'] == 0 and \588            kallsyms['arch'] == 'arm':589            offset = 0590            while offset+step < vmlen:591                num = do_offset_table_arm(kallsyms, offset, vmlinux)592                if num > min_numsyms:593                    kallsyms['numsyms'] = num594                    break595                else:596                    if num > 2:597                        offset += (num) * step598                    else:599                        offset += step600        step = kallsyms['ptr_size'] // 8 # recover normal step601    if kallsyms['numsyms'] == 0:602        print_log('[!]lookup_address_table error...')603        return604    print_log('[+]numsyms: ', kallsyms['numsyms'])605    kallsyms['address_table'] = offset606    print_log('[+]kallsyms_address_table = ', hex(offset))607    if is_offset_table == 0:608        offset += kallsyms['numsyms']*step609        offset = STRIPZERO(offset, vmlinux, step)610    else:611        offset += kallsyms['numsyms']*4612        offset = STRIPZERO(offset, vmlinux, 4)613        kallsyms_relative_base = INT(offset, vmlinux)614        # Update addresses615        for idx in range(0, len(kallsyms['address'])):616            kallsyms['address'][idx] += kallsyms_relative_base617        print_log('[+]kallsyms_relative_base = ', hex(kallsyms_relative_base))618        offset += step  # skip kallsyms_relative_base619        offset = STRIPZERO(offset, vmlinux, 4)620    num = INT(offset, vmlinux)621    offset += step622    print_log('[+]kallsyms_num = ', kallsyms['numsyms'], ' (', num, ')')623    if abs(num-kallsyms['numsyms']) > 128:624            kallsyms['numsyms'] = 0625            print_log('  [!]not equal, maybe error...'    )626            return627    if num > kallsyms['numsyms']:628        for i in range(kallsyms['numsyms'],num):629            kallsyms['address'].insert(0,0)630    kallsyms['numsyms'] = num631    offset = STRIPZERO(offset, vmlinux)632    do_name_table(kallsyms, offset, vmlinux)633    do_guess_start_address(kallsyms, vmlinux)634    print_log('[+]kallsyms_start_address = ', hex(kallsyms['_start']))635    # Fix missing _text636    if '_text' not in kallsyms['name']:637        print_log('[+]_text missing, fix by using guessed start')638        kallsyms['address'].insert(0, kallsyms['_start'])639        kallsyms['type'].insert(0, 'T')640        kallsyms['name'].insert(0, '_text')641        kallsyms['numsyms'] += 1642    # fix missing vermagic643    if 'vermagic' not in kallsyms['name']:644        if kallsyms['arch'] == 'arm64':645            pattern = b'(\\d+\\.\\d+\\.\\d+(\\S+)? SMP preempt [a-zA-Z_ ]*aarch64)'646            match = re.search(pattern, vmlinux)647            if match is None:648                pass649            else:650                sym_addr = kallsyms['_start'] + match.start()651                insert_symbol('vermagic', sym_addr, 'r')652                print_log('[!]no vermagic symbol, found @ %s' % (hex(sym_addr)))653    # fix missing linux_banner654    if 'linux_banner' not in kallsyms['name']:655        pattern = b'Linux version \\d+\\.\\d+\\.\\d+'656        match = re.search(pattern, vmlinux)657        if match is None:658            pass659        else:660            sym_addr = kallsyms['_start'] + match.start()661            insert_symbol('linux_banner', sym_addr, 'B')662            print_log('[!]no linux_banner symbol, found @ %s' % (hex(sym_addr)))663    # fix missing sys_call_table664    if 'sys_call_table' not in kallsyms['name']:665        find_sys_call_table(kallsyms, vmlinux)666    check_miasm_symbols(vmlinux)667    find_ksymtab(kallsyms, vmlinux)668    return669def do_get_arch(kallsyms, vmlinux):670    def fuzzy_arm64(vmlinux):671        step = 8672        offset = 0673        vmlen  = len(vmlinux) - len(vmlinux)%8674        addr_base = 0xffffff8008000000675        while offset+step < vmlen:676          for i in range(offset, vmlen, step):677                if INT64(i, vmlinux) < addr_base:678                    addrnum = (i-offset) // step679                    if addrnum > 10000:680                        return True681                    else:682                        offset = i+step683        return False684    if re.search(b'ARMd', vmlinux[:0x200]):685        kallsyms['arch'] = 'arm64'686        kallsyms['ptr_size'] = 64687    elif fuzzy_arm64(vmlinux):688        kallsyms['arch'] = 'arm64'689        kallsyms['ptr_size'] = 64690    else:691        kallsyms['arch'] = 'arm'692        kallsyms['ptr_size'] = 32693    print_log('[+]kallsyms_arch = ', kallsyms['arch'])694def print_kallsyms(kallsyms):695    buf = '\n'.join( '%x %c %s'%(kallsyms['address'][i],kallsyms['type'][i],kallsyms['name'][i]) for i in range(kallsyms['numsyms']) )696    # open('kallsyms','w').write(buf)697    print_sym(buf)698def print_kallsyms_json(kallsyms):699    try:700        kallsyms['linux_banner'] = str(kallsyms['linux_banner'], 'utf-8')701    except:702        pass703    kallsyms_json = json.dumps(kallsyms)704    print_sym(kallsyms_json)705#////////////////////////////////////////////////////////////////////////////////////////////706# Process ksymtab707c_identity_patt = re.compile(b"([_a-zA-Z][_a-zA-Z0-9]*)\\x00")708def is_ksymtab_pair(kallsyms, vmlinux, idx, symlist):709    ptr1 = 0710    ptr2 = 0711    max_size = 128 * 1024 * 1024712    if kallsyms['ptr_size'] == 64:713        (ptr1, ) = struct.unpack("Q", vmlinux[idx:idx+8])714        (ptr2, ) = struct.unpack("Q", vmlinux[idx+8:idx+16])715    elif kallsyms['ptr_size'] == 32:716        (ptr1, ) = struct.unpack("I", vmlinux[idx:idx+4])717        (ptr2, ) = struct.unpack("I", vmlinux[idx+4:idx+8])718    else:719        raise Exception("Unsupported ptr_size")720    # Must be in range721    # if ptr1 < kallsyms['_start'] or ptr1 >= (kallsyms['_start'] + len(vmlinux)):722    if ptr1 < kallsyms['_start'] or ptr1 >= (kallsyms['_start'] + max_size):723        return False724    if ptr2 < kallsyms['_start'] or ptr2 >= (kallsyms['_start'] + len(vmlinux)):725        return False726    # Check if ptr2 if pointing to a null-terminate string representing a valid C identity727    i = ptr2 - kallsyms['_start']728    substr = vmlinux[i:i+256]729    m = c_identity_patt.match(substr)730    if m is None:731        return False732    sym_name = m.group(1)733    try:734        sym_name = sym_name.decode('utf-8')735    except:736        pass737    symlist.append((ptr1, sym_name))738    return True739def find_ksymtab(kallsyms, vmlinux):740    idx = 0741    ksym_count = 0742    ksym_count_threshold = 256743    step = 0744    symlist = []745    if kallsyms['ptr_size'] == 64:746        step = 8747    elif kallsyms['ptr_size'] == 32:748        step = 4749    else:750        raise Exception("Unsupported ptr_size")751    # if we already have __start___ksymtab752    try:753        if idx == 0:754            i = kallsyms['name'].index('__start___ksymtab')755            addr = kallsyms['address'][i]756            idx = addr - kallsyms['_start']757    except:758        pass759    while idx < (len(vmlinux) - step*2):760        if is_ksymtab_pair(kallsyms, vmlinux, idx, symlist):761            ksym_count += 1762            idx += (step * 2)763            if (ksym_count >= ksym_count_threshold):764                break765        else:766            ksym_count = 0767            symlist = []768            idx += step769        continue770    if (ksym_count < ksym_count_threshold):771        print_log("[!]can't locate ksymtab")772        return773    while idx < (len(vmlinux) - step):774        if not is_ksymtab_pair(kallsyms, vmlinux, idx, symlist):775            break776        idx += (step * 2)777    print_log("[+]found %d symbols in ksymtab" % (len(symlist)))778    etext = kallsyms['_start'] + len(vmlinux)779    bss_start = kallsyms['_start'] + len(vmlinux)780    try:781        etext_idx = kallsyms['name'].index('_etext')782        etext = kallsyms['address'][etext_idx]783    except:784        try:785            etext_idx = kallsyms['name'].index('__start_rodata')786            etext = kallsyms['address'][etext_idx]787        except:788            pass789    for (addr, symname) in symlist:790        t = 'd'791        if addr < etext:792            t = 't'793        elif addr < bss_start:794            t = 'd'  # we don't know if it is read-only, don't care either :-S795        else:796            t = 'b'797        insert_symbol(symname, addr, t)798#////////////////////////////////////////////////////////////////////////////////////////////799# IDA Pro Plugin Support800def accept_file(li, n):801    """802    Check if the file is of supported format803    @param li: a file-like object which can be used to access the input data804    @param n : format number. The function will be called with incrementing805               number until it returns zero806    @return: 0 - no more supported formats807             string "name" - format name to display in the chooser dialog808             dictionary { 'format': "name", 'options': integer }809               options: should be 1, possibly ORed with ACCEPT_FIRST (0x8000)810               to indicate preferred format811    """812    # ida 7+ compatibility, n is filename813    # we support only one format per file814    if isinstance(n, int):815        if n > 0:816            return 0817    # magic = li.read(8)818    # if magic != 'ANDROID!':819    #     return 0820    return "Android/Linux Kernel Image(ARM)"821def load_file(li, neflags, format):822    """823    Load the file into database824    @param li: a file-like object which can be used to access the input data825    @param neflags: options selected by the user, see loader.hpp826    @return: 0-failure, 1-ok827    """828    li.seek(0)829    vmlinux = li.read(li.size())830    do_get_arch(kallsyms, vmlinux)831    do_kallsyms(kallsyms, vmlinux)832    if kallsyms['numsyms'] == 0:833        print_log('[!]get kallsyms error...')834        return 0835    idaapi.set_processor_type("arm", idaapi.SETPROC_LOADER_NON_FATAL|idaapi.SETPROC_LOADER)836    if kallsyms['arch'] == 'arm64':837        idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT838    li.file2base(0, kallsyms['_start'], kallsyms['_start']+li.size(), True)839    sinittext_addr = 0840    max_sym_addr = 0841    for i in range(kallsyms['numsyms']):842        if kallsyms['arch'] == 'arm':843            if kallsyms['address'][i] > 0xd0000000:844                continue845        if kallsyms['name'][i] == '_sinittext':846            sinittext_addr = kallsyms['address'][i]847        if kallsyms['address'][i] > max_sym_addr:848            max_sym_addr = kallsyms['address'][i]849    max_sym_addr = max_sym_addr + 1024850    print_log("max_sym_addr = ", hex(max_sym_addr))851    if (kallsyms['_start']+li.size()) > max_sym_addr:852        max_sym_addr = kallsyms['_start']+li.size()853    s = idaapi.segment_t()854    s.bitness = kallsyms['ptr_size'] // 32855    s.start_ea = kallsyms['_start']856    if sinittext_addr == 0:857        s.end_ea = max_sym_addr858    else:859        s.end_ea = sinittext_addr860    s.perm = 5861    idaapi.add_segm_ex(s,".text","CODE",idaapi.ADDSEG_OR_DIE)862    if sinittext_addr > 0:863        s = idaapi.segment_t()864        s.bitness = kallsyms['ptr_size'] // 32865        s.start_ea = sinittext_addr866        s.end_ea = max_sym_addr867        s.perm = 7868        idaapi.add_segm_ex(s,".data","DATA",idaapi.ADDSEG_OR_DIE)869    for i in range(kallsyms['numsyms']):870        if kallsyms['type'][i] in ['t','T']:871            idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 1)872        else:873            idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 0)874    print_log("Android/Linux vmlinux loaded...")875    return 1876#////////////////////////////////////////////////////////////////////////////////////////////877# Radare2 Plugin Support878def r2():879    r2p = r2pipe.open()880    info = r2p.cmdj("ij")881    with open(info["core"]["file"], 'rb') as f:882        vmlinux = f.read()883    do_get_arch(kallsyms, vmlinux)884    do_kallsyms(kallsyms, vmlinux)885    if kallsyms['numsyms'] == 0:886        print_log('[!]get kallsyms error...')887        return 0888    r2p.cmd("e asm.arch = arm")889    r2p.cmd("e asm.bits = %d" % kallsyms['ptr_size'])890    siol_map = r2p.cmdj("omj")[0]["map"]891    set_baddr = "omb " + str(siol_map) + " " + str(kallsyms["_start"])892    r2p.cmd(set_baddr)893    seg = "s 0 " + str(kallsyms["_start"]) + " " + str(len(vmlinux)) + " .text rx"894    r2p.cmd(seg)895    r2p.cmd("fs symbols")896    for i in range(kallsyms['numsyms']):897        if kallsyms["address"][i] == 0:898            continue899        if kallsyms['type'][i] in ['t','T']:900            cmd = "f fcn." + kallsyms["name"][i] + " @ " + str(kallsyms["address"][i])901            r2p.cmd(cmd)902        else:903            cmd = "f sym." + kallsyms["name"][i] + " @ " + str(kallsyms["address"][i])904            r2p.cmd(cmd)905    r2p.cmd("e anal.strings = true")906    r2p.cmd("s " + str(kallsyms["_start"]))907    print_log("Android/Linux vmlinux loaded...")908    return 1909#////////////////////////////////////////////////////////////////////////////////////////////910def parse_vmlinux(filename, log=None, sym=None):911    global log_file912    global sym_file913    log_file = log914    sym_file = sym915    if os.path.exists(filename):916        vmlinux = open(filename, 'rb').read()917        pat = re.compile(b"Linux version \d+\.\d+\.\d+.*")918        matches = pat.search(vmlinux)919        if matches is None:920            print_log("[!]can't locate linux banner...")921        else:922            kallsyms['linux_banner'] = matches.group(0)923            print_log(kallsyms['linux_banner'])924        do_get_arch(kallsyms, vmlinux)925        do_kallsyms(kallsyms, vmlinux)926    else:927        print_log('[!]vmlinux does not exist...')928def main(argv):929    global args930    parser = argparse.ArgumentParser()931    parser.add_argument("-j", "--json", help="output in json, which can be consumed by other systems", action="store_true")932    parser.add_argument("-m", "--miasm", help="enable miasm simulation engine for non-exported symbols (experimental)", action="store_true")933    parser.add_argument("image", help="kernel image filename", type=str)934    args = parser.parse_args()935    parse_vmlinux(args.image, sys.stderr, sys.stdout)936    if kallsyms['numsyms'] > 0:937        if args.json:938            print_kallsyms_json(kallsyms)939        else:940            print_kallsyms(kallsyms)941    else:942        print_log('[!]get kallsyms error...')943#////////////////////////////////////////////////////////////////////////////////////////////944if idaapi:945    pass946elif radare2:947    import r2pipe948    r2()949else:...ksum.py
Source:ksum.py  
1#!/usr/bin/env python32#3# Copyright (c) 2016, Intel Corporation.4#5# SPDX-License-Identifier: GPL-2.0-only6#7# DESCRIPTION 'ksum.py' generates a combined summary of vmlinux and8# module sizes for a built kernel, as a quick tool for comparing the9# overall effects of systemic tinification changes.  Execute from the10# base directory of the kernel build you want to summarize.  Setting11# the 'verbose' flag will display the sizes for each file included in12# the summary.13#14# AUTHORS15# Tom Zanussi <tom.zanussi (at] linux.intel.com>16#17__version__ = "0.1.0"18# Python Standard Library modules19import os20import sys21import getopt22from subprocess import *23def usage():24    prog = os.path.basename(sys.argv[0])25    print('Usage: %s [OPTION]...' % prog)26    print('  -v,                 display sizes for each file')27    print('  -h, --help          display this help and exit')28    print('')29    print('Run %s from the top-level Linux kernel build directory.' % prog)30verbose = False31n_ko_files = 032ko_file_list = []33ko_text = 034ko_data = 035ko_bss = 036ko_total = 037vmlinux_file = ""38vmlinux_level = 039vmlinux_text = 040vmlinux_data = 041vmlinux_bss = 042vmlinux_total = 043def is_vmlinux_file(filename):44    global vmlinux_level45    if filename == ("vmlinux") and vmlinux_level == 0:46        vmlinux_level += 147        return True48    return False49def is_ko_file(filename):50    if filename.endswith(".ko"):51        return True52    return False53def collect_object_files():54    print("Collecting object files recursively from %s..." % os.getcwd())55    for dirpath, dirs, files in os.walk(os.getcwd()):56        for filename in files:57            if is_ko_file(filename):58                ko_file_list.append(os.path.join(dirpath, filename))59            elif is_vmlinux_file(filename):60                global vmlinux_file61                vmlinux_file = os.path.join(dirpath, filename)62    print("Collecting object files [DONE]")63def add_ko_file(filename):64        p = Popen("size -t " + filename, shell=True, stdout=PIPE, stderr=PIPE)65        output = p.communicate()[0].splitlines()66        if len(output) > 2:67            sizes = output[-1].split()[0:4]68            if verbose:69                print("     %10d %10d %10d %10d\t" % \70                    (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])), end=' ')71                print("%s" % filename[len(os.getcwd()) + 1:])72            global n_ko_files, ko_text, ko_data, ko_bss, ko_total73            ko_text += int(sizes[0])74            ko_data += int(sizes[1])75            ko_bss += int(sizes[2])76            ko_total += int(sizes[3])77            n_ko_files += 178def get_vmlinux_totals():79        p = Popen("size -t " + vmlinux_file, shell=True, stdout=PIPE, stderr=PIPE)80        output = p.communicate()[0].splitlines()81        if len(output) > 2:82            sizes = output[-1].split()[0:4]83            if verbose:84                print("     %10d %10d %10d %10d\t" % \85                    (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])), end=' ')86                print("%s" % vmlinux_file[len(os.getcwd()) + 1:])87            global vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total88            vmlinux_text += int(sizes[0])89            vmlinux_data += int(sizes[1])90            vmlinux_bss += int(sizes[2])91            vmlinux_total += int(sizes[3])92def sum_ko_files():93    for ko_file in ko_file_list:94        add_ko_file(ko_file)95def main():96    try:97        opts, args = getopt.getopt(sys.argv[1:], "vh", ["help"])98    except getopt.GetoptError as err:99        print('%s' % str(err))100        usage()101        sys.exit(2)102    for o, a in opts:103        if o == '-v':104            global verbose105            verbose = True106        elif o in ('-h', '--help'):107            usage()108            sys.exit(0)109        else:110            assert False, "unhandled option"111    collect_object_files()112    sum_ko_files()113    get_vmlinux_totals()114    print("\nTotals:")115    print("\nvmlinux:")116    print("    text\tdata\t\tbss\t\ttotal")117    print("    %-10d\t%-10d\t%-10d\t%-10d" % \118        (vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total))119    print("\nmodules (%d):" % n_ko_files)120    print("    text\tdata\t\tbss\t\ttotal")121    print("    %-10d\t%-10d\t%-10d\t%-10d" % \122        (ko_text, ko_data, ko_bss, ko_total))123    print("\nvmlinux + modules:")124    print("    text\tdata\t\tbss\t\ttotal")125    print("    %-10d\t%-10d\t%-10d\t%-10d" % \126        (vmlinux_text + ko_text, vmlinux_data + ko_data, \127         vmlinux_bss + ko_bss, vmlinux_total + ko_total))128if __name__ == "__main__":129    try:130        ret = main()131    except Exception:132        ret = 1133        import traceback134        traceback.print_exc(5)...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
