├── Bin ├── PulseDbg.exe ├── bootx64.efi └── PulseConfig.exe ├── WikiPic ├── ajays.jpg ├── comres.png ├── usbkd.png ├── vmwcpu.png ├── vmwefi.png ├── vmwser.png ├── badcable.png ├── bootvars.png ├── bootxxxx.png ├── devbusy.png ├── fwpoll1.png ├── fwpoll2.png ├── usb2view.png └── vmwboot.png ├── SDK ├── Bin │ └── Windows │ │ ├── x64 │ │ ├── PulseEng.dll │ │ └── PulseEng.lib │ │ └── x86 │ │ ├── PulseEng.dll │ │ └── PulseEng.lib ├── Headers │ ├── ps_status.h │ ├── ps.h │ └── ps_ctx.h └── Example │ └── PulseEngClient.cpp └── README.md /Bin/PulseDbg.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/Bin/PulseDbg.exe -------------------------------------------------------------------------------- /Bin/bootx64.efi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/Bin/bootx64.efi -------------------------------------------------------------------------------- /WikiPic/ajays.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/ajays.jpg -------------------------------------------------------------------------------- /WikiPic/comres.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/comres.png -------------------------------------------------------------------------------- /WikiPic/usbkd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/usbkd.png -------------------------------------------------------------------------------- /WikiPic/vmwcpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/vmwcpu.png -------------------------------------------------------------------------------- /WikiPic/vmwefi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/vmwefi.png -------------------------------------------------------------------------------- /WikiPic/vmwser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/vmwser.png -------------------------------------------------------------------------------- /Bin/PulseConfig.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/Bin/PulseConfig.exe -------------------------------------------------------------------------------- /WikiPic/badcable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/badcable.png -------------------------------------------------------------------------------- /WikiPic/bootvars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/bootvars.png -------------------------------------------------------------------------------- /WikiPic/bootxxxx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/bootxxxx.png -------------------------------------------------------------------------------- /WikiPic/devbusy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/devbusy.png -------------------------------------------------------------------------------- /WikiPic/fwpoll1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/fwpoll1.png -------------------------------------------------------------------------------- /WikiPic/fwpoll2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/fwpoll2.png -------------------------------------------------------------------------------- /WikiPic/usb2view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/usb2view.png -------------------------------------------------------------------------------- /WikiPic/vmwboot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/WikiPic/vmwboot.png -------------------------------------------------------------------------------- /SDK/Bin/Windows/x64/PulseEng.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/SDK/Bin/Windows/x64/PulseEng.dll -------------------------------------------------------------------------------- /SDK/Bin/Windows/x64/PulseEng.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/SDK/Bin/Windows/x64/PulseEng.lib -------------------------------------------------------------------------------- /SDK/Bin/Windows/x86/PulseEng.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/SDK/Bin/Windows/x86/PulseEng.dll -------------------------------------------------------------------------------- /SDK/Bin/Windows/x86/PulseEng.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/honorarybot/PulseDbg/HEAD/SDK/Bin/Windows/x86/PulseEng.lib -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PulseDBG 2 | 3 | !!! Now moving to !!! 4 | https://pulsedbg.com 5 | 6 | Hypervisor-based debugger 7 | 8 | What does it consist of: 9 | - Hypervisor part: loaded on a debuggee site 10 | - Client part: client for the debugger 11 | - Transport: maintains communication between debuggee and debugger (which are different machines) 12 | 13 | Supported environment: 14 | - Intel Core I* processor 15 | - UEFI capable firmware 16 | - UEFI capable OS: by this I mean it was installed in UEFI mode on GPT partition 17 | - CSM capable firmware: i.e. UEFI that supports Compatibility Support Module for launching legacy bootloaders 18 | 19 | Supported transports: 20 | - Internal COM port 21 | - FireWire 1394 controller 22 | - USB 2 Debug Port (with USB 2.0 Debug Cable) 23 | - Intel Network Cards 24 | 25 | What's next: 26 | - Checkout project wiki pages 27 | - Check out a video by ApertureSecurity as an example of debugger configuration with VmWare https://www.youtube.com/watch?v=RU09zWsfIa0 28 | - Check out SDK documentation at https://github.com/honorarybot/PulseDbg/wiki/SDK-documentation 29 | -------------------------------------------------------------------------------- /SDK/Headers/ps_status.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma once 4 | 5 | typedef int64_t PULSE_STATUS; 6 | 7 | #define PULSE_SUCCESS(x) (((int32_t)x)>=0) 8 | 9 | #define PULSE_STATUS_SUCCESS 0x00000000 10 | #define PULSE_STATUS_PARTIAL_READ 0x00000005 11 | #define PULSE_STATUS_PARTIAL_WRITE 0x00000006 12 | #define PULSE_STATUS_UNSUCCESSFUL 0xC0000000 13 | #define PULSE_STATUS_TIMEOUT 0xC0000002 14 | #define PULSE_STATUS_ENGINE_INIT_FAILED 0xC0000003 15 | #define PULSE_STATUS_INSUFFICIENT_RESOURCES 0xC0000008 16 | #define PULSE_STATUS_TRANSPORT_INIT_FAILED 0xC000000A 17 | #define PULSE_STATUS_INVALID_PARAMETER 0xC000000E 18 | #define PULSE_STATUS_NOT_SUPPORTED 0xC000000D 19 | #define PULSE_STATUS_INVALID_TRANSLATION 0xC0000017 20 | #define PULSE_STATUS_NO_PACKET 0xC0000018 21 | #define PULSE_STATUS_BUFFER_OVERFLOW 0xC000001A 22 | #define PULSE_STATUS_INVALID_CHECKSUM 0xC000001B 23 | #define PULSE_STATUS_INVALID_START_OF_PACKET 0xC0000046 24 | #define PULSE_STATUS_INVALID_END_OF_PACKET 0xC000001C 25 | #define PULSE_STATUS_INVALID_PACKET 0xC000001D 26 | #define PULSE_STATUS_INVALID_CPU_MODE 0xC000001F 27 | #define PULSE_STATUS_PACKET_TOO_LARGE 0xC0000020 28 | #define PULSE_STATUS_TRANSPORT_RESET_FAILED 0xC000002A 29 | #define PULSE_STATUS_READ_FAILED 0xC000002B 30 | #define PULSE_STATUS_WRITE_FAILED 0xC000002C 31 | #define PULSE_STATUS_DEVICE_NOT_FOUND 0xC000002D 32 | #define PULSE_STATUS_DEVICE_MISCONFIGURATION 0xC000002E 33 | #define PULSE_STATUS_DEVICE_INIT_FAILED 0xC000002F 34 | #define PULSE_STATUS_GENERAL_PROTECTION 0xC0000045 35 | #define PULSE_STATUS_PATTERN_NOT_FOUND 0xC0000060 36 | #define PULSE_STATUS_BREAKPOINT_TABLE_EMPTY 0xC0000050 37 | #define PULSE_STATUS_BREAKPOINT_NOT_FOUND 0xC0000051 38 | #define PULSE_STATUS_BREAKPOINT_TABLE_FULL 0xC0000052 39 | #define PULSE_STATUS_BREAKPOINT_NOT_HIT 0xC0000053 40 | #define PULSE_STATUS_FILTER_TABLE_FULL 0xC0000054 41 | #define PULSE_STATUS_FILTER_TABLE_EMPTY 0xC0000055 42 | #define PULSE_STATUS_FILTER_NOT_FOUND 0xC0000056 43 | #define PULSE_STATUS_NOT_ALIGNED 0xC0000061 44 | #define PULSE_STATUS_INVALID_ACCESS_SIZE 0xC0000062 45 | #define PULSE_STATUS_INVALID_TYPE 0xC0000063 46 | #define PULSE_STATUS_INVALID_LENGTH 0xC0000064 47 | #define PULSE_STATUS_INVALID_REQUEST 0xC0000065 48 | -------------------------------------------------------------------------------- /SDK/Headers/ps.h: -------------------------------------------------------------------------------- 1 | #include "ps_status.h" 2 | #include "ps_ctx.h" 3 | 4 | #pragma once 5 | 6 | // 7 | // Transport-related functions 8 | // 9 | 10 | typedef void* PPS_TRANSPORT; 11 | typedef void* PPS_ENGINE; 12 | 13 | typedef enum _PS_TRANSPORT_TYPE 14 | { 15 | pttInvalid = 0, 16 | pttSerial = 1, 17 | pttNet = 6, 18 | pttPipe = 9, 19 | pttLocal = 10, 20 | pttMax = 10 21 | } PS_TRANSPORT_TYPE, *PPS_TRANSPORT_TYPE; 22 | 23 | typedef struct _PS_STATE_INFO 24 | { 25 | uint8_t Running; 26 | uint8_t EventCode; 27 | } PS_STATE_INFO, *PPS_STATE_INFO; 28 | 29 | #define PS_MAX_PAGE_TABLE_ENTRIES 4 30 | 31 | typedef enum _PS_PAGE_WALK_MODE 32 | { 33 | pwmNone = 0, 34 | pwm32 = 1, 35 | pwmPae = 2, 36 | pwmLvl4 = 3 37 | } PS_PAGE_WALK_MODE; 38 | 39 | typedef struct _PS_PAGE_WALK_INFO 40 | { 41 | uint16_t NumEntries; 42 | uint16_t MaxEntries; 43 | uint16_t PageWalkMode; 44 | uint8_t LastValidEntry; 45 | uint8_t ValidTranslation; 46 | uint64_t Entry[PS_MAX_PAGE_TABLE_ENTRIES]; 47 | } PS_PAGE_WALK_INFO, *PPS_PAGE_WALK_INFO; 48 | 49 | // Transport raw data callback 50 | typedef void (*lpfnRawDataCallback)(uintptr_t Context, void *pRawDataBuffer, uint32_t RawDataSize); 51 | 52 | PULSE_STATUS TransportCreate(PPS_TRANSPORT *pTransport, PS_TRANSPORT_TYPE TransportType); 53 | PULSE_STATUS TransportGetInterfaceCount(PPS_TRANSPORT pTransport, uint32_t *pInterfaceCount); 54 | PULSE_STATUS TransportGetInterfaceName(PPS_TRANSPORT pTransport, uint32_t InterfaceIndex, char *pcInterfaceNameBuffer, uint32_t *pcbBufSize); 55 | PULSE_STATUS TransportSetInterfaceName(PPS_TRANSPORT pTransport, char *lpcInterfaceName); 56 | PULSE_STATUS TransportSetInterfaceIndex(PPS_TRANSPORT pTransport, uint32_t InterfaceIndex); 57 | PULSE_STATUS TransportSetRawDataCallback(PPS_TRANSPORT pTransport, lpfnRawDataCallback RawDataCallback, uintptr_t Context); 58 | PULSE_STATUS TransportResetConnection(PPS_TRANSPORT pTransport); 59 | PULSE_STATUS TransportDestroy(PPS_TRANSPORT pTransport); 60 | 61 | PULSE_STATUS EngCreateEngine(PPS_ENGINE *ppEngine); 62 | PULSE_STATUS EngAssignTransport(PPS_ENGINE pEngine, PPS_TRANSPORT pTransport); 63 | PULSE_STATUS EngSetRequestTimeout(PPS_ENGINE pEngine, uint32_t Timeout); 64 | PULSE_STATUS EngStart(PPS_ENGINE pEngine); 65 | PULSE_STATUS EngStop(PPS_ENGINE pEngine); 66 | PULSE_STATUS EngDestroyEngine(PPS_ENGINE pEngine); 67 | 68 | PULSE_STATUS PsPing(PPS_ENGINE pEngine); 69 | PULSE_STATUS PsGo(PPS_ENGINE pEngine); 70 | PULSE_STATUS PsBreakIn(PPS_ENGINE pEngine); 71 | PULSE_STATUS PsStep(PPS_ENGINE pEngine, uint8_t SuppressInterrupts); 72 | PULSE_STATUS PsSwitchCpu(PPS_ENGINE pEngine, uint64_t TargetCpuIndex); 73 | PULSE_STATUS PsReboot(PPS_ENGINE pEngine); 74 | 75 | PULSE_STATUS PsReadVirtualMemory(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t SelectorValue, uint64_t Offset, void* pBuffer, 76 | uint64_t cbToRead, uint64_t *pcbRead); 77 | PULSE_STATUS PsWriteVirtualMemory(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t SelectorValue, uint64_t Offset, void* pBuffer, 78 | uint64_t cbToWrite, uint64_t* pcbWritten); 79 | PULSE_STATUS PsReadLinearMemory(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t Address, void* pBuffer, 80 | uint64_t cbToRead, uint64_t *pcbRead); 81 | PULSE_STATUS PsWriteLinearMemory(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t Address, void* pBuffer, 82 | uint64_t cbToWrite, uint64_t* pcbWritten); 83 | PULSE_STATUS PsReadPhysicalMemory(PPS_ENGINE pEngine, uint64_t Address, void* pBuffer, 84 | uint64_t cbToRead, uint64_t *pcbRead); 85 | PULSE_STATUS PsWritePhysicalMemory(PPS_ENGINE pEngine, uint64_t Address, void* pBuffer, 86 | uint64_t cbToWrite, uint64_t* pcbWritten); 87 | 88 | PULSE_STATUS PsGetContext(PPS_ENGINE pEngine, PPS_CTX pContext, uint64_t RegMask, PS_CPU_MODE *pCpuMode); 89 | PULSE_STATUS PsSetContext(PPS_ENGINE pEngine, PPS_CTX pContext, uint64_t RegMask); 90 | PULSE_STATUS PsGetExtendedContext(PPS_ENGINE pEngine, PPS_CTX_EXT pContextExt, uint64_t ExtRegMask); 91 | PULSE_STATUS PsSetExtendedContext(PPS_ENGINE pEngine, PPS_CTX_EXT pContextExt, uint64_t ExtRegMask); 92 | 93 | PULSE_STATUS PsReadIo(PPS_ENGINE pEngine, uint16_t Port, uint16_t AccessSize, void *pBuffer, uint32_t cbToRead, uint64_t *pcbRead); 94 | PULSE_STATUS PsWriteIo(PPS_ENGINE pEngine, uint16_t Port, uint16_t AccessSize, void *pBuffer, uint32_t cbToWrite, uint64_t *pcbWritten); 95 | 96 | PULSE_STATUS PsGetStateInfo(PPS_ENGINE pEngine, PPS_STATE_INFO pStateInfo); 97 | PULSE_STATUS PsGetCpuInfo(PPS_ENGINE pEngine, uint8_t *pActiveCpu, uint8_t *pCpuCount); 98 | PULSE_STATUS PsCpuId(PPS_ENGINE pEngine, uint32_t Leaf, uint32_t Subleaf, uint32_t CpuIdData[4]); 99 | 100 | PULSE_STATUS PsReadMsr(PPS_ENGINE pEngine, uint32_t MsrNumber, uint64_t *pMsrValue); 101 | PULSE_STATUS PsWriteMsr(PPS_ENGINE pEngine, uint32_t MsrNumber, uint64_t MsrValue); 102 | 103 | PULSE_STATUS PsSearchVirtualMemory(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t Selector, uint64_t StartOffset, uint64_t EndOffset, 104 | void* pPattern, uint32_t PatternSize, uint32_t SearchStep, uint8_t IgnoreGaps, uint64_t *pResult); 105 | PULSE_STATUS PsSearchLinearMemory(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t StartAddress, uint64_t EndAddress, 106 | void* pPattern, uint32_t PatternSize, uint32_t SearchStep, uint8_t IgnoreGaps, uint64_t *pResult); 107 | PULSE_STATUS PsSearchPhysicalMemory(PPS_ENGINE pEngine, uint64_t StartAddress, uint64_t EndAddress, 108 | void* pPattern, uint32_t PatternSize, uint32_t SearchStep, uint8_t IgnoreGaps, uint64_t *pResult); 109 | 110 | PULSE_STATUS PsWalkPageVirtual(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t Selector, uint64_t Offset, 111 | PPS_PAGE_WALK_INFO pPageWalkInfo); 112 | PULSE_STATUS PsWalkPageLinear(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t Address, 113 | PPS_PAGE_WALK_INFO pPageWalkInfo); 114 | 115 | PULSE_STATUS PsVirtualToPhysical(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t Selector, uint64_t Offset, uint64_t *pPhysicalAddress); 116 | PULSE_STATUS PsLinearToPhysical(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t Address, uint64_t *pPhysicalAddress); 117 | 118 | PULSE_STATUS PsSetBreakPoint(PPS_ENGINE pEngine, uint64_t PhysicalAddress, uint32_t *pBreakPointId); 119 | PULSE_STATUS PsRemoveBreakPoint(PPS_ENGINE pEngine, uint32_t BreakPointId); 120 | PULSE_STATUS PsClearBreakPoints(PPS_ENGINE pEngine); 121 | 122 | PULSE_STATUS PsAddBreakPointFilter(PPS_ENGINE pEngine, uint32_t BreakPointId, uint64_t PageTable, uint64_t Address, uint64_t ThreadBase, uint16_t Selector); 123 | PULSE_STATUS PsRemoveBreakPointFilter(PPS_ENGINE pEngine, uint32_t BreakPointId, uint64_t PageTable, uint64_t Address, uint64_t ThreadBase, uint16_t Selector); 124 | -------------------------------------------------------------------------------- /SDK/Headers/ps_ctx.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma once 4 | 5 | typedef enum _PS_CPU_MODE 6 | { 7 | cmReal = 0, 8 | cmSmm = 1, 9 | cmV86 = 2, 10 | cmProt32 = 3, 11 | cmProt16 = 4, 12 | cmLong64 = 5, 13 | cmLong32 = 6, 14 | cmLong16 = 7 15 | } PS_CPU_MODE; 16 | 17 | typedef struct _PS_CTX 18 | { 19 | // Location 20 | uint64_t rip; 21 | // Space 22 | uint64_t cr3; 23 | // Stack 24 | uint64_t rsp; 25 | // Gpr 26 | uint64_t rax; 27 | uint64_t rbx; 28 | uint64_t rcx; 29 | uint64_t rdx; 30 | uint64_t rsi; 31 | uint64_t rdi; 32 | uint64_t rbp; 33 | uint64_t rflags; 34 | uint64_t r8; 35 | uint64_t r9; 36 | uint64_t r10; 37 | uint64_t r11; 38 | uint64_t r12; 39 | uint64_t r13; 40 | uint64_t r14; 41 | uint64_t r15; 42 | // Segment 43 | uint16_t cs; 44 | uint32_t cs_access; 45 | uint64_t cs_base; 46 | uint32_t cs_limit; 47 | uint16_t ds; 48 | uint32_t ds_access; 49 | uint64_t ds_base; 50 | uint32_t ds_limit; 51 | uint16_t ss; 52 | uint32_t ss_access; 53 | uint64_t ss_base; 54 | uint32_t ss_limit; 55 | uint16_t es; 56 | uint32_t es_access; 57 | uint64_t es_base; 58 | uint32_t es_limit; 59 | uint16_t fs; 60 | uint32_t fs_access; 61 | uint64_t fs_base; 62 | uint32_t fs_limit; 63 | uint16_t gs; 64 | uint32_t gs_access; 65 | uint64_t gs_base; 66 | uint32_t gs_limit; 67 | // Control 68 | uint64_t cr0; 69 | uint64_t cr2; 70 | uint64_t cr4; 71 | uint64_t cr8; 72 | // Descriptor table 73 | uint64_t gdt_base; 74 | uint16_t gdt_limit; 75 | uint64_t idt_base; 76 | uint16_t idt_limit; 77 | // Descriptor 78 | uint16_t ldt; 79 | uint32_t ldt_access; 80 | uint64_t ldt_base; 81 | uint32_t ldt_limit; 82 | uint16_t tss; 83 | uint32_t tss_access; 84 | uint64_t tss_base; 85 | uint32_t tss_limit; 86 | // Debug 87 | uint64_t dr0; 88 | uint64_t dr1; 89 | uint64_t dr2; 90 | uint64_t dr3; 91 | uint64_t dr6; 92 | uint64_t dr7; 93 | } PS_CTX, *PPS_CTX; 94 | 95 | typedef struct _PS_CTX_EXT 96 | { 97 | // Feature control 98 | uint64_t xcr0; 99 | // FPU 100 | uint16_t fpu_ctrl; 101 | uint16_t fpu_sts; 102 | uint16_t fpu_tag; 103 | uint16_t fpu_opcode; 104 | uint64_t fpu_ip; 105 | uint64_t fpu_op_offs; 106 | uint8_t st0[10]; 107 | uint8_t st1[10]; 108 | uint8_t st2[10]; 109 | uint8_t st3[10]; 110 | uint8_t st4[10]; 111 | uint8_t st5[10]; 112 | uint8_t st6[10]; 113 | uint8_t st7[10]; 114 | // MMX 115 | uint64_t mm0; 116 | uint64_t mm1; 117 | uint64_t mm2; 118 | uint64_t mm3; 119 | uint64_t mm4; 120 | uint64_t mm5; 121 | uint64_t mm6; 122 | uint64_t mm7; 123 | // XMM 124 | uint32_t mxcsr; 125 | uint32_t mxcsr_mask; 126 | uint8_t xmm0[16]; 127 | uint8_t xmm1[16]; 128 | uint8_t xmm2[16]; 129 | uint8_t xmm3[16]; 130 | uint8_t xmm4[16]; 131 | uint8_t xmm5[16]; 132 | uint8_t xmm6[16]; 133 | uint8_t xmm7[16]; 134 | uint8_t xmm8[16]; 135 | uint8_t xmm9[16]; 136 | uint8_t xmm10[16]; 137 | uint8_t xmm11[16]; 138 | uint8_t xmm12[16]; 139 | uint8_t xmm13[16]; 140 | uint8_t xmm14[16]; 141 | uint8_t xmm15[16]; 142 | // YMM (16 * 256 bit) 143 | uint8_t ymm0[32]; 144 | uint8_t ymm1[32]; 145 | uint8_t ymm2[32]; 146 | uint8_t ymm3[32]; 147 | uint8_t ymm4[32]; 148 | uint8_t ymm5[32]; 149 | uint8_t ymm6[32]; 150 | uint8_t ymm7[32]; 151 | uint8_t ymm8[32]; 152 | uint8_t ymm9[32]; 153 | uint8_t ymm10[32]; 154 | uint8_t ymm11[32]; 155 | uint8_t ymm12[32]; 156 | uint8_t ymm13[32]; 157 | uint8_t ymm14[32]; 158 | uint8_t ymm15[32]; 159 | } PS_CTX_EXT, *PPS_CTX_EXT; 160 | 161 | // 162 | // Partial context request mask 163 | // 164 | 165 | #define DBG_CTX_PART_FLAG_RIP (1ULL << 0) 166 | #define DBG_CTX_PART_FLAG_CR3 (1ULL << 1) 167 | #define DBG_CTX_PART_FLAG_RSP (1ULL << 2) 168 | #define DBG_CTX_PART_FLAG_RAX (1ULL << 3) 169 | #define DBG_CTX_PART_FLAG_RBX (1ULL << 4) 170 | #define DBG_CTX_PART_FLAG_RCX (1ULL << 5) 171 | #define DBG_CTX_PART_FLAG_RDX (1ULL << 6) 172 | #define DBG_CTX_PART_FLAG_RSI (1ULL << 7) 173 | #define DBG_CTX_PART_FLAG_RDI (1ULL << 8) 174 | #define DBG_CTX_PART_FLAG_RBP (1ULL << 9) 175 | #define DBG_CTX_PART_FLAG_RFLAGS (1ULL << 10) 176 | #define DBG_CTX_PART_FLAG_R8 (1ULL << 11) 177 | #define DBG_CTX_PART_FLAG_R9 (1ULL << 12) 178 | #define DBG_CTX_PART_FLAG_R10 (1ULL << 13) 179 | #define DBG_CTX_PART_FLAG_R11 (1ULL << 14) 180 | #define DBG_CTX_PART_FLAG_R12 (1ULL << 15) 181 | #define DBG_CTX_PART_FLAG_R13 (1ULL << 16) 182 | #define DBG_CTX_PART_FLAG_R14 (1ULL << 17) 183 | #define DBG_CTX_PART_FLAG_R15 (1ULL << 18) 184 | #define DBG_CTX_PART_FLAG_CS (1ULL << 19) 185 | #define DBG_CTX_PART_FLAG_CS_ACCESS (1ULL << 20) 186 | #define DBG_CTX_PART_FLAG_CS_BASE (1ULL << 21) 187 | #define DBG_CTX_PART_FLAG_CS_LIMIT (1ULL << 22) 188 | #define DBG_CTX_PART_FLAG_DS (1ULL << 23) 189 | #define DBG_CTX_PART_FLAG_DS_ACCESS (1ULL << 24) 190 | #define DBG_CTX_PART_FLAG_DS_BASE (1ULL << 25) 191 | #define DBG_CTX_PART_FLAG_DS_LIMIT (1ULL << 26) 192 | #define DBG_CTX_PART_FLAG_SS (1ULL << 27) 193 | #define DBG_CTX_PART_FLAG_SS_ACCESS (1ULL << 28) 194 | #define DBG_CTX_PART_FLAG_SS_BASE (1ULL << 29) 195 | #define DBG_CTX_PART_FLAG_SS_LIMIT (1ULL << 30) 196 | #define DBG_CTX_PART_FLAG_ES (1ULL << 31) 197 | #define DBG_CTX_PART_FLAG_ES_ACCESS (1ULL << 32) 198 | #define DBG_CTX_PART_FLAG_ES_BASE (1ULL << 33) 199 | #define DBG_CTX_PART_FLAG_ES_LIMIT (1ULL << 34) 200 | #define DBG_CTX_PART_FLAG_FS (1ULL << 35) 201 | #define DBG_CTX_PART_FLAG_FS_ACCESS (1ULL << 36) 202 | #define DBG_CTX_PART_FLAG_FS_BASE (1ULL << 37) 203 | #define DBG_CTX_PART_FLAG_FS_LIMIT (1ULL << 38) 204 | #define DBG_CTX_PART_FLAG_GS (1ULL << 39) 205 | #define DBG_CTX_PART_FLAG_GS_ACCESS (1ULL << 40) 206 | #define DBG_CTX_PART_FLAG_GS_BASE (1ULL << 41) 207 | #define DBG_CTX_PART_FLAG_GS_LIMIT (1ULL << 42) 208 | #define DBG_CTX_PART_FLAG_CR0 (1ULL << 43) 209 | #define DBG_CTX_PART_FLAG_CR2 (1ULL << 44) 210 | #define DBG_CTX_PART_FLAG_CR4 (1ULL << 45) 211 | #define DBG_CTX_PART_FLAG_CR8 (1ULL << 46) 212 | #define DBG_CTX_PART_FLAG_GDT_BASE (1ULL << 47) 213 | #define DBG_CTX_PART_FLAG_GDT_LIMIT (1ULL << 48) 214 | #define DBG_CTX_PART_FLAG_IDT_BASE (1ULL << 49) 215 | #define DBG_CTX_PART_FLAG_IDT_LIMIT (1ULL << 50) 216 | #define DBG_CTX_PART_FLAG_LDT (1ULL << 51) 217 | #define DBG_CTX_PART_FLAG_LDT_ACCESS (1ULL << 52) 218 | #define DBG_CTX_PART_FLAG_LDT_BASE (1ULL << 53) 219 | #define DBG_CTX_PART_FLAG_LDT_LIMIT (1ULL << 54) 220 | #define DBG_CTX_PART_FLAG_TSS (1ULL << 55) 221 | #define DBG_CTX_PART_FLAG_TSS_ACCESS (1ULL << 56) 222 | #define DBG_CTX_PART_FLAG_TSS_BASE (1ULL << 57) 223 | #define DBG_CTX_PART_FLAG_TSS_LIMIT (1ULL << 58) 224 | #define DBG_CTX_PART_FLAG_DR0 (1ULL << 59) 225 | #define DBG_CTX_PART_FLAG_DR1 (1ULL << 60) 226 | #define DBG_CTX_PART_FLAG_DR2 (1ULL << 61) 227 | #define DBG_CTX_PART_FLAG_DR3 (1ULL << 62) 228 | #define DBG_CTX_PART_FLAG_DR6 (1ULL << 63) 229 | #define DBG_CTX_PART_FLAG_DR7 (1ULL << 63) 230 | 231 | // 232 | // Partial context request mask group aliases 233 | // 234 | 235 | #define DBG_CTX_PART_GPR_MASK 0x000000000007FFFD 236 | #define DBG_CTX_PART_CTRL_MASK 0x0000780000000002 237 | #define DBG_CTX_PART_SEG_MASK 0x000007FFFFF80000 238 | #define DBG_CTX_PART_DESC_MASK 0x07FF800000000000 239 | #define DBG_CTX_PART_DEBUG_MASK 0xF800000000000000 240 | #define DBG_CTX_PART_FULL_MASK 0xFFFFFFFFFFFFFFFF 241 | 242 | // 243 | // Partial extended context request mask 244 | // 245 | 246 | #define DBG_CTX_EX_PART_FLAG_XCR0 (1ULL << 0) 247 | #define DBG_CTX_EX_PART_FLAG_FCW (1ULL << 1) 248 | #define DBG_CTX_EX_PART_FLAG_FSW (1ULL << 2) 249 | #define DBG_CTX_EX_PART_FLAG_FTW (1ULL << 3) 250 | #define DBG_CTX_EX_PART_FLAG_FOP (1ULL << 4) 251 | #define DBG_CTX_EX_PART_FLAG_FIP (1ULL << 5) 252 | #define DBG_CTX_EX_PART_FLAG_FDP (1ULL << 6) 253 | #define DBG_CTX_EX_PART_FLAG_ST0 (1ULL << 7) 254 | #define DBG_CTX_EX_PART_FLAG_ST1 (1ULL << 8) 255 | #define DBG_CTX_EX_PART_FLAG_ST2 (1ULL << 9) 256 | #define DBG_CTX_EX_PART_FLAG_ST3 (1ULL << 10) 257 | #define DBG_CTX_EX_PART_FLAG_ST4 (1ULL << 11) 258 | #define DBG_CTX_EX_PART_FLAG_ST5 (1ULL << 12) 259 | #define DBG_CTX_EX_PART_FLAG_ST6 (1ULL << 13) 260 | #define DBG_CTX_EX_PART_FLAG_ST7 (1ULL << 14) 261 | #define DBG_CTX_EX_PART_FLAG_MM0 (1ULL << 15) 262 | #define DBG_CTX_EX_PART_FLAG_MM1 (1ULL << 16) 263 | #define DBG_CTX_EX_PART_FLAG_MM2 (1ULL << 17) 264 | #define DBG_CTX_EX_PART_FLAG_MM3 (1ULL << 18) 265 | #define DBG_CTX_EX_PART_FLAG_MM4 (1ULL << 19) 266 | #define DBG_CTX_EX_PART_FLAG_MM5 (1ULL << 20) 267 | #define DBG_CTX_EX_PART_FLAG_MM6 (1ULL << 21) 268 | #define DBG_CTX_EX_PART_FLAG_MM7 (1ULL << 22) 269 | #define DBG_CTX_EX_PART_FLAG_MXCSR (1ULL << 23) 270 | #define DBG_CTX_EX_PART_FLAG_MXCSR_MASK (1ULL << 24) 271 | #define DBG_CTX_EX_PART_FLAG_XMM0 (1ULL << 25) 272 | #define DBG_CTX_EX_PART_FLAG_XMM1 (1ULL << 26) 273 | #define DBG_CTX_EX_PART_FLAG_XMM2 (1ULL << 27) 274 | #define DBG_CTX_EX_PART_FLAG_XMM3 (1ULL << 28) 275 | #define DBG_CTX_EX_PART_FLAG_XMM4 (1ULL << 29) 276 | #define DBG_CTX_EX_PART_FLAG_XMM5 (1ULL << 30) 277 | #define DBG_CTX_EX_PART_FLAG_XMM6 (1ULL << 31) 278 | #define DBG_CTX_EX_PART_FLAG_XMM7 (1ULL << 32) 279 | #define DBG_CTX_EX_PART_FLAG_XMM8 (1ULL << 33) 280 | #define DBG_CTX_EX_PART_FLAG_XMM9 (1ULL << 34) 281 | #define DBG_CTX_EX_PART_FLAG_XMM10 (1ULL << 35) 282 | #define DBG_CTX_EX_PART_FLAG_XMM11 (1ULL << 36) 283 | #define DBG_CTX_EX_PART_FLAG_XMM12 (1ULL << 37) 284 | #define DBG_CTX_EX_PART_FLAG_XMM13 (1ULL << 38) 285 | #define DBG_CTX_EX_PART_FLAG_XMM14 (1ULL << 39) 286 | #define DBG_CTX_EX_PART_FLAG_XMM15 (1ULL << 40) 287 | #define DBG_CTX_EX_PART_FLAG_YMM0 (1ULL << 41) 288 | #define DBG_CTX_EX_PART_FLAG_YMM1 (1ULL << 42) 289 | #define DBG_CTX_EX_PART_FLAG_YMM2 (1ULL << 43) 290 | #define DBG_CTX_EX_PART_FLAG_YMM3 (1ULL << 44) 291 | #define DBG_CTX_EX_PART_FLAG_YMM4 (1ULL << 45) 292 | #define DBG_CTX_EX_PART_FLAG_YMM5 (1ULL << 46) 293 | #define DBG_CTX_EX_PART_FLAG_YMM6 (1ULL << 47) 294 | #define DBG_CTX_EX_PART_FLAG_YMM7 (1ULL << 48) 295 | #define DBG_CTX_EX_PART_FLAG_YMM8 (1ULL << 49) 296 | #define DBG_CTX_EX_PART_FLAG_YMM9 (1ULL << 50) 297 | #define DBG_CTX_EX_PART_FLAG_YMM10 (1ULL << 51) 298 | #define DBG_CTX_EX_PART_FLAG_YMM11 (1ULL << 52) 299 | #define DBG_CTX_EX_PART_FLAG_YMM12 (1ULL << 53) 300 | #define DBG_CTX_EX_PART_FLAG_YMM13 (1ULL << 54) 301 | #define DBG_CTX_EX_PART_FLAG_YMM14 (1ULL << 55) 302 | #define DBG_CTX_EX_PART_FLAG_YMM15 (1ULL << 56) 303 | -------------------------------------------------------------------------------- /SDK/Example/PulseEngClient.cpp: -------------------------------------------------------------------------------- 1 | // PulseEngClient.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | typedef PULSE_STATUS (*lpfnTransportCreate)(PPS_TRANSPORT *pTransport, PS_TRANSPORT_TYPE TransportType); 7 | typedef PULSE_STATUS (*lpfnTransportGetInterfaceCount)(PPS_TRANSPORT pTransport, uint32_t *pInterfaceCount); 8 | typedef PULSE_STATUS (*lpfnTransportGetInterfaceName)(PPS_TRANSPORT pTransport, uint32_t InterfaceIndex, char *pcInterfaceNameBuffer, uint32_t *pcbBufSize); 9 | typedef PULSE_STATUS (*lpfnTransportSetInterfaceName)(PPS_TRANSPORT pTransport, char *lpcInterfaceName); 10 | typedef PULSE_STATUS (*lpfnTransportSetInterfaceIndex)(PPS_TRANSPORT pTransport, uint32_t InterfaceIndex); 11 | typedef PULSE_STATUS (*lpfnTransportSetRawDataCallback)(PPS_TRANSPORT pTransport, lpfnRawDataCallback RawDataCallback, uintptr_t Context); 12 | typedef PULSE_STATUS (*lpfnTransportResetConnection)(PPS_TRANSPORT pTransport); 13 | typedef PULSE_STATUS (*lpfnTransportDestroy)(PPS_TRANSPORT pTransport); 14 | 15 | typedef PULSE_STATUS (*lpfnEngCreateEngine)(PPS_ENGINE *ppEngine); 16 | typedef PULSE_STATUS (*lpfnEngAssignTransport)(PPS_ENGINE pEngine, PPS_TRANSPORT pTransport); 17 | typedef PULSE_STATUS (*lpfnEngSetRequestTimeout)(PPS_ENGINE pEngine, uint32_t Timeout); 18 | typedef PULSE_STATUS (*lpfnEngStart)(PPS_ENGINE pEngine); 19 | typedef PULSE_STATUS (*lpfnEngStop)(PPS_ENGINE pEngine); 20 | typedef PULSE_STATUS (*lpfnEngDestroyEngine)(PPS_ENGINE pEngine); 21 | 22 | typedef PULSE_STATUS (*lpfnPsPing)(PPS_ENGINE pEngine); 23 | typedef PULSE_STATUS (*lpfnPsGo)(PPS_ENGINE pEngine); 24 | typedef PULSE_STATUS (*lpfnPsBreakIn)(PPS_ENGINE pEngine); 25 | typedef PULSE_STATUS (*lpfnPsStep)(PPS_ENGINE pEngine, uint8_t SuppressInterrupts); 26 | typedef PULSE_STATUS (*lpfnPsSwitchCpu)(PPS_ENGINE pEngine, uint64_t TargetCpuIndex); 27 | typedef PULSE_STATUS (*lpfnPsReboot)(PPS_ENGINE pEngine); 28 | 29 | typedef PULSE_STATUS (*lpfnPsReadVirtualMemory)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t SelectorValue, uint64_t Offset, void* pBuffer, uint64_t cbToRead, uint64_t *pcbRead); 30 | typedef PULSE_STATUS (*lpfnPsWriteVirtualMemory)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t SelectorValue, uint64_t Offset, void* pBuffer, uint64_t cbToWrite, uint64_t *pcbWritten); 31 | typedef PULSE_STATUS (*lpfnPsReadLinearMemory)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t Address, void* pBuffer, uint64_t cbToRead, uint64_t *pcbRead); 32 | typedef PULSE_STATUS (*lpfnPsWriteLinearMemory)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t Address, void* pBuffer, uint64_t cbToWrite, uint64_t *pcbWritten); 33 | typedef PULSE_STATUS (*lpfnPsReadPhysicalMemory)(PPS_ENGINE pEngine, uint64_t Address, void* pBuffer, uint64_t cbToRead, uint64_t *pcbRead); 34 | typedef PULSE_STATUS (*lpfnPsWritePhysicalMemory)(PPS_ENGINE pEngine, uint64_t Address, void* pBuffer, uint64_t cbToWrite, uint64_t *pcbWritten); 35 | 36 | typedef PULSE_STATUS (*lpfnPsGetContext)(PPS_ENGINE pEngine, PPS_CTX pContext, uint64_t RegMask, PS_CPU_MODE *pCpuMode); 37 | typedef PULSE_STATUS (*lpfnPsSetContext)(PPS_ENGINE pEngine, PPS_CTX pContext, uint64_t RegMask); 38 | typedef PULSE_STATUS (*lpfnPsGetExtendedContext)(PPS_ENGINE pEngine, PPS_CTX_EXT pContextExt, uint64_t ExtRegMask); 39 | typedef PULSE_STATUS (*lpfnPsSetExtendedContext)(PPS_ENGINE pEngine, PPS_CTX_EXT pContextExt, uint64_t ExtRegMask); 40 | 41 | typedef PULSE_STATUS (*lpfnPsReadIo)(PPS_ENGINE pEngine, uint16_t Port, uint16_t AccessSize, void *pBuffer, uint32_t cbToRead, uint64_t *pcbRead); 42 | typedef PULSE_STATUS (*lpfnPsWriteIo)(PPS_ENGINE pEngine, uint16_t Port, uint16_t AccessSize, void *pBuffer, uint32_t cbToWrite, uint64_t *pcbWritten); 43 | 44 | typedef PULSE_STATUS (*lpfnPsGetStateInfo)(PPS_ENGINE pEngine, PPS_STATE_INFO pStateInfo); 45 | typedef PULSE_STATUS (*lpfnPsGetCpuInfo)(PPS_ENGINE pEngine, uint8_t *pActiveCpu, uint8_t *pCpuCount); 46 | 47 | typedef PULSE_STATUS (*lpfnPsCpuId)(PPS_ENGINE pEngine, uint32_t Leaf, uint32_t Subleaf, uint32_t CpuIdData[4]); 48 | typedef PULSE_STATUS (*lpfnPsReadMsr)(PPS_ENGINE pEngine, uint32_t MsrNumber, uint64_t *pMsrValue); 49 | typedef PULSE_STATUS (*lpfnPsWriteMsr)(PPS_ENGINE pEngine, uint32_t MsrNumber, uint64_t MsrValue); 50 | 51 | typedef PULSE_STATUS (*lpfnPsSearchVirtualMemory)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t Selector, uint64_t StartOffset, uint64_t EndOffset, void* pPattern, uint32_t PatternSize, uint32_t SearchStep, uint8_t IgnoreGaps, uint64_t *pResult); 52 | typedef PULSE_STATUS (*lpfnPsSearchLinearMemory)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t StartAddress, uint64_t EndAddress, void* pPattern, uint32_t PatternSize, uint32_t SearchStep, uint8_t IgnoreGaps, uint64_t *pResult); 53 | typedef PULSE_STATUS (*lpfnPsSearchPhysicalMemory)(PPS_ENGINE pEngine, uint64_t StartAddress, uint64_t EndAddress, void* pPattern, uint32_t PatternSize, uint32_t SearchStep, uint8_t IgnoreGaps, uint64_t *pResult); 54 | 55 | typedef PULSE_STATUS (*lpfnPsWalkPageVirtual)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t Selector, uint64_t Offset, PPS_PAGE_WALK_INFO pPageWalkInfo); 56 | typedef PULSE_STATUS (*lpfnPsWalkPageLinear)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t Address, PPS_PAGE_WALK_INFO pPageWalkInfo); 57 | typedef PULSE_STATUS (*lpfnPsVirtualToPhysical)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint16_t Selector, uint64_t Offset, uint64_t *pPhysicalAddress); 58 | typedef PULSE_STATUS (*lpfnPsLinearToPhysical)(PPS_ENGINE pEngine, uint64_t PageTableAddress, uint64_t Address, uint64_t *pPhysicalAddress); 59 | 60 | typedef PULSE_STATUS (*lpfnPsSetBreakPoint)(PPS_ENGINE pEngine, uint64_t PhysicalAddress, uint32_t *pBreakPointId); 61 | typedef PULSE_STATUS (*lpfnPsRemoveBreakPoint)(PPS_ENGINE pEngine, uint32_t BreakPointId); 62 | typedef PULSE_STATUS (*lpfnPsClearBreakPoints)(PPS_ENGINE pEngine); 63 | 64 | typedef PULSE_STATUS (*lpfnPsAddBreakPointFilter)(PPS_ENGINE pEngine, uint32_t BreakPointId, uint64_t PageTable, uint64_t Address, uint64_t ThreadBase, uint16_t Selector); 65 | typedef PULSE_STATUS (*lpfnPsRemoveBreakPointFilter)(PPS_ENGINE pEngine, uint32_t BreakPointId, uint64_t PageTable, uint64_t Address, uint64_t ThreadBase, uint16_t Selector); 66 | 67 | // 68 | // Pulse engine function globals 69 | // 70 | 71 | typedef struct _PULSE_INTERFACE 72 | { 73 | // Transport functions 74 | lpfnTransportCreate TransportCreate = NULL; 75 | lpfnTransportGetInterfaceCount TransportGetInterfaceCount = NULL; 76 | lpfnTransportGetInterfaceName TransportGetInterfaceName = NULL; 77 | lpfnTransportSetInterfaceName TransportSetInterfaceName = NULL; 78 | lpfnTransportSetInterfaceIndex TransportSetInterfaceIndex = NULL; 79 | lpfnTransportSetRawDataCallback TransportSetRawDataCallback = NULL; 80 | lpfnTransportResetConnection TransportResetConnection = NULL; 81 | lpfnTransportDestroy TransportDestroy = NULL; 82 | 83 | // Engine auxiliary functions 84 | lpfnEngCreateEngine EngCreateEngine = NULL; 85 | lpfnEngAssignTransport EngAssignTransport = NULL; 86 | lpfnEngSetRequestTimeout EngSetRequestTimeout = NULL; 87 | lpfnEngStart EngStart = NULL; 88 | lpfnEngStop EngStop = NULL; 89 | lpfnEngDestroyEngine EngDestroyEngine = NULL; 90 | 91 | // Engine useful functions 92 | lpfnPsPing PsPing = NULL; 93 | lpfnPsGo PsGo = NULL; 94 | lpfnPsBreakIn PsBreakIn = NULL; 95 | lpfnPsStep PsStep = NULL; 96 | lpfnPsSwitchCpu PsSwitchCpu = NULL; 97 | lpfnPsReboot PsReboot = NULL; 98 | lpfnPsReadVirtualMemory PsReadVirtualMemory = NULL; 99 | lpfnPsWriteVirtualMemory PsWriteVirtualMemory = NULL; 100 | lpfnPsReadLinearMemory PsReadLinearMemory = NULL; 101 | lpfnPsWriteLinearMemory PsWriteLinearMemory = NULL; 102 | lpfnPsReadPhysicalMemory PsReadPhysicalMemory = NULL; 103 | lpfnPsWritePhysicalMemory PsWritePhysicalMemory = NULL; 104 | lpfnPsGetContext PsGetContext = NULL; 105 | lpfnPsSetContext PsSetContext = NULL; 106 | lpfnPsGetExtendedContext PsGetExtendedContext = NULL; 107 | lpfnPsSetExtendedContext PsSetExtendedContext = NULL; 108 | lpfnPsReadIo PsReadIo = NULL; 109 | lpfnPsWriteIo PsWriteIo = NULL; 110 | lpfnPsGetStateInfo PsGetStateInfo = NULL; 111 | lpfnPsGetCpuInfo PsGetCpuInfo = NULL; 112 | lpfnPsCpuId PsCpuId = NULL; 113 | lpfnPsReadMsr PsReadMsr = NULL; 114 | lpfnPsWriteMsr PsWriteMsr = NULL; 115 | lpfnPsSearchVirtualMemory PsSearchVirtualMemory = NULL; 116 | lpfnPsSearchLinearMemory PsSearchLinearMemory = NULL; 117 | lpfnPsSearchPhysicalMemory PsSearchPhysicalMemory = NULL; 118 | lpfnPsWalkPageVirtual PsWalkPageVirtual = NULL; 119 | lpfnPsWalkPageLinear PsWalkPageLinear = NULL; 120 | lpfnPsVirtualToPhysical PsVirtualToPhysical = NULL; 121 | lpfnPsLinearToPhysical PsLinearToPhysical = NULL; 122 | lpfnPsSetBreakPoint PsSetBreakPoint = NULL; 123 | lpfnPsRemoveBreakPoint PsRemoveBreakPoint = NULL; 124 | lpfnPsClearBreakPoints PsClearBreakPoints = NULL; 125 | lpfnPsAddBreakPointFilter PsAddBreakPointFilter = NULL; 126 | lpfnPsRemoveBreakPointFilter PsRemoveBreakPointFilter = NULL; 127 | } PULSE_INTERFACE, *PPULSE_INTERFACE; 128 | 129 | PULSE_INTERFACE Pulse; 130 | 131 | bool InitializeLibrary(wchar_t *lpwPulseDllPath) 132 | { 133 | bool bResult = true; 134 | 135 | HINSTANCE hPulseDll = LoadLibrary(lpwPulseDllPath); 136 | if (hPulseDll == NULL) 137 | return false; 138 | 139 | RtlZeroMemory(&Pulse, sizeof(PULSE_INTERFACE)); 140 | 141 | // Lookup functions 142 | Pulse.TransportCreate = (lpfnTransportCreate)GetProcAddress(hPulseDll, "TransportCreate"); 143 | bResult &= (Pulse.TransportCreate != NULL); 144 | Pulse.TransportGetInterfaceCount = (lpfnTransportGetInterfaceCount)GetProcAddress(hPulseDll, "TransportGetInterfaceCount"); 145 | bResult &= (Pulse.TransportGetInterfaceCount != NULL); 146 | Pulse.TransportGetInterfaceName = (lpfnTransportGetInterfaceName)GetProcAddress(hPulseDll, "TransportGetInterfaceName"); 147 | bResult &= (Pulse.TransportGetInterfaceName != NULL); 148 | Pulse.TransportSetInterfaceName = (lpfnTransportSetInterfaceName)GetProcAddress(hPulseDll, "TransportSetInterfaceName"); 149 | bResult &= (Pulse.TransportSetInterfaceName != NULL); 150 | Pulse.TransportSetInterfaceIndex = (lpfnTransportSetInterfaceIndex)GetProcAddress(hPulseDll, "TransportSetInterfaceIndex"); 151 | bResult &= (Pulse.TransportSetInterfaceIndex != NULL); 152 | Pulse.TransportSetRawDataCallback = (lpfnTransportSetRawDataCallback)GetProcAddress(hPulseDll, "TransportSetRawDataCallback"); 153 | bResult &= (Pulse.TransportSetRawDataCallback != NULL); 154 | Pulse.TransportResetConnection = (lpfnTransportResetConnection)GetProcAddress(hPulseDll, "TransportResetConnection"); 155 | bResult &= (Pulse.TransportResetConnection != NULL); 156 | Pulse.TransportDestroy = (lpfnTransportDestroy)GetProcAddress(hPulseDll, "TransportDestroy"); 157 | bResult &= (Pulse.TransportDestroy != NULL); 158 | 159 | Pulse.EngCreateEngine = (lpfnEngCreateEngine)GetProcAddress(hPulseDll, "EngCreateEngine"); 160 | bResult &= (Pulse.EngCreateEngine != NULL); 161 | Pulse.EngAssignTransport = (lpfnEngAssignTransport)GetProcAddress(hPulseDll, "EngAssignTransport"); 162 | bResult &= (Pulse.EngAssignTransport != NULL); 163 | Pulse.EngSetRequestTimeout = (lpfnEngSetRequestTimeout)GetProcAddress(hPulseDll, "EngSetRequestTimeout"); 164 | bResult &= (Pulse.EngSetRequestTimeout != NULL); 165 | Pulse.EngStart = (lpfnEngStart)GetProcAddress(hPulseDll, "EngStart"); 166 | bResult &= (Pulse.EngStart != NULL); 167 | Pulse.EngStop = (lpfnEngStop)GetProcAddress(hPulseDll, "EngStop"); 168 | bResult &= (Pulse.EngStop != NULL); 169 | Pulse.EngDestroyEngine = (lpfnEngDestroyEngine)GetProcAddress(hPulseDll, "EngDestroyEngine"); 170 | bResult &= (Pulse.EngDestroyEngine != NULL); 171 | 172 | Pulse.PsPing = (lpfnPsPing)GetProcAddress(hPulseDll, "PsPing"); 173 | bResult &= (Pulse.PsPing != NULL); 174 | Pulse.PsGo = (lpfnPsGo)GetProcAddress(hPulseDll, "PsGo"); 175 | bResult &= (Pulse.PsGo != NULL); 176 | Pulse.PsBreakIn = (lpfnPsBreakIn)GetProcAddress(hPulseDll, "PsBreakIn"); 177 | bResult &= (Pulse.PsBreakIn != NULL); 178 | Pulse.PsStep = (lpfnPsStep)GetProcAddress(hPulseDll, "PsStep"); 179 | bResult &= (Pulse.PsStep != NULL); 180 | Pulse.PsSwitchCpu = (lpfnPsSwitchCpu)GetProcAddress(hPulseDll, "PsSwitchCpu"); 181 | bResult &= (Pulse.PsSwitchCpu != NULL); 182 | Pulse.PsReboot = (lpfnPsReboot)GetProcAddress(hPulseDll, "PsReboot"); 183 | bResult &= (Pulse.PsReboot != NULL); 184 | Pulse.PsReadVirtualMemory = (lpfnPsReadVirtualMemory)GetProcAddress(hPulseDll, "PsReadVirtualMemory"); 185 | bResult &= (Pulse.PsReadVirtualMemory != NULL); 186 | Pulse.PsWriteVirtualMemory = (lpfnPsWriteVirtualMemory)GetProcAddress(hPulseDll, "PsWriteVirtualMemory"); 187 | bResult &= (Pulse.PsWriteVirtualMemory != NULL); 188 | Pulse.PsReadLinearMemory = (lpfnPsReadLinearMemory)GetProcAddress(hPulseDll, "PsReadLinearMemory"); 189 | bResult &= (Pulse.PsReadLinearMemory != NULL); 190 | Pulse.PsWriteLinearMemory = (lpfnPsWriteLinearMemory)GetProcAddress(hPulseDll, "PsWriteLinearMemory"); 191 | bResult &= (Pulse.PsWriteLinearMemory != NULL); 192 | Pulse.PsReadPhysicalMemory = (lpfnPsReadPhysicalMemory)GetProcAddress(hPulseDll, "PsReadPhysicalMemory"); 193 | bResult &= (Pulse.PsReadPhysicalMemory != NULL); 194 | Pulse.PsWritePhysicalMemory = (lpfnPsWritePhysicalMemory)GetProcAddress(hPulseDll, "PsWritePhysicalMemory"); 195 | bResult &= (Pulse.PsWritePhysicalMemory != NULL); 196 | Pulse.PsGetContext = (lpfnPsGetContext)GetProcAddress(hPulseDll, "PsGetContext"); 197 | bResult &= (Pulse.PsGetContext != NULL); 198 | Pulse.PsSetContext = (lpfnPsSetContext)GetProcAddress(hPulseDll, "PsSetContext"); 199 | bResult &= (Pulse.PsSetContext != NULL); 200 | Pulse.PsGetExtendedContext = (lpfnPsGetExtendedContext)GetProcAddress(hPulseDll, "PsGetExtendedContext"); 201 | bResult &= (Pulse.PsGetExtendedContext != NULL); 202 | Pulse.PsSetExtendedContext = (lpfnPsSetExtendedContext)GetProcAddress(hPulseDll, "PsSetExtendedContext"); 203 | bResult &= (Pulse.PsSetExtendedContext != NULL); 204 | Pulse.PsReadIo = (lpfnPsReadIo)GetProcAddress(hPulseDll, "PsReadIo"); 205 | bResult &= (Pulse.PsReadIo != NULL); 206 | Pulse.PsWriteIo = (lpfnPsWriteIo)GetProcAddress(hPulseDll, "PsWriteIo"); 207 | bResult &= (Pulse.PsWriteIo != NULL); 208 | Pulse.PsGetStateInfo = (lpfnPsGetStateInfo)GetProcAddress(hPulseDll, "PsGetStateInfo"); 209 | bResult &= (Pulse.PsGetStateInfo != NULL); 210 | Pulse.PsGetCpuInfo = (lpfnPsGetCpuInfo)GetProcAddress(hPulseDll, "PsGetCpuInfo"); 211 | bResult &= (Pulse.PsGetCpuInfo != NULL); 212 | Pulse.PsCpuId = (lpfnPsCpuId)GetProcAddress(hPulseDll, "PsCpuId"); 213 | bResult &= (Pulse.PsCpuId != NULL); 214 | Pulse.PsReadMsr = (lpfnPsReadMsr)GetProcAddress(hPulseDll, "PsReadMsr"); 215 | bResult &= (Pulse.PsReadMsr != NULL); 216 | Pulse.PsWriteMsr = (lpfnPsWriteMsr)GetProcAddress(hPulseDll, "PsWriteMsr"); 217 | bResult &= (Pulse.PsWriteMsr != NULL); 218 | Pulse.PsSearchVirtualMemory = (lpfnPsSearchVirtualMemory)GetProcAddress(hPulseDll, "PsSearchVirtualMemory"); 219 | bResult &= (Pulse.PsSearchVirtualMemory != NULL); 220 | Pulse.PsSearchLinearMemory = (lpfnPsSearchLinearMemory)GetProcAddress(hPulseDll, "PsSearchLinearMemory"); 221 | bResult &= (Pulse.PsSearchLinearMemory != NULL); 222 | Pulse.PsSearchPhysicalMemory = (lpfnPsSearchPhysicalMemory)GetProcAddress(hPulseDll, "PsSearchPhysicalMemory"); 223 | bResult &= (Pulse.PsSearchPhysicalMemory != NULL); 224 | Pulse.PsWalkPageVirtual = (lpfnPsWalkPageVirtual)GetProcAddress(hPulseDll, "PsWalkPageVirtual"); 225 | bResult &= (Pulse.PsWalkPageVirtual != NULL); 226 | Pulse.PsWalkPageLinear = (lpfnPsWalkPageLinear)GetProcAddress(hPulseDll, "PsWalkPageLinear"); 227 | bResult &= (Pulse.PsWalkPageLinear != NULL); 228 | Pulse.PsVirtualToPhysical = (lpfnPsVirtualToPhysical)GetProcAddress(hPulseDll, "PsVirtualToPhysical"); 229 | bResult &= (Pulse.PsVirtualToPhysical != NULL); 230 | Pulse.PsLinearToPhysical = (lpfnPsLinearToPhysical)GetProcAddress(hPulseDll, "PsLinearToPhysical"); 231 | bResult &= (Pulse.PsLinearToPhysical != NULL); 232 | Pulse.PsSetBreakPoint = (lpfnPsSetBreakPoint)GetProcAddress(hPulseDll, "PsSetBreakPoint"); 233 | bResult &= (Pulse.PsSetBreakPoint != NULL); 234 | Pulse.PsRemoveBreakPoint = (lpfnPsRemoveBreakPoint)GetProcAddress(hPulseDll, "PsRemoveBreakPoint"); 235 | bResult &= (Pulse.PsRemoveBreakPoint != NULL); 236 | Pulse.PsClearBreakPoints = (lpfnPsClearBreakPoints)GetProcAddress(hPulseDll, "PsClearBreakPoints"); 237 | bResult &= (Pulse.PsClearBreakPoints != NULL); 238 | Pulse.PsAddBreakPointFilter = (lpfnPsAddBreakPointFilter)GetProcAddress(hPulseDll, "PsAddBreakPointFilter"); 239 | bResult &= (Pulse.PsAddBreakPointFilter != NULL); 240 | Pulse.PsRemoveBreakPointFilter = (lpfnPsRemoveBreakPointFilter)GetProcAddress(hPulseDll, "PsRemoveBreakPointFilter"); 241 | bResult &= (Pulse.PsRemoveBreakPointFilter != NULL); 242 | 243 | if (!bResult) 244 | { 245 | Pulse.TransportCreate = NULL; 246 | Pulse.TransportGetInterfaceCount = NULL; 247 | Pulse.TransportGetInterfaceName = NULL; 248 | Pulse.TransportSetInterfaceName = NULL; 249 | Pulse.TransportSetInterfaceIndex = NULL; 250 | Pulse.TransportSetRawDataCallback = NULL; 251 | Pulse.TransportResetConnection = NULL; 252 | Pulse.TransportDestroy = NULL; 253 | 254 | Pulse.EngCreateEngine = NULL; 255 | Pulse.EngAssignTransport = NULL; 256 | Pulse.EngSetRequestTimeout = NULL; 257 | Pulse.EngStart = NULL; 258 | Pulse.EngStop = NULL; 259 | Pulse.EngDestroyEngine = NULL; 260 | 261 | Pulse.PsPing = NULL; 262 | Pulse.PsGo = NULL; 263 | Pulse.PsBreakIn = NULL; 264 | Pulse.PsStep = NULL; 265 | Pulse.PsSwitchCpu = NULL; 266 | Pulse.PsReboot = NULL; 267 | Pulse.PsReadVirtualMemory = NULL; 268 | Pulse.PsWriteVirtualMemory = NULL; 269 | Pulse.PsReadLinearMemory = NULL; 270 | Pulse.PsWriteLinearMemory = NULL; 271 | Pulse.PsReadPhysicalMemory = NULL; 272 | Pulse.PsWritePhysicalMemory = NULL; 273 | Pulse.PsGetContext = NULL; 274 | Pulse.PsSetContext = NULL; 275 | Pulse.PsGetExtendedContext = NULL; 276 | Pulse.PsSetExtendedContext = NULL; 277 | Pulse.PsReadIo = NULL; 278 | Pulse.PsWriteIo = NULL; 279 | Pulse.PsGetStateInfo = NULL; 280 | Pulse.PsGetCpuInfo = NULL; 281 | Pulse.PsCpuId = NULL; 282 | Pulse.PsReadMsr = NULL; 283 | Pulse.PsWriteMsr = NULL; 284 | Pulse.PsSearchVirtualMemory = NULL; 285 | Pulse.PsSearchLinearMemory = NULL; 286 | Pulse.PsSearchPhysicalMemory = NULL; 287 | Pulse.PsWalkPageVirtual = NULL; 288 | Pulse.PsWalkPageLinear = NULL; 289 | Pulse.PsVirtualToPhysical = NULL; 290 | Pulse.PsLinearToPhysical = NULL; 291 | Pulse.PsSetBreakPoint = NULL; 292 | Pulse.PsRemoveBreakPoint = NULL; 293 | Pulse.PsClearBreakPoints = NULL; 294 | Pulse.PsAddBreakPointFilter = NULL; 295 | Pulse.PsRemoveBreakPointFilter = NULL; 296 | 297 | FreeLibrary(hPulseDll); 298 | } 299 | 300 | return true; 301 | } 302 | 303 | void TestRawDataCallback(uintptr_t Context, void *pRawDataBuffer, uint32_t RawDataSize) 304 | { 305 | UNREFERENCED_PARAMETER(Context); 306 | printf("%.*s", RawDataSize, (char*)pRawDataBuffer); 307 | } 308 | 309 | int main() 310 | { 311 | if (!InitializeLibrary(L"PulseEng.dll")) 312 | return GetLastError(); 313 | 314 | PULSE_STATUS status = PULSE_STATUS_SUCCESS; 315 | PPS_TRANSPORT TransportHandle = NULL; 316 | PPS_ENGINE EngineHandle = NULL; 317 | 318 | // TransportCreate creates a transport instance. It's a first step in creating a transport for engine 319 | status = Pulse.TransportCreate(&TransportHandle, pttNet); 320 | if (status != PULSE_STATUS_SUCCESS) 321 | { 322 | printf("TransportCreate failed with status %llx\n", status); 323 | return 0; 324 | } 325 | 326 | // 327 | // You can enumerate transport interfaces like this 328 | // 329 | 330 | uint32_t InterfaceCount = 0; 331 | 332 | // TransportGetInterfaceCount tell available interfaces for the current transport type 333 | // N.B. Transport might not have enumerable interfaces (like pipe names or network addresses), 334 | // in that case specify interface name, f.e. "\\.\pipe\com_1", "192.168.13.37:50100" 335 | status = Pulse.TransportGetInterfaceCount(TransportHandle, &InterfaceCount); 336 | if (status != PULSE_STATUS_SUCCESS) 337 | { 338 | printf("TransportGetInterfaceCount failed with status %llx\n", status); 339 | Pulse.TransportDestroy(TransportHandle); 340 | return 0; 341 | } 342 | 343 | for (uint32_t iFace = 0; iFace < InterfaceCount; iFace++) 344 | { 345 | char cInterfaceName[50] = { 0 }; 346 | uint32_t cbBuf = 50; 347 | 348 | // cbBuf is an in/out parameter 349 | status = Pulse.TransportGetInterfaceName(TransportHandle, iFace, cInterfaceName, &cbBuf); 350 | if (status == PULSE_STATUS_SUCCESS) 351 | { 352 | printf("%d: %s\n", iFace, cInterfaceName); 353 | } 354 | } 355 | 356 | // Raw data callback is used to output the logs from the hypervisor 357 | status = Pulse.TransportSetRawDataCallback(TransportHandle, TestRawDataCallback, 0); 358 | if (status != PULSE_STATUS_SUCCESS) 359 | { 360 | printf("TransportSetRawDataCallback failed with status %llx\n", status); 361 | Pulse.TransportDestroy(TransportHandle); 362 | return 0; 363 | } 364 | 365 | // We need to set interface in order to try if it even works 366 | status = Pulse.TransportSetInterfaceIndex(TransportHandle, 0); 367 | if (status != PULSE_STATUS_SUCCESS) 368 | { 369 | status = Pulse.TransportSetInterfaceName(TransportHandle, "\\\\.\\pipe\\com_1"); 370 | if (status != PULSE_STATUS_SUCCESS) 371 | { 372 | status = Pulse.TransportSetInterfaceName(TransportHandle, "192.168.85.100:50100"); 373 | if (status != PULSE_STATUS_SUCCESS) 374 | { 375 | printf("TransportSetInterfaceIndex failed with status %llx\n", status); 376 | Pulse.TransportDestroy(TransportHandle); 377 | return 0; 378 | } 379 | } 380 | } 381 | 382 | // 383 | // Now launch the debug engine 384 | // 385 | 386 | // Create pulse debug engine instance 387 | status = Pulse.EngCreateEngine(&EngineHandle); 388 | if (status != PULSE_STATUS_SUCCESS) 389 | { 390 | printf("EngCreateEngine failed with status %llx\n", status); 391 | Pulse.TransportDestroy(TransportHandle); 392 | return 0; 393 | } 394 | 395 | // Transport assignment is required before start 396 | status = Pulse.EngAssignTransport(EngineHandle, TransportHandle); 397 | if (status != PULSE_STATUS_SUCCESS) 398 | { 399 | printf("EngAssignTransport failed with status %llx\n", status); 400 | Pulse.EngDestroyEngine(EngineHandle); 401 | Pulse.TransportDestroy(TransportHandle); 402 | return 0; 403 | } 404 | 405 | status = Pulse.EngStart(EngineHandle); 406 | if (status != PULSE_STATUS_SUCCESS) 407 | { 408 | printf("EngStart failed with status %llx\n", status); 409 | Pulse.EngDestroyEngine(EngineHandle); 410 | Pulse.TransportDestroy(TransportHandle); 411 | return 0; 412 | } 413 | 414 | // Ping function tests the transport connectivity 415 | status = Pulse.PsPing(EngineHandle); 416 | 417 | // Even though you can technically call any function while the guest is running, 418 | // there's a delay in a result due to polling rate. So if you need to perform 419 | // some sort of introspection, it is better to stop the guest with "BreakIn" function 420 | // N.B. BreakIn doesn't work on live targets (because it would deadlock otherwise) 421 | status = Pulse.PsBreakIn(EngineHandle); 422 | 423 | // Test random useful function 424 | char TestBuf[65536] = { 0 }; 425 | Pulse.PsReadPhysicalMemory(EngineHandle, 0x1000, &TestBuf, sizeof(TestBuf), NULL); 426 | Pulse.PsReadPhysicalMemory(EngineHandle, 0x1000, &TestBuf, sizeof(TestBuf), NULL); 427 | Pulse.PsReadPhysicalMemory(EngineHandle, 0x1000, &TestBuf, sizeof(TestBuf), NULL); 428 | Pulse.PsReadPhysicalMemory(EngineHandle, 0x1000, &TestBuf, sizeof(TestBuf), NULL); 429 | Pulse.PsReadPhysicalMemory(EngineHandle, 0x1000, &TestBuf, sizeof(TestBuf), NULL); 430 | Pulse.PsReadPhysicalMemory(EngineHandle, 0x1000, &TestBuf, sizeof(TestBuf), NULL); 431 | Pulse.PsReadPhysicalMemory(EngineHandle, 0x1000, &TestBuf, sizeof(TestBuf), NULL); 432 | 433 | PS_CPU_MODE CpuMode; 434 | PS_CTX PsCtx = { 0 }; 435 | Pulse.PsGetContext(EngineHandle, &PsCtx, 0, &CpuMode); 436 | Pulse.PsGetContext(EngineHandle, &PsCtx, DBG_CTX_PART_FULL_MASK, NULL); 437 | 438 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 439 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 440 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 441 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 442 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 443 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 444 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 445 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 446 | Pulse.PsReadVirtualMemory(EngineHandle, PsCtx.cr3, PsCtx.ds, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 447 | 448 | Pulse.PsReadLinearMemory(EngineHandle, PsCtx.cr3, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 449 | Pulse.PsReadLinearMemory(EngineHandle, PsCtx.cr3, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 450 | Pulse.PsReadLinearMemory(EngineHandle, PsCtx.cr3, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 451 | Pulse.PsReadLinearMemory(EngineHandle, PsCtx.cr3, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 452 | Pulse.PsReadLinearMemory(EngineHandle, PsCtx.cr3, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 453 | Pulse.PsReadLinearMemory(EngineHandle, PsCtx.cr3, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 454 | Pulse.PsReadLinearMemory(EngineHandle, PsCtx.cr3, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 455 | Pulse.PsReadLinearMemory(EngineHandle, PsCtx.cr3, PsCtx.rip, &TestBuf, sizeof(TestBuf), NULL); 456 | 457 | PS_CTX_EXT PsCtxExt = { 0 }; 458 | Pulse.PsGetExtendedContext(EngineHandle, &PsCtxExt, 0xFFFFFFFFFFFFFFFF); 459 | 460 | // Let the target go 461 | status = Pulse.PsGo(EngineHandle); 462 | 463 | // Cleanup 464 | status = Pulse.EngDestroyEngine(EngineHandle); 465 | status = Pulse.TransportDestroy(TransportHandle); 466 | 467 | return 0; 468 | } 469 | --------------------------------------------------------------------------------