API函数的调用过程
API函数的调用过程(ring3)
Windows API
Application Programing Interface (应用程序接口) 简称API函数
Windows 有多少个API?
主要是存放在C:\WINDOWS\system32下面所有的dll几个重要的dll
Kernel32.dll:最核心的功能模块,比如管理内存,进程和线程相关的函数等.
User32.dll:是Windows用户界面相关的应用程序接口,如创建窗口和发送消息等.
GDI32.dll全称是Graphical Device Interface(图形设备接口),包含用于画图和显示
Ntdll.dll:大多数API都会通过这个dll进入内核(0环)
绝大部分核心功能是在0环实现的,3环只是使用了0环提供给他的一个接口.
Kernel32.dll ->ReadProcessMemory
在C:\WINDOWS\system32\目录下找到kernel32.dll模块,放到IDA中 查看ReadProcessMemory的代码
我们看到在用户层的核心功能模块中的ReadProcessMemory函数再将参数压栈后,又调用了另一个模块的函数NtReadVirtualMemory
ReadProcessMemory:
ring3所做的事情:
接下来看看NtReadVirtualMemory函数 (ring 0)所做的事情
这时候再打开另一个ntdll.dll模块 查看其中的NtReadVirtualMemory函数:
这个函数传进去一个调用号,以及一个地址,再去call这个地址中的值,这个值就是存在于内核的一个函数.
//这个函数的功能: 提供编号
找到函数
通过函数进入ring 0也就是说ntdll也只是做了个引荐人的功能,引荐进ring 0
真正对内存读写是在ring 0实现的
那就再继续跟跟看7FFE0300处的值是什么?
7c92e4f0
再继续跟7c92e4f0:
这就跟到了sysenter 汇编指令:
该汇编指令的作用是?:
通过寄存器,切换EIP,ESP
1.将IA32_SYSENTER_CS 和IA32_SYSENTER_EIP分别装到cs和eip寄存器中2.将IA32_SYSENTER_CS+8 和IA32_SYSENTER_ESP 分别装载到ss和esp寄存器中,切换特权级0;
之后程序在ring 0环境下跳转到指定eip去执行,执行结束后使用sysexit 汇编指令返回,这条指令功能与sysenter相反:
1.将IA32_SYSENTER_CS+16装载到cs寄存器,将edx寄存器中的指令的指针装载到eip;2.将IA32_SYSENTER_CS+24装载到ss寄存器中;3.cx寄存器中的指针装载到esp中,切换到特权3IA32_SYSENTER_CS之类的属于MSR寄存器
KiFastSystemCall,KiIntSystemCall
操作系统会检测CPU支不支持快速调用,如果支持,就会调用KiFastSystemCall 进ring 0,如果CPU比较老旧不支持快速调用 就会调用 KiIntSystemCall去进入ring 0
在ntdll.dll模块中找到该函数
发现他的本质其实还是调用了int 2e 号中断进入的ring 0
我们现在尝试在ntoskrnl.exe模块中查看一下int 2e是怎么进ring 0的?
SEP位
那CPU到底是怎么验证支不支持KiFastSystemCall的呢?
CPUID 指令
//该指令需要传入一个参数
//当eax = 1 来执行cpuid指令时,处理器的特征信息被放在ecx,和edx寄存器中,其中edx包含了一个SEP位(11位),该位指明了当前处理器是否支持
当SEP位 == 1 时,说明是支持的
1 1 1 1 1 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
15 11 0
这两种的区别
KiIntSystemCall:
这个主要是使用INT 2E 中断门去做,中断门中CS,EIP都已经在IDT表中存储好了,SS与ESP需要TSS提供,所以使用一次int 2e 会读取IDT中的CS,和查找TSS
KiFastSystemCall:
sysenter : 系统会提前将CS/SS/ESP/EIP的值存储在MSR寄存器中,sysenter指令执行时,会将MSR寄存器值直接写入相关寄存器,直接就是寄存器的读,没有读内存的过程,这是快速调用的本质。
_KUSER_SHARED_DATA
这个结构体是在User层和Kernel层分别定义了一个_KUSER_SHARED_DATA结构体 用于User和Kernel层共享某些数据
他们使用固定的地址值映射,_KUSER_SHARED_DATA结构区域在User和Kernel层地址分别为:
User 层地址为:0x7ffe0000
Kernel层地址为:0xffdf0000
注意:虽然指向同一个物理页,但在User层是只读的,在Kernel层是可读写的
回到上面的内容:
也就是说,call这个地址里的内容,我们并不能武断的就说这里面一定是什么,CPU新旧不同,可能会导致调用的函数是不同的.有可能是KiFastSystemCall,也有可能是KiIntSystemCall
附件:
MSR | 地址 |
---|---|
IA32_SYSENTER_CS | 174H |
IA32_SYSENTER_ESP | 175H |
IA32_SYSENTER_EIP | 176H |
SS = CS + 8
可以通过RDMSR/WRMST 来进行读写(操作系统使用WRMST写该寄存器)
内核模块:
ntoskrnl.exe(CPU以10-10-12分页模式启动)
ntkrnlpa.exe(CPU以2-9-9-12分页模式启动)
API函数的调用过程相关推荐
- 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程
标 题: [原创]使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程. 作 者: shayi 时 间: 2015-02-12,05:19:54 链 ...
- 案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程。 首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下:
案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程. 首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下: 1 ...
- 代码 or 指令,浅析ARM架构下的函数的调用过程
摘要:linux程序运行的状态以及如何推导调用栈. 1.背景知识 1.ARM64寄存器介绍: 2.STP指令详解(ARMV8手册): 我们先看一下指令格式(64bit),以及指令对于寄存机执行结果的影 ...
- C#中对 API函数的调用
C#中对 API函数的调用 1 C#中对 API函数的调用 2 3 4 using System ...
- JAVA学习第五篇--java中对象的创建过程以及函数的调用过程
下面本文将详细介绍java语言中对象的创建过程,以及函数的调用过程. class Person{public String name="zhao";public int ege;p ...
- VB中API函数的调用
1.API函数 API的英文全称(Application Programming Interface),WIN32 API也就是MicrosoftWindows32位平台的应用程序编程接口 ...
- Linux的open函数的调用过程,Linux 中open系统调用实现原理
用户空间的函数在内核里面的入口函数是sys_open 通过grep open /usr/include/asm/unistd_64.h查找到的 #define __NR_open2 __SYSCALL ...
- ebp 函数堆栈esp_函数堆栈调用过程
从内存的角度详细的分析C语言中的函数调用过程: 首先写一个测试用的代码: #include int add(int x, int y) { int z = 0; z = x + y; return z ...
- c语言 中断 局部变量 not allocated,C语言(函数)调用过程(略译)
C语言(函数)调用过程 Introduction A calling sequence is the conventional sequence of instructions that call a ...
- VS2010中VB.NET中API函数的调用
API有两种调用方式: 第一种使用declare的API调用, Declare Function publicname Lib "libname" [Alias "ali ...
最新文章
- Linux安装无法运行install,Linux新手安装Debian-8.2.0可能遇到的问题
- Vue的自定义滚动,我用el-scrollbar
- Linux C编程--string.h函数解析
- 根据关键字检索相关视频
- SQL PL/SQL SQL*PLUS三者的区别
- 微信小程序自定义组件,提示组件
- 2013年上半年全国高等学校(安徽考区)计算机水平考试试卷,2013年上半年全国高等学校(安徽考区)计算机水平考试试卷...
- linux path环境变量起什么作用,shell基础(5)PATH环境变量的作用和使用方法
- 微软sharepoint团队博客
- POJ NOI MATH-7826 分苹果
- 在向服务器发送请求时发生传输级错误。 (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接。)...
- 华为eNSP下载阿里云盘
- 【Python游戏】Python实现一个推箱子小游戏 | 附带源码
- 程序员集体意识大爆发:996背后的深问题
- 盘点!物流移动机器人的几种定位技术
- 设计一个O(n2)时间的算法, 找出由n个数组成的序列的最长单调递增子序列。
- 限时免费领取育碧75元游戏《纪元Anno1404:历史版》
- 数据库SQLite之嵌入式Linux实际网关项目使用初步
- 小镇故事介绍 这个世界很喧哗,有的时候只需要一个人静一静
- 《实用C++》第8课:赋值运算符和赋值表达式
热门文章
- 算法笔记(胡凡)刷题笔记目录
- 倍福--ModbusTCP配置
- android fragment 设置透明,DialogFragment背景透明设置
- 一级造价工程师(安装)- 计量笔记
- 欧华android导航刷机,寻找欧华DVD导航一体机刷机文件。
- Datasqueeze v2.0.7
- python爬虫 导出/乱码/中英文夹杂问题解决
- 小米小钢炮等常用蓝牙设备(音箱/键盘/打印机)连接电脑(Windows/Linux)使用笔记
- 罗技鼠标G304驱动与讲解(其余类型驱动见文末)
- 航空订票系统C++课程设计