API函数的调用过程(ring3)

Windows API

  1. Application Programing Interface (应用程序接口) 简称API函数

  2. Windows 有多少个API?
    主要是存放在C:\WINDOWS\system32下面所有的dll

  3. 几个重要的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

  1. 这个结构体是在User层和Kernel层分别定义了一个_KUSER_SHARED_DATA结构体 用于User和Kernel层共享某些数据

  2. 他们使用固定的地址值映射,_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函数的调用过程相关推荐

  1. 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程

    标 题: [原创]使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程. 作 者: shayi 时 间: 2015-02-12,05:19:54 链 ...

  2. 案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程。 首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下:

    案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程. 首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下: 1 ...

  3. 代码 or 指令,浅析ARM架构下的函数的调用过程

    摘要:linux程序运行的状态以及如何推导调用栈. 1.背景知识 1.ARM64寄存器介绍: 2.STP指令详解(ARMV8手册): 我们先看一下指令格式(64bit),以及指令对于寄存机执行结果的影 ...

  4. C#中对 API函数的调用

    C#中对 API函数的调用  1                                              C#中对 API函数的调用  2  3  4    using System ...

  5. JAVA学习第五篇--java中对象的创建过程以及函数的调用过程

    下面本文将详细介绍java语言中对象的创建过程,以及函数的调用过程. class Person{public String name="zhao";public int ege;p ...

  6. VB中API函数的调用

    1.API函数       API的英文全称(Application Programming Interface),WIN32 API也就是MicrosoftWindows32位平台的应用程序编程接口 ...

  7. Linux的open函数的调用过程,Linux 中open系统调用实现原理

    用户空间的函数在内核里面的入口函数是sys_open 通过grep open /usr/include/asm/unistd_64.h查找到的 #define __NR_open2 __SYSCALL ...

  8. ebp 函数堆栈esp_函数堆栈调用过程

    从内存的角度详细的分析C语言中的函数调用过程: 首先写一个测试用的代码: #include int add(int x, int y) { int z = 0; z = x + y; return z ...

  9. c语言 中断 局部变量 not allocated,C语言(函数)调用过程(略译)

    C语言(函数)调用过程 Introduction A calling sequence is the conventional sequence of instructions that call a ...

  10. VS2010中VB.NET中API函数的调用

    API有两种调用方式: 第一种使用declare的API调用, Declare Function publicname Lib "libname" [Alias "ali ...

最新文章

  1. Linux安装无法运行install,Linux新手安装Debian-8.2.0可能遇到的问题
  2. Vue的自定义滚动,我用el-scrollbar
  3. Linux C编程--string.h函数解析
  4. 根据关键字检索相关视频
  5. SQL   PL/SQL   SQL*PLUS三者的区别
  6. 微信小程序自定义组件,提示组件
  7. 2013年上半年全国高等学校(安徽考区)计算机水平考试试卷,2013年上半年全国高等学校(安徽考区)计算机水平考试试卷...
  8. linux path环境变量起什么作用,shell基础(5)PATH环境变量的作用和使用方法
  9. 微软sharepoint团队博客
  10. POJ NOI MATH-7826 分苹果
  11. 在向服务器发送请求时发生传输级错误。 (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接。)...
  12. 华为eNSP下载阿里云盘
  13. 【Python游戏】Python实现一个推箱子小游戏 | 附带源码
  14. 程序员集体意识大爆发:996背后的深问题
  15. 盘点!物流移动机器人的几种定位技术
  16. 设计一个O(n2)时间的算法, 找出由n个数组成的序列的最长单调递增子序列。
  17. 限时免费领取育碧75元游戏《纪元Anno1404:历史版》
  18. 数据库SQLite之嵌入式Linux实际网关项目使用初步
  19. 小镇故事介绍 这个世界很喧哗,有的时候只需要一个人静一静
  20. 《实用C++》第8课:赋值运算符和赋值表达式

热门文章

  1. 算法笔记(胡凡)刷题笔记目录
  2. 倍福--ModbusTCP配置
  3. android fragment 设置透明,DialogFragment背景透明设置
  4. 一级造价工程师(安装)- 计量笔记
  5. 欧华android导航刷机,寻找欧华DVD导航一体机刷机文件。
  6. Datasqueeze v2.0.7
  7. python爬虫 导出/乱码/中英文夹杂问题解决
  8. 小米小钢炮等常用蓝牙设备(音箱/键盘/打印机)连接电脑(Windows/Linux)使用笔记
  9. 罗技鼠标G304驱动与讲解(其余类型驱动见文末)
  10. 航空订票系统C++课程设计