数据结构复习(2)
线性表章节。
线性表的定义和操作线性表的定义线性表是具有相同数据类型的 n 个数据元素的有限序列。
线性表是逻辑结构,表示了元素之间一对一的相邻关系。而顺序表(顺序存取表)和链表(链式存储表)是指存储结构。
线性表具有先后顺序。
线性表每个元素具有相同大小的存储空间。
线性表的操作有以下操作:
初始化分配内存空间。
求表长。
按值查找。
读取某个元素。
插入操作。
删除操作
顺序输出所有元素。
判断元素个数是否为 0。
销毁线性表。
线性表的顺序实现概念顺序表是指,逻辑上相邻的数据元素在物理地址上也相邻。
结论就是:
随机存取方便,插入删除困难,顺序表是一种随机存取的数据结构。
例题遇到的概念没什么好说的,连续多次删除元素的话不一定要重复 k 次的移动,可以一次移动完。具体算法思路是这样的:
定义一个下表 index=0 和循环变量 i=0。
循环遍历:
如果该元素要被删除,则不作任何操作。
如果该元素不会被删除,把它存入下标为 index 的数组,并使得 index++。
结束循环
最后让长度 = index 即可。
或者用下面的思路:
...
计算机网络复习(1)
计算机网络体系结构
计算机网络概述这一章比较多的是概念,记一下主要的就好了。
计算机网络的概念将分散的,具有独立功能的计算机系统,通过通信设备与线路连接起来,由功能完善的软件实现资源共享和信息传递的系统。计算机网络就是一些互联的、自治的计算机系统的集合。
广义观点只要能实现远程信息处理的系统,或者资源共享就是计算机网络。
资源共享观点跟开头差不多,包含三层涵义:
目的——资源共享
组成单元——分布在不同地理位置的多台独立的自治计算机
计算机必须遵守的统一规则——网络协议
计算机网络的组成组成部分上来看完整的计算机网络上包括硬件、软件、协议三大部分组成。
硬件主要由端系统,链路,交换设备,网卡等组成。
软件主要由一些应用程序实现。
协议是计算机网络的核心。
工作方式上来看计算机网络可分为边缘网络和核心网络。
从功能上来看计算机网络由通信子网和资源子网组成。
计算机网络的功能
数据通信:最基本最重要的功能
资源共享
分布式处理
提高可靠性
负载均衡
计算机网络的分类分布范围分类
广域网
城域网
局域网
个域网
按传输分类
广播式网络
点对点网络
按拓扑结构分类
总线型
星 ...
高等数学复习(8)
高等数学复习(8)——一元积分学概念
概念原函数存在定理:
当函数 $f(x)$ 在任意一点上都具有 $\int f(x)=F(x)+C$ ,则称 $F(x)$ 是 $f(x)$ 的一个原函数。
只有含有有界震荡间断点的函数具有原函数,其余情况没有原函数。
定积分概念:
即是黎曼积分的定义 $\int a ^b f(x)dx=\sum^{n}{i=1}\lim\limits _{n\to \infty} f(a+\frac{b-a}{n}i)\frac{b-a}{n}$
特别的,当 a=0,b=1 的时候,式子退化成 $\int 0 ^1 f(x)dx=\sum^{n}{i=1}\lim\limits _{n\to \infty} f(\frac{i}{n})\frac{1}{n}$
所以做数列极限题的时候,可以尝试化成这样的式子,转而求定积分。
定积分存在定理:
$f(x)$ 在 $[a,b]$ 上连续,则 $\int _a ^b f(x)dx$ 存在。
$f(x)$ 在 $[a,b]$ 上单调,则 $ ...
Windows驱动开发(10)——内核保护进程
在内核中保护特定进程
本来想着掌握一种方法差不多就够了,后面想想还是一步一步走过来吧。
获取进程名在回调中,每有一个进程相关事件,就会触发这个回调。一般我们很多跨进程的操作第一步都是 OpenProcess 去获得进程句柄,后续操作都通过句柄操作。在回调函数中我们可以使用 OperationInformation->Object 这个对象拿到当前被操作进程的结构体指针。
这样子我们获得了一个 EProcess 的指针,可以用这个所指向的结构来取得进程名,通过访问使用API PsGetProcessImageFileName 来获得进程名。
最后我们使用 _stricmp((char *)processName, "msedge.exe") 进行一波判断即可。
通过进程ID保护进程同样,还有一个 API 是 PsGetCurrentProcessId 用来获取当前进程的 pid 的,同样我们可以使用这个 API 来和预期的进程 id 进行比较,相同就保护起来,因为我们很可能不确定要保护的进程 ID 是多少,因此不能再 sys 中写死,我们可能需要实现一些驱动 ...
考研周报(11)
第11篇周报
本周小结英语每天都背了 200 个单词,check。
专业课没动
数学进了一点。
windows驱动学了挺多,高产简直。
下周目标英语:每天背单词至少 300。
数学:看完第九章。
专业课:
计算机网络:开第二轮吧,但是物理层自顶向下是没有的,所以预计先看看物理层。
数据结构:不知道,大概给三个星期看完吧(目前:第二个星期)。
windows 内核基础:同样先等上面完成目标吧。
Windows驱动开发(9)——双机调试
今天具体学习一下双机调试。
前言肯定主要就是这个调试器怎么去用了,这里我贴一下 VirtualKD 的项目地址——(https://github.com/4d61726b/VirtualKD-Redux)。也由衷地感谢这些开发者给我们开发了这么好用的工具,让我们环境搭建这一步走了很大的捷径,上一篇博客中遇到的问题,当时因为比较急直接去提了 issue,而作者也给出了很耐心的解释,应该是照顾我这个萌新吧。
真的是非常感谢。
Windbg的使用我是实在用不来那个纯命令行的调试器,因为根本不知道跑起来之后怎么加断点,所以我使用了 Windbg preview,这个据说是要在微软商店下载的,如果停用了 windows 更新的话,好像就直接用不了了,为了这个我重新打开了我 windows 的更新。
初始布局大概是这样:
当提示 Debuggee is running 的时候,是没办法在 KD 命令行输入指令的,断点也打不了。
最开始的情况应该是:这里根本就不知道在哪的,左边的反汇编窗口应该也不是指向了自己想要的位置,此时不知道在哪里断就可以先放着,然后点 break 暂停,这个暂停是 ...
Windows驱动开发(8)——双机调试
今天还有学习一下双机调试。
环境准备先添加一个串行端口,使用命名管道。
然后开启虚拟机,运行命令
1bcdedit /copy {current} /d "win10 x64 debug for windbg"
这个命令的意思是把当前启动项复制一份命名为 win10 x64 debug for windbg
然后再运行 msconfig,选择刚复制的一份启动项,打开高级选项,勾选调试,选择 COM1。
然后重启之后就完事了,选择第三个选项即可。
这里用一下 VirtualDK 这个软件,非常好用,直接在虚拟机运行 target64 的 exe 文件,然后注意,最重要的一点:
F8 选择禁用驱动签名
F8 选择禁用驱动签名
F8 选择禁用驱动签名
重要的事情说三遍,不然根本连不上,后面 Windbg 再慢慢学吧,今天因为这个环境搞了很久。
Windows驱动开发(7)——句柄回调
今天学习驱动保护进程。
实现原理我们在驱动层注册一个进程回调,当调用 OpenProcess 的时候,会触发这个回调,我们在这里取消掉进程结束的权限就可以达到防止进程被结束的目的。
回调函数先写一下回调函数:
1234567891011121314151617181920212223242526OB_PREOP_CALLBACK_STATUS MyProtect( PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation){ if (OperationInformation->KernelHandle) { } else { ACCESS_MASK AccessBitsToClear = PROCESS_TERMINATE; PEPROCESS process = (PEPROCESS)OperationInformation->Object; PUCHAR p ...
Windows驱动开发(6)——加载驱动过程
今天顺便再解决一下应用层加载卸载驱动的方式。
加载驱动加载驱动过程
用OpenSCManager打开服务控制管理器
用CreateService创建对应服务
如果驱动服务已经创建过,则用OpenService打开服务
用StartService加载启动驱动服务
清理工作,用CloseServiceHandle关闭释放句柄
一个一个介绍一下每一步的详细步骤吧
打开服务控制管理器使用如下代码获得一个SCM管理器的句柄。
1SC_HANDLE hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
第一个参数是目标计算机的名称。 如果指针为 NULL 或指向空字符串,则该函数将连接到本地计算机上的服务控制管理器。
第二个参数是服务控制管理器数据库的名称。 此参数应设置为SERVICES_ACTIVE_DATABASE。 如果为 NULL,则默认打开SERVICES_ACTIVE_DATABASE数据库。
第三个参数是我们获得句柄的权限,SC_MANAGER_ALL_ACCESS 表示获得所有权限。
创建服务 ...
Windows驱动开发(5)——设备通信
今顺便再来搞搞这个 IRP_MJ_READ 和 IRP_MJ_WRITE 等事件。
应用层读写设备文件写文件同样在函数的 SWITCH 分发中添加 case,然后在 DriverEntry 中注册回调,我们先了解三个指针,这里后面有大用,这三个指针是传参的三种方式。
1234567case IRP_MJ_WRITE: { char *ptr1 = pirp->UserBuffer; char *ptr2 = pirp->MdlAddress; char *ptr3 = pirp->AssociatedIrp.SystemBuffer; kprintf(("Line %d:xia0ji233: ring3 calls ReadFile ptr1=%p ptr2=%p ptr3=%p\n"), __LINE__, ptr1, ptr2, ptr3); break;}
WriteFile 是 ring3 向 ring0 写入数据的一个过程,因此我们在 ring0 层要拷贝 UserBuffer 里面 ...