1*c2e0c6b5SAndroid Build Coastguard Worker /*
2*c2e0c6b5SAndroid Build Coastguard Worker * The PCI Library -- PCI config space access using Kernel Local Debugging Driver
3*c2e0c6b5SAndroid Build Coastguard Worker *
4*c2e0c6b5SAndroid Build Coastguard Worker * Copyright (c) 2022 Pali Rohár <[email protected]>
5*c2e0c6b5SAndroid Build Coastguard Worker *
6*c2e0c6b5SAndroid Build Coastguard Worker * Can be freely distributed and used under the terms of the GNU GPL v2+.
7*c2e0c6b5SAndroid Build Coastguard Worker *
8*c2e0c6b5SAndroid Build Coastguard Worker * SPDX-License-Identifier: GPL-2.0-or-later
9*c2e0c6b5SAndroid Build Coastguard Worker */
10*c2e0c6b5SAndroid Build Coastguard Worker
11*c2e0c6b5SAndroid Build Coastguard Worker #include <windows.h>
12*c2e0c6b5SAndroid Build Coastguard Worker #include <winioctl.h>
13*c2e0c6b5SAndroid Build Coastguard Worker
14*c2e0c6b5SAndroid Build Coastguard Worker #include <stdio.h> /* for sprintf() */
15*c2e0c6b5SAndroid Build Coastguard Worker #include <string.h> /* for memset() and memcpy() */
16*c2e0c6b5SAndroid Build Coastguard Worker
17*c2e0c6b5SAndroid Build Coastguard Worker #include "internal.h"
18*c2e0c6b5SAndroid Build Coastguard Worker #include "win32-helpers.h"
19*c2e0c6b5SAndroid Build Coastguard Worker
20*c2e0c6b5SAndroid Build Coastguard Worker #ifndef ERROR_NOT_FOUND
21*c2e0c6b5SAndroid Build Coastguard Worker #define ERROR_NOT_FOUND 1168
22*c2e0c6b5SAndroid Build Coastguard Worker #endif
23*c2e0c6b5SAndroid Build Coastguard Worker
24*c2e0c6b5SAndroid Build Coastguard Worker #ifndef LOAD_LIBRARY_AS_IMAGE_RESOURCE
25*c2e0c6b5SAndroid Build Coastguard Worker #define LOAD_LIBRARY_AS_IMAGE_RESOURCE 0x20
26*c2e0c6b5SAndroid Build Coastguard Worker #endif
27*c2e0c6b5SAndroid Build Coastguard Worker #ifndef LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
28*c2e0c6b5SAndroid Build Coastguard Worker #define LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE 0x40
29*c2e0c6b5SAndroid Build Coastguard Worker #endif
30*c2e0c6b5SAndroid Build Coastguard Worker
31*c2e0c6b5SAndroid Build Coastguard Worker #ifndef IOCTL_KLDBG
32*c2e0c6b5SAndroid Build Coastguard Worker #define IOCTL_KLDBG CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1, METHOD_NEITHER, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
33*c2e0c6b5SAndroid Build Coastguard Worker #endif
34*c2e0c6b5SAndroid Build Coastguard Worker
35*c2e0c6b5SAndroid Build Coastguard Worker #ifndef BUS_DATA_TYPE
36*c2e0c6b5SAndroid Build Coastguard Worker #define BUS_DATA_TYPE LONG
37*c2e0c6b5SAndroid Build Coastguard Worker #endif
38*c2e0c6b5SAndroid Build Coastguard Worker #ifndef PCIConfiguration
39*c2e0c6b5SAndroid Build Coastguard Worker #define PCIConfiguration (BUS_DATA_TYPE)4
40*c2e0c6b5SAndroid Build Coastguard Worker #endif
41*c2e0c6b5SAndroid Build Coastguard Worker
42*c2e0c6b5SAndroid Build Coastguard Worker #ifndef SYSDBG_COMMAND
43*c2e0c6b5SAndroid Build Coastguard Worker #define SYSDBG_COMMAND ULONG
44*c2e0c6b5SAndroid Build Coastguard Worker #endif
45*c2e0c6b5SAndroid Build Coastguard Worker #ifndef SysDbgReadBusData
46*c2e0c6b5SAndroid Build Coastguard Worker #define SysDbgReadBusData (SYSDBG_COMMAND)18
47*c2e0c6b5SAndroid Build Coastguard Worker #endif
48*c2e0c6b5SAndroid Build Coastguard Worker #ifndef SysDbgWriteBusData
49*c2e0c6b5SAndroid Build Coastguard Worker #define SysDbgWriteBusData (SYSDBG_COMMAND)19
50*c2e0c6b5SAndroid Build Coastguard Worker #endif
51*c2e0c6b5SAndroid Build Coastguard Worker
52*c2e0c6b5SAndroid Build Coastguard Worker #ifndef SYSDBG_BUS_DATA
53*c2e0c6b5SAndroid Build Coastguard Worker typedef struct _SYSDBG_BUS_DATA {
54*c2e0c6b5SAndroid Build Coastguard Worker ULONG Address;
55*c2e0c6b5SAndroid Build Coastguard Worker PVOID Buffer;
56*c2e0c6b5SAndroid Build Coastguard Worker ULONG Request;
57*c2e0c6b5SAndroid Build Coastguard Worker BUS_DATA_TYPE BusDataType;
58*c2e0c6b5SAndroid Build Coastguard Worker ULONG BusNumber;
59*c2e0c6b5SAndroid Build Coastguard Worker ULONG SlotNumber;
60*c2e0c6b5SAndroid Build Coastguard Worker } SYSDBG_BUS_DATA, *PSYSDBG_BUS_DATA;
61*c2e0c6b5SAndroid Build Coastguard Worker #define SYSDBG_BUS_DATA SYSDBG_BUS_DATA
62*c2e0c6b5SAndroid Build Coastguard Worker #endif
63*c2e0c6b5SAndroid Build Coastguard Worker
64*c2e0c6b5SAndroid Build Coastguard Worker #ifndef PCI_SEGMENT_BUS_NUMBER
65*c2e0c6b5SAndroid Build Coastguard Worker typedef struct _PCI_SEGMENT_BUS_NUMBER {
66*c2e0c6b5SAndroid Build Coastguard Worker union {
67*c2e0c6b5SAndroid Build Coastguard Worker struct {
68*c2e0c6b5SAndroid Build Coastguard Worker ULONG BusNumber:8;
69*c2e0c6b5SAndroid Build Coastguard Worker ULONG SegmentNumber:16;
70*c2e0c6b5SAndroid Build Coastguard Worker ULONG Reserved:8;
71*c2e0c6b5SAndroid Build Coastguard Worker } bits;
72*c2e0c6b5SAndroid Build Coastguard Worker ULONG AsULONG;
73*c2e0c6b5SAndroid Build Coastguard Worker } u;
74*c2e0c6b5SAndroid Build Coastguard Worker } PCI_SEGMENT_BUS_NUMBER, *PPCI_SEGMENT_BUS_NUMBER;
75*c2e0c6b5SAndroid Build Coastguard Worker #define PCI_SEGMENT_BUS_NUMBER PCI_SEGMENT_BUS_NUMBER
76*c2e0c6b5SAndroid Build Coastguard Worker #endif
77*c2e0c6b5SAndroid Build Coastguard Worker
78*c2e0c6b5SAndroid Build Coastguard Worker #ifndef PCI_SLOT_NUMBER
79*c2e0c6b5SAndroid Build Coastguard Worker typedef struct _PCI_SLOT_NUMBER {
80*c2e0c6b5SAndroid Build Coastguard Worker union {
81*c2e0c6b5SAndroid Build Coastguard Worker struct {
82*c2e0c6b5SAndroid Build Coastguard Worker ULONG DeviceNumber:5;
83*c2e0c6b5SAndroid Build Coastguard Worker ULONG FunctionNumber:3;
84*c2e0c6b5SAndroid Build Coastguard Worker ULONG Reserved:24;
85*c2e0c6b5SAndroid Build Coastguard Worker } bits;
86*c2e0c6b5SAndroid Build Coastguard Worker ULONG AsULONG;
87*c2e0c6b5SAndroid Build Coastguard Worker } u;
88*c2e0c6b5SAndroid Build Coastguard Worker } PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER;
89*c2e0c6b5SAndroid Build Coastguard Worker #define PCI_SLOT_NUMBER PCI_SLOT_NUMBER
90*c2e0c6b5SAndroid Build Coastguard Worker #endif
91*c2e0c6b5SAndroid Build Coastguard Worker
92*c2e0c6b5SAndroid Build Coastguard Worker #ifndef KLDBG
93*c2e0c6b5SAndroid Build Coastguard Worker typedef struct _KLDBG {
94*c2e0c6b5SAndroid Build Coastguard Worker SYSDBG_COMMAND Command;
95*c2e0c6b5SAndroid Build Coastguard Worker PVOID Buffer;
96*c2e0c6b5SAndroid Build Coastguard Worker DWORD BufferLength;
97*c2e0c6b5SAndroid Build Coastguard Worker } KLDBG, *PKLDBG;
98*c2e0c6b5SAndroid Build Coastguard Worker #define KLDBG KLDBG
99*c2e0c6b5SAndroid Build Coastguard Worker #endif
100*c2e0c6b5SAndroid Build Coastguard Worker
101*c2e0c6b5SAndroid Build Coastguard Worker static BOOL debug_privilege_enabled;
102*c2e0c6b5SAndroid Build Coastguard Worker static LUID luid_debug_privilege;
103*c2e0c6b5SAndroid Build Coastguard Worker static BOOL revert_only_privilege;
104*c2e0c6b5SAndroid Build Coastguard Worker static HANDLE revert_token;
105*c2e0c6b5SAndroid Build Coastguard Worker
106*c2e0c6b5SAndroid Build Coastguard Worker static HANDLE kldbg_dev = INVALID_HANDLE_VALUE;
107*c2e0c6b5SAndroid Build Coastguard Worker
108*c2e0c6b5SAndroid Build Coastguard Worker static BOOL
109*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_pci_bus_data(BOOL WriteBusData, USHORT SegmentNumber, BYTE BusNumber, BYTE DeviceNumber, BYTE FunctionNumber, USHORT Address, PVOID Buffer, ULONG BufferSize, LPDWORD Length);
110*c2e0c6b5SAndroid Build Coastguard Worker
111*c2e0c6b5SAndroid Build Coastguard Worker static WORD
win32_get_current_process_machine(void)112*c2e0c6b5SAndroid Build Coastguard Worker win32_get_current_process_machine(void)
113*c2e0c6b5SAndroid Build Coastguard Worker {
114*c2e0c6b5SAndroid Build Coastguard Worker IMAGE_DOS_HEADER *dos_header;
115*c2e0c6b5SAndroid Build Coastguard Worker IMAGE_NT_HEADERS *nt_header;
116*c2e0c6b5SAndroid Build Coastguard Worker
117*c2e0c6b5SAndroid Build Coastguard Worker dos_header = (IMAGE_DOS_HEADER *)GetModuleHandle(NULL);
118*c2e0c6b5SAndroid Build Coastguard Worker if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
119*c2e0c6b5SAndroid Build Coastguard Worker return IMAGE_FILE_MACHINE_UNKNOWN;
120*c2e0c6b5SAndroid Build Coastguard Worker
121*c2e0c6b5SAndroid Build Coastguard Worker nt_header = (IMAGE_NT_HEADERS *)((BYTE *)dos_header + dos_header->e_lfanew);
122*c2e0c6b5SAndroid Build Coastguard Worker if (nt_header->Signature != IMAGE_NT_SIGNATURE)
123*c2e0c6b5SAndroid Build Coastguard Worker return IMAGE_FILE_MACHINE_UNKNOWN;
124*c2e0c6b5SAndroid Build Coastguard Worker
125*c2e0c6b5SAndroid Build Coastguard Worker return nt_header->FileHeader.Machine;
126*c2e0c6b5SAndroid Build Coastguard Worker }
127*c2e0c6b5SAndroid Build Coastguard Worker
128*c2e0c6b5SAndroid Build Coastguard Worker static BOOL
win32_check_driver(BYTE * driver_data)129*c2e0c6b5SAndroid Build Coastguard Worker win32_check_driver(BYTE *driver_data)
130*c2e0c6b5SAndroid Build Coastguard Worker {
131*c2e0c6b5SAndroid Build Coastguard Worker IMAGE_DOS_HEADER *dos_header;
132*c2e0c6b5SAndroid Build Coastguard Worker IMAGE_NT_HEADERS *nt_headers;
133*c2e0c6b5SAndroid Build Coastguard Worker WORD current_machine;
134*c2e0c6b5SAndroid Build Coastguard Worker
135*c2e0c6b5SAndroid Build Coastguard Worker current_machine = win32_get_current_process_machine();
136*c2e0c6b5SAndroid Build Coastguard Worker if (current_machine == IMAGE_FILE_MACHINE_UNKNOWN)
137*c2e0c6b5SAndroid Build Coastguard Worker return FALSE;
138*c2e0c6b5SAndroid Build Coastguard Worker
139*c2e0c6b5SAndroid Build Coastguard Worker dos_header = (IMAGE_DOS_HEADER *)driver_data;
140*c2e0c6b5SAndroid Build Coastguard Worker if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
141*c2e0c6b5SAndroid Build Coastguard Worker return FALSE;
142*c2e0c6b5SAndroid Build Coastguard Worker
143*c2e0c6b5SAndroid Build Coastguard Worker nt_headers = (IMAGE_NT_HEADERS *)((BYTE *)dos_header + dos_header->e_lfanew);
144*c2e0c6b5SAndroid Build Coastguard Worker if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
145*c2e0c6b5SAndroid Build Coastguard Worker return FALSE;
146*c2e0c6b5SAndroid Build Coastguard Worker
147*c2e0c6b5SAndroid Build Coastguard Worker if (nt_headers->FileHeader.Machine != current_machine)
148*c2e0c6b5SAndroid Build Coastguard Worker return FALSE;
149*c2e0c6b5SAndroid Build Coastguard Worker
150*c2e0c6b5SAndroid Build Coastguard Worker if (!(nt_headers->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
151*c2e0c6b5SAndroid Build Coastguard Worker return FALSE;
152*c2e0c6b5SAndroid Build Coastguard Worker
153*c2e0c6b5SAndroid Build Coastguard Worker #ifndef _WIN64
154*c2e0c6b5SAndroid Build Coastguard Worker if (!(nt_headers->FileHeader.Characteristics & IMAGE_FILE_32BIT_MACHINE))
155*c2e0c6b5SAndroid Build Coastguard Worker return FALSE;
156*c2e0c6b5SAndroid Build Coastguard Worker #endif
157*c2e0c6b5SAndroid Build Coastguard Worker
158*c2e0c6b5SAndroid Build Coastguard Worker /* IMAGE_NT_OPTIONAL_HDR_MAGIC is alias for the header magic used on the target compiler architecture. */
159*c2e0c6b5SAndroid Build Coastguard Worker if (nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
160*c2e0c6b5SAndroid Build Coastguard Worker return FALSE;
161*c2e0c6b5SAndroid Build Coastguard Worker
162*c2e0c6b5SAndroid Build Coastguard Worker if (nt_headers->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_NATIVE)
163*c2e0c6b5SAndroid Build Coastguard Worker return FALSE;
164*c2e0c6b5SAndroid Build Coastguard Worker
165*c2e0c6b5SAndroid Build Coastguard Worker return TRUE;
166*c2e0c6b5SAndroid Build Coastguard Worker }
167*c2e0c6b5SAndroid Build Coastguard Worker
168*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_unpack_driver(struct pci_access * a,LPTSTR driver_path)169*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_unpack_driver(struct pci_access *a, LPTSTR driver_path)
170*c2e0c6b5SAndroid Build Coastguard Worker {
171*c2e0c6b5SAndroid Build Coastguard Worker BOOL use_kd_exe = FALSE;
172*c2e0c6b5SAndroid Build Coastguard Worker HMODULE exe_with_driver = NULL;
173*c2e0c6b5SAndroid Build Coastguard Worker HRSRC driver_resource_info = NULL;
174*c2e0c6b5SAndroid Build Coastguard Worker HGLOBAL driver_resource = NULL;
175*c2e0c6b5SAndroid Build Coastguard Worker BYTE *driver_data = NULL;
176*c2e0c6b5SAndroid Build Coastguard Worker DWORD driver_size = 0;
177*c2e0c6b5SAndroid Build Coastguard Worker HANDLE driver_handle = INVALID_HANDLE_VALUE;
178*c2e0c6b5SAndroid Build Coastguard Worker DWORD written = 0;
179*c2e0c6b5SAndroid Build Coastguard Worker DWORD error = 0;
180*c2e0c6b5SAndroid Build Coastguard Worker int ret = 0;
181*c2e0c6b5SAndroid Build Coastguard Worker
182*c2e0c6b5SAndroid Build Coastguard Worker /* Try to find and open windbg.exe or kd.exe file in PATH. */
183*c2e0c6b5SAndroid Build Coastguard Worker exe_with_driver = LoadLibraryEx(TEXT("windbg.exe"), NULL, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
184*c2e0c6b5SAndroid Build Coastguard Worker if (!exe_with_driver)
185*c2e0c6b5SAndroid Build Coastguard Worker {
186*c2e0c6b5SAndroid Build Coastguard Worker use_kd_exe = TRUE;
187*c2e0c6b5SAndroid Build Coastguard Worker exe_with_driver = LoadLibraryEx(TEXT("kd.exe"), NULL, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
188*c2e0c6b5SAndroid Build Coastguard Worker }
189*c2e0c6b5SAndroid Build Coastguard Worker if (!exe_with_driver)
190*c2e0c6b5SAndroid Build Coastguard Worker {
191*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
192*c2e0c6b5SAndroid Build Coastguard Worker if (error == ERROR_FILE_NOT_FOUND ||
193*c2e0c6b5SAndroid Build Coastguard Worker error == ERROR_MOD_NOT_FOUND)
194*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot find windbg.exe or kd.exe file in PATH");
195*c2e0c6b5SAndroid Build Coastguard Worker else
196*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot load %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(error));
197*c2e0c6b5SAndroid Build Coastguard Worker goto out;
198*c2e0c6b5SAndroid Build Coastguard Worker }
199*c2e0c6b5SAndroid Build Coastguard Worker
200*c2e0c6b5SAndroid Build Coastguard Worker /* kldbgdrv.sys is embedded in windbg.exe/kd.exe as a resource with name id 0x7777 and type id 0x4444. */
201*c2e0c6b5SAndroid Build Coastguard Worker driver_resource_info = FindResource(exe_with_driver, MAKEINTRESOURCE(0x7777), MAKEINTRESOURCE(0x4444));
202*c2e0c6b5SAndroid Build Coastguard Worker if (!driver_resource_info)
203*c2e0c6b5SAndroid Build Coastguard Worker {
204*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot find kldbgdrv.sys resource in %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(GetLastError()));
205*c2e0c6b5SAndroid Build Coastguard Worker goto out;
206*c2e0c6b5SAndroid Build Coastguard Worker }
207*c2e0c6b5SAndroid Build Coastguard Worker
208*c2e0c6b5SAndroid Build Coastguard Worker driver_resource = LoadResource(exe_with_driver, driver_resource_info);
209*c2e0c6b5SAndroid Build Coastguard Worker if (!driver_resource)
210*c2e0c6b5SAndroid Build Coastguard Worker {
211*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot load kldbgdrv.sys resource from %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(GetLastError()));
212*c2e0c6b5SAndroid Build Coastguard Worker goto out;
213*c2e0c6b5SAndroid Build Coastguard Worker }
214*c2e0c6b5SAndroid Build Coastguard Worker
215*c2e0c6b5SAndroid Build Coastguard Worker driver_size = SizeofResource(exe_with_driver, driver_resource_info);
216*c2e0c6b5SAndroid Build Coastguard Worker if (!driver_size)
217*c2e0c6b5SAndroid Build Coastguard Worker {
218*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot determinate size of kldbgdrv.sys resource from %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(GetLastError()));
219*c2e0c6b5SAndroid Build Coastguard Worker goto out;
220*c2e0c6b5SAndroid Build Coastguard Worker }
221*c2e0c6b5SAndroid Build Coastguard Worker
222*c2e0c6b5SAndroid Build Coastguard Worker driver_data = LockResource(driver_resource);
223*c2e0c6b5SAndroid Build Coastguard Worker if (!driver_data)
224*c2e0c6b5SAndroid Build Coastguard Worker {
225*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot load kldbgdrv.sys resouce data from %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(GetLastError()));
226*c2e0c6b5SAndroid Build Coastguard Worker goto out;
227*c2e0c6b5SAndroid Build Coastguard Worker }
228*c2e0c6b5SAndroid Build Coastguard Worker
229*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_check_driver(driver_data))
230*c2e0c6b5SAndroid Build Coastguard Worker {
231*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot use kldbgdrv.sys driver from %s file: Driver is from different architecture.", use_kd_exe ? "kd.exe" : "windbg.exe");
232*c2e0c6b5SAndroid Build Coastguard Worker goto out;
233*c2e0c6b5SAndroid Build Coastguard Worker }
234*c2e0c6b5SAndroid Build Coastguard Worker
235*c2e0c6b5SAndroid Build Coastguard Worker driver_handle = CreateFile(driver_path, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
236*c2e0c6b5SAndroid Build Coastguard Worker if (driver_handle == INVALID_HANDLE_VALUE)
237*c2e0c6b5SAndroid Build Coastguard Worker {
238*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
239*c2e0c6b5SAndroid Build Coastguard Worker if (error != ERROR_FILE_EXISTS)
240*c2e0c6b5SAndroid Build Coastguard Worker {
241*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot create kldbgdrv.sys driver file in system32 directory: %s.", win32_strerror(error));
242*c2e0c6b5SAndroid Build Coastguard Worker goto out;
243*c2e0c6b5SAndroid Build Coastguard Worker }
244*c2e0c6b5SAndroid Build Coastguard Worker /* If driver file in system32 directory already exists then treat it as successfull unpack. */
245*c2e0c6b5SAndroid Build Coastguard Worker ret = 1;
246*c2e0c6b5SAndroid Build Coastguard Worker goto out;
247*c2e0c6b5SAndroid Build Coastguard Worker }
248*c2e0c6b5SAndroid Build Coastguard Worker
249*c2e0c6b5SAndroid Build Coastguard Worker if (!WriteFile(driver_handle, driver_data, driver_size, &written, NULL) ||
250*c2e0c6b5SAndroid Build Coastguard Worker written != driver_size)
251*c2e0c6b5SAndroid Build Coastguard Worker {
252*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot store kldbgdrv.sys driver file to system32 directory: %s.", win32_strerror(GetLastError()));
253*c2e0c6b5SAndroid Build Coastguard Worker /* On error, delete file from system32 directory to allow another unpack attempt. */
254*c2e0c6b5SAndroid Build Coastguard Worker CloseHandle(driver_handle);
255*c2e0c6b5SAndroid Build Coastguard Worker driver_handle = INVALID_HANDLE_VALUE;
256*c2e0c6b5SAndroid Build Coastguard Worker DeleteFile(driver_path);
257*c2e0c6b5SAndroid Build Coastguard Worker goto out;
258*c2e0c6b5SAndroid Build Coastguard Worker }
259*c2e0c6b5SAndroid Build Coastguard Worker
260*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Driver kldbgdrv.sys was successfully unpacked from %s and stored in system32 directory...", use_kd_exe ? "kd.exe" : "windbg.exe");
261*c2e0c6b5SAndroid Build Coastguard Worker ret = 1;
262*c2e0c6b5SAndroid Build Coastguard Worker
263*c2e0c6b5SAndroid Build Coastguard Worker out:
264*c2e0c6b5SAndroid Build Coastguard Worker if (driver_handle != INVALID_HANDLE_VALUE)
265*c2e0c6b5SAndroid Build Coastguard Worker CloseHandle(driver_handle);
266*c2e0c6b5SAndroid Build Coastguard Worker
267*c2e0c6b5SAndroid Build Coastguard Worker if (driver_resource)
268*c2e0c6b5SAndroid Build Coastguard Worker FreeResource(driver_resource);
269*c2e0c6b5SAndroid Build Coastguard Worker
270*c2e0c6b5SAndroid Build Coastguard Worker if (exe_with_driver)
271*c2e0c6b5SAndroid Build Coastguard Worker FreeLibrary(exe_with_driver);
272*c2e0c6b5SAndroid Build Coastguard Worker
273*c2e0c6b5SAndroid Build Coastguard Worker return ret;
274*c2e0c6b5SAndroid Build Coastguard Worker }
275*c2e0c6b5SAndroid Build Coastguard Worker
276*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_register_driver(struct pci_access * a,SC_HANDLE manager,SC_HANDLE * service)277*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_register_driver(struct pci_access *a, SC_HANDLE manager, SC_HANDLE *service)
278*c2e0c6b5SAndroid Build Coastguard Worker {
279*c2e0c6b5SAndroid Build Coastguard Worker UINT system32_len;
280*c2e0c6b5SAndroid Build Coastguard Worker LPTSTR driver_path;
281*c2e0c6b5SAndroid Build Coastguard Worker HANDLE driver_handle;
282*c2e0c6b5SAndroid Build Coastguard Worker
283*c2e0c6b5SAndroid Build Coastguard Worker /*
284*c2e0c6b5SAndroid Build Coastguard Worker * COM library dbgeng.dll unpacks kldbg driver to file "\\system32\\kldbgdrv.sys"
285*c2e0c6b5SAndroid Build Coastguard Worker * and register this driver with service name kldbgdrv. Implement same behavior.
286*c2e0c6b5SAndroid Build Coastguard Worker * GetSystemDirectory() returns path to "\\system32" directory on all Windows versions.
287*c2e0c6b5SAndroid Build Coastguard Worker */
288*c2e0c6b5SAndroid Build Coastguard Worker
289*c2e0c6b5SAndroid Build Coastguard Worker system32_len = GetSystemDirectory(NULL, 0); /* Returns number of TCHARs plus 1 for nul-term. */
290*c2e0c6b5SAndroid Build Coastguard Worker if (!system32_len)
291*c2e0c6b5SAndroid Build Coastguard Worker system32_len = sizeof("C:\\Windows\\System32");
292*c2e0c6b5SAndroid Build Coastguard Worker
293*c2e0c6b5SAndroid Build Coastguard Worker driver_path = pci_malloc(a, (system32_len + sizeof("\\kldbgdrv.sys")-1) * sizeof(TCHAR));
294*c2e0c6b5SAndroid Build Coastguard Worker
295*c2e0c6b5SAndroid Build Coastguard Worker system32_len = GetSystemDirectory(driver_path, system32_len); /* Now it returns number of TCHARs without nul-term. */
296*c2e0c6b5SAndroid Build Coastguard Worker if (!system32_len)
297*c2e0c6b5SAndroid Build Coastguard Worker {
298*c2e0c6b5SAndroid Build Coastguard Worker system32_len = sizeof("C:\\Windows\\System32")-1;
299*c2e0c6b5SAndroid Build Coastguard Worker memcpy(driver_path, TEXT("C:\\Windows\\System32"), system32_len);
300*c2e0c6b5SAndroid Build Coastguard Worker }
301*c2e0c6b5SAndroid Build Coastguard Worker
302*c2e0c6b5SAndroid Build Coastguard Worker /* GetSystemDirectory returns path without backslash unless the system directory is the root directory. */
303*c2e0c6b5SAndroid Build Coastguard Worker if (driver_path[system32_len-1] != '\\')
304*c2e0c6b5SAndroid Build Coastguard Worker driver_path[system32_len++] = '\\';
305*c2e0c6b5SAndroid Build Coastguard Worker
306*c2e0c6b5SAndroid Build Coastguard Worker memcpy(driver_path + system32_len, TEXT("kldbgdrv.sys"), sizeof(TEXT("kldbgdrv.sys")));
307*c2e0c6b5SAndroid Build Coastguard Worker
308*c2e0c6b5SAndroid Build Coastguard Worker driver_handle = CreateFile(driver_path, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
309*c2e0c6b5SAndroid Build Coastguard Worker if (driver_handle != INVALID_HANDLE_VALUE)
310*c2e0c6b5SAndroid Build Coastguard Worker CloseHandle(driver_handle);
311*c2e0c6b5SAndroid Build Coastguard Worker else if (GetLastError() == ERROR_FILE_NOT_FOUND)
312*c2e0c6b5SAndroid Build Coastguard Worker {
313*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Driver kldbgdrv.sys is missing, trying to unpack it from windbg.exe or kd.exe...");
314*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_kldbg_unpack_driver(a, driver_path))
315*c2e0c6b5SAndroid Build Coastguard Worker {
316*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(driver_path);
317*c2e0c6b5SAndroid Build Coastguard Worker return 0;
318*c2e0c6b5SAndroid Build Coastguard Worker }
319*c2e0c6b5SAndroid Build Coastguard Worker }
320*c2e0c6b5SAndroid Build Coastguard Worker
321*c2e0c6b5SAndroid Build Coastguard Worker *service = CreateService(manager, TEXT("kldbgdrv"), TEXT("kldbgdrv"), SERVICE_START, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, driver_path, NULL, NULL, NULL, NULL, NULL);
322*c2e0c6b5SAndroid Build Coastguard Worker if (!*service)
323*c2e0c6b5SAndroid Build Coastguard Worker {
324*c2e0c6b5SAndroid Build Coastguard Worker if (GetLastError() != ERROR_SERVICE_EXISTS)
325*c2e0c6b5SAndroid Build Coastguard Worker {
326*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot create kldbgdrv service: %s.", win32_strerror(GetLastError()));
327*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(driver_path);
328*c2e0c6b5SAndroid Build Coastguard Worker return 0;
329*c2e0c6b5SAndroid Build Coastguard Worker }
330*c2e0c6b5SAndroid Build Coastguard Worker
331*c2e0c6b5SAndroid Build Coastguard Worker *service = OpenService(manager, TEXT("kldbgdrv"), SERVICE_START);
332*c2e0c6b5SAndroid Build Coastguard Worker if (!*service)
333*c2e0c6b5SAndroid Build Coastguard Worker {
334*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot open kldbgdrv service: %s.", win32_strerror(GetLastError()));
335*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(driver_path);
336*c2e0c6b5SAndroid Build Coastguard Worker return 0;
337*c2e0c6b5SAndroid Build Coastguard Worker }
338*c2e0c6b5SAndroid Build Coastguard Worker }
339*c2e0c6b5SAndroid Build Coastguard Worker
340*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Service kldbgdrv was successfully registered...");
341*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(driver_path);
342*c2e0c6b5SAndroid Build Coastguard Worker return 1;
343*c2e0c6b5SAndroid Build Coastguard Worker }
344*c2e0c6b5SAndroid Build Coastguard Worker
345*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_start_driver(struct pci_access * a)346*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_start_driver(struct pci_access *a)
347*c2e0c6b5SAndroid Build Coastguard Worker {
348*c2e0c6b5SAndroid Build Coastguard Worker SC_HANDLE manager = NULL;
349*c2e0c6b5SAndroid Build Coastguard Worker SC_HANDLE service = NULL;
350*c2e0c6b5SAndroid Build Coastguard Worker DWORD error = 0;
351*c2e0c6b5SAndroid Build Coastguard Worker int ret = 0;
352*c2e0c6b5SAndroid Build Coastguard Worker
353*c2e0c6b5SAndroid Build Coastguard Worker manager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
354*c2e0c6b5SAndroid Build Coastguard Worker if (!manager)
355*c2e0c6b5SAndroid Build Coastguard Worker manager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
356*c2e0c6b5SAndroid Build Coastguard Worker if (!manager)
357*c2e0c6b5SAndroid Build Coastguard Worker {
358*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot open Service Manager: %s.", win32_strerror(GetLastError()));
359*c2e0c6b5SAndroid Build Coastguard Worker return 0;
360*c2e0c6b5SAndroid Build Coastguard Worker }
361*c2e0c6b5SAndroid Build Coastguard Worker
362*c2e0c6b5SAndroid Build Coastguard Worker service = OpenService(manager, TEXT("kldbgdrv"), SERVICE_START);
363*c2e0c6b5SAndroid Build Coastguard Worker if (!service)
364*c2e0c6b5SAndroid Build Coastguard Worker {
365*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
366*c2e0c6b5SAndroid Build Coastguard Worker if (error != ERROR_SERVICE_DOES_NOT_EXIST)
367*c2e0c6b5SAndroid Build Coastguard Worker {
368*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot open kldbgdrv service: %s.", win32_strerror(error));
369*c2e0c6b5SAndroid Build Coastguard Worker goto out;
370*c2e0c6b5SAndroid Build Coastguard Worker }
371*c2e0c6b5SAndroid Build Coastguard Worker
372*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Kernel Local Debugging Driver (kldbgdrv.sys) is not registered, trying to register it...");
373*c2e0c6b5SAndroid Build Coastguard Worker
374*c2e0c6b5SAndroid Build Coastguard Worker if (win32_is_32bit_on_64bit_system())
375*c2e0c6b5SAndroid Build Coastguard Worker {
376*c2e0c6b5SAndroid Build Coastguard Worker /* TODO */
377*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Registering driver from 32-bit process on 64-bit system is not implemented yet.");
378*c2e0c6b5SAndroid Build Coastguard Worker goto out;
379*c2e0c6b5SAndroid Build Coastguard Worker }
380*c2e0c6b5SAndroid Build Coastguard Worker
381*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_kldbg_register_driver(a, manager, &service))
382*c2e0c6b5SAndroid Build Coastguard Worker goto out;
383*c2e0c6b5SAndroid Build Coastguard Worker }
384*c2e0c6b5SAndroid Build Coastguard Worker
385*c2e0c6b5SAndroid Build Coastguard Worker if (!StartService(service, 0, NULL))
386*c2e0c6b5SAndroid Build Coastguard Worker {
387*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
388*c2e0c6b5SAndroid Build Coastguard Worker if (error != ERROR_SERVICE_ALREADY_RUNNING)
389*c2e0c6b5SAndroid Build Coastguard Worker {
390*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot start kldbgdrv service: %s.", win32_strerror(error));
391*c2e0c6b5SAndroid Build Coastguard Worker goto out;
392*c2e0c6b5SAndroid Build Coastguard Worker }
393*c2e0c6b5SAndroid Build Coastguard Worker }
394*c2e0c6b5SAndroid Build Coastguard Worker
395*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Service kldbgdrv successfully started...");
396*c2e0c6b5SAndroid Build Coastguard Worker ret = 1;
397*c2e0c6b5SAndroid Build Coastguard Worker
398*c2e0c6b5SAndroid Build Coastguard Worker out:
399*c2e0c6b5SAndroid Build Coastguard Worker if (service)
400*c2e0c6b5SAndroid Build Coastguard Worker CloseServiceHandle(service);
401*c2e0c6b5SAndroid Build Coastguard Worker
402*c2e0c6b5SAndroid Build Coastguard Worker if (manager)
403*c2e0c6b5SAndroid Build Coastguard Worker CloseServiceHandle(manager);
404*c2e0c6b5SAndroid Build Coastguard Worker
405*c2e0c6b5SAndroid Build Coastguard Worker return ret;
406*c2e0c6b5SAndroid Build Coastguard Worker }
407*c2e0c6b5SAndroid Build Coastguard Worker
408*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_setup(struct pci_access * a)409*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_setup(struct pci_access *a)
410*c2e0c6b5SAndroid Build Coastguard Worker {
411*c2e0c6b5SAndroid Build Coastguard Worker OSVERSIONINFO version;
412*c2e0c6b5SAndroid Build Coastguard Worker DWORD ret_len;
413*c2e0c6b5SAndroid Build Coastguard Worker DWORD error;
414*c2e0c6b5SAndroid Build Coastguard Worker DWORD id;
415*c2e0c6b5SAndroid Build Coastguard Worker
416*c2e0c6b5SAndroid Build Coastguard Worker if (kldbg_dev != INVALID_HANDLE_VALUE)
417*c2e0c6b5SAndroid Build Coastguard Worker return 1;
418*c2e0c6b5SAndroid Build Coastguard Worker
419*c2e0c6b5SAndroid Build Coastguard Worker /* Check for Windows Vista (NT 6.0). */
420*c2e0c6b5SAndroid Build Coastguard Worker version.dwOSVersionInfoSize = sizeof(version);
421*c2e0c6b5SAndroid Build Coastguard Worker if (!GetVersionEx(&version) ||
422*c2e0c6b5SAndroid Build Coastguard Worker version.dwPlatformId != VER_PLATFORM_WIN32_NT ||
423*c2e0c6b5SAndroid Build Coastguard Worker version.dwMajorVersion < 6)
424*c2e0c6b5SAndroid Build Coastguard Worker {
425*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Accessing PCI config space via Kernel Local Debugging Driver requires Windows Vista or higher version.");
426*c2e0c6b5SAndroid Build Coastguard Worker return 0;
427*c2e0c6b5SAndroid Build Coastguard Worker }
428*c2e0c6b5SAndroid Build Coastguard Worker
429*c2e0c6b5SAndroid Build Coastguard Worker kldbg_dev = CreateFile(TEXT("\\\\.\\kldbgdrv"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
430*c2e0c6b5SAndroid Build Coastguard Worker if (kldbg_dev == INVALID_HANDLE_VALUE)
431*c2e0c6b5SAndroid Build Coastguard Worker {
432*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
433*c2e0c6b5SAndroid Build Coastguard Worker if (error != ERROR_FILE_NOT_FOUND)
434*c2e0c6b5SAndroid Build Coastguard Worker {
435*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot open \"\\\\.\\kldbgdrv\" device: %s.", win32_strerror(error));
436*c2e0c6b5SAndroid Build Coastguard Worker return 0;
437*c2e0c6b5SAndroid Build Coastguard Worker }
438*c2e0c6b5SAndroid Build Coastguard Worker
439*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Kernel Local Debugging Driver (kldbgdrv.sys) is not running, trying to start it...");
440*c2e0c6b5SAndroid Build Coastguard Worker
441*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_kldbg_start_driver(a))
442*c2e0c6b5SAndroid Build Coastguard Worker return 0;
443*c2e0c6b5SAndroid Build Coastguard Worker
444*c2e0c6b5SAndroid Build Coastguard Worker kldbg_dev = CreateFile(TEXT("\\\\.\\kldbgdrv"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
445*c2e0c6b5SAndroid Build Coastguard Worker if (kldbg_dev == INVALID_HANDLE_VALUE)
446*c2e0c6b5SAndroid Build Coastguard Worker {
447*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
448*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot open \"\\\\.\\kldbgdrv\" device: %s.", win32_strerror(error));
449*c2e0c6b5SAndroid Build Coastguard Worker return 0;
450*c2e0c6b5SAndroid Build Coastguard Worker }
451*c2e0c6b5SAndroid Build Coastguard Worker }
452*c2e0c6b5SAndroid Build Coastguard Worker
453*c2e0c6b5SAndroid Build Coastguard Worker /*
454*c2e0c6b5SAndroid Build Coastguard Worker * Try to read PCI id register from PCI device 0000:00:00.0.
455*c2e0c6b5SAndroid Build Coastguard Worker * If this device does not exist and kldbg API is working then
456*c2e0c6b5SAndroid Build Coastguard Worker * kldbg returns success with read value 0xffffffff.
457*c2e0c6b5SAndroid Build Coastguard Worker */
458*c2e0c6b5SAndroid Build Coastguard Worker if (win32_kldbg_pci_bus_data(FALSE, 0, 0, 0, 0, 0, &id, sizeof(id), &ret_len) && ret_len == sizeof(id))
459*c2e0c6b5SAndroid Build Coastguard Worker return 1;
460*c2e0c6b5SAndroid Build Coastguard Worker
461*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
462*c2e0c6b5SAndroid Build Coastguard Worker
463*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot read PCI config space via Kernel Local Debugging Driver: %s.", win32_strerror(error));
464*c2e0c6b5SAndroid Build Coastguard Worker
465*c2e0c6b5SAndroid Build Coastguard Worker if (error != ERROR_ACCESS_DENIED)
466*c2e0c6b5SAndroid Build Coastguard Worker {
467*c2e0c6b5SAndroid Build Coastguard Worker CloseHandle(kldbg_dev);
468*c2e0c6b5SAndroid Build Coastguard Worker kldbg_dev = INVALID_HANDLE_VALUE;
469*c2e0c6b5SAndroid Build Coastguard Worker return 0;
470*c2e0c6b5SAndroid Build Coastguard Worker }
471*c2e0c6b5SAndroid Build Coastguard Worker
472*c2e0c6b5SAndroid Build Coastguard Worker a->debug("..Trying again with Debug privilege...");
473*c2e0c6b5SAndroid Build Coastguard Worker
474*c2e0c6b5SAndroid Build Coastguard Worker if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid_debug_privilege))
475*c2e0c6b5SAndroid Build Coastguard Worker {
476*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Debug privilege is not supported.");
477*c2e0c6b5SAndroid Build Coastguard Worker CloseHandle(kldbg_dev);
478*c2e0c6b5SAndroid Build Coastguard Worker kldbg_dev = INVALID_HANDLE_VALUE;
479*c2e0c6b5SAndroid Build Coastguard Worker return 0;
480*c2e0c6b5SAndroid Build Coastguard Worker }
481*c2e0c6b5SAndroid Build Coastguard Worker
482*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_enable_privilege(luid_debug_privilege, &revert_token, &revert_only_privilege))
483*c2e0c6b5SAndroid Build Coastguard Worker {
484*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Process does not have right to enable Debug privilege.");
485*c2e0c6b5SAndroid Build Coastguard Worker CloseHandle(kldbg_dev);
486*c2e0c6b5SAndroid Build Coastguard Worker kldbg_dev = INVALID_HANDLE_VALUE;
487*c2e0c6b5SAndroid Build Coastguard Worker return 0;
488*c2e0c6b5SAndroid Build Coastguard Worker }
489*c2e0c6b5SAndroid Build Coastguard Worker
490*c2e0c6b5SAndroid Build Coastguard Worker if (win32_kldbg_pci_bus_data(FALSE, 0, 0, 0, 0, 0, &id, sizeof(id), &ret_len) && ret_len == sizeof(id))
491*c2e0c6b5SAndroid Build Coastguard Worker {
492*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Succeeded.");
493*c2e0c6b5SAndroid Build Coastguard Worker debug_privilege_enabled = TRUE;
494*c2e0c6b5SAndroid Build Coastguard Worker return 1;
495*c2e0c6b5SAndroid Build Coastguard Worker }
496*c2e0c6b5SAndroid Build Coastguard Worker
497*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
498*c2e0c6b5SAndroid Build Coastguard Worker
499*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot read PCI config space via Kernel Local Debugging Driver: %s.", win32_strerror(error));
500*c2e0c6b5SAndroid Build Coastguard Worker
501*c2e0c6b5SAndroid Build Coastguard Worker CloseHandle(kldbg_dev);
502*c2e0c6b5SAndroid Build Coastguard Worker kldbg_dev = INVALID_HANDLE_VALUE;
503*c2e0c6b5SAndroid Build Coastguard Worker
504*c2e0c6b5SAndroid Build Coastguard Worker win32_revert_privilege(luid_debug_privilege, revert_token, revert_only_privilege);
505*c2e0c6b5SAndroid Build Coastguard Worker revert_token = NULL;
506*c2e0c6b5SAndroid Build Coastguard Worker revert_only_privilege = FALSE;
507*c2e0c6b5SAndroid Build Coastguard Worker return 0;
508*c2e0c6b5SAndroid Build Coastguard Worker }
509*c2e0c6b5SAndroid Build Coastguard Worker
510*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_detect(struct pci_access * a)511*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_detect(struct pci_access *a)
512*c2e0c6b5SAndroid Build Coastguard Worker {
513*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_kldbg_setup(a))
514*c2e0c6b5SAndroid Build Coastguard Worker return 0;
515*c2e0c6b5SAndroid Build Coastguard Worker
516*c2e0c6b5SAndroid Build Coastguard Worker return 1;
517*c2e0c6b5SAndroid Build Coastguard Worker }
518*c2e0c6b5SAndroid Build Coastguard Worker
519*c2e0c6b5SAndroid Build Coastguard Worker static void
win32_kldbg_init(struct pci_access * a)520*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_init(struct pci_access *a)
521*c2e0c6b5SAndroid Build Coastguard Worker {
522*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_kldbg_setup(a))
523*c2e0c6b5SAndroid Build Coastguard Worker {
524*c2e0c6b5SAndroid Build Coastguard Worker a->debug("\n");
525*c2e0c6b5SAndroid Build Coastguard Worker a->error("PCI config space via Kernel Local Debugging Driver cannot be accessed.");
526*c2e0c6b5SAndroid Build Coastguard Worker }
527*c2e0c6b5SAndroid Build Coastguard Worker }
528*c2e0c6b5SAndroid Build Coastguard Worker
529*c2e0c6b5SAndroid Build Coastguard Worker static void
win32_kldbg_cleanup(struct pci_access * a UNUSED)530*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_cleanup(struct pci_access *a UNUSED)
531*c2e0c6b5SAndroid Build Coastguard Worker {
532*c2e0c6b5SAndroid Build Coastguard Worker if (kldbg_dev == INVALID_HANDLE_VALUE)
533*c2e0c6b5SAndroid Build Coastguard Worker return;
534*c2e0c6b5SAndroid Build Coastguard Worker
535*c2e0c6b5SAndroid Build Coastguard Worker CloseHandle(kldbg_dev);
536*c2e0c6b5SAndroid Build Coastguard Worker kldbg_dev = INVALID_HANDLE_VALUE;
537*c2e0c6b5SAndroid Build Coastguard Worker
538*c2e0c6b5SAndroid Build Coastguard Worker if (debug_privilege_enabled)
539*c2e0c6b5SAndroid Build Coastguard Worker {
540*c2e0c6b5SAndroid Build Coastguard Worker win32_revert_privilege(luid_debug_privilege, revert_token, revert_only_privilege);
541*c2e0c6b5SAndroid Build Coastguard Worker revert_token = NULL;
542*c2e0c6b5SAndroid Build Coastguard Worker revert_only_privilege = FALSE;
543*c2e0c6b5SAndroid Build Coastguard Worker debug_privilege_enabled = FALSE;
544*c2e0c6b5SAndroid Build Coastguard Worker }
545*c2e0c6b5SAndroid Build Coastguard Worker }
546*c2e0c6b5SAndroid Build Coastguard Worker
547*c2e0c6b5SAndroid Build Coastguard Worker struct acpi_mcfg {
548*c2e0c6b5SAndroid Build Coastguard Worker char signature[4];
549*c2e0c6b5SAndroid Build Coastguard Worker u32 length;
550*c2e0c6b5SAndroid Build Coastguard Worker u8 revision;
551*c2e0c6b5SAndroid Build Coastguard Worker u8 checksum;
552*c2e0c6b5SAndroid Build Coastguard Worker char oem_id[6];
553*c2e0c6b5SAndroid Build Coastguard Worker char oem_table_id[8];
554*c2e0c6b5SAndroid Build Coastguard Worker u32 oem_revision;
555*c2e0c6b5SAndroid Build Coastguard Worker char asl_compiler_id[4];
556*c2e0c6b5SAndroid Build Coastguard Worker u32 asl_compiler_revision;
557*c2e0c6b5SAndroid Build Coastguard Worker u64 reserved;
558*c2e0c6b5SAndroid Build Coastguard Worker struct {
559*c2e0c6b5SAndroid Build Coastguard Worker u64 address;
560*c2e0c6b5SAndroid Build Coastguard Worker u16 pci_segment;
561*c2e0c6b5SAndroid Build Coastguard Worker u8 start_bus_number;
562*c2e0c6b5SAndroid Build Coastguard Worker u8 end_bus_number;
563*c2e0c6b5SAndroid Build Coastguard Worker u32 reserved;
564*c2e0c6b5SAndroid Build Coastguard Worker } allocations[0];
565*c2e0c6b5SAndroid Build Coastguard Worker } PCI_PACKED;
566*c2e0c6b5SAndroid Build Coastguard Worker
567*c2e0c6b5SAndroid Build Coastguard Worker static void
win32_kldbg_scan(struct pci_access * a)568*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_scan(struct pci_access *a)
569*c2e0c6b5SAndroid Build Coastguard Worker {
570*c2e0c6b5SAndroid Build Coastguard Worker /*
571*c2e0c6b5SAndroid Build Coastguard Worker * There is no kldbg API to retrieve list of PCI segments. WinDBG pci plugin
572*c2e0c6b5SAndroid Build Coastguard Worker * kext.dll loads debug symbols from pci.pdb file for kernel module pci.sys.
573*c2e0c6b5SAndroid Build Coastguard Worker * Then it reads kernel memory which belongs to PciSegmentList local variable
574*c2e0c6b5SAndroid Build Coastguard Worker * which is the first entry of struct _PCI_SEGMENT linked list. And then it
575*c2e0c6b5SAndroid Build Coastguard Worker * iterates all entries in linked list and reads SegmentNumber for each entry.
576*c2e0c6b5SAndroid Build Coastguard Worker *
577*c2e0c6b5SAndroid Build Coastguard Worker * This is extremly ugly hack and does not work on systems without installed
578*c2e0c6b5SAndroid Build Coastguard Worker * kernel debug symbol files.
579*c2e0c6b5SAndroid Build Coastguard Worker *
580*c2e0c6b5SAndroid Build Coastguard Worker * Do something less ugly. Retrieve ACPI MCFG table via GetSystemFirmwareTable
581*c2e0c6b5SAndroid Build Coastguard Worker * and parse all PCI segment numbers from it. ACPI MCFG table contains PCIe
582*c2e0c6b5SAndroid Build Coastguard Worker * ECAM definitions, so all PCI segment numbers.
583*c2e0c6b5SAndroid Build Coastguard Worker */
584*c2e0c6b5SAndroid Build Coastguard Worker
585*c2e0c6b5SAndroid Build Coastguard Worker UINT (*WINAPI MyGetSystemFirmwareTable)(DWORD FirmwareTableProviderSignature, DWORD FirmwareTableID, PVOID pFirmwareTableBuffer, DWORD BufferSize);
586*c2e0c6b5SAndroid Build Coastguard Worker int i, allocations_count;
587*c2e0c6b5SAndroid Build Coastguard Worker struct acpi_mcfg *mcfg;
588*c2e0c6b5SAndroid Build Coastguard Worker HMODULE kernel32;
589*c2e0c6b5SAndroid Build Coastguard Worker byte *segments;
590*c2e0c6b5SAndroid Build Coastguard Worker DWORD error;
591*c2e0c6b5SAndroid Build Coastguard Worker DWORD size;
592*c2e0c6b5SAndroid Build Coastguard Worker
593*c2e0c6b5SAndroid Build Coastguard Worker /* Always scan PCI segment 0. */
594*c2e0c6b5SAndroid Build Coastguard Worker pci_generic_scan_domain(a, 0);
595*c2e0c6b5SAndroid Build Coastguard Worker
596*c2e0c6b5SAndroid Build Coastguard Worker kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
597*c2e0c6b5SAndroid Build Coastguard Worker if (!kernel32)
598*c2e0c6b5SAndroid Build Coastguard Worker return;
599*c2e0c6b5SAndroid Build Coastguard Worker
600*c2e0c6b5SAndroid Build Coastguard Worker /* Function GetSystemFirmwareTable() is available since Windows Vista. */
601*c2e0c6b5SAndroid Build Coastguard Worker MyGetSystemFirmwareTable = (void *)GetProcAddress(kernel32, "GetSystemFirmwareTable");
602*c2e0c6b5SAndroid Build Coastguard Worker if (!MyGetSystemFirmwareTable)
603*c2e0c6b5SAndroid Build Coastguard Worker return;
604*c2e0c6b5SAndroid Build Coastguard Worker
605*c2e0c6b5SAndroid Build Coastguard Worker /* 0x41435049 = 'ACPI', 0x4746434D = 'MCFG' */
606*c2e0c6b5SAndroid Build Coastguard Worker size = MyGetSystemFirmwareTable(0x41435049, 0x4746434D, NULL, 0);
607*c2e0c6b5SAndroid Build Coastguard Worker if (size == 0)
608*c2e0c6b5SAndroid Build Coastguard Worker {
609*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
610*c2e0c6b5SAndroid Build Coastguard Worker if (error == ERROR_INVALID_FUNCTION) /* ACPI is not present, so only PCI segment 0 is available. */
611*c2e0c6b5SAndroid Build Coastguard Worker return;
612*c2e0c6b5SAndroid Build Coastguard Worker else if (error == ERROR_NOT_FOUND) /* MCFG table is not present, so only PCI segment 0 is available. */
613*c2e0c6b5SAndroid Build Coastguard Worker return;
614*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot retrieve ACPI MCFG table: %s.\n", win32_strerror(error));
615*c2e0c6b5SAndroid Build Coastguard Worker return;
616*c2e0c6b5SAndroid Build Coastguard Worker }
617*c2e0c6b5SAndroid Build Coastguard Worker
618*c2e0c6b5SAndroid Build Coastguard Worker mcfg = pci_malloc(a, size);
619*c2e0c6b5SAndroid Build Coastguard Worker
620*c2e0c6b5SAndroid Build Coastguard Worker if (MyGetSystemFirmwareTable(0x41435049, 0x4746434D, mcfg, size) != size)
621*c2e0c6b5SAndroid Build Coastguard Worker {
622*c2e0c6b5SAndroid Build Coastguard Worker error = GetLastError();
623*c2e0c6b5SAndroid Build Coastguard Worker a->debug("Cannot retrieve ACPI MCFG table: %s.\n", win32_strerror(error));
624*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(mcfg);
625*c2e0c6b5SAndroid Build Coastguard Worker return;
626*c2e0c6b5SAndroid Build Coastguard Worker }
627*c2e0c6b5SAndroid Build Coastguard Worker
628*c2e0c6b5SAndroid Build Coastguard Worker if (size < sizeof(*mcfg) || size < mcfg->length)
629*c2e0c6b5SAndroid Build Coastguard Worker {
630*c2e0c6b5SAndroid Build Coastguard Worker a->debug("ACPI MCFG table is broken.\n");
631*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(mcfg);
632*c2e0c6b5SAndroid Build Coastguard Worker return;
633*c2e0c6b5SAndroid Build Coastguard Worker }
634*c2e0c6b5SAndroid Build Coastguard Worker
635*c2e0c6b5SAndroid Build Coastguard Worker segments = pci_malloc(a, 0xFFFF/8);
636*c2e0c6b5SAndroid Build Coastguard Worker memset(segments, 0, 0xFFFF/8);
637*c2e0c6b5SAndroid Build Coastguard Worker
638*c2e0c6b5SAndroid Build Coastguard Worker /* Scan all MCFG allocations and set available PCI segments into bit field. */
639*c2e0c6b5SAndroid Build Coastguard Worker allocations_count = (mcfg->length - ((unsigned char *)&mcfg->allocations - (unsigned char *)mcfg)) / sizeof(mcfg->allocations[0]);
640*c2e0c6b5SAndroid Build Coastguard Worker for (i = 0; i < allocations_count; i++)
641*c2e0c6b5SAndroid Build Coastguard Worker segments[mcfg->allocations[i].pci_segment / 8] |= 1 << (mcfg->allocations[i].pci_segment % 8);
642*c2e0c6b5SAndroid Build Coastguard Worker
643*c2e0c6b5SAndroid Build Coastguard Worker /* Skip PCI segment 0 which was already scanned. */
644*c2e0c6b5SAndroid Build Coastguard Worker for (i = 1; i < 0xFFFF; i++)
645*c2e0c6b5SAndroid Build Coastguard Worker if (segments[i / 8] & (1 << (i % 8)))
646*c2e0c6b5SAndroid Build Coastguard Worker pci_generic_scan_domain(a, i);
647*c2e0c6b5SAndroid Build Coastguard Worker
648*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(segments);
649*c2e0c6b5SAndroid Build Coastguard Worker pci_mfree(mcfg);
650*c2e0c6b5SAndroid Build Coastguard Worker }
651*c2e0c6b5SAndroid Build Coastguard Worker
652*c2e0c6b5SAndroid Build Coastguard Worker static BOOL
win32_kldbg_pci_bus_data(BOOL WriteBusData,USHORT SegmentNumber,BYTE BusNumber,BYTE DeviceNumber,BYTE FunctionNumber,USHORT Address,PVOID Buffer,ULONG BufferSize,LPDWORD Length)653*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_pci_bus_data(BOOL WriteBusData, USHORT SegmentNumber, BYTE BusNumber, BYTE DeviceNumber, BYTE FunctionNumber, USHORT Address, PVOID Buffer, ULONG BufferSize, LPDWORD Length)
654*c2e0c6b5SAndroid Build Coastguard Worker {
655*c2e0c6b5SAndroid Build Coastguard Worker KLDBG kldbg_cmd;
656*c2e0c6b5SAndroid Build Coastguard Worker SYSDBG_BUS_DATA sysdbg_cmd;
657*c2e0c6b5SAndroid Build Coastguard Worker PCI_SLOT_NUMBER pci_slot;
658*c2e0c6b5SAndroid Build Coastguard Worker PCI_SEGMENT_BUS_NUMBER pci_seg_bus;
659*c2e0c6b5SAndroid Build Coastguard Worker
660*c2e0c6b5SAndroid Build Coastguard Worker memset(&pci_slot, 0, sizeof(pci_slot));
661*c2e0c6b5SAndroid Build Coastguard Worker memset(&sysdbg_cmd, 0, sizeof(sysdbg_cmd));
662*c2e0c6b5SAndroid Build Coastguard Worker memset(&pci_seg_bus, 0, sizeof(pci_seg_bus));
663*c2e0c6b5SAndroid Build Coastguard Worker
664*c2e0c6b5SAndroid Build Coastguard Worker sysdbg_cmd.Address = Address;
665*c2e0c6b5SAndroid Build Coastguard Worker sysdbg_cmd.Buffer = Buffer;
666*c2e0c6b5SAndroid Build Coastguard Worker sysdbg_cmd.Request = BufferSize;
667*c2e0c6b5SAndroid Build Coastguard Worker sysdbg_cmd.BusDataType = PCIConfiguration;
668*c2e0c6b5SAndroid Build Coastguard Worker pci_seg_bus.u.bits.BusNumber = BusNumber;
669*c2e0c6b5SAndroid Build Coastguard Worker pci_seg_bus.u.bits.SegmentNumber = SegmentNumber;
670*c2e0c6b5SAndroid Build Coastguard Worker sysdbg_cmd.BusNumber = pci_seg_bus.u.AsULONG;
671*c2e0c6b5SAndroid Build Coastguard Worker pci_slot.u.bits.DeviceNumber = DeviceNumber;
672*c2e0c6b5SAndroid Build Coastguard Worker pci_slot.u.bits.FunctionNumber = FunctionNumber;
673*c2e0c6b5SAndroid Build Coastguard Worker sysdbg_cmd.SlotNumber = pci_slot.u.AsULONG;
674*c2e0c6b5SAndroid Build Coastguard Worker
675*c2e0c6b5SAndroid Build Coastguard Worker kldbg_cmd.Command = WriteBusData ? SysDbgWriteBusData : SysDbgReadBusData;
676*c2e0c6b5SAndroid Build Coastguard Worker kldbg_cmd.Buffer = &sysdbg_cmd;
677*c2e0c6b5SAndroid Build Coastguard Worker kldbg_cmd.BufferLength = sizeof(sysdbg_cmd);
678*c2e0c6b5SAndroid Build Coastguard Worker
679*c2e0c6b5SAndroid Build Coastguard Worker *Length = 0;
680*c2e0c6b5SAndroid Build Coastguard Worker return DeviceIoControl(kldbg_dev, IOCTL_KLDBG, &kldbg_cmd, sizeof(kldbg_cmd), &sysdbg_cmd, sizeof(sysdbg_cmd), Length, NULL);
681*c2e0c6b5SAndroid Build Coastguard Worker }
682*c2e0c6b5SAndroid Build Coastguard Worker
683*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_read(struct pci_dev * d,int pos,byte * buf,int len)684*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_read(struct pci_dev *d, int pos, byte *buf, int len)
685*c2e0c6b5SAndroid Build Coastguard Worker {
686*c2e0c6b5SAndroid Build Coastguard Worker DWORD ret_len;
687*c2e0c6b5SAndroid Build Coastguard Worker
688*c2e0c6b5SAndroid Build Coastguard Worker if ((unsigned int)d->domain > 0xffff)
689*c2e0c6b5SAndroid Build Coastguard Worker return 0;
690*c2e0c6b5SAndroid Build Coastguard Worker
691*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_kldbg_pci_bus_data(FALSE, d->domain, d->bus, d->dev, d->func, pos, buf, len, &ret_len))
692*c2e0c6b5SAndroid Build Coastguard Worker return 0;
693*c2e0c6b5SAndroid Build Coastguard Worker
694*c2e0c6b5SAndroid Build Coastguard Worker if (ret_len != (unsigned int)len)
695*c2e0c6b5SAndroid Build Coastguard Worker return 0;
696*c2e0c6b5SAndroid Build Coastguard Worker
697*c2e0c6b5SAndroid Build Coastguard Worker return 1;
698*c2e0c6b5SAndroid Build Coastguard Worker }
699*c2e0c6b5SAndroid Build Coastguard Worker
700*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_write(struct pci_dev * d,int pos,byte * buf,int len)701*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_write(struct pci_dev *d, int pos, byte *buf, int len)
702*c2e0c6b5SAndroid Build Coastguard Worker {
703*c2e0c6b5SAndroid Build Coastguard Worker DWORD ret_len;
704*c2e0c6b5SAndroid Build Coastguard Worker
705*c2e0c6b5SAndroid Build Coastguard Worker if ((unsigned int)d->domain > 0xffff)
706*c2e0c6b5SAndroid Build Coastguard Worker return 0;
707*c2e0c6b5SAndroid Build Coastguard Worker
708*c2e0c6b5SAndroid Build Coastguard Worker if (!win32_kldbg_pci_bus_data(TRUE, d->domain, d->bus, d->dev, d->func, pos, buf, len, &ret_len))
709*c2e0c6b5SAndroid Build Coastguard Worker return 0;
710*c2e0c6b5SAndroid Build Coastguard Worker
711*c2e0c6b5SAndroid Build Coastguard Worker if (ret_len != (unsigned int)len)
712*c2e0c6b5SAndroid Build Coastguard Worker return 0;
713*c2e0c6b5SAndroid Build Coastguard Worker
714*c2e0c6b5SAndroid Build Coastguard Worker return 1;
715*c2e0c6b5SAndroid Build Coastguard Worker }
716*c2e0c6b5SAndroid Build Coastguard Worker
717*c2e0c6b5SAndroid Build Coastguard Worker struct pci_methods pm_win32_kldbg = {
718*c2e0c6b5SAndroid Build Coastguard Worker .name = "win32-kldbg",
719*c2e0c6b5SAndroid Build Coastguard Worker .help = "Win32 PCI config space access using Kernel Local Debugging Driver",
720*c2e0c6b5SAndroid Build Coastguard Worker .detect = win32_kldbg_detect,
721*c2e0c6b5SAndroid Build Coastguard Worker .init = win32_kldbg_init,
722*c2e0c6b5SAndroid Build Coastguard Worker .cleanup = win32_kldbg_cleanup,
723*c2e0c6b5SAndroid Build Coastguard Worker .scan = win32_kldbg_scan,
724*c2e0c6b5SAndroid Build Coastguard Worker .fill_info = pci_generic_fill_info,
725*c2e0c6b5SAndroid Build Coastguard Worker .read = win32_kldbg_read,
726*c2e0c6b5SAndroid Build Coastguard Worker .write = win32_kldbg_write,
727*c2e0c6b5SAndroid Build Coastguard Worker };
728