VirtualBox

source: vbox/trunk/src/VBox/VMM/DBGFMem.cpp@ 13577

最後變更 在這個檔案從13577是 13502,由 vboxsync 提交於 16 年 前

VMM: Prevent the debugger from crashing the VMM passing it guest addresses above 4GB when the guest is in 32-bit mode.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 8.7 KB
 
1/* $Id: DBGFMem.cpp 13502 2008-10-22 15:52:53Z vboxsync $ */
2/** @file
3 * DBGF - Debugger Facility, Memory Methods.
4 */
5
6/*
7 * Copyright (C) 2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_DBGF
27#include <VBox/dbgf.h>
28#include <VBox/pgm.h>
29#include "DBGFInternal.h"
30#include <VBox/vm.h>
31#include <VBox/err.h>
32#include <VBox/log.h>
33
34
35
36/**
37 * Scan guest memory for an exact byte string.
38 *
39 * @returns VBox status code.
40 * @param pVM The VM handle.
41 * @param pAddress Where to store the mixed address.
42 * @param cbRange The number of bytes to scan.
43 * @param pabNeedle What to search for - exact search.
44 * @param cbNeedle Size of the search byte string.
45 * @param pHitAddress Where to put the address of the first hit.
46 */
47static DECLCALLBACK(int) dbgfR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle,
48 PDBGFADDRESS pHitAddress)
49{
50 /*
51 * Validate the input we use, PGM does the rest.
52 */
53 if (!DBGFR3AddrIsValid(pVM, pAddress))
54 return VERR_INVALID_POINTER;
55 if (!VALID_PTR(pHitAddress))
56 return VERR_INVALID_POINTER;
57 if (DBGFADDRESS_IS_HMA(pAddress))
58 return VERR_INVALID_POINTER;
59
60 /*
61 * Select DBGF worker by addressing mode.
62 */
63 int rc;
64 PGMMODE enmMode = PGMGetGuestMode(pVM);
65 if ( enmMode == PGMMODE_REAL
66 || enmMode == PGMMODE_PROTECTED
67 || DBGFADDRESS_IS_PHYS(pAddress)
68 )
69 {
70 RTGCPHYS PhysHit;
71 rc = PGMR3DbgScanPhysical(pVM, pAddress->FlatPtr, cbRange, pabNeedle, cbNeedle, &PhysHit);
72 if (RT_SUCCESS(rc))
73 DBGFR3AddrFromPhys(pVM, pHitAddress, PhysHit);
74 }
75 else
76 {
77 if ( ( pAddress->FlatPtr >= _4G
78 || pAddress->FlatPtr + cbRange > _4G)
79 && enmMode != PGMMODE_AMD64
80 && enmMode != PGMMODE_AMD64_NX)
81 return VERR_DBGF_MEM_NOT_FOUND;
82 RTGCUINTPTR GCPtrHit;
83 rc = PGMR3DbgScanVirtual(pVM, pAddress->FlatPtr, cbRange, pabNeedle, cbNeedle, &GCPtrHit);
84 if (RT_SUCCESS(rc))
85 DBGFR3AddrFromFlat(pVM, pHitAddress, GCPtrHit);
86 }
87
88 return rc;
89}
90
91
92/**
93 * Scan guest memory for an exact byte string.
94 *
95 * @returns VBox status codes:
96 * @retval VINF_SUCCESS and *pGCPtrHit on success.
97 * @retval VERR_DBGF_MEM_NOT_FOUND if not found.
98 * @retval VERR_INVALID_POINTER if any of the pointer arguments are invalid.
99 * @retval VERR_INVALID_ARGUMENT if any other arguments are invalid.
100 *
101 * @param pVM The VM handle.
102 * @param pAddress Where to store the mixed address.
103 * @param cbRange The number of bytes to scan.
104 * @param pabNeedle What to search for - exact search.
105 * @param cbNeedle Size of the search byte string.
106 * @param pHitAddress Where to put the address of the first hit.
107 *
108 * @thread Any thread.
109 */
110VMMR3DECL(int) DBGFR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress)
111{
112 PVMREQ pReq;
113 int rc = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT, (PFNRT)dbgfR3MemScan, 6,
114 pVM, pAddress, cbRange, pabNeedle, cbNeedle, pHitAddress);
115 if (VBOX_SUCCESS(rc))
116 rc = pReq->iStatus;
117 VMR3ReqFree(pReq);
118
119 return rc;
120}
121
122
123/**
124 * Read guest memory.
125 *
126 * @returns VBox status code.
127 * @param pVM Pointer to the shared VM structure.
128 * @param pAddress Where to start reading.
129 * @param pvBuf Where to store the data we've read.
130 * @param cbRead The number of bytes to read.
131 */
132static DECLCALLBACK(int) dbgfR3MemRead(PVM pVM, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead)
133{
134 /*
135 * Validate the input we use, PGM does the rest.
136 */
137 if (!DBGFR3AddrIsValid(pVM, pAddress))
138 return VERR_INVALID_POINTER;
139 if (!VALID_PTR(pvBuf))
140 return VERR_INVALID_POINTER;
141 if (DBGFADDRESS_IS_HMA(pAddress))
142 return VERR_INVALID_POINTER;
143
144 /*
145 * Select DBGF worker by addressing mode.
146 */
147 int rc;
148 PGMMODE enmMode = PGMGetGuestMode(pVM);
149 if ( enmMode == PGMMODE_REAL
150 || enmMode == PGMMODE_PROTECTED
151 || DBGFADDRESS_IS_PHYS(pAddress) )
152 rc = PGMPhysSimpleReadGCPhys(pVM, pvBuf, pAddress->FlatPtr, cbRead);
153 else
154 {
155 if ( ( pAddress->FlatPtr >= _4G
156 || pAddress->FlatPtr + cbRead > _4G)
157 && enmMode != PGMMODE_AMD64
158 && enmMode != PGMMODE_AMD64_NX)
159 return VERR_PAGE_TABLE_NOT_PRESENT;
160 rc = PGMPhysSimpleReadGCPtr(pVM, pvBuf, pAddress->FlatPtr, cbRead);
161 }
162 return rc;
163}
164
165
166/**
167 * Read guest memory.
168 *
169 * @returns VBox status code.
170 * @param pVM Pointer to the shared VM structure.
171 * @param pAddress Where to start reading.
172 * @param pvBuf Where to store the data we've read.
173 * @param cbRead The number of bytes to read.
174 */
175VMMR3DECL(int) DBGFR3MemRead(PVM pVM, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead)
176{
177 PVMREQ pReq;
178 int rc = VMR3ReqCallU(pVM->pUVM, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)dbgfR3MemRead, 4,
179 pVM, pAddress, pvBuf, cbRead);
180 if (VBOX_SUCCESS(rc))
181 rc = pReq->iStatus;
182 VMR3ReqFree(pReq);
183
184 return rc;
185}
186
187
188/**
189 * Read a zero terminated string from guest memory.
190 *
191 * @returns VBox status code.
192 * @param pVM Pointer to the shared VM structure.
193 * @param pAddress Where to start reading.
194 * @param pszBuf Where to store the string.
195 * @param cchBuf The size of the buffer.
196 */
197static DECLCALLBACK(int) dbgfR3MemReadString(PVM pVM, PCDBGFADDRESS pAddress, char *pszBuf, size_t cchBuf)
198{
199 /*
200 * Validate the input we use, PGM does the rest.
201 */
202 if (!DBGFR3AddrIsValid(pVM, pAddress))
203 return VERR_INVALID_POINTER;
204 if (!VALID_PTR(pszBuf))
205 return VERR_INVALID_POINTER;
206 if (DBGFADDRESS_IS_HMA(pAddress))
207 return VERR_INVALID_POINTER;
208
209 /*
210 * Select DBGF worker by addressing mode.
211 */
212 int rc;
213 PGMMODE enmMode = PGMGetGuestMode(pVM);
214 if ( enmMode == PGMMODE_REAL
215 || enmMode == PGMMODE_PROTECTED
216 || DBGFADDRESS_IS_PHYS(pAddress) )
217 rc = PGMPhysSimpleReadGCPhys(pVM, pszBuf, pAddress->FlatPtr, cchBuf);
218 else
219 {
220 if ( ( pAddress->FlatPtr >= _4G
221 || pAddress->FlatPtr + cchBuf > _4G)
222 && enmMode != PGMMODE_AMD64
223 && enmMode != PGMMODE_AMD64_NX)
224 return VERR_PAGE_TABLE_NOT_PRESENT;
225 rc = PGMPhysSimpleReadGCPtr(pVM, pszBuf, pAddress->FlatPtr, cchBuf);
226 }
227
228 /*
229 * Make sure the result is terminated and that overflow is signaled.
230 */
231 if (!memchr(pszBuf, '\0', cchBuf))
232 {
233 pszBuf[cchBuf - 1] = '\0';
234 rc = VINF_BUFFER_OVERFLOW;
235 }
236 /*
237 * Handle partial reads (not perfect).
238 */
239 else if (RT_FAILURE(rc))
240 {
241 if (pszBuf[0])
242 rc = VINF_SUCCESS;
243 }
244
245 return rc;
246}
247
248
249/**
250 * Read a zero terminated string from guest memory.
251 *
252 * @returns VBox status code.
253 * @param pVM Pointer to the shared VM structure.
254 * @param pAddress Where to start reading.
255 * @param pszBuf Where to store the string.
256 * @param cchBuf The size of the buffer.
257 */
258VMMR3DECL(int) DBGFR3MemReadString(PVM pVM, PCDBGFADDRESS pAddress, char *pszBuf, size_t cchBuf)
259{
260 /*
261 * Validate and zero output.
262 */
263 if (!VALID_PTR(pszBuf))
264 return VERR_INVALID_POINTER;
265 if (cchBuf <= 0)
266 return VERR_INVALID_PARAMETER;
267 memset(pszBuf, 0, cchBuf);
268
269 /*
270 * Pass it on to the EMT.
271 */
272 PVMREQ pReq;
273 int rc = VMR3ReqCallU(pVM->pUVM, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)dbgfR3MemReadString, 4,
274 pVM, pAddress, pszBuf, cchBuf);
275 if (VBOX_SUCCESS(rc))
276 rc = pReq->iStatus;
277 VMR3ReqFree(pReq);
278
279 return rc;
280}
281
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette