Kernel Javascript support
This document details the kernel javascript debugging extension
recently added to the reactos kernel.
Enabling
The extension is enabled when KDBG := 1 is set in config in the reactos source
tree.
kdb presents the usual prompt when ReactOS starts, but the 'js' command initializes the
javascript system and allows the user to start working with the system
in javascript. A welcome banner is displayed when the system is
ready, along with the prompt kjs:>.
Using
You may type as many lines in each input as needed. To cancel
some input, just enter '.' as the only character on an input
line. To exit from the javascript interpreter, enter '.' on the
first input line. In order to determine when the user is finished
typing, the kernel javascript system uses the harmless ';;'
sequence. Entering ';;' anywhere in the input terminates input
and evaluates the current input buffer. The buffer is emptied
afterward. Any javascript error messages or output are printed
before the next prompt is displayed. Note that the interpreter
does not automatically print the evaluation results, so it's useful to
wrap simple evaluations with write().
Sample Session
kdb:> js
JS Registry Init Complete. Welcome to ReactOS kernel scripting
Kernel Debugger Script Interface (JavaScript :-)
Terminate input with ;; and end scripting with .
kjs:> write(System.getmodule(1));;
hal.dll,3225501696
kjs:> write(System.getmodule(1)[1].toString(16));;
c0414000
kjs:> write(ebp().toString(16));;
cee8bf84
kjs:> function dump_sec(base) {
..... base2 = peekw(base + 0x3c) + base;
..... sec_off = 0xf8;
..... for( i = 0; peekl(base2 + sec_off + (40 * i)); i++ ) {
..... base_sec = base2 + sec_off + (40 * i);
..... write("Section: " + System.mread(0,base_sec) + "\n");
..... write("RVA: " + peekl(base_sec + 12).toString(16) + "\n");
..... }
..... }
..... ;;
kjs:> dump_sec(0xc0000000);;
Section: .text
RVA: 1000
Section: init
RVA: e6000
Section: .data
RVA: f4000
Section: .edata
RVA: 10d000
Section: .idata
RVA: 115000
Section: .rsrc
RVA: 116000
Section: .bss
RVA: 118000
Section: .reloc
RVA: 15a000
kjs:> var key = "\\registry\\machine\\system\\currentcontrolset\\services\\ne20001\\parameters\\tcpip";;
kjs:> write(regread(key,"defaultgateway"));;
10.0.0.1
Builtin and initialized functions
These functions are available after a successful javascript
initialization:
System.getmodule(n) => (string,int)
array
Returns the name and base address of the nth module in the kernel
module list.
System.mread(s,address) =>
integer/string
System.mread reads a value from memory and returns it. s
determines what type of read is performed, and address specifies the
starting address of the operation.
Valid values of s are:
0 -- Read a null-terminated ascii string
1 -- Read a byte
2 -- Read a word
4 -- Read a dword
System.mwrite(s,address,value) =>
bool
System.mwrite writes a value to a memory address. The operand
size depends on s, 1 for byte, 2 for word, 4 for dword.
System.print(...) => undefined
Uses DbgPrint to print the specified output. In javascript, every
value is printable, so feel free to give any value type to print.
Use C style escapes for tabs and newlines: \t and \n.
System.regs(int) => int
System.regs read the specified word value from the TRAP_FRAME given to
kdb when it was started. This is useful for locating the stack,
along with various other queries. The machine registers are also
provided as named functions by javascript, for example ebp() and eax().
System.regread(key,value) =>
string/undefined
System.regread reads a string value from the registry (as a member of
the specified registry key). If the read is successful, the
string value contained in it is returned. If the value cannot be
read, then undefined is returned.
This method is used by the registry initializer to read the
initialization strings.
ebp(), eip(), esp() ... vm86_gs()
=> int
Every register provided by the system trap frame is available as a
global function of the same name. This makes reading specific
registers easy.
peek,peekw,peekl(int addr) => int
Aliases for System.mread([1,2,4],addr)
poke,pokew,pokel(int addr, int value)
=> int
Aliases for System.mwrite([1,2,4],addr,value)
write(...) => undefined
Alias for System.print