import binaryninja
import ctypes, os
from typing import Optional
from . import kernelcache_enums
# Load core module
import platform
core = None
core_platform = platform.system()
from binaryninja._binaryninjacore import BNFreeString, BNFreeStringList, BNAllocString
from binaryninja import Settings
if Settings().get_bool("corePlugins.view.kernelCache"):
from binaryninja._binaryninjacore import BNGetBundledPluginDirectory
if core_platform == "Darwin":
_base_path = BNGetBundledPluginDirectory()
core = ctypes.CDLL(os.path.join(_base_path, "libkernelcache.dylib"))
elif core_platform == "Linux":
_base_path = BNGetBundledPluginDirectory()
core = ctypes.CDLL(os.path.join(_base_path, "libkernelcache.so"))
elif (core_platform == "Windows") or (core_platform.find("CYGWIN_NT") == 0):
_base_path = BNGetBundledPluginDirectory()
core = ctypes.CDLL(os.path.join(_base_path, "kernelcache.dll"))
else:
raise Exception("OS not supported")
else:
from binaryninja._binaryninjacore import BNGetUserPluginDirectory
if core_platform == "Darwin":
_base_path = BNGetUserPluginDirectory()
core = ctypes.CDLL(os.path.join(_base_path, "libkernelcache.dylib"))
elif core_platform == "Linux":
_base_path = BNGetUserPluginDirectory()
core = ctypes.CDLL(os.path.join(_base_path, "libkernelcache.so"))
elif (core_platform == "Windows") or (core_platform.find("CYGWIN_NT") == 0):
_base_path = BNGetUserPluginDirectory()
core = ctypes.CDLL(os.path.join(_base_path, "kernelcache.dll"))
else:
raise Exception("OS not supported")
[docs]
def cstr(var) -> Optional[ctypes.c_char_p]:
if var is None:
return None
if isinstance(var, bytes):
return var
return var.encode("utf-8")
[docs]
def pyNativeStr(arg):
if isinstance(arg, str):
return arg
else:
return arg.decode('utf8')
[docs]
def free_string(value:ctypes.c_char_p) -> None:
BNFreeString(ctypes.cast(value, ctypes.POINTER(ctypes.c_byte)))
# Type definitions
from binaryninja._binaryninjacore import BNBinaryView, BNBinaryViewHandle
[docs]
class BNKernelCacheController(ctypes.Structure):
pass
BNKernelCacheControllerHandle = ctypes.POINTER(BNKernelCacheController)
KernelCacheEntryTypeEnum = ctypes.c_int
[docs]
class BNKernelCacheImage(ctypes.Structure):
@property
def name(self):
return pyNativeStr(self._name)
@name.setter
def name(self, value):
self._name = cstr(value)
BNKernelCacheImageHandle = ctypes.POINTER(BNKernelCacheImage)
[docs]
class BNKernelCacheMappingInfo(ctypes.Structure):
pass
BNKernelCacheMappingInfoHandle = ctypes.POINTER(BNKernelCacheMappingInfo)
[docs]
class BNKernelCacheRegion(ctypes.Structure):
@property
def name(self):
return pyNativeStr(self._name)
@name.setter
def name(self, value):
self._name = cstr(value)
BNKernelCacheRegionHandle = ctypes.POINTER(BNKernelCacheRegion)
KernelCacheRegionTypeEnum = ctypes.c_int
[docs]
class BNKernelCacheSymbol(ctypes.Structure):
@property
def name(self):
return pyNativeStr(self._name)
@name.setter
def name(self, value):
self._name = cstr(value)
BNKernelCacheSymbolHandle = ctypes.POINTER(BNKernelCacheSymbol)
SegmentFlagEnum = ctypes.c_int
SymbolTypeEnum = ctypes.c_int
# Structure definitions
BNKernelCacheImage._fields_ = [
("_name", ctypes.c_char_p),
("headerVirtualAddress", ctypes.c_ulonglong),
("headerFileAddress", ctypes.c_ulonglong),
]
BNKernelCacheMappingInfo._fields_ = [
("vmAddress", ctypes.c_ulonglong),
("size", ctypes.c_ulonglong),
("fileOffset", ctypes.c_ulonglong),
]
BNKernelCacheRegion._fields_ = [
("regionType", KernelCacheRegionTypeEnum),
("_name", ctypes.c_char_p),
("vmAddress", ctypes.c_ulonglong),
("size", ctypes.c_ulonglong),
("imageStart", ctypes.c_ulonglong),
("flags", SegmentFlagEnum),
]
BNKernelCacheSymbol._fields_ = [
("symbolType", SymbolTypeEnum),
("address", ctypes.c_ulonglong),
("_name", ctypes.c_char_p),
]
# Function definitions
# -------------------------------------------------------
# _BNFreeKernelCacheControllerReference
_BNFreeKernelCacheControllerReference = core.BNFreeKernelCacheControllerReference
_BNFreeKernelCacheControllerReference.restype = None
_BNFreeKernelCacheControllerReference.argtypes = [
ctypes.POINTER(BNKernelCacheController),
]
# noinspection PyPep8Naming
[docs]
def BNFreeKernelCacheControllerReference(
controller: ctypes.POINTER(BNKernelCacheController)
) -> None:
return _BNFreeKernelCacheControllerReference(controller)
# -------------------------------------------------------
# _BNGetKernelCacheController
_BNGetKernelCacheController = core.BNGetKernelCacheController
_BNGetKernelCacheController.restype = ctypes.POINTER(BNKernelCacheController)
_BNGetKernelCacheController.argtypes = [
ctypes.POINTER(BNBinaryView),
]
# noinspection PyPep8Naming
[docs]
def BNGetKernelCacheController(
data: ctypes.POINTER(BNBinaryView)
) -> Optional[ctypes.POINTER(BNKernelCacheController)]:
result = _BNGetKernelCacheController(data)
if not result:
return None
return result
# -------------------------------------------------------
# _BNKernelCacheControllerApplyImage
_BNKernelCacheControllerApplyImage = core.BNKernelCacheControllerApplyImage
_BNKernelCacheControllerApplyImage.restype = ctypes.c_bool
_BNKernelCacheControllerApplyImage.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.POINTER(BNBinaryView),
ctypes.POINTER(BNKernelCacheImage),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerApplyImage(
controller: ctypes.POINTER(BNKernelCacheController),
view: ctypes.POINTER(BNBinaryView),
image: ctypes.POINTER(BNKernelCacheImage)
) -> bool:
return _BNKernelCacheControllerApplyImage(controller, view, image)
# -------------------------------------------------------
# _BNKernelCacheControllerGetImageAt
_BNKernelCacheControllerGetImageAt = core.BNKernelCacheControllerGetImageAt
_BNKernelCacheControllerGetImageAt.restype = ctypes.c_bool
_BNKernelCacheControllerGetImageAt.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.c_ulonglong,
ctypes.POINTER(BNKernelCacheImage),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetImageAt(
controller: ctypes.POINTER(BNKernelCacheController),
address: int,
image: ctypes.POINTER(BNKernelCacheImage)
) -> bool:
return _BNKernelCacheControllerGetImageAt(controller, address, image)
# -------------------------------------------------------
# _BNKernelCacheControllerGetImageContaining
_BNKernelCacheControllerGetImageContaining = core.BNKernelCacheControllerGetImageContaining
_BNKernelCacheControllerGetImageContaining.restype = ctypes.c_bool
_BNKernelCacheControllerGetImageContaining.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.c_ulonglong,
ctypes.POINTER(BNKernelCacheImage),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetImageContaining(
controller: ctypes.POINTER(BNKernelCacheController),
address: int,
image: ctypes.POINTER(BNKernelCacheImage)
) -> bool:
return _BNKernelCacheControllerGetImageContaining(controller, address, image)
# -------------------------------------------------------
# _BNKernelCacheControllerGetImageDependencies
_BNKernelCacheControllerGetImageDependencies = core.BNKernelCacheControllerGetImageDependencies
_BNKernelCacheControllerGetImageDependencies.restype = ctypes.POINTER(ctypes.c_char_p)
_BNKernelCacheControllerGetImageDependencies.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.POINTER(BNKernelCacheImage),
ctypes.POINTER(ctypes.c_ulonglong),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetImageDependencies(
controller: ctypes.POINTER(BNKernelCacheController),
image: ctypes.POINTER(BNKernelCacheImage),
count: ctypes.POINTER(ctypes.c_ulonglong)
) -> Optional[ctypes.POINTER(ctypes.c_char_p)]:
result = _BNKernelCacheControllerGetImageDependencies(controller, image, count)
if not result:
return None
return result
# -------------------------------------------------------
# _BNKernelCacheControllerGetImageWithName
_BNKernelCacheControllerGetImageWithName = core.BNKernelCacheControllerGetImageWithName
_BNKernelCacheControllerGetImageWithName.restype = ctypes.c_bool
_BNKernelCacheControllerGetImageWithName.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.c_char_p,
ctypes.POINTER(BNKernelCacheImage),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetImageWithName(
controller: ctypes.POINTER(BNKernelCacheController),
name: Optional[str],
image: ctypes.POINTER(BNKernelCacheImage)
) -> bool:
return _BNKernelCacheControllerGetImageWithName(controller, cstr(name), image)
# -------------------------------------------------------
# _BNKernelCacheControllerGetImages
_BNKernelCacheControllerGetImages = core.BNKernelCacheControllerGetImages
_BNKernelCacheControllerGetImages.restype = ctypes.POINTER(BNKernelCacheImage)
_BNKernelCacheControllerGetImages.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.POINTER(ctypes.c_ulonglong),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetImages(
controller: ctypes.POINTER(BNKernelCacheController),
count: ctypes.POINTER(ctypes.c_ulonglong)
) -> Optional[ctypes.POINTER(BNKernelCacheImage)]:
result = _BNKernelCacheControllerGetImages(controller, count)
if not result:
return None
return result
# -------------------------------------------------------
# _BNKernelCacheControllerGetLoadedImages
_BNKernelCacheControllerGetLoadedImages = core.BNKernelCacheControllerGetLoadedImages
_BNKernelCacheControllerGetLoadedImages.restype = ctypes.POINTER(BNKernelCacheImage)
_BNKernelCacheControllerGetLoadedImages.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.POINTER(ctypes.c_ulonglong),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetLoadedImages(
controller: ctypes.POINTER(BNKernelCacheController),
count: ctypes.POINTER(ctypes.c_ulonglong)
) -> Optional[ctypes.POINTER(BNKernelCacheImage)]:
result = _BNKernelCacheControllerGetLoadedImages(controller, count)
if not result:
return None
return result
# -------------------------------------------------------
# _BNKernelCacheControllerGetSymbolAt
_BNKernelCacheControllerGetSymbolAt = core.BNKernelCacheControllerGetSymbolAt
_BNKernelCacheControllerGetSymbolAt.restype = ctypes.c_bool
_BNKernelCacheControllerGetSymbolAt.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.c_ulonglong,
ctypes.POINTER(BNKernelCacheSymbol),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetSymbolAt(
controller: ctypes.POINTER(BNKernelCacheController),
address: int,
symbol: ctypes.POINTER(BNKernelCacheSymbol)
) -> bool:
return _BNKernelCacheControllerGetSymbolAt(controller, address, symbol)
# -------------------------------------------------------
# _BNKernelCacheControllerGetSymbolWithName
_BNKernelCacheControllerGetSymbolWithName = core.BNKernelCacheControllerGetSymbolWithName
_BNKernelCacheControllerGetSymbolWithName.restype = ctypes.c_bool
_BNKernelCacheControllerGetSymbolWithName.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.c_char_p,
ctypes.POINTER(BNKernelCacheSymbol),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetSymbolWithName(
controller: ctypes.POINTER(BNKernelCacheController),
name: Optional[str],
symbol: ctypes.POINTER(BNKernelCacheSymbol)
) -> bool:
return _BNKernelCacheControllerGetSymbolWithName(controller, cstr(name), symbol)
# -------------------------------------------------------
# _BNKernelCacheControllerGetSymbols
_BNKernelCacheControllerGetSymbols = core.BNKernelCacheControllerGetSymbols
_BNKernelCacheControllerGetSymbols.restype = ctypes.POINTER(BNKernelCacheSymbol)
_BNKernelCacheControllerGetSymbols.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.POINTER(ctypes.c_ulonglong),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerGetSymbols(
controller: ctypes.POINTER(BNKernelCacheController),
count: ctypes.POINTER(ctypes.c_ulonglong)
) -> Optional[ctypes.POINTER(BNKernelCacheSymbol)]:
result = _BNKernelCacheControllerGetSymbols(controller, count)
if not result:
return None
return result
# -------------------------------------------------------
# _BNKernelCacheControllerIsImageLoaded
_BNKernelCacheControllerIsImageLoaded = core.BNKernelCacheControllerIsImageLoaded
_BNKernelCacheControllerIsImageLoaded.restype = ctypes.c_bool
_BNKernelCacheControllerIsImageLoaded.argtypes = [
ctypes.POINTER(BNKernelCacheController),
ctypes.POINTER(BNKernelCacheImage),
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheControllerIsImageLoaded(
controller: ctypes.POINTER(BNKernelCacheController),
image: ctypes.POINTER(BNKernelCacheImage)
) -> bool:
return _BNKernelCacheControllerIsImageLoaded(controller, image)
# -------------------------------------------------------
# _BNKernelCacheFreeImage
_BNKernelCacheFreeImage = core.BNKernelCacheFreeImage
_BNKernelCacheFreeImage.restype = None
_BNKernelCacheFreeImage.argtypes = [
BNKernelCacheImage,
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheFreeImage(
image: BNKernelCacheImage
) -> None:
return _BNKernelCacheFreeImage(image)
# -------------------------------------------------------
# _BNKernelCacheFreeImageList
_BNKernelCacheFreeImageList = core.BNKernelCacheFreeImageList
_BNKernelCacheFreeImageList.restype = None
_BNKernelCacheFreeImageList.argtypes = [
ctypes.POINTER(BNKernelCacheImage),
ctypes.c_ulonglong,
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheFreeImageList(
images: ctypes.POINTER(BNKernelCacheImage),
count: int
) -> None:
return _BNKernelCacheFreeImageList(images, count)
# -------------------------------------------------------
# _BNKernelCacheFreeSymbol
_BNKernelCacheFreeSymbol = core.BNKernelCacheFreeSymbol
_BNKernelCacheFreeSymbol.restype = None
_BNKernelCacheFreeSymbol.argtypes = [
BNKernelCacheSymbol,
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheFreeSymbol(
symbol: BNKernelCacheSymbol
) -> None:
return _BNKernelCacheFreeSymbol(symbol)
# -------------------------------------------------------
# _BNKernelCacheFreeSymbolList
_BNKernelCacheFreeSymbolList = core.BNKernelCacheFreeSymbolList
_BNKernelCacheFreeSymbolList.restype = None
_BNKernelCacheFreeSymbolList.argtypes = [
ctypes.POINTER(BNKernelCacheSymbol),
ctypes.c_ulonglong,
]
# noinspection PyPep8Naming
[docs]
def BNKernelCacheFreeSymbolList(
symbols: ctypes.POINTER(BNKernelCacheSymbol),
count: int
) -> None:
return _BNKernelCacheFreeSymbolList(symbols, count)
# -------------------------------------------------------
# _BNNewKernelCacheControllerReference
_BNNewKernelCacheControllerReference = core.BNNewKernelCacheControllerReference
_BNNewKernelCacheControllerReference.restype = ctypes.POINTER(BNKernelCacheController)
_BNNewKernelCacheControllerReference.argtypes = [
ctypes.POINTER(BNKernelCacheController),
]
# noinspection PyPep8Naming
[docs]
def BNNewKernelCacheControllerReference(
controller: ctypes.POINTER(BNKernelCacheController)
) -> Optional[ctypes.POINTER(BNKernelCacheController)]:
result = _BNNewKernelCacheControllerReference(controller)
if not result:
return None
return result
# Helper functions
[docs]
def handle_of_type(value, handle_type):
if isinstance(value, ctypes.POINTER(handle_type)) or isinstance(value, ctypes.c_void_p):
return ctypes.cast(value, ctypes.POINTER(handle_type))
raise ValueError('expected pointer to %s' % str(handle_type))