Disable TrustModel
From t-hack.com - Hack X300T / X301T
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
