Search notes:

Logging function parameter values with the JavaScript extension of Windows Debugger

prog.c

Here's a simple program that is used to demonstrate how it is possible to log function parameter values with the the JavaScript extension for Debugging Tools for Windows.
We're particularly interested in displaying the values of the three parameters of the function func as it is called.
#include <windows.h>

HANDLE stdOut;

static void func(int number, const char* ansi_text, const wchar_t* utf16_text) {

   wchar_t        buf[200];
   wchar_t* out = buf;

   out += wsprintfW(out, L"number = %d, ansi_text = ", number);
//
// Convert ansi text to wtf16 and write directly
// to output buffer:
//
   out += MultiByteToWideChar(CP_ACP, 0, ansi_text, -1, out, 50)
       -  1; // subtract terminating zero

   out += wsprintfW(out, L", utf16_text = %-15s\n", utf16_text);

   DWORD charsWritten;
   WriteConsoleW(stdOut, buf, (DWORD) (out - buf) , &charsWritten, NULL);
}


ULONG __stdcall run(void* PEB) {

   stdOut = GetStdHandle(STD_OUTPUT_HANDLE);

   func( 7, "seven"    , L"sieben"        );
   func( 2, "two"      , L"zwei"          );
   func(42, "forty-two", L"zweiundvierzig");
   func( 5, "five"     , L"fünf"          );

   return 0;
}
Github repository Windows-Debugging-Tools, path: /scripting/JavaScript/log-function-parameters/prog.c

Compilation

The program is compiled with the Visual C compiler like so:
cl   /nologo /Zi /c /W4 /wd4100 /GS- prog.c
link /nologo /debug /nodefaultlib prog.obj /entry:run /subsystem:console user32.lib kernel32.lib /out:prog.exe
Github repository Windows-Debugging-Tools, path: /scripting/JavaScript/log-function-parameters/compile.ps1

The script

We also need a script that contains the function that is called whenever func is brokein into.
This function is func_breakpoint. It basically reads the values of the three registers ecx (32-bit), rdx and r8 which store the three function parameter values. (See calling convention for x64).
The values of the two latter parameters (rdx and r8) are pointers to memory that contain the actual strings. So, we use host.memory.readString(reg.rdx) and host.memory.readWideString(reg.r8`) to get corresponding string values.
var ctrl;

var log_file_name = "log.out"
var text_writer;


function create_log_file () {
   var log_file    = host.namespace.Debugger.Utility.FileSystem.CreateFile      (log_file_name, 'CreateNew');
   log_file.Close();
}


function log(text) {
   log_file    = host.namespace.Debugger.Utility.FileSystem.CreateFile      (log_file_name, 'OpenExisting');
//
// This lines seems actually necessary!
//
   log_file.Position = log_file.Size;

   text_writer = host.namespace.Debugger.Utility.FileSystem.CreateTextWriter(log_file     );

   text_writer.WriteLine(text);

   log_file.Close();
}


function func_breakpoint() {

   var reg        = host.currentThread.Registers.User;

   var num        =                            reg.ecx ; // 1st parameter in rcx/ecx
   var ansi_text  = host.memory.readString    (reg.rdx); // 2nd parameter in rdx/edx
   var utf16_text = host.memory.readWideString(reg.r8 ); // 3rd parameter in r8d/r8

   log(
     'num = '          + num +
     ', ansi_text = '  + ansi_text +
     ', utf16_text = ' + utf16_text);

   if (num != 42) {
   //
   // go on if num = 42
   //
      host.namespace.Debugger.Utility.Control.ExecuteCommand("g");

   }
}

function invokeScript() {

   ctrl = host.namespace.Debugger.Utility.Control;

   create_log_file();

   log('setting breakpoint');
   ctrl.ExecuteCommand('bp  prog!func "dx @$scriptContents.func_breakpoint()"')

   log('running program');
   ctrl.ExecuteCommand('g');

   log('Num is 42. Explore your environment.');
   log('Use g to continue');

}
Github repository Windows-Debugging-Tools, path: /scripting/JavaScript/log-function-parameters/log-parameters.js

Starting the debugger

We're now ready to start the debugger and execute the script. The script initialize function invokeScript (which is called when the script is loaded) sets the breakpoint on func and makes sure that hitting the breakpoint calls func_breakpoint:
cdb -2  -c ".scriptrun log-parameters.js" .\prog.exe
Github repository Windows-Debugging-Tools, path: /scripting/JavaScript/log-function-parameters/run-cdb.ps1
The script writes the following content into the log file (log.out):
setting breakpoint
running program
num = 7, ansi_text = seven, utf16_text = sieben
num = 2, ansi_text = two, utf16_text = zwei
num = 42, ansi_text = forty-two, utf16_text = zweiundvierzig
Num is 42. Explore your environment.
Use g to continue
num = 5, ansi_text = five, utf16_text = fünf

Index