summaryrefslogblamecommitdiffstats
path: root/private/sdktools/dumpexam/dbgext.c
blob: 6b05d27c9827e500793ce67f9d070f2c4c8f3ee7 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430













































































































































































































































































































































































































































                                                                                                                            
/*++


Copyright (c) 1992  Microsoft Corporation

Module Name:

    Cmdexec0.c

Abstract:

    This file contains the front end code for parsing the various commands
    for the command window, and the code for the debugger control commands.

Author:

    David J. Gilman (davegi) 21-Apr-92

Environment:

    Win32, User Mode

--*/

#define NOEXTAPI

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntdbg.h>
#include <ntos.h>
#include <windows.h>
#include <imagehlp.h>
#include <crash.h>
#include <wdbgexts.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <disasm.h>
#include "dumpexam.h"

//
// prototypes
//
DWORD  ExtGetExpression(LPSTR lpsz);
VOID   ExtGetSymbol(LPVOID offset, PUCHAR pchBuffer, LPDWORD lpDisplacement);
DWORD  ExtDisasm(LPDWORD lpOffset, LPSTR lpBuffer, ULONG fShowEffectiveAddress);
BOOL   ExtReadProcessMemory(DWORD offset, LPVOID lpBuffer, DWORD cb, LPDWORD lpcbBytesRead);
BOOL   ExtWriteProcessMemory(DWORD offset, LPVOID lpBuffer, DWORD cb, LPDWORD lpcbBytesWritten);
BOOL   ExtGetThreadContext(DWORD Processor, LPCONTEXT lpContext, DWORD cbSizeOfContext);
BOOL   ExtSetThreadContext(DWORD Processor, LPCONTEXT lpContext, DWORD cbSizeOfContext);
BOOL   ExtIoctl(USHORT IoctlType, LPVOID lpvData, DWORD cbSize);
DWORD  ExtCallStack(DWORD FramePointer, DWORD StackPointer, DWORD ProgramCounter, PEXTSTACKTRACE StackFrames, DWORD Frames);
VOID   ExtOutput(PSTR,...);
ULONG  ExtCheckCtrlCTrap(VOID);

extern FILE         *FileOut;
extern struct DIS   *pdis;

DWORD OsVersion;


static WINDBG_EXTENSION_APIS WindbgExtensions =
    {
    sizeof(WindbgExtensions),
    (PWINDBG_OUTPUT_ROUTINE)                 ExtOutput,
    (PWINDBG_GET_EXPRESSION)                 ExtGetExpression,
    (PWINDBG_GET_SYMBOL)                     ExtGetSymbol,
    (PWINDBG_DISASM)                         ExtDisasm,
    (PWINDBG_CHECK_CONTROL_C)                ExtCheckCtrlCTrap,
    (PWINDBG_READ_PROCESS_MEMORY_ROUTINE)    ExtReadProcessMemory,
    (PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE)   ExtWriteProcessMemory,
    (PWINDBG_GET_THREAD_CONTEXT_ROUTINE)     ExtGetThreadContext,
    (PWINDBG_SET_THREAD_CONTEXT_ROUTINE)     ExtSetThreadContext,
    (PWINDBG_IOCTL_ROUTINE)                  ExtIoctl,
    (PWINDBG_STACKTRACE_ROUTINE)             ExtCallStack
    };




BOOL       fDoVersionCheck = TRUE;
HINSTANCE  hModKd;

#define BUILD_MAJOR_VERSION 3
#define BUILD_MINOR_VERSION 5
#define BUILD_REVISION      API_VERSION_NUMBER
API_VERSION ApiVersion = { BUILD_MAJOR_VERSION, BUILD_MINOR_VERSION, API_VERSION_NUMBER, 0 };



LPSTR
CPSkipWhitespace(
    LPSTR lpszIn
    )
{
    while (*lpszIn == ' ' || *lpszIn == '\t') lpszIn++;
    return( lpszIn );
}


VOID
ExtOutput(
    PSTR format,
    ...
    )
{
    char      vbuf[1024];
    va_list   arg_ptr;


    va_start(arg_ptr, format);
    _vsnprintf(vbuf, sizeof(vbuf), format, arg_ptr);
    fprintf( FileOut, "%s", vbuf );
}


ULONG
ExtCheckCtrlCTrap(
    VOID
    )
{
    return 0;
}


DWORD
ExtGetExpression(
                 LPSTR lpsz
                 )
{
    PIMAGEHLP_SYMBOL    Symbol;


    lpsz = CPSkipWhitespace(lpsz);
    if (*lpsz == '&') {
        lpsz += 1;
    }

    if (SymGetSymFromName( DmpHeader, lpsz, sym )) {
        return sym->Address;
    }

    return 0;
}


VOID
ExtGetSymbol(
             LPVOID  offset,
             PUCHAR  pchBuffer,
             LPDWORD lpDisplacement
             )
{
    if (SymGetSymFromAddr( DmpHeader, (ULONG)offset, lpDisplacement, sym )) {
        strcpy( pchBuffer, sym->Name );
    } else {
        pchBuffer[0] = 0;
    }
}



DWORD
ExtDisasm(
          LPDWORD lpOffset,
          LPSTR   lpBuffer,
          ULONG   fShowEffectiveAddress
          )
{
    #define CODE_BUFFER_SIZE 256
    BYTE                CodeBuffer[CODE_BUFFER_SIZE];


    DmpReadMemory( (LPVOID)*lpOffset, CodeBuffer, CODE_BUFFER_SIZE );

    *lpOffset += Disassemble(
        pdis,
        (ULONG)*lpOffset,
        CodeBuffer,
        CODE_BUFFER_SIZE,
        "    ",
        lpBuffer,
        256
        );

    return TRUE;
}


BOOL
ExtReadProcessMemory(
                     DWORD   offset,
                     LPVOID  lpBuffer,
                     DWORD   nSize,
                     LPDWORD lpcbBytesRead
                     )
{
    DWORD cb = DmpReadMemory( (PVOID)offset, lpBuffer, nSize );
    if (lpcbBytesRead) {
        *lpcbBytesRead = cb;
    }
    return cb == nSize;
}


BOOL
ExtWriteProcessMemory(
                      DWORD   offset,
                      LPVOID  lpBuffer,
                      DWORD   cb,
                      LPDWORD lpcbBytesWritten
                      )
{
    return FALSE;
}


BOOL
ExtGetThreadContext(
                    DWORD       Processor,
                    LPCONTEXT   lpContext,
                    DWORD       cbSizeOfContext
                    )
{
    GetContext( Processor, lpContext );
    return TRUE;
}


BOOL
ExtSetThreadContext(
                    DWORD       Processor,
                    LPCONTEXT   lpContext,
                    DWORD       cbSizeOfContext
                    )
{
    return FALSE;
}


BOOL
ExtIoctl(
    USHORT   IoctlType,
    LPVOID   lpvData,
    DWORD    cbSize
    )
{
    PREADCONTROLSPACE prc;
    ULONG             cb;


    if (IoctlType == IG_READ_CONTROL_SPACE) {
        prc = lpvData;
        return DmpReadControlSpace(
            (USHORT)prc->Processor,
            (PVOID)prc->Address,
            prc->Buf,
            prc->BufLen,
            &cb
            );
    }

    return FALSE;
}

DWORD
ExtGetModuleBase(
    PDUMP_HEADER DmpHeader,
    ULONG        Address
    )
{
    IMAGEHLP_MODULE     ModuleInfo;

    if (SymGetModuleInfo( DmpHeader, Address, &ModuleInfo )) {
        return ModuleInfo.BaseOfImage;
    }

    return 0;
}

DWORD
ExtCallStack(
    DWORD             FramePointer,
    DWORD             StackPointer,
    DWORD             ProgramCounter,
    PEXTSTACKTRACE    StackFrames,
    DWORD             Frames
    )
{
    extern PVOID    ExtContext;
    DWORD           i;
    STACKFRAME      StackFrame;
    PVOID           Context;



    ZeroMemory( &StackFrame, sizeof(STACKFRAME) );

    //
    // setup the program counter
    //
    StackFrame.AddrPC.Offset       = ProgramCounter;
    StackFrame.AddrPC.Mode         = AddrModeFlat;

    //
    // setup the frame pointer
    //
    StackFrame.AddrFrame.Offset    = FramePointer;
    StackFrame.AddrFrame.Mode      = AddrModeFlat;

    //
    // setup the stack pointer
    //
    StackFrame.AddrStack.Offset    = StackPointer;
    StackFrame.AddrStack.Mode      = AddrModeFlat;

    i = 0;
    Context = LocalAlloc( LPTR, MAX_CONTEXT_SIZE );
    CopyMemory( Context, ExtContext, MAX_CONTEXT_SIZE );
    while( TRUE ) {
        if (!StackWalk(
                DmpHeader->MachineImageType,
                DmpHeader,
                NULL,
                &StackFrame,
                Context,
                SwReadMemory,
                SymFunctionTableAccess,
                ExtGetModuleBase,
                NULL
                )) {
            //
            // end of the stack
            //
            break;
        }

        StackFrames[i].FramePointer    =  StackFrame.AddrFrame.Offset;
        StackFrames[i].ProgramCounter  =  StackFrame.AddrPC.Offset;
        StackFrames[i].ReturnAddress   =  StackFrame.AddrReturn.Offset;
        StackFrames[i].Args[0]         =  StackFrame.Params[0];
        StackFrames[i].Args[1]         =  StackFrame.Params[1];
        StackFrames[i].Args[2]         =  StackFrame.Params[2];
        StackFrames[i].Args[3]         =  StackFrame.Params[3];
        i += 1;
    }

    LocalFree( Context );

    return i;
}


LONG
ExtensionExceptionFilterFunction(
    LPSTR                msg,
    LPEXCEPTION_POINTERS lpep
    )
{
    fprintf( FileOut, "\n%s addr=0x%08x, ec=0x%08x\n\n",
               msg,
               lpep->ExceptionRecord->ExceptionAddress,
               lpep->ExceptionRecord->ExceptionCode );

    return EXCEPTION_EXECUTE_HANDLER;
}


BOOL
LoadKd(
    LPSTR KdName
    )
{
    PWINDBG_EXTENSION_DLL_INIT  pDllInit;



    hModKd = LoadLibrary( KdName );
    if (!hModKd) {
        return FALSE;
    }

    pDllInit = (PWINDBG_EXTENSION_DLL_INIT)GetProcAddress( hModKd, "WinDbgExtensionDllInit" );
    if (!pDllInit) {
        return FALSE;
    }

    (pDllInit)( &WindbgExtensions, 0, 0 );

    return TRUE;
}


BOOL
DoExtension(
    LPSTR   FuncName,
    LPSTR   FuncArgs,
    DWORD   Processor,
    DWORD   Ip
    )
{
    PWINDBG_EXTENSION_ROUTINE       WindbgExtRoutine;
    extern PVOID                    ExtContext;
    PVOID                           Context;



    WindbgExtRoutine = (PWINDBG_EXTENSION_ROUTINE)GetProcAddress( hModKd, FuncName );

    Context = LocalAlloc( LPTR, MAX_CONTEXT_SIZE );
    ExtContext = Context;

    PrintHeading( "!%s %s", FuncName, FuncArgs );

    if (!WindbgExtRoutine) {
        fprintf( FileOut, "**** could not call [ %s ]\n", FuncName );
        return FALSE;
    }

    try {
        (WindbgExtRoutine)( 0, 0, Ip, Processor, FuncArgs );
    } except (ExtensionExceptionFilterFunction(
                  "Extension function faulted", GetExceptionInformation())) {
    }

    LocalFree( Context );

    return TRUE;
}