Patched Watchdog

Started by DarkNeo, 29. Oct 2008, 11:49

previous topic - next topic
Go Down

DarkNeo

I've managed to disable the Watchdog in TV2Client.dll, and I've updated isO-Micks NK Patcher on the Wiki to patch it. Test it out and let me know if you have any problems. ;D

Hoernchen

#1
29. Oct 2008, 12:55 Last Edit: 29. Oct 2008, 14:04 by Hoernchen
Needs the "32bit only" flag, otherwise loading the 32bit compress.dll on a 64bit host will fail ;)
Recompile it with "x86" instead of "any cpu", or use "corflags /32bit+ nkpatcher.exe" to fix it.

Btw, the watchdog setup works like this:
COREDLL_1489 is KernelLibIOControl,
Code: [Select]
BOOL KernelLibIoControl(
  HANDLE hModule,
  DWORD dwIoControlCode,
  LPVOID lpInBuf,
  DWORD nInBufSize,
  LPVOID lpOutBuf,
  DWORD nOutBufSize,
  LPDWORD lpBytesReturned
);

the call is KernelLibIoControl(KMOD_CORE, IOCTL_KLIB_WDOGAPI, WDAPIStruct, sizeof(WDAPIStruct), 0, 0, &buf) - the bold zero is important as we will see later.
Code: [Select]
BOOL SC_KernelLibIoControl(
    HANDLE  hLib,
    DWORD   dwIoControlCode,
    LPVOID  lpInBuf,
    DWORD   nInBufSize,
    LPVOID  lpOutBuf,
    DWORD   nOutBufSize,
    LPDWORD lpBytesReturned
    )
calls
Code: [Select]
BOOL NKKernelLibIoControl(
    HANDLE  hLib,
    DWORD   dwIoControlCode,
    LPVOID  lpInBuf,
    DWORD   nInBufSize,
    LPVOID  lpOutBuf,
    DWORD   nOutBufSize,
    LPDWORD lpBytesReturned
    )
which calls
Code: [Select]
BOOL KernelLibIoControl_Core(
    DWORD   dwIoControlCode,
    LPVOID  lpInBuf,
    DWORD   nInBufSize,
    LPVOID  lpOutBuf,
    DWORD   nOutBufSize,
    LPDWORD lpBytesReturned
    )
because we passed KMOD_CORE to KernelLibIOControl.
KernelLibIoControl_Core looks like this:
Code: [Select]
BOOL KernelLibIoControl_Core(
    DWORD   dwIoControlCode,
    LPVOID  lpInBuf,
    DWORD   nInBufSize,
    LPVOID  lpOutBuf,
    DWORD   nOutBufSize,
    LPDWORD lpBytesReturned
    )
{
    switch (dwIoControlCode) {
  [..snip...]
    case IOCTL_KLIB_WDOGAPI:
        // watchdog support
        // lpInBuf: pointer to WDAPIStruct struct
        // nInBufSize: sizeof (WDAPIStruct)
        // nOutBufSize: apiCode (irregular usage)
        if (sizeof (WDAPIStruct) == nInBufSize) {
            return WatchDogAPI (nOutBufSize, (PCWDAPIStruct) lpInBuf);
        }
        return FALSE;
}


As you can see the first parameter to WatchDogAPI, nOutBufSize, is 0 - also known as WDAPI_CREATE.

The PCWDAPIStruct used to create the watchdog timer looks like this :

Code: [Select]
//
// watchdog default actions
//
#define WDOG_NO_DFLT_ACTION         0
#define WDOG_KILL_PROCESS           1
#define WDOG_RESET_DEVICE           2

typedef struct _WDAPIStruct {
    LPCVOID watchdog = "MyTimer"; // name (in create/open) or handle (in other) of the watchdog
    DWORD   dwPeriod = 60000;      // watchdog period
    DWORD   dwWait = 60000;        // wait time before default action taken
    DWORD   dwDfltAction = 2;        // default action
    DWORD   dwParam = 0;             // param passed to IOCTL_HAL_REBOOT if reset is the default action
    DWORD   dwFlags = 0;              // flags
} WDAPIStruct, *PWDAPIStruct;
typedef const WDAPIStruct *PCWDAPIStruct;


So the default action if the timer expires is to reboot the box - changing the default action to WDOG_NO_DFLT_ACTION works, too ;)
bringer of linux, conqueror of hdmi, jack of all trades.

DarkNeo

Ok, I'll recompile when I get home  :)

Thanks for the info, I took a more heavy handed approach and changed a branch instruction to branch around the timer setup, so it never starts up the watchdog, although admittedly this could cause problems say if TickleWatchdog is called (in my TV2Client I've commented out that call). I'm not so good at mapping assembly to API calls, the stack offsets never seem to match up right ???

Hoernchen

#3
29. Oct 2008, 16:34 Last Edit: 29. Oct 2008, 16:38 by Hoernchen
Tickling the watchdog will automagically start it, so your current approach would work as long as you modify the tickler to do nothing or stop instead of update the watchdog, or if you don't call ticklewatchdog at all.
Code: [Select]

the tickler :

.text:032E96FC sub_32E96FC:                             # CODE XREF: sub_32EA7E0+10
.text:032E96FC                 addiu   $sp, -0x40
.text:032E9700                 sw      $ra, 0x38($sp)
.text:032E9704                 sw      $a0, 0x20($sp)<-------store the watchdog handle
.text:032E9708                 li      $v0, 4   <------------apiCode is #define WDAPI_REFRESH 4 - change this to #define WDAPI_STOP 3
.text:032E970C                 sw      $a1, 0x34($sp)
.text:032E9710                 li      $a3, 0x18 <-----------sizeof(WDAPIStruct)
.text:032E9714                 addiu   $a2, $sp, 0x20 <------lpinbuf (the WDAPIStruct) starts at $sp+0x20
.text:032E9718                 li      $a1, 0x13 <-----------#define IOCTL_KLIB_WDOGAPI = 19
.text:032E971C                 li      $a0, 1 <--------------#define KMOD_CORE 1
.text:032E9720                 sw      $0, 0x24($sp)
.text:032E9724                 sw      $0, 0x28($sp)
.text:032E9728                 sw      $0, 0x2C($sp)
.text:032E972C                 sw      $0, 0x30($sp)
.text:032E9730                 sw      $0, 0x18($sp)
.text:032E9734                 sw      $v0, 0x14($sp) <------store the apiCode (nOutBufSize of KernelLibIoControl)
.text:032E9738                 jal     COREDLL_1489 <--------call KernelLibIoControl
.text:032E973C                 sw      $0, 0x10($sp)
.text:032E9740                 lw      $ra, 0x38($sp)
.text:032E9744                 jr      $ra
.text:032E9748                 addiu   $sp, 0x40
.text:032E9748  # End of function sub_32E96FC
bringer of linux, conqueror of hdmi, jack of all trades.

Mulder3

What`s the benefit of disabling Watchdog?

is0-mick


What`s the benefit of disabling Watchdog?


If you are debugging the box in visual studio, and the box is running... it would normally reset due to the watchdog running (thinking the box has hung or crashed).

Disabling the watchdog allows you to freely break the code and examine variables etc without the box resetting after about 5-15 seconds :)

Mick

Mulder3

Can you, guys, make the nk.bin patcher source avaliable?

bdn

Hi,

I get System.OutOfMemoryException? :-\


DarkNeo


Can you, guys, make the nk.bin patcher source avaliable?


It will be available soon :)


Tickling the watchdog will automagically start it, so your current approach would work as long as you modify the tickler to do nothing or stop instead of update the watchdog, or if you don't call ticklewatchdog at all.


Strange...not calling TickleWatchdog was the first thing I tried, but it had no effect.


Hi,

I get System.OutOfMemoryException? :-\


If you're using the new version you should only need about 30MB of free space (.net has a fat ass :P), the old version requires more since it loads the whole NK.BIN into memory. Try freeing up some memory and trying again, if it still happens, try opening the task manager so you can see how much memory the program is taking up, and let me know.

bdn

Hi,

no time lately...

Quote
Try freeing up some memory and trying again, if it still happens, try opening the task manager so you can see how much memory the program is taking up



I've checked: old patcher really needs  more memory but  functions OK :)
Seems to be some obscure .net problem, i know too little about it...

for instance:
http://support.microsoft.com/kb/949458

or is something more then .NET Framework 2.0 needed?


bdn

Hi,

I'm slow. I know...

OutOfMemoryException is thrown in in NKBin.cs in line

Code: [Select]
this.Modules = new List<ModuleEntry>( (int) header.ModuleEntryCount);

because:

(int) header.ModuleEntryCount = 691863584

I'm trying to learn C# on the fly, does anybody have some tip?
My box is German x300t, could this be the reason? In German Forum nobody complained!

DarkNeo

That sounds like it's reading the wrong figure (it definitely shouldn't be that high!) which means it's trying to create a list with 691863584 items in it, no wonder it's running out of memory...has anyone tried it successfully on the German x300t?

bdn: are you sure the NK.BIN you have is original and not corrupted?

chrishx

i have the same box. original file. is0-micks patcher works without problem. i get the same error other any computer i use.

bdn

#13
15. Feb 2009, 20:48 Last Edit: 15. Feb 2009, 23:11 by bdn
Hi,

finally i got around to solve this problem  :)!

@Dark-Neo:
your code (its Reflector really), my comments:
Code: [Select]


    public class NKBin
{
   ...       

   DataRecord record = this.Records[0x4c];     //record #76           

   this.Seek((long) record.DataOffset, SeekOrigin.Begin);  //pointer at the start of data block of record #76
   ROMHeader header = new ROMHeader(this); 

   DataRecord record2 = this.Records[0x4d];                    //record #77
   this.Seek((long)record2.DataOffset, SeekOrigin.Begin);  //pointer at the start of data block of record #77
   
   this.Modules = new List<ModuleEntry>( (int) header.ModuleEntryCount);


...etc


but in my NK.BIN the ROMHEADER entry is in record #77 so:

Code: [Select]

   ...       

   DataRecord record = this.Records[0x4d];     //record #77           
   this.Seek((long) record.DataOffset, SeekOrigin.Begin);
   ROMHeader header = new ROMHeader(this); 

   DataRecord record2 = this.Records[0x4f];    //record #78
   this.Seek((long)record2.DataOffset, SeekOrigin.Begin);
   
  ...



work just fine :).
I guess BT NK.BIN is smaller or differently build than T_COM's. Universal solution should not be so difficult.

but i have another problem :-[:

[removed]

[Edit]

now this was a really stupid question :-[... forget it...
I get of course
Quote

Unknown version to patch: Watchdog Disable in module...


so it works only for BT version of TV2Engine.dll :'(.
But it was a good way to learn something about NK.BIN



Go Up