|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1990 Microsoft Corporation
4:
5: Module Name:
6:
7: kdexts.c
8:
9: Abstract:
10:
11: This function contains some example KD debugger extensions
12:
13: Author:
14:
15: John Vert (jvert) 6-Aug-1992
16:
17: Revision History:
18:
19: --*/
20:
21: #include <ntddk.h>
22: #include <windef.h>
23: #include <ntkdexts.h>
24: #include <stdlib.h>
25: #include <string.h>
26:
27: CHAR igrepLastPattern[256];
28: DWORD igrepSearchStartAddress;
29: DWORD igrepLastPc;
30:
31:
32: VOID
33: igrep(
34: DWORD dwCurrentPc,
35: PNTKD_EXTENSION_APIS lpExtensionApis,
36: LPSTR lpArgumentString
37: )
38:
39: /*++
40:
41: Routine Description:
42:
43: This function is called as a KD extension to grep the instruction
44: stream for a particular pattern.
45:
46: Called as:
47:
48: !kdext.igrep [pattern [expression]]
49:
50: If a pattern is not given, the last pattern is used. If expression
51: is not given, the last hit address is used.
52:
53: Arguments:
54:
55: CurrentPc - Supplies the current pc at the time the extension is
56: called.
57:
58: lpExtensionApis - Supplies the address of the functions callable
59: by this extension.
60:
61: lpArgumentString - Supplies the pattern and expression for this
62: command.
63:
64:
65: Return Value:
66:
67: None.
68:
69: --*/
70:
71: {
72: DWORD dwNextGrepAddr;
73: DWORD dwCurrGrepAddr;
74: CHAR SourceLine[256];
75: BOOL NewPc;
76: DWORD d;
77: PNTKD_OUTPUT_ROUTINE lpOutputRoutine;
78: PNTKD_GET_EXPRESSION lpGetExpressionRoutine;
79: PNTKD_GET_SYMBOL lpGetSymbolRoutine;
80: PNTKD_DISASM lpDisasmRoutine;
81: PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
82: LPSTR pc;
83: LPSTR Pattern;
84: LPSTR Expression;
85: CHAR Symbol[64];
86: DWORD Displacement;
87:
88: lpOutputRoutine = lpExtensionApis->lpOutputRoutine;
89: lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
90: lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine;
91: lpDisasmRoutine = lpExtensionApis->lpDisasmRoutine;
92: lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
93:
94: if ( igrepLastPc && igrepLastPc == dwCurrentPc ) {
95: NewPc = FALSE;
96: }
97: else {
98: igrepLastPc = dwCurrentPc;
99: NewPc = TRUE;
100: }
101:
102: //
103: // check for pattern.
104: //
105:
106: pc = lpArgumentString;
107: Pattern = NULL;
108: Expression = NULL;
109: if ( *pc ) {
110: Pattern = pc;
111: while (*pc > ' ') {
112: pc++;
113: }
114:
115: //
116: // check for an expression
117: //
118:
119: if ( *pc != '\0' ) {
120: *pc = '\0';
121: pc++;
122: if ( *pc <= ' ') {
123: while (*pc <= ' '){
124: pc++;
125: }
126: }
127: if ( *pc ) {
128: Expression = pc;
129: }
130: }
131: }
132:
133: if ( Pattern ) {
134: strcpy(igrepLastPattern,Pattern);
135:
136: if ( Expression ) {
137: igrepSearchStartAddress = (lpGetExpressionRoutine)(Expression);
138: if ( !igrepSearchStartAddress ) {
139: igrepSearchStartAddress = igrepLastPc;
140: return;
141: }
142: }
143: else {
144: igrepSearchStartAddress = igrepLastPc;
145: }
146: }
147:
148: dwNextGrepAddr = igrepSearchStartAddress;
149: dwCurrGrepAddr = dwNextGrepAddr;
150: d = (lpDisasmRoutine)(&dwNextGrepAddr,SourceLine,FALSE);
151: while(d) {
152: if (strstr(SourceLine,igrepLastPattern)) {
153: igrepSearchStartAddress = dwNextGrepAddr;
154: (lpGetSymbolRoutine)((LPVOID)dwCurrGrepAddr,Symbol,&Displacement);
155: (lpOutputRoutine)("%s",SourceLine);
156: return;
157: }
158: if ((lpCheckControlCRoutine)()) {
159: return;
160: }
161: dwCurrGrepAddr = dwNextGrepAddr;
162: d = (lpDisasmRoutine)(&dwNextGrepAddr,SourceLine,FALSE);
163: }
164: }
165:
166: VOID
167: str(
168: DWORD dwCurrentPc,
169: PNTKD_EXTENSION_APIS lpExtensionApis,
170: LPSTR lpArgumentString
171: )
172:
173: /*++
174:
175: Routine Description:
176:
177: This function is called as a KD extension to format and dump
178: counted (ansi) string.
179:
180: Arguments:
181:
182: CurrentPc - Supplies the current pc at the time the extension is
183: called.
184:
185: lpExtensionApis - Supplies the address of the functions callable
186: by this extension.
187:
188: lpArgumentString - Supplies the asciiz string that describes the
189: ansi string to be dumped.
190:
191: Return Value:
192:
193: None.
194:
195: --*/
196:
197: {
198: ANSI_STRING AnsiString;
199: DWORD dwAddrString;
200: CHAR Symbol[64];
201: LPSTR StringData;
202: DWORD Displacement;
203: BOOL b;
204: PNTKD_OUTPUT_ROUTINE lpOutputRoutine;
205: PNTKD_GET_EXPRESSION lpGetExpressionRoutine;
206: PNTKD_GET_SYMBOL lpGetSymbolRoutine;
207: PNTKD_READ_VIRTUAL_MEMORY lpReadMemoryRoutine;
208:
209:
210: lpOutputRoutine = lpExtensionApis->lpOutputRoutine;
211: lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
212: lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine;
213: lpReadMemoryRoutine = lpExtensionApis->lpReadVirtualMemRoutine;
214:
215: //
216: // Evaluate the argument string to get the address of
217: // the string to dump.
218: //
219:
220: dwAddrString = (lpGetExpressionRoutine)(lpArgumentString);
221: if ( !dwAddrString ) {
222: return;
223: }
224:
225:
226: //
227: // Get the symbolic name of the string
228: //
229:
230: (lpGetSymbolRoutine)((LPVOID)dwAddrString,Symbol,&Displacement);
231:
232: //
233: // Read the string from the debuggees address space into our
234: // own.
235:
236: b = (lpReadMemoryRoutine)((LPVOID)dwAddrString,
237: &AnsiString,
238: sizeof(AnsiString),
239: NULL);
240:
241: if ( !b ) {
242: return;
243: }
244:
245: StringData = malloc(AnsiString.Length+1);
246:
247: b = (lpReadMemoryRoutine)((LPVOID)AnsiString.Buffer,
248: StringData,
249: AnsiString.Length,
250: NULL);
251: if ( !b ) {
252: free(StringData);
253: return;
254: }
255:
256: (lpOutputRoutine)(
257: "String(%d,%d) %s+%lx at %lx: %s\n",
258: AnsiString.Length,
259: AnsiString.MaximumLength,
260: Symbol,
261: Displacement,
262: dwAddrString,
263: StringData
264: );
265:
266: free(StringData);
267: }
268:
269: VOID
270: ustr(
271: DWORD dwCurrentPc,
272: PNTKD_EXTENSION_APIS lpExtensionApis,
273: LPSTR lpArgumentString
274: )
275:
276: /*++
277:
278: Routine Description:
279:
280: This function is called as a KD extension to format and dump
281: counted unicode string.
282:
283: Arguments:
284:
285: CurrentPc - Supplies the current pc at the time the extension is
286: called.
287:
288: lpExtensionApis - Supplies the address of the functions callable
289: by this extension.
290:
291: lpArgumentString - Supplies the asciiz string that describes the
292: ansi string to be dumped.
293:
294: Return Value:
295:
296: None.
297:
298: --*/
299:
300: {
301: ANSI_STRING AnsiString;
302: UNICODE_STRING UnicodeString;
303: DWORD dwAddrString;
304: CHAR Symbol[64];
305: LPSTR StringData;
306: DWORD Displacement;
307: BOOL b;
308: PNTKD_OUTPUT_ROUTINE lpOutputRoutine;
309: PNTKD_GET_EXPRESSION lpGetExpressionRoutine;
310: PNTKD_GET_SYMBOL lpGetSymbolRoutine;
311: PNTKD_READ_VIRTUAL_MEMORY lpReadMemoryRoutine;
312:
313: lpOutputRoutine = lpExtensionApis->lpOutputRoutine;
314: lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
315: lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine;
316: lpReadMemoryRoutine = lpExtensionApis->lpReadVirtualMemRoutine;
317:
318: //
319: // Evaluate the argument string to get the address of
320: // the string to dump.
321: //
322:
323: dwAddrString = (lpGetExpressionRoutine)(lpArgumentString);
324: if ( !dwAddrString ) {
325: return;
326: }
327:
328:
329: //
330: // Get the symbolic name of the string
331: //
332:
333: (lpGetSymbolRoutine)((LPVOID)dwAddrString,Symbol,&Displacement);
334:
335: //
336: // Read the string from the debuggees address space into our
337: // own.
338:
339: b = (lpReadMemoryRoutine)((LPVOID)dwAddrString,
340: &UnicodeString,
341: sizeof(UnicodeString),
342: NULL);
343:
344: if ( !b ) {
345: return;
346: }
347:
348: StringData = malloc(UnicodeString.Length+sizeof(UNICODE_NULL));
349:
350: b = (lpReadMemoryRoutine)((LPVOID)UnicodeString.Buffer,
351: StringData,
352: UnicodeString.Length,
353: NULL);
354: if ( !b ) {
355: free(StringData);
356: return;
357: }
358:
359: UnicodeString.Buffer = (PWSTR)StringData;
360: UnicodeString.MaximumLength = UnicodeString.Length+(USHORT)sizeof(UNICODE_NULL);
361:
362: RtlUnicodeStringToAnsiString(&AnsiString,&UnicodeString,TRUE);
363: free(StringData);
364:
365: (lpOutputRoutine)(
366: "String(%d,%d) %s+%lx at %lx: %s\n",
367: UnicodeString.Length,
368: UnicodeString.MaximumLength,
369: Symbol,
370: Displacement,
371: dwAddrString,
372: AnsiString.Buffer
373: );
374:
375: RtlFreeAnsiString(&AnsiString);
376: }
377:
378: VOID
379: obja(
380: DWORD dwCurrentPc,
381: PNTKD_EXTENSION_APIS lpExtensionApis,
382: LPSTR lpArgumentString
383: )
384:
385: /*++
386:
387: Routine Description:
388:
389: This function is called as a KD extension to format and dump
390: an object attributes structure.
391:
392: Arguments:
393:
394: CurrentPc - Supplies the current pc at the time the extension is
395: called.
396:
397: lpExtensionApis - Supplies the address of the functions callable
398: by this extension.
399:
400: lpArgumentString - Supplies the asciiz string that describes the
401: ansi string to be dumped.
402:
403: Return Value:
404:
405: None.
406:
407: --*/
408:
409: {
410: UNICODE_STRING UnicodeString;
411: DWORD dwAddrObja;
412: OBJECT_ATTRIBUTES Obja;
413: DWORD dwAddrString;
414: CHAR Symbol[64];
415: LPSTR StringData;
416: DWORD Displacement;
417: BOOL b;
418: PNTKD_OUTPUT_ROUTINE lpOutputRoutine;
419: PNTKD_GET_EXPRESSION lpGetExpressionRoutine;
420: PNTKD_GET_SYMBOL lpGetSymbolRoutine;
421: PNTKD_READ_VIRTUAL_MEMORY lpReadMemoryRoutine;
422:
423: lpOutputRoutine = lpExtensionApis->lpOutputRoutine;
424: lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
425: lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine;
426: lpReadMemoryRoutine = lpExtensionApis->lpReadVirtualMemRoutine;
427:
428: //
429: // Evaluate the argument string to get the address of
430: // the Obja to dump.
431: //
432:
433: dwAddrObja = (lpGetExpressionRoutine)(lpArgumentString);
434: if ( !dwAddrObja ) {
435: return;
436: }
437:
438:
439: //
440: // Get the symbolic name of the Obja
441: //
442:
443: (lpGetSymbolRoutine)((LPVOID)dwAddrObja,Symbol,&Displacement);
444:
445: //
446: // Read the obja from the debuggees address space into our
447: // own.
448:
449: b = (lpReadMemoryRoutine)((LPVOID)dwAddrObja,
450: &Obja,
451: sizeof(Obja),
452: NULL);
453: if ( !b ) {
454: return;
455: }
456: StringData = NULL;
457: if ( Obja.ObjectName ) {
458: dwAddrString = (DWORD)Obja.ObjectName;
459: b = (lpReadMemoryRoutine)((LPVOID)dwAddrString,
460: &UnicodeString,
461: sizeof(UnicodeString),
462: NULL);
463: if ( !b ) {
464: return;
465: }
466:
467: StringData = malloc(UnicodeString.Length+sizeof(UNICODE_NULL));
468:
469: b = (lpReadMemoryRoutine)((LPVOID)UnicodeString.Buffer,
470: StringData,
471: UnicodeString.Length,
472: NULL);
473: if ( !b ) {
474: free(StringData);
475: return;
476: }
477: UnicodeString.Buffer = (PWSTR)StringData;
478: UnicodeString.MaximumLength = UnicodeString.Length+(USHORT)sizeof(UNICODE_NULL);
479: }
480:
481: //
482: // We got the object name in UnicodeString. StringData is NULL if no name.
483: //
484:
485: (lpOutputRoutine)(
486: "Obja %s+%lx at %lx:\n",
487: Symbol,
488: Displacement,
489: dwAddrObja
490: );
491: if ( StringData ) {
492: (lpOutputRoutine)("\t%s is %ws\n",
493: Obja.RootDirectory ? "Relative Name" : "Full Name",
494: UnicodeString.Buffer
495: );
496: free(StringData);
497: }
498: if ( Obja.Attributes ) {
499: if ( Obja.Attributes & OBJ_INHERIT ) {
500: (lpOutputRoutine)("\tOBJ_INHERIT\n");
501: }
502: if ( Obja.Attributes & OBJ_PERMANENT ) {
503: (lpOutputRoutine)("\tOBJ_PERMANENT\n");
504: }
505: if ( Obja.Attributes & OBJ_EXCLUSIVE ) {
506: (lpOutputRoutine)("\tOBJ_EXCLUSIVE\n");
507: }
508: if ( Obja.Attributes & OBJ_CASE_INSENSITIVE ) {
509: (lpOutputRoutine)("\tOBJ_CASE_INSENSITIVE\n");
510: }
511: if ( Obja.Attributes & OBJ_OPENIF ) {
512: (lpOutputRoutine)("\tOBJ_OPENIF\n");
513: }
514: }
515: }
516:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.