Circumventing Windows RT’s Code Integrity Mechanism

clrokr (@clrokr) – 6. Jan 2013
It’s taken longer than expected but it has finally happened: unsigned desktop applications run on Windows RT. Ironically, a vulnerability in the Windows kernel that has existed for some time and got ported to ARM just like the rest of Windows made this possible. MSFT’s artificial incompatibility does not work because Windows RT is not in any way reduced in functionality. It’s a clean port, and a good one. But deep in the kernel, in a hashed and signed data section protected by UEFI’s Secure Boot, lies a byte that represents the minimum signing level.

Finding the right spot

The minimum signing level determines how good an executable’s signature is on a scale like this: Unsigned(0), Authenticode(4), Microsoft(8), Windows(12). The default value on x86 machines is of course 0 because you can run anything you like on your computer. On ARM machines, it defaults to 8.
That means that even if you sign your apps using your Authenticode certificate, the Surface or any other Windows RT device (at this moment) will not run them. This is not a user setting, but a hardcoded global value in the kernel itself. It cannot be changed permanently on devices with UEFI’s Secure Boot enabled. It can, however, be changed in memory.
Finding this byte in the kernel takes a while, there is no exported symbol for it and not even in the symbol database at MSFT. I found it using WinDbg and a machine running Windows 8 Pro, creating processes and watching how the system behaves when the signature checks happen all the way through CI.dll and back. Because Windows 8 and Windows RT are so similar, locating it in the ARM kernel was not hard:

SeGetImageRequiredSigningLevel+0x18
LDR R3, =0x59FFA6 This is our byte, 0x19FFA6 at 0x400000 image base
LDRB R3, [R3]
CMP R3, #4
BHI loc_HighSigReq
B.W loc_LowSigReq

There are many more places where you can find this byte accessed, but none of them have an exported symbol.

Prerequisites

A while ago I read an article about how the Windows kernel assumes that data passed by certain processes is always well-formed [1]. This vulnerability exists in Windows RT, but exploitation is a bit harder than on Windows 8 because unsigned binaries can’t be run in the first place (and store apps don’t have the security context you need to attach to other processes). But Microsoft decided to provide something very important [2] that made this whole endeavour a lot easier. This remote debugger, when run as Administrator, can attach to the user’s CSRSS process and manipulate its memory.
CSRSS contains a lot of calls to the vulnerable NtUserSetInformationThread function, including some that use the right parameters to exploit it. This is one of them (from winsrv.dll):

TerminalServerRequestThread+0x230
MOVS R3, #0xC
ADD R2, SP, #0x58
MOVS R1, #9
MOV R0, 0xFFFFFFFE
BL NtUserSetInformationThread

A CSRSS thread executes this code. Using a breakpoint, we can change the data structure pointed to by R2 before the NtUserSetInformationThread call happens to exploit the vulnerability. Sadly, this is very impractical because the exploit subtracts 1 from the specified address and we need to subtract 0x80000. This is because we can’t do an unaligned access on ARM (remember, our byte’s offset is 0x19FFA6), so we need to use 0x19FFA4.
We also need the linear address at which the kernel image resides. We can find this out by calling (on the device, this can be done from a store app which will run unsigned) NtQuerySystemInformation with information class 11. If you want to know how to use NtQuerySystemInformation from a store app, read [3]. This gives us a list of all loaded drivers and their image bases, effectively bypassing ASLR in this case (although this is not what ASLR is for, it is annoying in these situations).

Exploitation

Using the remote debugger and MSFT’s armasm, I used a half-empty code page in winsrv.dll (0x10800 from the image base) to store this small payload:

push {r5-r8}
mov r7, 0x80000
ldr r8, my_addr
loc_loop_begin:
movs r3, 0xC
add r2, sp, 0x68 ;0x58 org.
add r5, r2, 4
str r8, [r5]
movs r1, 9
mvn r0, 1
mov r12, 0x10E1
svc 1
subs r7, r7, 1
cmp r7, 0
bne loc_loop_begin
pop {r5-r8}
mov r0, r0
my_addr dcd 0x12345678 the kernel's base address + 0x18

We now set a breakpoint directly after the legitimate NtUserSetInformationThread call in TerminalServerRequestThread, pressing a volume button will trigger it. This is where it gets interesting.
Redirect the instruction pointer to the payload in memory and set a breakpoint at the mov r0, r0 instruction at the end. Press F5. Now set the instruction back to the first breakpoint and remove both. Press F5 again.
Congratulations, your Windows RT device is unlocked!

Conclusion

Windows RT is a clean port of Windows 8. They are the same thing and MSFT enforces Code Integrity to artificially separate these platforms. It does not stop pirates from modifying store apps (and their license checks) because store apps are the only things that can actually run unsigned. The fact that this method works on Windows 8 as well shows how similar the systems are. You can even enforce Code Integrity on Windows 8 to see what Windows RT feels like!
The decision to ban traditional desktop applications was not a technical one, but a bad marketing decision. Windows RT needs the Win32 ecosystem to strengthen its position as a productivity tool. There are enough “consumption” tablets already.

Microsoft, please consider making code signing optional and thereby increasing the value of your Windows RT devices!

Drawbacks

  • Sometimes this triggers a bugcheck because we can’t control the bytes at 0x19FFA4 and 0x19FFA5 from the kernel base and they sometimes are zero, causing a 0x18 bugcheck.
  • This method is not practical for most users, especially because tablet buyers are less likely to know enough about computers to do this than PC users.

Sources

[1] j00ru//vx tech blog: Defeating Windows Driver Signature Enforcement #2: CSRSS and thread desktops
[2] Visual Studio 2012 Remote Tools
[3] Using the complete Windows API in store apps (mamaich at XDA-Developers)
also for further reading
[*] Discussion about this on XDA-Developers

Changelog

6. Jan 2013: Added 0x18 offset in payload because it is very important and the article at [1] doesn’t mention it. Also added link to discussion on XDA-Developers for further reading.


365 comments

  1. I don’t think it was a bad marketing decision, I think they essentially want(ed) users to live in the Modern UI and make those apps the de facto standard as much as possible in RT. They provided Office on the desktop (and in effect File Explorer and some others), but it looks like what they were trying to avoid with allowing desktop applications to be installed:

    1. Users being confused why their x86/x64 apps won’t install. They just give a general message to users.
    2. Prevent malware from being installed via USB, internet, etc.
    3. Keep boot times as fast as possible since desktop applications that are notorious for slowing down boot won’t be installed
    4. Keep battery life as high as possible since users should be living in the Modern UI. If they’re installing desktop apps, they will essentially kill battery life.
    5. Push users to using Windows Store apps in RT to try and make the desktop essentially just for productivity.

    Now, should it be a configuration item a la Android (giving users the ability to install non-Store apps)? I think so, and I’m guessing you do too.

    I’m kind of curious if the desktop would have been available if they had Windows Store app versions of the Office suite.

    • While you are totally right that doesnt mean we shouldnt feel bitter about being denied functionallity. I have been annoyed about this issue for some time in regards to tablets and phones. I appreciate things can be too complicated for most people so there is a trend towards simplicity. But that simplicity can still be present whilst providing deeper functionality. If there was a setting in the control panel that allowed a simple switch with ample warnings then it would be totally fine. People who want a “simple” experience can do so. But if those who are savy want more it is right there. Instead companies go to extrodinary lengths to lock down and “simplify” their devices. Im sick of being patronised by tech companies. I know what I want and I know the hardware and software can deliever. Stop holding out for no good reason.

  2. Pingback: The Surface Review

  3. Pingback: Microsoft News | Hack allows Windows RT tablets to run unsigned non-Windows Store apps

  4. Pingback: Windows RT Jailbreak Allows Unsigned Apps To Run | Pocketnow

  5. Impressive detective work.

    I can see this being very useful if we can run managed .Net Windows Forms and/or WPF exectuables, as they will not require recompilation for ARM. That would depend on whether the relevant .Net assemblies are included, or could be ported. I will have to have a look on my Surface.

    Being able to run .Net desktop apps would instantly make a lot of software available. It’s frustrating that MS deliberately crippled this OS (even though I haven’t missed any desktop apps yet, other than uTorrent and Chrome).

  6. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | eMagility :: defining mobile agility

  7. Pingback: Windows RT 'code integrity mechanism' gets sidestepped, allows unsigned desktop apps to run | The Worlds Tech Blog

  8. Pingback: Windows RT 'code integrity mechanism' gets sidestepped, allows unsigned desktop apps to run ← techtings

  9. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | Daily News! Blogger International

  10. Pingback: MS SurfaceRT Security Broken–Now you can run ANY Desktop App « McAkins Online

  11. Pingback: Windows RT 'code integrity mechanism' gets sidestepped, allows unsigned desktop apps to run | allcom.se

  12. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | Google Android news and more!

  13. Pingback: Windows RT 'code integrity mechanism' gets sidestepped, allows unsigned desktop apps to run | H Tanalepy

  14. Pingback: Windows RT 'code integrity mechanism' gets sidestepped, allows unsigned desktop apps to run - FourTech Plus

  15. Pingback: » Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run » webaligns

  16. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | Everheartz15's Tech Blog

  17. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | Top Technology News

  18. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | Project Konnect

  19. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | The Memory Bank

  20. “The minimum signing level determines how good an executable’s signature is on a scale like this: Unsigned(0), Authenticode(4), Microsoft(8), Windows(12).”
    That seems more like a bitfield than a level indicator.

  21. Pingback: Windows RT has been jailbroken!

  22. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | tekifeed.com – Gadget Feeds, Gadget News and more!

  23. Possibly stupid question here: are you saying that using this exploit Windows RT can run *any* Win32 desktop app, or that it can run unsigned apps developed specifically for ARM?

  24. Pingback: Windows RT reportedly jailbroken | t-break: Tech @ Its Fastest

  25. Pingback: Windows 8 RT had been jailbroken! | Matt Gebran's IT Blog

  26. Pingback: MSOSHQ - Microsoft OS News and Rumors | Windows RT jailbroken to run ARM-based desktop apps

  27. Pingback: Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run | FeedLinks.net

  28. Pingback: » Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run Gamez Menu

  29. Pingback: Wondows RT and Windows 8 one and the same

  30. Pingback: – Windows RT ‘code integrity mechanism’ gets sidestepped, allows unsigned desktop apps to run

  31. Pingback: Hacking Windows RT and Surface to run desktop apps « Tim Anderson's ITWriting

  32. Pingback: Windows RT jailbreak edildi, ARM tabanlı masaüstü uygulamaların çalışması önündeki engel kalktı

  33. Pingback: Windows RT, eseguito il jailbreak | Geekissimo

  34. Pingback: Windows RT Is Now Jailbroken: Details & facts | The Tech Journal

  35. Pingback: Windows RT are jailbreak: se pot rula aplicații ARM nesemnate | Mobzine.RO ::: Your mobile IT world!

  36. Pingback: Windows 8 RT – Une faille permet de faire tourner toutes les applications non signées sous RT | Korben

  37. Pingback: Windows RT jailbroken to run ARM-compiled desktop applications » TechAttack.my

  38. Pingback: Draaien desktop-apps op Windows RT is mogelijk « view on Windows

  39. Pingback: Installer n'importe quelle application sur Windows RT

  40. Pingback: Une nouvelle faille dans Windows 8 RT qui permet de faire tourner toutes les applications non signées : une piste pour l’activation ? | lemondedestuts

  41. Pingback: Technable | Making you Technically Able

  42. Pingback: Windows RT Jailbroken to Run Desktop Apps | 1v8 NET

  43. Pingback: THEWIND » Windows RT已被破解,可运行未经签名的桌面程序

  44. Fantastic work, this has made my day and really excites me! Do you have any plans for a little step-by-step guide for us noobs? I know how to remotely debug a WinRT app on a Windows RT device, but that’s as far as my knowledge currently extends. Congrats again for your work so far though!

  45. Pingback: Windows RT is Jailbroken Facts And Other Details | Technology Hits


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s