Can you write to the GDT (Global Descriptor Table) on Windows 95 from protected mode? Why, and how?

In some old notes of mine, I have:

"In Windows 95 the descriptor tables are accessible from the user space context. They are both readable and writable. Arbitrary code execution may be gained by adding an entry to the LDT, GDT, or IDT and then execute the corresponding interrupt or far call."
From the paper "Attacking the Windows Kernel", presented at Black Hat, also at NCG research group

This was mentioned as an aside for legacy Windows systems. I know that Windows 95 is completely outdated and is not of a security concern, this is a retro-computing question.

First off, is the statement even true?

In what context is this? Is it for a win32 application running in protected mode in Windows 95? Or is it for a DOS application running in VM86 mode?

While I've implemented paging myself in a toy OS, I will admit I've never bothered with looking into the details of VM86. I would imagine that VM86 does allow you to manipulate the descriptor tables (which is not affecting the actual descriptor tables), but how that would get you code execution outside of the VM86 is unclear to me. Am I mistaken?

If it is meant from a protected mode context, writing to the descriptor tables, then why is this possible? What purpose does it serve? And moreover, how is this achieved? I thought that from ring 3 you simply cannot write to the descriptor tables, the instructions to do so are privileged.

But maybe I've forgotten something crucial or misunderstand something else.

  • 3
    the instructions to do so are privileged. -- the tables themselves are in plain old memory accessible by ordinary move instructions, so it's a question of how that memory is protected.
    – dave
    Commented Mar 10 at 11:50
  • @dave Fair enough, but why would it be writable from ring 3? Why is the R/W bit set for this page table entry? Commented Mar 10 at 19:25
  • 3
    I don't know, but a big feature of Windows 95 was application compatibility, for which robustness could be sacrificed (if you wanted the opposite tradeoff, there was Windows NT). Maybe this was such - perhaps part of the 'first megabyte is common to all processes' requirement.
    – dave
    Commented Mar 10 at 19:56
  • 1
    Why don't you try it out? Spin up a VM with Win95, write a bit of assembly to get the GDT address, try to read from it or write to it with ordinary instructions, and see what happens.
    – dirkt
    Commented Mar 11 at 5:51

1 Answer 1


Due to being required to run in 4Mb of RAM, a number of security protections were compromised. As a result, those tables were indeed writable. The CIH virus took advantage of this, for example, by hooking an interrupt in the IDT, and then issuing the interrupt to elevate privileges. It was also possible to set a process image base inside the VxD space (0xC0000000+), resulting in instant ring 0 execution privilege.

  • 1
    Four megabarns? Also, I think this particular one had less to do with limited memory, but having to work around hardware bugs of obscure CPU steppings. Commented Mar 16 at 13:19
  • Raymond Chen says that the design target of Windows 95 (original edition) was to be "basically usable on a machine with 4MB of RAM". That's for example why the clock has no blinking colon (while other system had it). They were desperate to be able to swap out the code to disk that would have been required to constantly re-paint the clock. See devblogs.microsoft.com/oldnewthing/20031010-00/?p=42203 (until MS breaks the links to their blogs again) (Sorry if your comment was just about the small instead of capital "B" in "4Mb") Commented Mar 17 at 18:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .