Disable TrustModel

From t-hack.com - Hack X300T / X301T

Jump to: navigation, search

WinCE Trust Model

The WinCE Kernel has an option to verify exe and dll files before they are allowed to start.

since IPTV firmware 1.2.xxxx this has been enabled. Although they screwed up the verification ;)

it is even metioned in the source code of loader.c of the kernel.

   // for files in ROM -- fully trusted unless specified otherwise in the flag
   // NOTE: we perform the test before testing pOEMLoadInit/pOEMLoadModule so
   //       OEM can have a close system with trusted model without implementing
   //       pOEMLoadInit/pOEMLoadModule. However, if an OEM has RAM filesys, he
   //       must implement the functions or files in RAM will be fully trusted.

this basically means that any file can be executed when /windows is writeable. but the space in /windows folder is too limited for bigger applications and it wastes precious RAM.

how it works

when the kernel wants to load a binary, it calls the VerifyBinary() method. the VerifyBinary() method in the nk.exe calls the CertVerify() method of filesys.exe which forwards the call to certmod.dll CertVerify() if that exists.

when all these calls returned without error, then the binary is actually loaded and executed.

certmod.dll was added in IPTV firmware 1.2.

to to fix it

the trust model can be easily killed. either certmod.dll, filesys.exe or nk.exe can be patched.

patching nk.exe is the easiest, because it is stored uncompressed in the nk.bin.

the VerifyBinary() method can be found with IDA Pro when searching for

  li      $v0, 0x80090006

the constant is NTE_BAD_SIGNATURE, which is returned when the binary is untrusted.

first part to be patched is found at the beginning of the method:

  .text:91E08CC8                 sw      $s4, 0x450+arg_C($sp)
  .text:91E08CCC                 sw      $s5, 0x450+arg_8($sp)
  .text:91E08CD0                 move    $s7, $a1
  .text:91E08CD4                 andi    $v1, $v0, 2
  .text:91E08CD8                 beqz    $v1, loc_91E08D58       //  <--- this jumps to the Kernel Flag check
  .text:91E08CDC                 sw      $0, 0x450+var_430($sp)

the "beqz" needs to be changed to a "b" so that we always get to the kernel flag check


so this is the kernel flag check:

  .text:91E08D58 loc_91E08D58:                            # CODE XREF: VerifyBinary+4C�j
  .text:91E08D58                 li      $v0, 0x91E0101C
  .text:91E08D60                 lw      $t3, 0($v0)
  .text:91E08D64                 lw      $t4, 0x34($t3)
  .text:91E08D68                 andi    $t5, $t4, 0x10
  .text:91E08D6C                 beqz    $t5, loc_91E08D80    // binary doesnt have Kernel flag so jump to next check
  .text:91E08D70                 nop
  .text:91E08D74                 li      $t6, 1              // binary has Kernel Flag, so KERN_TRUST_RUN is set
  .text:91E08D78                 b       loc_91E08EF8        // and jump to exit code
  .text:91E08D7C                 sb      $t6, 0($s5)

here we only need to "nop" out the beqz, so that all binaries get kernel permissions :) to make things even better, the "li $t6, 1" should be changed to "li $t6, 2" which means the binary gets KERN_TRUST_FULL permissions (the highest trust level)


this is work in progress. I just wanted to write stuff down

Program to patch the NK.BIN and fix the checksum

Personal tools