自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(38)
  • 收藏
  • 关注

原创 windows 消息机制

windows 操作系统是由事件驱动的 也叫消息机制 一般来说分为四步用户动作也就是事件 ->windows 将事件翻译成消息->将消息放入消息队列->消息循环从消息队列中取出消息并发送给窗口处理程序我们来看一下窗口最简单窗口的过程创建一个窗口必须先注册这个窗口的窗口类RegisterClass(&wndclass);每一个窗口程序都有一个类名和标题名是不变这...

2019-04-27 12:31:38 268 2

原创 冒泡排序,选择排序插入排序的本质分析

排序算法问题 冒泡排序 选择排序 插入排序分析排序算法是十大经典算法之一,对于一些初学者可能没那么容易真正的理解本质 希望我的贴子可以给各位一点帮助冒泡排序算法 我们将序列分为 有序区和无序区冒泡排序他是通过将相邻的数不断的比较 然后将较大或较小的数往后移位 实现排序的目的 有n个无序的数 冒泡排序的每一轮执行完后有序区的元素个数都加1对于n个数需要n-1...

2019-04-21 23:29:51 481

原创 数组和指针,内存之间的关系

首先论证一维数组和一级指针之前的关系,我们常常使用一级指针指针的方式访问一维数组,只有对内存的理解到位才能理解它们直接的关系。1.数组名是数组的首地址2.对数组名取地址得到的还是数组的首地址3.数组的访问方式其实就是首地址+偏移的寻址访问我们在程序中会定义很多变量,有基本类型和自定义类型在进行开发的时候我对内存的访问访问就是通过变量名赋值的方式读写内存但是如果你看到的直接变量的符号名你将不可能理解内存。每一种类型都有字节宽度,char 1字节 short 2字节 int 字节 floa

2022-01-30 16:16:20 5567 5

原创 滴水中级班保护模式阶段测试作业

// 保护模式阶段测试第一题.cpp : Defines the entry point for the console application.//1给定一个线性地址,长度,读取内容2-9-9-12#include "stdafx.h"#include <Windows.h>typedef struct PAGE{ DWORD PTELinkAddress; DWORD PDELinkAddress; DWORD PTELow; DWORD P...

2020-11-08 18:15:21 1231

原创 什么是可读,可写,可执行。 线性地址和TLB的关系

C/C++的编程过程中应该都遇到过 0xC0000005,访问权限异常,当访问没有权限访问的页时候就会出现这个问题经过这一段时间的学习,我发现我对可读可写可执行有了不一样的理解,从汇编层面mov ds:[0x12345678],eax 是把eax的值存放到 0x12345678线性地址对应的物理地址 这个线性地址对应的物理页既是可写mov eax,ds:[0x22222222] 这个线性地址0x22222222对应的物理页既是可读想要理解什么是可读可写可执行首先需要理解页机制...

2020-11-07 22:27:42 2255 2

原创 static关键字,在面向过程和面向对象中的应用

static关键字在面向过程中的使用1.static关键字修饰局部变量,static修饰的局部变量使一个本函数私有全局变量,只能在定义它的函数里面使用,而且这个变量只会被初始化一次,在编译好的时候内存就开辟了 和全局变量一样内存开辟在静态全局变量区2.static关键字修饰函数和全局变量,我们知道函数和全局变量只要其他文件申明就可以直接调用,(使用其他文件的变量的时候声明的时候要加上extern 而函数可以不用加)全局变量和函数都可以看成一个全局的符号,而static修饰后的函数和全局变量.

2020-11-07 13:44:16 313

原创 编译器的过程,从源文件到.exe文件经过就几步,是如何进行的

从一个.cpp文件到一个exe会经过如下几步1.预处理2.编译3.汇编4.链接1:预处理阶段有预处理器进行,会将每一个.cpp(源文件(c语言程序和c++语言程序是一样的)预处理器会将所有源文件中的与预处 理指令进行处理,所谓的预处理执行就是 #开头的语句 如#define #include #if 1 #endif 宏定义,头文件包含 条件偏移等等都是预处理指令 #pragma once(加上头文件的开头,能够保证这个头...

2020-11-03 20:48:29 1900 1

原创 页机制和2-9-9-12分页线性地址页表之间的映射关系

学完本章,各位就能够真正的理解虚拟内存和物理内存之前的关系了 前面我们讲过每个进程都有自己4GB的虚拟内存,其中第2GB各不相同,而高2GB所有进程都是同用的,虚拟内存机制可以实现,不同进程空间的隔离,A进程只能访问A进程的空间,B进程只能访问B进程的空间,从而是A进程挂了不会响应B进程,如果高2GB挂了那就所有进程都挂了直接蓝,不同进程之间的隔离是因为进程的低2GB映射的物理页都不同,访问A的0x10000000地址和B进程0x10000000实际访问的是不同的物理页,这就出现了一个问题,...

2020-11-02 14:36:50 982

原创 通过代码挂上物理页

给0地址挂上物理页,吧VirtualAlloc函数开辟的线性地址物理页给0地址挂上,这样这两个线性地址访问的就是同一个物理页,内存映射的本质就是相同或者不同进程的两个线性地址,使用同一个物理页这个是2-9-9-12分页的,如果10-10-12分页会更简单,代码可以在此基础上改这里我将只提几个需要注意到的问题1.memset填充是为了 VirutalAlloc开辟内存后,线性地址并不会马上挂上物理页,PTE没有指向物理页需要注意2.那个裸函数注释掉的代码需要注意,虽然说要把那个线性地址P.

2020-10-28 23:49:05 712

原创 任务段进行任务切换,Jmp Call指令实现任务切换

任务段描述符的格式我们就不说了太基本了,它的Base指向TSS结构的地址,Limit设置为0x68就够了TSS结构的大小就是104个字节,我们之前讲过,通过中断门,调用们提权的时候 ring0的堆栈ESP和SS都是TSS提供的,TSS结构每个核只有一个和KPCR结构一样,每当线程切换的时候会把当前线程的ESP0写入TSS结构中(以后进行线程切换逆向的时候会找到具体的代码),所以我们所Ring3提权到Ring0得到ESP都是当前线程的Ring的栈顶。 TSS是CPU设计的实现多...

2020-10-18 19:28:21 1472 3

原创 什么是内核态,什么是用户态,谁定义的?从段页层面解析用户态和内核态

应该学习过一段时间的人,都能唱出来,低2GB是用户空间,高2GB是内核空间,我们如果在用户空间访问内核空间数据,直接给你一个0xC0000005异常,告诉你你没有权限访问, 今天就给大家完全的解析什么是内核空间,什么是用户空间CPU有4个运行级别,如下图,我们所说的内核就是Ring0当CPU运行ring0态的时候就是内核态(也就是CPL=0),此时拥有最 高的权限而在用户态的时候就是CPL=3此时CPU处于用户态 再次提出几个问题解决...

2020-10-11 15:53:47 1369

原创 一致代码段,非一致代码段的本意和详细测试

不知道有没有人尝试过mov cs,ax这样的指令结果肯定挂,因为不能直接修改cs段寄存器的值,不能直接修改,那肯定可以间接咯,cs段寄存器和其他的段寄存器不太一样,它能加载的段描述符有:代码段描述符,调用门,TSS任务段,任务门,如果加载数据段描述符直接挂,(用数据段加载代码段描述符的时候,直接过,访问内存的时候才挂),而用cs加载数据段描述符直接挂。 这篇帖子只讲代码段描述符(调用门,任务门这些系统段描述符会后面会讲)代码段描述符S=1时TYPE>=8 此时这个段描述符...

2020-10-11 12:51:55 664

原创 段权限检查,段保护机制

这节会从多个方面测试段会进行哪些权限检查,首先CPU可以在4个级别上运行ring 0,ring 1,ring 2,ring 3,运行的级别越低权限越高,我们常常挂在嘴边的内核,就是当CPU运行在Ring 0级别上运行的时候,CPU当前运行级别就是在执行当前指令的时候CS段寄存器或者或者SS段寄存器,可见16位的低2位值就是当前CPU处理哪个级别,也称为了CPL。CS寄存器存储的选择子任何时候和SS段寄存器存储的选择子低2为任何时候都是一样的,因为CPU运行在不同的级别,会使用不同的堆栈,...

2020-10-08 21:02:48 657

原创 段描述符详解

上一节讲啦段寄存器具有属性特征,本节会讲到段描述符和段选择子的上节讲了段寄存器有96位,其中只有16位是可见的(剩下的80位缓冲到CPU里面去了),这可见的16位就是段选择子其中这16位分为3部分0~1位:为RPL 称为请求特权级别,2个位就有4种权限 0 ,1,2,3 数字越大,权限越小反之第2位:TL 当TL=0的时候去GDT(全局描述符表中去加载段描述符) TL=1去LDT(局部描述符表,这个Windows没有使用)3~15: Index 索引这个值会作为下标去...

2020-10-07 23:08:41 7698 2

原创 指针指向字符串常量和给字符数组赋值字符串常量的本质

众所周知任何类型的指针在32位模式下大小都为4BYTE,很多人对数组和指针并不能很好的区分它们的区别,首先在C语言层面,数组名是一个常量不可修改,而指针可以随意指向,其次如果在a.cpp中定义了 char a[100]; 的全局变量在main.cpp中声明了一个 extern char*a ; 有些变成经验的人就能看出来 cha a[100] 开辟的空间是 100*int类型的大小而extern char* a告诉编译器 有一个 a类型是 char* 大小是4...

2020-10-06 09:57:46 1750

原创 保护模式验证段寄存器的属性

保护模式第一篇段寄存器,学习过8086汇编的同学应该知道段寄存器在8086种的重要程度,8086CPU的寄存器都是16位,8086CPU能够以16位的地址总线访问到1MB的内存地址,采用的就是段地址*16+偏移地址=物理地址的方式,以16位地址总线访问1MB的物理内存,8086时代访问的地址都是物理地址没有虚拟地址的概念,进程访问的都是物理地址,如果不小心改了系统数据这是非常的危险的,本人在保护模式下编写驱动都没少蓝过,实在不敢想象如果应用程序能直接访问操作系统,得让操作系统崩溃多少次,实...

2020-10-06 01:52:46 380

原创 网络基础

每个TCP套接字在被创建的时候内核都会给该套接字创建一个输入缓冲和一个输出缓存,不同的操作系统输入缓存和输出缓存的大小都是不同的,通过getsockopt函数可以获取输入输出缓存的大小,通过setsockopt函数也可以设置输入输出缓存的大小,但是有最大值和最小值,TCP首部中的窗口字段占16bit,切勿混淆,TCP的发送窗口和接受窗口与发送缓冲与接受缓冲有关系,发送窗口可以说是至于发送缓...

2019-12-06 14:17:52 129

原创 从内网访问Internet网站的过程

从内外访问外网的过程:首先我们的明白每个地方使用了那些协议,协议的功能是什么?了解了这些我们就能明白每一步需要做什么,首先我们输入进入一个网站需要输入网址,再互联网上通信我们都知道需要源IP地址和目地IP地址,而没说需要域名,每个域名就对应着一个IP地址,但是我们如何知道这个IP地址?如果不知道目地IP地址就无法通信。试想一个如果每个主机里保存一个DNS表,全世界有这么多域名,造成的...

2019-10-27 13:42:22 3121

原创 FindNextFile函数发送异常0x77716005 (ntdll.dll)处(位于 Project34.exe 中)引发的异常: 0xC0000005: 写入位置 0xCCCCCCEC 时发生访

0x77716005 (ntdll.dll)处(位于 Project34.exe 中)引发的异常: 0xC0000005: 写入位置 0xCCCCCCEC 时发生访问冲突。 如果使用FindNextFile函数报这样的异常 ,不用想使FindNextFile函数的第一个参数HANDLE 类型的句柄出了问题 如果是在遍历文件是就是FindFirstFile的返回值出了问题...

2019-09-11 22:45:19 4717

原创 8086的中断机制

8086在内存中00000H-003FFH这 1024个存储单元存放的是中断向量表,由256个表项被称为中断向量,所谓中断向量就是中断处理程序的入口地址,每个中断向量占4个字节,这是由原因的,8086的寄存器段地址和偏移地址都是16位的所有中断处理程序的入口地址需要4个字节存放。 中断向量表不是说真的就是一张表,它只是内存的一段区域,并且只存放中断处理程序的入口地址。提到了中断还...

2019-09-10 17:11:32 2587

原创 Win32菜单

上一章我们将了Win32里面的一些最常用的重要消息,本章讲述的是菜单很多学到这里的人肯定都知道了菜单有什么用,每一个菜单项可能都由一个功能,我们在开发软件时,肯定得在一个窗体中添加一些菜单和按钮并加上标题,用户才知道时干什么的,而且我们在每一个菜单项里如果要让它在用户的操作时,我们就得在回调函数里加上对应消息处理菜单又分为三类 系统菜单 ,顶层菜单,弹出式菜单注意(菜单时不具备功能 ...

2019-09-06 22:59:08 256

原创 消息机制之重要消息

上一节我们讲了Windows是由事件驱动的,任何事件都会被封装成消息,并保存在系统创建的MSG结构里typddef struct tagMSG{HWND hWnd; 窗口句柄UINT Message; 消息的idWPARAM wParam; 消息的附加信息LPARAM lParam; 消息的附加信息DWORD time...

2019-08-29 23:17:54 122

原创 8086CPU段地址*16+偏移地址的寻址方式

8086CPU的设计者设计之初地址总线有20根,支持的寻址范围应当是1M,但是8086寄存器都是16位的8086CPU可以说是16位的,寻址范围64K,设计者为了更合理的使用地址总线的,采用段地址16+偏移地址=物理地址的思想,引进了 四个段寄存器 CS,SS,ES,DS和四个偏移地址寄存器 BX,BP,SI,DI 都是16位寄存器用一个16位寄存器是无法让寻址范围到达1M的,引入了 段寄...

2019-08-04 21:46:53 2019

原创 统计字符串中单词数

统计字符串中单词数,我们先限定这里我们对单词的定义, 一段包含字母或数字或其他符号的序列,可以是一个 。 知道了单词的定义接下来,我们需要找到关键,什么条件必定存在单词? 1:空格前一个字符非空格 :可以构成单词 2:空格后一个字符非空格 :肯定存在一个单词 3:从单词序列着手单词序列不为空格切长度大于1 :存在单词这三种条件从每一种着可以写出一种...

2019-07-23 11:57:37 945

原创 二分查找的递归和非递归

二分查找是一种要求数组元素在又序情况下的一种查找算法,平均时间复杂为log(n) 因为数据元素都是有序的,每次比较都可以排除一半的元素 用递归和非递归都可以很好的实现,其实这里的递归和非递归没什么区别 ...

2019-07-15 14:25:39 206

原创 内存分区

内存对于很多人来说都会有一中,感觉很抽象有种很虚拟的感觉,内存是实体,是由很多内存条构成,我们知道有每8个晶体管称为一个存储单元(一个字节),内存也划分了很多分区,而存储在不同区域的变量有不同的特性,如存储在栈中的我们必须给初始化在程序中我们应该看到的不是变量,而是内存,变量名只是一个标识符,我们通过它操作内存每一个变量都是有一个地址,在内存中占据一段内存,而变量名是这段内存的(标识),我们...

2019-06-27 16:08:07 269

原创 值传递与地址传递的理解

相信很多c语言的初学者在刚刚面对指针时的窘迫,确实指针是c语言的精华,从开始时强记指针就是地址,到现在的,我认为如果计算机中的数据看作均看作对象,指针就用来指引着这些对象,通过指针可以用来对这些对象进行修改。值传递和地址传递是一个非常容易犯错的地方,给大家带来一个#include<stdio.h>int fun(int a,int *b){a=100;*b=200;prin...

2019-06-26 02:39:35 541

原创 结构体变量和结构体指针的区别,

学了结构体很久了,以为自己能够很熟练了,今天发现自己今天成员运算符 (.) 和指向运算符(->) 之间竟然犹豫了其实成员运算符是结构体变量访问成员是用的。而指向运算符则是结构体指针访问成员时使用的,因为一直都是再用结构体指针,突然用结构体变量,使用了指向运算符,看了半天才看出来,当然结构体指针也可以使用成员运算符但需要先取值,但一般没人这么用,我一直是这样认为 你对基础的掌握程度,决定...

2019-06-23 13:11:44 12546 2

原创 数字矩阵

数字矩阵 输出N*N的数字旋转方阵 首先我们先定义一个二位数组 int a [N][N];我们很明显的能够看出规律,最外层 依次从1~20 第二层依次从21 ~32 第三层从 33 ~ 到36,如何程序描述这个呢?首先我们把问题拆分一下先实现最外层 ,,每一层都有四个条边组成,而且相邻两个边(导致有一个点重合)所以我,我们让第一层每 每条边赋值N-1个点 最外层实际有...

2019-06-22 14:05:37 3890

原创 完全数 c语言实现

完全数是指 如 6=1+2+3 28=1+2+4+7+14 这样的该数的各个因数(不包含本身的)之和刚好等于本身的数 ,为完全数所以在程序设计是我们得首先想到的是肯定要求解出一个数的所有因数 并判断是否等于本身,就解决了,是不是感觉很简单?把你的问题写下来,问题就解决了一半,如何求解该数的因数,求因数,首先得有因数把?所以判断因数取余就可以了我们用算法语言描述一下上述这个过程...

2019-06-22 13:12:34 7649

原创 斐波那契数列 迭代递归

斐波那契数列是一串 1 1 2 3 5 8 …F(n)= F(n-1)+F(n-2) (n>2) F(n)=1;(n=1||n=2)我们就简单的讨论一下的斐波那契数列 ,在初学者这里 递归可能比较难以理解这里我们用三种 方法 带大家 了解一下1:递归 当然递归的本质其实也是一循环 ,递归也都是在栈中也实现的,栈具有先进后出的如果想要真正的了解递归是必须...

2019-06-21 19:51:48 608

原创 C语言验证歌德巴赫猜想再20000内成立

歌德巴赫猜想是世界三大难题之一,知道现在还是无解,世界三大难题都是类似这种看是平淡,实际蕴含的奥义无比的深刻歌德巴赫猜想 任何不小于四的偶数都可以分解成二个质数之和我们运用一种叫厄拉多塞法 赛选出n以内的素数 从4开始依次找到所有小于n的偶数 对于每一个偶数 证明都有两个质数小于它对于每一个偶数我们找出它所有质数,比较即可,穷举法的思维吧,如果n的值过大 可再堆里开辟内存...

2019-06-14 19:45:37 478

原创 1 11 21 1211 111221 312211 序列 c语言实现

111211211111221312211实现这个序列 我们不难发现规律, 但是肯定有的同志不知道如何着手,跟着我的思路带大家一起来看一下。这个序列具有规律 ,我们得从初值着手 将初值保存再字符数组里算法着东西还是只可意会不可言传 希望可以给大家带来帮助#include<stdio.h>int main(){int n;scanf("%d",&am...

2019-06-14 18:41:07 1823

原创 查找字符串中每个单词的个数出现的次数

查找字符串中每个单词的个数出现的次数 看到题目的第一感觉给人时比较复杂涉及到的子算法比较多 ,写这个算法的木的是给大家看看 我们现在学到算法可能就是以后一些复杂功能的一小部分我们先把这个算法的大概了解一下1:我们首先统计出 该字符串单词的个数2:统计了单词的个数 保存再链表里(每个节点保存一个单词)3:再删除重复的单词 在计数 就可以得出每个单词出现的次数 然...

2019-06-07 15:33:28 3732 1

原创 链表删除重复元素

链表删除重复元素 删除重复的元素我们可以知道头节点是不会改变的我们需要 链表每一个位置的元素和后面所有元素相比较 若相等则删除后面的元素 链表删除元素需要找到删除节点的前一个节点 所以我们会加一个变量s记录要删除节点的前一个节点 希望可以让读者学到更多void deleList(List p,int val){//删除链表的重复元素List r=p;whi...

2019-06-07 14:33:07 509 1

原创 链表删除指定元素算法

链表删除指定元素算法我们只需要分情况理清楚就很简单在算法分析的时候记清楚自己的思路是最重要的只要链表里有一个元素与给定的元素不相同 第一次与给定元素不相同的节点就为头节点1:改变头节点2:不改变头节点List deleList(List p,int val){List r=p;List head=NULL;while(r ){-------if(r->data==val...

2019-06-07 14:23:22 1952

原创 页面调度算法

我操作系统是如此伟大 令人敬佩的 在这里就不讲理论就只讲如何实现算法OPT 最佳置换算法最佳置换算法 是一理论上的算法 ,不可能是实现 选择淘汰的页面是后面长时间不在被访问的页面,或永久不使用的页面:该算法一般作为模板 评价其他算法的效率先进先去的页面置换算法(FIFO)该算法要求(在块装满时)我们首先淘汰 最先进来入内存的页面需要注意几个点 1:每一个进来的页面 ...

2019-05-31 14:26:52 3082

原创 快速排序的原理

快速排序是一种非常高效的排序算法,可以说比归并排序还有优秀点,快速排序的优点是在原地进行的,时间复杂度为O(nlog n)快速排序的是将要排序的部分成两部分比如我们找一个元素核心的代码为int swap(int a[],int s,int t){int i=s,j=t;while(i<j){while(i<j&&a[i]<=a[j]) j–;if(...

2019-05-26 21:19:07 406

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除