├── structs-32.txt.gz ├── structs-64.txt.gz ├── README └── kstructhunter.py /structs-32.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonoberheide/kstructhunter/HEAD/structs-32.txt.gz -------------------------------------------------------------------------------- /structs-64.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonoberheide/kstructhunter/HEAD/structs-64.txt.gz -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | kstructhunter.py 2 | 3 | Jon Oberheide 4 | http://jon.oberheide.org 5 | 6 | Routines for hunting down kernel structs. 7 | 8 | Example: 9 | 10 | $ python kstructhunter.py sctp_ssnmap 11 | struct sctp_ssnmap is size 40 12 | struct sctp_ssnmap is allocated in kmalloc-64 13 | other structs allocated in kmalloc-64: 14 | ARCMSR_CDB 15 | ArcProto 16 | BC_DEC_YUV_BUFFS 17 | ... 18 | -------------------------------------------------------------------------------- /kstructhunter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # kstructhunter.py 4 | # 5 | # Jon Oberheide 6 | # http://jon.oberheide.org 7 | # 8 | # Routines for hunting down kernel structs. 9 | # 10 | # Ships with data files for the stock Ubuntu Natty kernels. 11 | # 12 | 13 | import os, sys, optparse, platform, gzip, bz2 14 | 15 | KMALLOC_CACHES = [ 16 | 8, 16, 32, 64, 96, 128, 192, 256, 512, 1024, 2048, 4096, 8192 17 | ] 18 | 19 | def hunt(data, target): 20 | structs = {} 21 | caches = {} 22 | 23 | # prime cache lists 24 | for cache in KMALLOC_CACHES: 25 | caches[cache] = [] 26 | 27 | for line in data: 28 | line = line.strip('\n') 29 | line = line.strip() 30 | if not line: 31 | continue 32 | 33 | # parse pahole output 34 | struct, size_str, _ = line.split('\t') 35 | size = int(size_str) 36 | 37 | # only consider kmalloc caches for now 38 | if size > KMALLOC_CACHES[-1]: 39 | continue 40 | 41 | # naive search for proper cache 42 | for cache in KMALLOC_CACHES: 43 | if size <= cache: 44 | structs[struct] = (size, cache) 45 | caches[cache].append(struct) 46 | break 47 | 48 | if target not in structs: 49 | print 'target struct %s not found' % (target) 50 | sys.exit(1) 51 | 52 | size, cache = structs[target] 53 | 54 | print 'struct %s is size %d' % (target, size) 55 | print 'struct %s is allocated in kmalloc-%d' % (target, cache) 56 | print 'other structs allocated in kmalloc-%d:' % (cache) 57 | 58 | for struct in caches[cache]: 59 | print '\t%s' % struct 60 | 61 | def main(): 62 | usage = 'usage: %prog [options] struct_name' 63 | opt = optparse.OptionParser(usage=usage) 64 | opt.add_option('-f', '--file', dest='path', help='specify the path to a custom data file', metavar='PATH') 65 | options, args = opt.parse_args() 66 | 67 | if len(args) != 1: 68 | opt.error('no target struct name was provided') 69 | 70 | if options.path and not os.path.exists(options.path): 71 | opt.error('invalid path to the custom data file') 72 | 73 | bits, linkage = platform.architecture() 74 | 75 | if options.path: 76 | path = options.path 77 | elif bits == '32bit': 78 | path = 'structs-32.txt.gz' 79 | elif bits == '64bit': 80 | path = 'structs-64.txt.gz' 81 | else: 82 | opt.error('invalid architecture') 83 | 84 | if path.endswith('.bz2'): 85 | fopen = bz2.BZ2File 86 | elif path.endswith('.gz'): 87 | fopen = gzip.GzipFile 88 | else: 89 | fopen = file 90 | 91 | f = fopen(path, 'rb') 92 | data = f.readlines() 93 | f.close() 94 | 95 | hunt(data, args[0]) 96 | 97 | if __name__ == '__main__': 98 | main() 99 | --------------------------------------------------------------------------------