《windows核心编程》第3章 内核对象

news2024/11/17 21:27:59

一、内核对象简介

1.1 内核对象有哪些

令牌对象 token、事件对象 Event、文件对象 File、文件映射对象 Mapping_File、线程对象 Thread、时钟对象 Timer、线程池对象 ThreadPool、I/O完成端口对象 Completion port、工作对象 job、邮槽对象 mailslot、互斥对象 Mutex、管道对象 pipe、进程对象 process、信号灯对象 semaphore

1.2 内核对象简介

每个进程创建的内核对象是一个索引,通过这个索引会在每个进程的内核对象表中找到这个内核对象的内存块,同一个内核对象在不同进程中的句柄是不一样的

内核对象用一个句柄来标识。

内核对象的内存块位于操作系统的内核空间,应用程序不能直接操作内核对象,需要系统给定的函数来操作

内核对象的结构:公用部分(安全描述符、计数)和个性部分

1.3 内核对象计数的作用

如果一个内核对象能被多个进程共用。每当一个进程使用这个内核对象的时候,内核对象计数值就加1;每当有一个进程不使用这个内核对象的时候,内核对象计数值就减1。当计数值为0的时候,系统会释放这个内核对象资源

1.4 区分内核对象和用户对象

区分应用层对象和内核对象是看创建对象的函数,如果创建对象的函数有安全描述符,那么这个函数创建的对象就是内核对象

内核对象:

HANDLE CreateFileMapping(
    HANDLE hFile,                       //物理文件句柄
    LPSECURITY_ATTRIBUTES lpAttributes, //安全设置
    DWORD flProtect,                    //保护设置
    DWORD dwMaximumSizeHigh,            //高位文件大小
    DWORD dwMaximumSizeLow,             //低位文件大小
    LPCTSTR lpName                      //共享内存名称
);

应用层对象:

BOOL CreateBitmap(
    int nWidth,          // 指定位图的宽度(以像素为单位)
    int nHeight,         // 指定位图的高度(以像素为单位)
    UINT nPlanes,        // 指定位图中的颜色平面的数量
    UINT nBitcount,      // 指定每个显示像素的颜色位的数量
    const void* lpBits   // 指向包含的出师未土值的字节的数组。如果为NULL,则不初始化新图
);

1.5 继承选项的含义

创建进程内核

BOOL CreateProcess(  
 LPCTSTR lpApplicationName,                 // 应用程序名称  
 LPTSTR lpCommandLine,                      // 命令行字符串  
 LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程的安全属性  
 LPSECURITY_ATTRIBUTES lpThreadAttributes,  // 线程的安全属性  
 BOOL bInheritHandles,                      // 是否继承父进程的属性  
 DWORD dwCreationFlags,                     // 创建标志  
 LPVOID lpEnvironment,                      // 指向新的环境块的指针  
 LPCTSTR lpCurrentDirectory,                // 指向当前目录名的指针  
 LPSTARTUPINFO lpStartupInfo,               // 传递给新进程的信息  
 LPPROCESS_INFORMATION lpProcessInformation // 新进程返回的信息  
);

如果上面创建进程内核函数中的继承选项传入了TRUE,父进程在创建子进程的时候会把内核对象继承给他。也就是子进程也有父进程的内核对象

二、内核对象操作

2.1 关闭内核对象

CloseHandle(HANDLE);

2.2 内核对象信息获取与修改

1、修改内核对象信息

BOOL SetHandleInformation(
  [in] HANDLE hObject,
  [in] DWORD  dwMask,
  [in] DWORD  dwFlags
);

[in] dwMask

一个掩码,指定要更改的位标志。 使用 dwFlags 说明中显示的相同常量。

[in] dwFlags

指定对象句柄的属性的位标志集。 此参数可以是 0 或以下一个或多个值。

含义

HANDLE_FLAG_INHERIT

0x00000001

如果设置了此标志,则使用 CreateProcess 设置为 TRUE 的 bInheritHandles 参数创建的子进程将继承对象句柄。

HANDLE_FLAG_PROTECT_FROM_CLOSE

0x00000002

如果设置了此标志,则调用 CloseHandle 函数不会关闭对象句柄。

2、获取内核信息

BOOL GetHandleInformation(
  [in]  HANDLE  hObject,
  [out] LPDWORD lpdwFlags
);

函数的使用

GetHandleInformation(handle, &dw);

if (dw & HANDLE_FLAG_INHERIT)
{
        该对象可以被继承
​​​​​​​}

三、防止多开的程序

3.1 命名内核对象

命名内核对象主要是为了进程间共享内核对象。创建内核对象的函数中,如果有pszName参数,说明这个内核对象可以被命名,也就是可以创建命名内核对象。命名内核对象可以在不同进程中使用

3.2 用互斥的内核对象实现防止多开程序

#include <Windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <Windows.h>
#include <tchar.h>

int _tmain()
{
	HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("huan"));	
												// 创建了一个名字叫huan的互斥内核对象
	if (GetLastError() == ERROR_ALREADY_EXISTS)
	{
		_tprintf(TEXT("Can't open this program.\n"));
		_gettchar();
		return 0;
	}
	DWORD sessionid = 0;
	ProcessIdToSessionId(GetProcessId(NULL), &sessionid);

	_tprintf(TEXT("%s,\n"), TEXT("this is the first instance! and session id is"));

	_gettchar();

	return 0;
}

3.3 破解防止软件多开

方法1:反汇编,修改判定 if (GetLastError() == ERROR_ALREADY_EXISTS) 这个判定条件,让这个条件不成立

方法2:使用Process explorer(进程资源管理器)删除内核

官方下载链接:进程资源管理器 - Sysinternals | Microsoft Learn

1、以管理员权限打开软件

2、显示进程内核对象

3、关闭内核对象句柄

注意:我们编写的软件可以轻松列举其他进程用到的所有内核对象,但是想要实现杀死内核对象很困难,首先要注入到所有用到内核对象的程序,然后关闭内核对象,最终杀死内核对象。而微软内部员工有源码,所以编写上面的程序相比比较轻松

四、session会话

4.1 简介

windows还没人登录的时候就会创建一个session0会话,windows服务程序在session0中。每当有一个用户登录就会创建一个session

4.2 查看当前程序运行在哪个session中

获取当前进程句柄,根据句柄获取当前进程id,根据id获取程序运行在哪个会话中,获取成功返回非0

#include <Windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <Windows.h>
#include <tchar.h>

int _tmain()
{
	HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("huan"));	// 创建了一个名字叫huan的互斥内核对象
	if (GetLastError() == ERROR_ALREADY_EXISTS)
	{
		_tprintf(TEXT("Can't open this program.\n"));
		_gettchar();
		return 0;
	}

	DWORD sessionid = 0;
	DWORD processid = 0;

	processid = GetProcessId(GetCurrentProcess());
	ProcessIdToSessionId(processid, &sessionid);	
	if (ProcessIdToSessionId(processid, &sessionid)) // 获取当前程序运行在哪个session会话中
		_tprintf(TEXT("%s, %d\n"), TEXT("this is the first instance! and session id is"), sessionid);

	_gettchar();

	return 0;
}

4.2 会话和命名空间

第1部分 全局命名空间

一个远程桌面的服务可以为自己的命名内核对象设置多个命名空间,这些内核对象包括:event、sernaphores、waitable timers、file-mapping、job object。在client/server类型的应用程序中,服务都有一个全局命名空间global namespace。除此之外,每个客户会话都可以有自己单独的命名空间,来防止自己独有的内核对象。

独立的客户会话命名空间能够让多个客户运行同一个应用程序而不互相干扰。在一个话中使用使用会话名称作为内核对象的缺省命名空间, 另外,进程还可以使用全局命名空间,使用的方法是在内核对象的名字前,加上"Global\" 前缀

通俗说就是程序命名前面不加global前缀,其他的会话就访问不到你会话中的内核对象,全局命名空间内核对象创建方法如下:

CreateEvent(NULL, FALSE, FALSE, "Global\\CSAPP");

第2部分 本地命名空间

如果要在本会话下创建一个命名对象,可以内核对象前加上“Local\”前缀,注意关键字是大小写敏感的。"Session\"前缀被系统保留,不要使用这个前缀来创建命名内核对象

第3部分 私有命名空间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1121209.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hook原理--逆向开发

今天我们将继续讲解逆向开发工程另一个重要内容--Hook原理讲解。Hook&#xff0c;可以中文译为“挂钩”或者“钩子”&#xff0c;逆向开发中改变程序运行的一种技术。按照如下过程进行讲解 Hook概述Hook技术方式fishhook原理及实例符号表查看函数名称总结 一、Hook概述 在逆…

LeetCode刷题---有效的括号

这里用到了栈的思想 栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说&#xff0c;表尾端称为栈顶&#xff08;top&#xff09;&#xff0c;表头端称为栈低&#xff08;bottom&#xff09;。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除&#xff0c…

生成包含10个随机字母或数字的字符串,然后统计每个字符的出现次数

from random import choices from string import ascii_letters, digitsx .join(choices(ascii_lettersdigits, k10)) d dict() # 创建空字典 for ch in x:d[ch] d.get(ch, 0) 1 # x中有ch字符,个数1,并作为字典的值 print(x) print(d)也可以使用collections模块的defaul…

从车窗升降一探 Android 车机的重要 API:车辆属性 CarProperty

前言 前面我们介绍过 Android 车机 Automotive OS 的几块重要内容&#xff1a; 一文了解 Android 车机如何处理中控的旋钮输入从实体按键看 Android 车机的自定义事件机制深度入门 Android 车机核心 CarService 的构成和链路 本篇文章我们聚焦 Android 车机上最重要、最常用…

LeetCode--180 连续出现的数字

文章目录 1 题目描述2 结果示例3 解题思路3.1 MySQL 代码 4 知识拓展 1 题目描述 Logs表: ---------------------- | Column Name | Type | ---------------------- | id | int | | num | varchar | ----------------------在 SQL 中&#xff0c;id …

Mybatis的SqlRunner执行流程

Mybatis的SqlRunner执行流程 SqlRunner exec new SqlRunner(connection); Map<String, Object> row exec.selectOne("SELECT * FROM PRODUCT WHERE PRODUCTID ?", "FI-SW-01");connection.close();assertEquals("FI-SW-01", row.ge…

YOLOv5算法改进(19)— 手把手教你去更换NMS(DIoU-NMS/CIoU-NMS/EIoU-NMS/GIoU-NMS/SIoU-NMS)

前言:Hello大家好,我是小哥谈。YOLOv5中的NMS指非极大值抑制(Non-Maximum Suppression),它是一种用于目标检测算法中的后处理技术。在检测到多个重叠的边界框时,NMS可以帮助选择最佳的边界框。NMS的工作原理是首先根据预测边界框的置信度对它们进行排序,然后从置信度最高…

iOS逆向工程之Theos

如果你对iOS逆向工程有所了解&#xff0c;那么你对Tweak并不陌生。那么由Tweak我们又会引出Theos, 那么什么是Theos呢&#xff0c;简单一句话&#xff0c;Theos是一个越狱开发工具包&#xff0c;Theos是越狱开发工具的首先&#xff0c;因为其最大的特点就是简单。大道至简&…

python中多行注释与取消注释

在小白学习python编程的过程中&#xff0c;我们经常会发现很多同学们喜欢问的一个问题&#xff1a; 怎么多行注释呢&#xff1f; 怎么取消多行注释呢&#xff1f; 以上种种问题我相信来到这里都会得到相应答案 那我们接下来开始吧&#xff01; 文章目录 单行注释多行注释取消多…

c初阶检测题

选择题 1.局部变量的作用域是&#xff1a;&#xff08;D&#xff09; A.main函数内部 B.整个程序 C.main函数之前 D.局部变量所在的局部范围 2.字符串的结束标志是&#xff1a;&#xff08;A&#xff09; 作业内容 A.是’0’ B.是EOF C. 是’\0’ D.是空格 3.下面那个不是…

精选六个大学生可以做的兼职副业,学习赚钱两不误

在当今的社会中&#xff0c;大学生们面临着学业压力和生活开销。为了减轻家庭的负担&#xff0c;同时也为了更好地拓宽自己的视野和实践能力&#xff0c;许多大学生开始寻找一种既可以学习又能赚钱的副业。这样的选择&#xff0c;不仅可以弥补金钱上的不足&#xff0c;还可以提…

【java计算机毕设】博客管理系统 javaweb springboot vue mysql

目录 1.项目功能截图​ 2.项目简介 3.源码下载地址 1.项目功能截图 2.项目简介 博客管理系统 idea mysql5.7/8 vue html jdk1.8 系统功能&#xff1a; 前台功能&#xff1a;文章信息&#xff0c;相册信息&#xff0c;留言板&#xff0c;个人中心&#xff0c;后台管理 后…

闭包(函数)

把内部函数通过return扔出去 必要条件

靶机 DC-2

DC_2 信息搜集 存活检测 详细扫描 添加 host 后台网页扫描 网页信息搜集 主页面 找到 flag1&#xff0c;提示使用 cewl 密码生成工具 wp 登陆界面 使用 wpscan 扫描用户 wpscan --url http://dc-2/ --enumerate u 扫描出用户 tom、jerry、admin 将三个用户名写入文件中…

一文解密网络背后的秘密

一文解密网络背后的秘密 网络的发展史从键入网址到网页进行显示期间法上了什么&#xff1f;首先我们需要了解一下URLDNS解析建立连接什么是三次握手&#xff0c;可不可以两次呢&#xff1f; 本地发送请求&#xff0c;服务器处理请求断开连接 实践一下 相信大家对网络都不陌生了…

《认知觉醒:开启自我改变的原动力》

目录 第一章 大脑 — 一切问题的起源 第二章 潜意识 — 生命留给我们的彩蛋 第三章 元认知 — 人类的终极能能力 第四章 专注力——情绪和智慧的交叉地带 第五章 学习力——学习不是一味地努力 第六章 行动力 — 没有行动世界只是个概念 第七章 情绪力 — 情绪是多角度看…

【JavaScript】深入讲解浏览器渲染原理

一. 浏览器是如何渲染页面的&#xff1f; 当浏览器的网络线程收到 HTML 文档后&#xff0c;会产生一个渲染任务&#xff0c;并将其传递给渲染主线程的消息队列。 在事件循环机制的作用下&#xff0c;渲染主线程取出消息队列中的渲染任务&#xff0c;开启渲染流程。 渲染&…

Python数据分析实战-使用numpy.where方法基于条件替换某列的值(附源码和实现效果)

实现功能 在Pandas中&#xff0c;replace方法默认是基于精确匹配进行替换&#xff0c;而不是基于条件匹配。要实现基于条件的替换&#xff0c;可以使用numpy.where函数。将DataFrame中某一列的指定的两个值分别替换为0和1&#xff0c;其他值替换为2 实现代码 import pandas …

【tg】3:线程模型:4个主要线程

media :调用主线程worker therad 、network thread 是webrtc要求的module thread 也是webrtc的moudle需要的代码分布 G:\CDN\P2P-DEV\tdesktop-offical\Telegram\ThirdParty\tgcalls\tgcalls\StaticThreads.hgetThreads 触发创建线程 分别获取,看起来是分别只有1个的 Threads…

不愧是疑问解决神器(二)!你强任你强

不愧是疑问解决神器(二)&#xff01;你强任你强&#x1f44d;&#x1f44d;&#x1f44d; 第3章 代码的坏味道 1.神秘命令(Mysterious Name)? 整洁代码中最重要的一环就是有一个好名字&#xff0c;使他们能够清晰地表明自己的功能和用法。但正因为如此&#xff0c;命名就成了…