A closer look at TV2Engine MacrovisionEnable

From t-hack.com - Hack X300T / X301T

Jump to: navigation, search

So, TV2Engine_MacrovisionEnable sounds quite interesting. Lets take a look at what it does:

tv2engine.dll :Function TV2Engine_MacrovisionEnable(bool val)

calls

coredll.dll: ExtEscape(GetDC(0), 0x186A9, 4, &val, 0, 0)

So, how does ExtEscape in coredll.dll call the real function ? Let's take a look at the wince source.... Shit. Still no idea. But wait ! The MSDN says
"This function allows applications to access capabilities of a particular device that are not available through the graphics display interface (GDI). The device capabilities this function accesses must be implemented by an OEM."
What might our display driver be ? (hint: ask the wince registry) - it's shareddisplay.dll. So coredll calls DrvEscape in shareddisplay.dll, so it should be easy to find it, but the driver exports only DrvEnableDriver ! A search for 0x186A9 returns no results either.
So, what does DrvEnableDriver do ? MSDNagain: "[...]It fills a DRVENABLEDATA structure with the driver version number and calling addresses of functions supported by the driver."
DRVENABLEDATA... functions... Oh, look ! The second last entry is DrvEscape. That's quite convenient.
After a small stub
Image:Drv1.png
the sub starts to load and store the functions referenced by pEngCallbacks, but then there is a suspiscious looking memcpy :
Image:Drv2.png
So, what's at memcopy's source address ? Looks like a function table:
Image:Drv3.png
Finally ! The real DrvEscape
Image:Drv4.png
The left side is not important, we know our argument is not 0x8 (= QUERYESCSUPPORT), but it's not 0x183a (= DRVESC_GETGAMMAVALUE) or 0x1839 (= DRVESC_SETGAMMAVALUE) either so.. damn it !
Another jump ! Obviously $a0 is a pointer to another function table. Like the MSDN says, "dhpdev [in] Handle to the device that is getting the DrvEscape call."
DHPDEV is a unknown driver-specific struct, but DrvEnablePDEV will return a DHPDEV struct, so let's take a look at DrvEnablePDEV, which is the first entry in the DRVENABLEDATA struct.
We know the function will return DHPDEV, so $v0 = DHPDEV. Let's follow $v0 !
Image:Drv5.png
If the function succeeds it returns $6, so obviously DHPDEV is $s6, and $s6 is the return value of our fist sub, so lets look at the first sub:
Image:Drv6.png
Obviously DHPDEV can't be 0x7b, so it has to be the return value of the sub.
Image:Drv7.png

new unsigned int[0x4c]

looks like the birth of a new DHPDEV struct, the sub gets the newly created array as $a0, so it's going to fill it with values.
Image:Drv8.png
YES!! The address gets stored at DHPDEV[0], so it has to be the address of our function table !
Image:Drv9.png
The jump is to address+0x40, so we finally found the function which handles our 0x186A9.
Image:Drv10.png
Ahem. This function does... nothing !
:(

Personal tools