I've been playing a little with ILDASM and ILASM.
It seems the tv2client.exe decompiles to IL with ILDASM, and recompiles on with ILASM (I haven't tried running the created exe on the box but it seems to compile OK with no errors).
I was thinking it may be possible to modify the IL code to fake the data from the bootstrap, and get the box to work as a stand alone PVR.
I was thinking of something like this:
Original Code:
IL_0162: ldsflda valuetype Microsoft.TV2.ClientConfiguration/*0200057A*/ Microsoft.TV2.Bootstrap/*020004C5*/::mConfig /* 04001A6D */
IL_0167: ldloc.2
IL_0168: ldfld valuetype [mscorlib/*23000001*/]System.Guid/*01000021*/ Microsoft.TV2.Proxy.Bootstrap.ClientInfo/*02000511*/::accountId /* 04001C08 */
IL_016d: stfld valuetype [mscorlib/*23000001*/]System.Guid/*01000021*/ Microsoft.TV2.ClientConfiguration/*0200057A*/::AccountID /* 04001F5C */
Modified Code:
IL_0162: ldstr "6CC2EE32-FC06-44bf-8A63-B88629FC2DC1" /* 7000685F */
IL_0167: newobj instance void [mscorlib/*23000001*/]System.Guid/*01000021*/::.ctor(string) /* 0A00009A */
IL_016d: stfld valuetype [mscorlib/*23000001*/]System.Guid/*01000021*/ Microsoft.TV2.ClientConfiguration/*0200057A*/::AccountID /* 04001F5C */
Any comments or thoughts on this approach?
Mick
Here is an update...
Old Code:
IL_0162: ldsflda valuetype Microsoft.TV2.ClientConfiguration/*0200057A*/ Microsoft.TV2.Bootstrap/*020004C5*/::mConfig /* 04001A6D */
IL_0167: ldloc.2
IL_0168: ldfld valuetype [mscorlib/*23000001*/]System.Guid/*01000021*/ Microsoft.TV2.Proxy.Bootstrap.ClientInfo/*02000511*/::accountId /* 04001C08 */
IL_016d: stfld valuetype [mscorlib/*23000001*/]System.Guid/*01000021*/ Microsoft.TV2.ClientConfiguration/*0200057A*/::AccountID /* 04001F5C */
new code:
IL_0162: ldsflda valuetype Microsoft.TV2.ClientConfiguration/*0200057A*/ Microsoft.TV2.Bootstrap/*020004C5*/::mConfig /* 04001A6D */
IL_0168: ldstr "6CC2EE32-FC06-44bf-8A63-B88629FC2DC1" /* 7000685F */
IL_0169: newobj instance void [mscorlib/*23000001*/]System.Guid/*01000021*/::.ctor(string) /* 0A00009A */
IL_016d: stfld valuetype [mscorlib/*23000001*/]System.Guid/*01000021*/ Microsoft.TV2.ClientConfiguration/*0200057A*/::AccountID /* 04001F5C */
In reflector it gives the following results:
Old Code:
case 0:
BootPrefs.LastBootstrapUrl = proxy.Url;
mConfig[BootstrapServiceType.sms] = new Uri(proxy.Url);
mConfig.AccountID = info.accountId;
mConfig.Bps = info.bps;
New Code:
case 0:
BootPrefs.LastBootstrapUrl = proxy.Url;
mConfig[BootstrapServiceType.sms] = new Uri(proxy.Url);
mConfig.AccountID = new Guid("6CC2EE32-FC06-44bf-8A63-B88629FC2DC1");
mConfig.Bps = info.bps;
Mick
I guess that will work if you change enough code.
actually I tried to do something similar by fixing the errors that resulted from decompiling with various dot net decompilers.
then modifying the code and running it on the box.
the init part was working to some extend, but I had to change many things to get it running.
but I never managed to make it usable, because I didn't know how the data structures look like on a working box.
I have also been trying to re-assemble the C# code (tried a few different decompilers).
I found that <PrivateImplementationDetails> usually relates to a switch on a string. switch (string) .. case "blahblah" for example.
Dot net seems to store those into a dictionary, then uses the lookup for the switch, and the case is the index.
So i managed to revert that code back to orignal form.
List`1 I think used to be a for each loop, but havent figured out how to reconstruct those yet.
There are lots of other things which I have no idea how to fix :(
for example...
while (TV2Engine.ThreadInfo[,].Address(i1, i2).ThreadID != 0)
{
if (!arrThreadInfo.ContainsKey(TV2Engine.ThreadInfo[,].Address(i1, i2).ThreadID))
{
TV2Engine.ThreadInfo[,].Address(i1, i2).ThreadID.Add("", string.Concat("{0:X}", string.Format(arrThreadInfo, TV2Engine.ThreadInfo[,].Address(i1, i2).ThreadID), ": "));
}
i3 = 0;
while (TV2Engine.ThreadInfo[,].Address(i1 + 1, i3).ThreadID != 0)
{
if (arrThreadInfo == TV2Engine.ThreadInfo[,].Address(i1 + 1, i3).ThreadID)
{
TV2Engine.ThreadInfo[,].Address(i1, i2).ThreadID[hashtable] = string.Concat((arrThreadInfo[TV2Engine.ThreadInfo[,].Address(i1, i2).ThreadID] as string), (((int)(TV2Engine.ThreadInfo[,].Address(i1 + 1, i3).UserTime + (arrThreadInfo - TV2Engine.ThreadInfo[,].Address(i1, i2).UserTime)))) / 100000, "% ");
}
i3++;
if (i3 >= 256)
{
break;
}
}
It does not like the [,] fields.
Any help would be appriciated.
Thanks
Micl
reflexil SVN #121 and reflector 5.1.1.0 - i guess it's time to update your tools ;) for (int i = 0; i < 15; i++)
{
for (int j = 0; (j < 0x100) && (threadTimes[i, j].ThreadID != 0); j++)
{
if (!hashtable.ContainsKey(threadTimes[i, j].ThreadID))
{
hashtable.Add(threadTimes[i, j].ThreadID, "" + string.Format("{0:X}", threadTimes[i, j].ThreadID) + ": ");
}
for (int k = 0; (k < 0x100) && (threadTimes[i + 1, k].ThreadID != 0); k++)
{
if (threadTimes[i, j].ThreadID == threadTimes[i + 1, k].ThreadID)
{
int num4 = ((int) ((threadTimes[i + 1, k].KernelTime - threadTimes[i, j].KernelTime) + (threadTimes[i + 1, k].UserTime - threadTimes[i, j].UserTime))) / 0x186a0;
hashtable[threadTimes[i, j].ThreadID] = ((string) hashtable[threadTimes[i, j].ThreadID]) + num4 + "% ";
}
}
}
}
I did notice that in reflector it seems to decompile OK.
I tried spices.net which I thought would have decompiled it better.. but obviously not.
I tried the online version of remotesoft salamander which seems to do a better job than both of the above!
Perhaps if we had the full version it would produce fully recompilable code.
Mick
last time i checked, salamandar wasnt doing a good job on the tv2client either.
but it could be that the new generics support in the 3.0 version is the key ;)
havent tried that yet.
Did some tested this one already?
http://www.netdecompiler.com/
I tried the online version of remotesoft salamander which seems to do a better job than both of the above!
Perhaps if we had the full version it would produce fully recompilable code.
maybe we can write an email to remotesoft and ask if they decompile it for free ::)
Asgard
Update: I wrote them an email...maybe we get an answere :)
Did some tested this one already?
http://www.netdecompiler.com/
yep... tried that ... does not look too good either.
reflector is still getting the best output.
Yes, you wont be able to re-inject into the NK.BIN if its larger.
I did cheat, and used a hex editor and changed the "this program cannot be run it dos mode" at the start to all bytes of 0x00.
Then it compresses better....
BooterCE does look for a file called TV2ClientCE2.exe which goes in the TV2Client folder.
If it exists it will run that instead of the NK.BIN one.
This is the method I have been using, but it only works on versions less than 1.2.14642
This is because on the latest version (1.2.14642) the trust model is back, so exe's wont run outside of the \windows folder unless they are signed.
version 1.2.14612 works fine.
Mick
I think it has to be slightly smaller.. even the same size did not work for me.
As said, use a text editor and edit the "this program cannot be... " to bytes of all 00.
It will then compress better.
Mick
Check your pm's
I may be able to help...
Mick