freemyipod r816 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r815‎ | r816 | r817 >
Date:22:37, 22 November 2011
Author:theseven
Status:new
Tags:
Comment:
tlsfanalyze.py: Add some more checks
Modified paths:
  • /emcore/trunk/tools/misc.py (modified) (history)
  • /emcore/trunk/tools/tlsfanalyze.py (modified) (history)

Diff [purge]

Index: emcore/trunk/tools/misc.py
@@ -284,6 +284,22 @@
285285 thread = scheduler_thread()._to_bunch()
286286 thread.name = "[Invalid Thread 0x%08X]" % address
287287 return thread
 288+
 289+
 290+def string_from_image(data, base, ptr, maxlen):
 291+ if ptr == 0: name = "<NULL>"
 292+ try:
 293+ string = ""
 294+ end = data.find(b"\0", ptr - base, ptr - base + maxlen)
 295+ if end < 0: return "<BAD_STRING>"
 296+ else:
 297+ d = data[ptr - base : end]
 298+ for i in range(len(d)):
 299+ byte = ord(d[i : i + 1])
 300+ if byte < 0x20: return "<BAD_STRING>"
 301+ else: string = string + chr(byte)
 302+ except: return "<BAD_PTR>"
 303+ return string
288304
289305
290306 def gethwname(id):
@@ -445,4 +461,5 @@
446462 Returns the major version of python
447463 """
448464 import sys
449 - return sys.hexversion // 0x1000000
\ No newline at end of file
 465+ return sys.hexversion // 0x1000000
 466+
\ No newline at end of file
Index: emcore/trunk/tools/tlsfanalyze.py
@@ -24,7 +24,8 @@
2525
2626 import sys
2727 import struct
28 -from misc import ExtendedCStruct
 28+from misc import ExtendedCStruct, string_from_image
 29+from libemcoredata import scheduler_thread
2930 from ctypes import *
3031
3132
@@ -132,13 +133,45 @@
133134 break
134135 blocks.append(prev_addr)
135136 if prev_free:
 137+ try:
 138+ nfa = block.get_next_free().get_address()
 139+ if nfa >= prev_addr and nfa < prev_addr + block.get_size() + 4:
 140+ print("%08X: Next free block (%08X) lies within the block itself" % (prev_addr, nfa))
 141+ except: print("%08X: Invalid next free block pointer: %08X" % (prev_addr, block.next_free))
 142+ try:
 143+ pfa = block.get_prev_free().get_address()
 144+ if pfa >= prev_addr and pfa < prev_addr + block.get_size() + 4:
 145+ print("%08X: Previous free block (%08X) lies within the block itself" % (prev_addr, pfa))
 146+ except:
 147+ print("%08X: Invalid previous free block pointer: %08X" % (prev_addr, block.prev_free))
136148 print("%08X: %08X bytes free" % (prev_addr + 4, block.get_size() + 4))
137149 free_blocks.append(prev_addr)
138150 bytes_free = bytes_free + block.get_size() + 4
139151 else:
140 - owner_address = prev_addr - image_base + block.get_size() - 4
 152+ owner_address = prev_addr - image_base + block.get_size() + 4
141153 owner = struct.unpack("<I", data[owner_address : owner_address + 4])[0]
142 - print("%08X: %08X+8 bytes owned by %08X" % (prev_addr + 8, block.get_size() - 4, owner))
 154+ if (owner & 3) == 0:
 155+ if (owner & 0xfffc0000) == 0x22000000: name = "<KERNEL_THREAD>"
 156+ else:
 157+ try:
 158+ thread = scheduler_thread(data, image_base, owner & ~3)
 159+ name = "Thread: " + string_from_image(data, image_base, thread.name, 128)
 160+ except: name = "<BAD_THREAD>"
 161+ elif (owner & 3) == 1:
 162+ try:
 163+ handle = struct.unpack("<I", data[(owner & ~3) - image_base + 4 : (owner & ~3) - image_base + 8])[0]
 164+ lib = struct.unpack("<4sI", data[(handle & ~3) - image_base + 4 : (handle & ~3) - image_base + 12])
 165+ name = "Library: " + lib[0].decode("latin_1") + "_v%d" % lib[1]
 166+ except: name = "<BAD_LIBRARY>"
 167+ elif (owner & 3) == 2:
 168+ if (owner >> 2) == 0: name = "<KERNEL_UNKNOWN>";
 169+ elif (owner >> 2) == 1: name = "<KERNEL_USB_MONITOR>";
 170+ elif (owner >> 2) == 2: name = "<KERNEL_FILE_HANDLE>";
 171+ elif (owner >> 2) == 3: name = "<KERNEL_DIR_HANDLE>";
 172+ elif (owner >> 2) == 4: name = "<KERNEL_ATA_BBT>";
 173+ else: name = "<KERNEL_UNKNOWN_TYPE>";
 174+ else: name = "<UNKNOWN_TYPE>"
 175+ print("%08X: %08X+8 bytes owned by %08X (%s)" % (prev_addr + 8, block.get_size() - 4, owner, name))
143176 bytes_used = bytes_used + block.get_size() + 4
144177 try: block = block.get_next_phys()
145178 except:
@@ -166,6 +199,7 @@
167200 elif block.is_null():
168201 print("[%d:%d:%08X] Block list is null, but second-level map indicates there are free blocks" % (i, j, ba))
169202 blocks = []
 203+ prev = None
170204 while not block.is_null():
171205 fatal = False
172206 addr = block.get_address()
@@ -173,6 +207,8 @@
174208 print("[%d:%d:%08X] Detected block loop" % (i, j, addr))
175209 break
176210 blocks.append(addr)
 211+ size = block.get_size()
 212+ print("[%d:%d] Block at %08X (%08X bytes)" % (i, j, addr, size + 4))
177213 if not block.is_free():
178214 print("[%d:%d:%08X] Non-free block on free list" % (i, j, addr))
179215 fatal = True
@@ -183,8 +219,6 @@
184220 print("[%d:%d:%08X] Block should have coalesced with next one" % (i, j, addr))
185221 except:
186222 print("Block %08X has invalid size: %08X" % (addr, block.get_size()))
187 - fatal = True
188 - size = block.get_size()
189223 if size < block_size_min:
190224 print("[%d:%d:%08X] Block violates minimum size: %d (should be at least %d)" % (i, j, addr, size, block_size_min))
191225 if size > block_size_max:
@@ -209,7 +243,8 @@
210244 if (size & 0x80000000) == 0:
211245 size = size << 1
212246 fl = fl - 1
213 - sl = (block.get_size() >> (fl - SL_INDEX_COUNT_LOG2 + FL_INDEX_SHIFT - 1)) ^ (1 << SL_INDEX_COUNT_LOG2)
 247+ size = block.get_size()
 248+ sl = (size >> (fl - SL_INDEX_COUNT_LOG2 + FL_INDEX_SHIFT - 1)) ^ (1 << SL_INDEX_COUNT_LOG2)
214249 if fl != i or sl != j:
215250 print("Block %08X is in wrong free list: [%d:%d] (should be [%d:%d])" % (addr, i, j, fl, sl))
216251 if free_blocks.count(addr) != 1:
@@ -217,9 +252,28 @@
218253 if handled_blocks.count(addr) > 0:
219254 print("[%d:%d:%08X] Block appears in multiple free lists" % (i, j, addr))
220255 else: handled_blocks.append(addr)
 256+ try:
 257+ nfa = block.get_next_free().get_address()
 258+ if nfa >= addr and nfa < addr + size + 4:
 259+ print("[%d:%d:%08X] Next free block (%08X) lies within the block itself" % (i, j, addr, nfa))
 260+ fatal = True
 261+ except:
 262+ print("[%d:%d:%08X] Invalid next free block pointer: %08X" % (i, j, addr, block.next_free))
 263+ fatal = True
 264+ try:
 265+ pfa = block.get_prev_free().get_address()
 266+ if pfa >= addr and pfa < addr + size + 4:
 267+ print("[%d:%d:%08X] Previous free block (%08X) lies within the block itself" % (i, j, addr, pfa))
 268+ if prev == None and not block.get_prev_free().is_null():
 269+ print("[%d:%d:%08X] Previous free block pointer is broken: %08X (should be NULL)" % (i, j, addr, pfa))
 270+ if prev != None and prev != pfa:
 271+ print("[%d:%d:%08X] Previous free block pointer is broken: %08X (should be %08X)" % (i, j, addr, pfa, prev))
 272+ except:
 273+ print("[%d:%d:%08X] Invalid previous free block pointer: %08X" % (i, j, addr, block.prev_free))
221274 if fatal:
222275 print("Fatal error in block chain, continuing with next chain")
223276 break
 277+ prev = addr
224278 block = block.get_next_free()
225279
226280 for addr in free_blocks: