# Path: dbginterface.py
# def LocalKernelDebugger(quiet=True):
#     """| Check that all conditions to Local Kernel Debugging are met
#        | and return a LKD (subclass of :class:`LocalKernelDebuggerBase`
#     """
#     if not windows.utils.check_debug():
#         raise LocalKernelDebuggerError("Cannot perform LocalKernelDebugging on kernel not in DEBUG mode")
#     if not windows.utils.check_is_elevated():
#         raise LocalKernelDebuggerError("Cannot perform LocalKernelDebugging from non-Admin process")
#     windows.utils.enable_privilege(SE_DEBUG_NAME, True)
#     if windows.system.bitness == 64:
#         if windows.current_process.is_wow_64:
#             raise LocalKernelDebuggerError("Cannot perform LocalKernelDebugging from SysWow64 process (please launch from 64bits python)")
#         return LocalKernelDebugger64(quiet)
#     return LocalKernelDebugger32(quiet)


import ctypes
import sys
import os
import time
from windows.generated_def.winstructs import *
from dbginterface import LocalKernelDebugger
        # Re-activate IA32_PMC0
        kdbg.write_msr(MSR_PERF_GLOBAL_CTRL, 1)

    # PEBS records getters
    def get_number_pebs_records(self, proc_nb):
        """Get the number of PEBS entries stored in the buffer for proc `proc_nb`"""
        ds_addr, ds_content = self.get_DsManagementArea(proc_nb)
        return (ds_content.PEBSIndex - ds_content.PEBSBufferBase) / ctypes.sizeof(self.PEBSRecord)

    def get_pebs_records(self, proc_nb, max_dump=0xffffffffffffffff):
        """Get the PEBS entries stored in the buffer for proc `proc_nb`"""
        ds_addr, ds_content = self.get_DsManagementArea(proc_nb)
        nb_pebs_entry = self.get_number_pebs_records(proc_nb)
        print("Buffer contains {0} entries".format(nb_pebs_entry))
        nb_pebs_entry = min(nb_pebs_entry, max_dump)
        print("Dumping {0} first entries".format(nb_pebs_entry))
        pebs_entries_buffer = (self.PEBSRecord * nb_pebs_entry)()
        kdbg.read_virtual_memory_into(ds_content.PEBSBufferBase, pebs_entries_buffer)
        return pebs_entries_buffer

    def dump_PEBS_records(self):
        ds_addr, ds_content = self.get_DsManagementArea(proc_nb)
        print("PEBSBufferBase = {0}".format(hex(ds_content.PEBSBufferBase)))
        x = self.get_pebs_records(0)
        for pebs_record in x:
            print("    {0} = {1}".format("rip", hex(pebs_record.rip)))            
            
            

# BTS

# Path: dbginterface.py
# def LocalKernelDebugger(quiet=True):
#     """| Check that all conditions to Local Kernel Debugging are met
#        | and return a LKD (subclass of :class:`LocalKernelDebuggerBase`
#     """
#     if not windows.utils.check_debug():
#         raise LocalKernelDebuggerError("Cannot perform LocalKernelDebugging on kernel not in DEBUG mode")
#     if not windows.utils.check_is_elevated():
#         raise LocalKernelDebuggerError("Cannot perform LocalKernelDebugging from non-Admin process")
#     windows.utils.enable_privilege(SE_DEBUG_NAME, True)
#     if windows.system.bitness == 64:
#         if windows.current_process.is_wow_64:
#             raise LocalKernelDebuggerError("Cannot perform LocalKernelDebugging from SysWow64 process (please launch from 64bits python)")
#         return LocalKernelDebugger64(quiet)
#     return LocalKernelDebugger32(quiet)


# Path: example/PEBS_BTS_demo.py
import ctypes
import sys
import os
import time
from windows.generated_def.winstructs import *
from dbginterface import LocalKernelDebugger

        # Re-activate IA32_PMC0
        kdbg.write_msr(MSR_PERF_GLOBAL_CTRL, 1)

    # PEBS records getters
    def get_number_pebs_records(self, proc_nb):
        """Get the number of PEBS entries stored in the buffer for proc `proc_nb`"""
        ds_addr, ds_content = self.get_DsManagementArea(proc_nb)
        return (ds_content.PEBSIndex - ds_content.PEBSBufferBase) / ctypes.sizeof(self.PEBSRecord)

    def get_pebs_records(self, proc_nb, max_dump=0xffffffffffffffff):
        """Get the PEBS entries stored in the buffer for proc `proc_nb`"""
        ds_addr, ds_content = self.get_DsManagementArea(proc_nb)
        nb_pebs_entry = self.get_number_pebs_records(proc_nb)
        print("Buffer contains {0} entries".format(nb_pebs_entry))
        nb_pebs_entry = min(nb_pebs_entry, max_dump)
        print("Dumping {0} first entries".format(nb_pebs_entry))
        pebs_entries_buffer = (self.PEBSRecord * nb_pebs_entry)()
        kdbg.read_virtual_memory_into(ds_content.PEBSBufferBase, pebs_entries_buffer)
        return pebs_entries_buffer

    def dump_PEBS_records(self):
        ds_addr, ds_content = self.get_DsManagementArea(proc_nb)
        print("PEBSBufferBase = {0}".format(hex(ds_content.PEBSBufferBase)))
        x = self.get_pebs_records(0)
        for pebs_record in x:
            print("    {0} = {1}".format("rip", hex(pebs_record.rip)))            
            
            

# BTS

kdbg = LocalKernelDebugger()