|
|
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.