News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

wdbgexts header

Started by FlySky, January 21, 2012, 03:17:41 PM

Previous topic - Next topic

FlySky

I am currently working on translating the wdbgexts header from WinDBG.
It's the header file which allows to write Extension DLL's (Plugins) / like OllyDbg has.

I've came across a part I am not sure of how to translate and hopefully some of you guys can tell me how this needs to be
translated to get a working GoASM header file.

#ifndef NOEXTAPI

#if   defined(KDEXT_64BIT)
#define WINDBG_EXTENSION_APIS WINDBG_EXTENSION_APIS64
#define PWINDBG_EXTENSION_APIS PWINDBG_EXTENSION_APIS64
#define PWINDBG_EXTENSION_ROUTINE PWINDBG_EXTENSION_ROUTINE64
#define DECLARE_API(s) DECLARE_API64(s)
#elif defined(KDEXT_32BIT)
#define WINDBG_EXTENSION_APIS WINDBG_EXTENSION_APIS32
#define PWINDBG_EXTENSION_APIS PWINDBG_EXTENSION_APIS32
#define PWINDBG_EXTENSION_ROUTINE PWINDBG_EXTENSION_ROUTINE32
#define DECLARE_API(s) DECLARE_API32(s)
#else
#define DECLARE_API(s)                             \
    CPPMOD VOID                                    \
    s(                                             \
        HANDLE                 hCurrentProcess,    \
        HANDLE                 hCurrentThread,     \
        ULONG                  dwCurrentPc,        \
        ULONG                  dwProcessor,        \
        PCSTR                  args                \
     )
#endif

#define DECLARE_API32(s)                           \
    CPPMOD VOID                                    \
    s(                                             \
        HANDLE                 hCurrentProcess,    \
        HANDLE                 hCurrentThread,     \
        ULONG                  dwCurrentPc,        \
        ULONG                  dwProcessor,        \
        PCSTR                  args                \
     )

#define DECLARE_API64(s)                           \
    CPPMOD VOID                                    \
    s(                                             \
        HANDLE                 hCurrentProcess,    \
        HANDLE                 hCurrentThread,     \
        ULONG64                dwCurrentPc,        \
        ULONG                  dwProcessor,        \
        PCSTR                  args                \
     )


extern WINDBG_EXTENSION_APIS   ExtensionApis;


#define dprintf          (ExtensionApis.lpOutputRoutine)
#define GetExpression    (ExtensionApis.lpGetExpressionRoutine)
#define CheckControlC    (ExtensionApis.lpCheckControlCRoutine)
#define GetContext       (ExtensionApis.lpGetThreadContextRoutine)
#define SetContext       (ExtensionApis.lpSetThreadContextRoutine)
#define Ioctl            (ExtensionApis.lpIoctlRoutine)
#define Disasm           (ExtensionApis.lpDisasmRoutine)
#define GetSymbol        (ExtensionApis.lpGetSymbolRoutine)
#define ReadMemory       (ExtensionApis.lpReadProcessMemoryRoutine)
#define WriteMemory      (ExtensionApis.lpWriteProcessMemoryRoutine)
#define StackTrace       (ExtensionApis.lpStackTraceRoutine)

donkey

Hi Flysky,

They can be left out completely. They are redefinitions, macros and prototypes and are not useful to GoAsm code.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

FlySky

There is one thing I do not understand than donkey. Leaving them out because of redefinitions I can understand;).
The question that pops up here is this.
WinDBG has commands like !address to see information about a memory address, memory page, protection on it etc.. etc..
Those commands are used in Extension DLL's. Automaticly a couple of extension dll's are loaded from Microsoft themselves.

To create a command like that in C++ for example:

We would need to code a function like:

/***********************************************************
* !help
*
* Purpose: WINDBG will call this API when the user types !help
*         
*
*  Parameters:
*     N/A
*
*  Return Values:
*     N/A
*
***********************************************************/

DECLARE_API(help)
{
   dprintf(
         "WinDBG Extension help file\n"
      );
}

This is shown on the screen when a user types !help.

How would that need to be translated without having the DECLARE definitions? I don't know how that would work.


donkey

DECLARE_API is not a definition in the sense that it is strictly an equate, it is a macro that sets up a procedure. You can't have code in a header file so you will have to make your own functions using FRAME/ENDF in your ASM file. I am not completely sure where to get the addresses of the ExtensionApis callbacks, obviously if you are using WinDbg it must expose some of these via the IDebugControl interface however I am not sure whether you must supply them or they are resident in WinDbg. You'll have to do a bit of reading in order to find out how to get the address of each of the ExtensionApis functions. At that point it appears to be a simple PUSH/CALL (in x32) followed by fixing up the stack (they are most likely cdecl calls).

I don't have the time to look into what's involved in writing a WinDbg extension this weekend but I will try to find the time later this week if you haven't already figured it out by then.

As a guess, to get the dprintf function I would try

IDebugControl::GetExtensionFunction, 0, "dprintf", offset lpOutputRoutine
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

FlySky

#4
After a bit of reading about the ExtensionDLL's.
The function name and the extension command name are identical, except that the extension command begins with an exclamation point ( ! ).
When typing !help for example it searches for an exported function called help.
So basicly to use extended commands we would need to create the functions we want to use as EXPORTED functions.
like this:

EXPORT Test:
invoke MessageBoxA, NULL, 'I am a test', 'I am a test', MB_OK
Ret

I am diving further to see what else I might have missed or not

*EDIT*

CoInvoke(pIDebugControl,IDebugControl.GetExtensionFunction, 0, 0, 'dprintf', offset lpOutputRoutine --> giving me error in argument syntax

donkey

reading the "Debugging Tools for Windows (x64)\sdk\samples\simplext\Readme.txt" file looks like it might not be too hard to make an extension. However, I seem to remember reading somewhere that all extension function names must be preceeded by EFN_ since the debugger adds that automatically, not sure where I saw the reference though. Wish I could help you more but I really have never looked at writing an extension for WinDbg, sounds like an interesting project though, be nice to write a code filter to have it output in GoAsm syntax.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable