import os
import KernelCollection
def findSymbolVMAddr(kernel_cache, dylib_index, symbol_name):
for symbol_and_addr in kernel_cache.dictionary()["dylibs"][dylib_index]["global-symbols"]:
if symbol_and_addr["name"] == symbol_name:
return symbol_and_addr["vmAddr"]
return None
def findFixupVMAddr(kernel_cache, fixup_name):
for fixup_vmaddr, fixup_target in kernel_cache.dictionary()["fixups"].iteritems():
if fixup_target == fixup_name:
return fixup_vmaddr
return None
def findPagableFixupVMAddr(kernel_cache, dylib_index, fixup_name):
for fixup_vmaddr, fixup_target in kernel_cache.dictionary()["dylibs"][dylib_index]["fixups"].iteritems():
if fixup_target == fixup_name:
return fixup_vmaddr
return None
def findAuxFixupVMAddr(kernel_cache, dylib_index, fixup_name):
for fixup_vmaddr, fixup_target in kernel_cache.dictionary()["dylibs"][dylib_index]["fixups"].iteritems():
if fixup_target == fixup_name:
return fixup_vmaddr
return None
def offsetVMAddr(vmAddr, offset):
het_int = int(vmAddr, 16)
het_int = het_int + offset
return ''.join([ '0x', hex(het_int).upper()[2:] ])
def check(kernel_cache):
enableLogging = False
kernel_cache.buildKernelCollection("x86_64", "/auxkc-pageablekc-vtable-patching/main.kc", "/auxkc-pageablekc-vtable-patching/main.kernel", "", [], [])
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/main.kc", ["-layout", "-arch", "x86_64"])
assert len(kernel_cache.dictionary()["dylibs"]) == 1
assert kernel_cache.dictionary()["dylibs"][0]["name"] == "com.apple.kernel"
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/main.kc", ["-symbols", "-arch", "x86_64"])
kernelClassFooVMAddr = findSymbolVMAddr(kernel_cache, 0, "__ZN11KernelClass3fooEv")
if enableLogging:
print "kernelClassFooVMAddr: " + kernelClassFooVMAddr
kernelClassUsed0VMAddr = findSymbolVMAddr(kernel_cache, 0, "__ZN11KernelClass16kernelClassUsed0Ev")
if enableLogging:
print "kernelClassUsed0VMAddr: " + kernelClassUsed0VMAddr
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/main.kc", ["-fixups", "-arch", "x86_64"])
kernelFooFixupAddr = findFixupVMAddr(kernel_cache, "kc(0) + " + kernelClassFooVMAddr + " : pointer64")
if enableLogging:
print "kernelFooFixupAddr: " + kernelFooFixupAddr
kernelFooNextFixupAddr = offsetVMAddr(kernelFooFixupAddr, 8)
if enableLogging:
print "kernelFooNextFixupAddr: " + kernelFooNextFixupAddr
assert kernel_cache.dictionary()["fixups"][kernelFooNextFixupAddr] == "kc(0) + " + kernelClassUsed0VMAddr + " : pointer64"
kernelClassUsed0VMOffset = offsetVMAddr(kernelClassUsed0VMAddr, -0x4000)
if enableLogging:
print "kernelClassUsed0VMOffset: " + kernelClassUsed0VMOffset
kernel_cache.buildPageableKernelCollection("x86_64", "/auxkc-pageablekc-vtable-patching/pageable.kc", "/auxkc-pageablekc-vtable-patching/main.kc", "/auxkc-pageablekc-vtable-patching/extensions", ["com.apple.foo1", "com.apple.foo2"], [])
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/pageable.kc", ["-layout", "-arch", "x86_64"])
assert len(kernel_cache.dictionary()["dylibs"]) == 2
assert kernel_cache.dictionary()["dylibs"][0]["name"] == "com.apple.foo1"
assert kernel_cache.dictionary()["dylibs"][1]["name"] == "com.apple.foo2"
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/pageable.kc", ["-symbols", "-arch", "x86_64"])
pageableFoo1FooVMAddr = findSymbolVMAddr(kernel_cache, 0, "__ZN4Foo13fooEv")
if enableLogging:
print "pageableFoo1FooVMAddr: " + pageableFoo1FooVMAddr
pageableFoo1FooUsed0VMAddr = findSymbolVMAddr(kernel_cache, 0, "__ZN4Foo19foo1Used0Ev")
if enableLogging:
print "pageableFoo1FooUsed0VMAddr: " + pageableFoo1FooUsed0VMAddr
pageableFoo1FooUsed1VMAddr = findSymbolVMAddr(kernel_cache, 0, "__ZN4Foo19foo1Used1Ev")
if enableLogging:
print "pageableFoo1FooUsed1VMAddr: " + pageableFoo1FooUsed1VMAddr
pageableFoo2FooVMAddr = findSymbolVMAddr(kernel_cache, 1, "__ZN4Foo23fooEv")
if enableLogging:
print "pageableFoo2FooVMAddr: " + pageableFoo2FooVMAddr
pageableFoo2FooUsed0VMAddr = findSymbolVMAddr(kernel_cache, 1, "__ZN4Foo29foo1Used0Ev")
if enableLogging:
print "pageableFoo2FooUsed0VMAddr: " + pageableFoo2FooUsed0VMAddr
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/pageable.kc", ["-fixups", "-arch", "x86_64"])
kernel_cache.dictionary()["fixups"] == "none"
pageableFoo1FooFixupAddr = findPagableFixupVMAddr(kernel_cache, 0, "kc(1) + " + pageableFoo1FooVMAddr)
if enableLogging:
print "pageableFoo1FooFixupAddr: " + pageableFoo1FooFixupAddr
pageableFoo1FooNextFixupAddr = offsetVMAddr(pageableFoo1FooFixupAddr, 8)
if enableLogging:
print "pageableFoo1FooNextFixupAddr: " + pageableFoo1FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][0]["fixups"][pageableFoo1FooNextFixupAddr] == "kc(0) + " + kernelClassUsed0VMOffset
pageableFoo1FooNextFixupAddr = offsetVMAddr(pageableFoo1FooFixupAddr, 16)
if enableLogging:
print "pageableFoo1FooNextFixupAddr: " + pageableFoo1FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][0]["fixups"][pageableFoo1FooNextFixupAddr] == "kc(1) + " + pageableFoo1FooUsed0VMAddr
pageableFoo1FooNextFixupAddr = offsetVMAddr(pageableFoo1FooFixupAddr, 24)
if enableLogging:
print "pageableFoo1FooNextFixupAddr: " + pageableFoo1FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][0]["fixups"][pageableFoo1FooNextFixupAddr] == "kc(1) + " + pageableFoo1FooUsed1VMAddr
pageableFoo2FooFixupAddr = findPagableFixupVMAddr(kernel_cache, 1, "kc(1) + " + pageableFoo2FooVMAddr)
if enableLogging:
print "pageableFoo2FooFixupAddr: " + pageableFoo2FooFixupAddr
pageableFoo2FooNextFixupAddr = offsetVMAddr(pageableFoo2FooFixupAddr, 8)
if enableLogging:
print "pageableFoo2FooNextFixupAddr: " + pageableFoo2FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][1]["fixups"][pageableFoo2FooNextFixupAddr] == "kc(0) + " + kernelClassUsed0VMOffset
pageableFoo2FooNextFixupAddr = offsetVMAddr(pageableFoo2FooFixupAddr, 16)
if enableLogging:
print "pageableFoo2FooNextFixupAddr: " + pageableFoo2FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][1]["fixups"][pageableFoo2FooNextFixupAddr] == "kc(1) + " + pageableFoo2FooUsed0VMAddr
pageableFoo2FooNextFixupAddr = offsetVMAddr(pageableFoo2FooFixupAddr, 24)
if enableLogging:
print "pageableFoo2FooNextFixupAddr: " + pageableFoo2FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][1]["fixups"][pageableFoo2FooNextFixupAddr] == "kc(1) + " + pageableFoo1FooUsed1VMAddr
kernel_cache.buildAuxKernelCollection("x86_64", "/auxkc-pageablekc-vtable-patching/aux.kc", "/auxkc-pageablekc-vtable-patching/main.kc", "/auxkc-pageablekc-vtable-patching/pageable.kc", "/auxkc-pageablekc-vtable-patching/extensions", ["com.apple.bar1", "com.apple.bar2"], [])
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/aux.kc", ["-layout", "-arch", "x86_64"])
assert len(kernel_cache.dictionary()["dylibs"]) == 2
assert kernel_cache.dictionary()["dylibs"][0]["name"] == "com.apple.bar1"
assert kernel_cache.dictionary()["dylibs"][1]["name"] == "com.apple.bar2"
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/aux.kc", ["-symbols", "-arch", "x86_64"])
auxBar1FooVMAddr = findSymbolVMAddr(kernel_cache, 0, "__ZN4Bar13fooEv")
if enableLogging:
print "auxBar1FooVMAddr: " + auxBar1FooVMAddr
auxBar2FooVMAddr = findSymbolVMAddr(kernel_cache, 1, "__ZN4Bar23fooEv")
if enableLogging:
print "auxBar2FooVMAddr: " + auxBar2FooVMAddr
kernel_cache.analyze("/auxkc-pageablekc-vtable-patching/aux.kc", ["-fixups", "-arch", "x86_64"])
auxBar1FooFixupAddr = findAuxFixupVMAddr(kernel_cache, 0, "kc(3) + " + auxBar1FooVMAddr)
if enableLogging:
print "auxBar1FooFixupAddr: " + auxBar1FooFixupAddr
auxBar1FooNextFixupAddr = offsetVMAddr(auxBar1FooFixupAddr, 8)
if enableLogging:
print "auxBar1FooNextFixupAddr: " + auxBar1FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][0]["fixups"][auxBar1FooNextFixupAddr] == "kc(0) + " + kernelClassUsed0VMOffset
auxBar1FooNextFixupAddr = offsetVMAddr(auxBar1FooFixupAddr, 16)
if enableLogging:
print "auxBar1FooNextFixupAddr: " + auxBar1FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][0]["fixups"][auxBar1FooNextFixupAddr] == "kc(1) + " + pageableFoo2FooUsed0VMAddr
auxBar1FooNextFixupAddr = offsetVMAddr(auxBar1FooFixupAddr, 24)
if enableLogging:
print "auxBar1FooNextFixupAddr: " + auxBar1FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][0]["fixups"][auxBar1FooNextFixupAddr] == "kc(1) + " + pageableFoo1FooUsed1VMAddr
auxBar2FooFixupAddr = findAuxFixupVMAddr(kernel_cache, 1, "kc(3) + " + auxBar2FooVMAddr)
if enableLogging:
print "auxBar2FooFixupAddr: " + auxBar2FooFixupAddr
auxBar2FooNextFixupAddr = offsetVMAddr(auxBar2FooFixupAddr, 8)
if enableLogging:
print "auxBar2FooNextFixupAddr: " + auxBar2FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][1]["fixups"][auxBar2FooNextFixupAddr] == "kc(0) + " + kernelClassUsed0VMOffset
auxBar2FooNextFixupAddr = offsetVMAddr(auxBar2FooFixupAddr, 16)
if enableLogging:
print "auxBar2FooNextFixupAddr: " + auxBar2FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][1]["fixups"][auxBar2FooNextFixupAddr] == "kc(1) + " + pageableFoo2FooUsed0VMAddr
auxBar2FooNextFixupAddr = offsetVMAddr(auxBar2FooFixupAddr, 24)
if enableLogging:
print "auxBar2FooNextFixupAddr: " + auxBar2FooNextFixupAddr
assert kernel_cache.dictionary()["dylibs"][1]["fixups"][auxBar2FooNextFixupAddr] == "kc(1) + " + pageableFoo1FooUsed1VMAddr