《Windows内核编程》の基本汇编指令

【Claude Code】Claude Code 使用指南 本文介绍了AI编码助手Claude的基础和进阶操作指南。基础部分涵盖启动命令、模式切换(自动编辑/Plan/Yolo模式)、资源监控等核心功能,重点讲解了斜杠命令的使用方法。进阶操作详细说明了CLAUDE.md文件的创建与管理,包括项目规范、代码风格等内容的配置,以及如何通过该文件建立持久上下文。同时提醒了使用过程中的安全风险,建议通过配置文件限制AI对关键代码的访问权限。全文提供了完整的操作指引和安全建议,帮助开发者高效安全地使用Claude进行编码辅助。 阅读详情

 

1)用VS2010新建Win32 Console Application,工程名为ACECore,工程建立完成后得到打开文件ACECore.cpp,代码如下:

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

return 0;

}

 

2)用VS2010查看汇编代码的方法:

1. VC必须处于debug状态才能看到汇编指令窗口。因此在上面代码return 0一句上设置断点。

2.按下F5键调试程序,当程序停在断点处时,打开菜单“Debug”下的“Windows”子菜单,选择“Disassembly”。这样就出现反汇编窗口,显示汇编代码:

 --- g:/acecore/acecore/acecore.cpp ---------------------------------------------

// ACECore.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

00411350  push        ebp 

00411351  mov         ebp,esp 

00411353  sub         esp,0C0h 

00411359  push        ebx 

0041135A  push        esi 

0041135B  push        edi 

0041135C  lea         edi,[ebp-0C0h] 

00411362  mov         ecx,30h 

00411367  mov         eax,0CCCCCCCCh 

0041136C  rep stos    dword ptr es:[edi] 

         return 0;

0041136E  xor         eax,eax 

}


3
)相关汇编指令:

push:把一个32位的操作数压入堆栈中,这个操作导致esp被减4。esp被称为栈顶,压入堆栈的数据越多,这个堆栈也就越堆越高,esp地址就越来越小。在32位平台上,esp每次减少4(字节)。

 

pop:esp被加4,一个数据出栈。pop的参数一般是一个寄存器,栈顶数据被弹出到这个寄存器中。

 

某些指令会“自动”地操作堆栈:call指令会把它的下一条指令的地址压入堆栈中,然后跳转到它调用的函数的开头处;而单纯的jmp是不会这样做的。同时,ret会自动弹出返回地址。

call的本质相当于push+jmp,ret的本质相当于pop+jmp。

 

不但push、pop、call和ret会操作堆栈,sub和add也可以用于操作堆栈。如果要一次在堆栈中分配4个4字节长整型的空间,那么没有必要4次调用push,很简单地把esp减去4*4=16即可。当然,也可以同样地用add指令来恢复它。

 

lea:取得地址(第二个参数)后放入到前面的寄存器(第一个参数)中。实际上,有时候lea用来做和mov同样的事情,比如赋值:

lea edi,[ebp – 0cch]

其中,方括弧表示存储器,也就是ebp-0cch这个地址所指的存储器内容。但是lea语法要求取[ebp-0cch]的地址,这个地址就是ebp-0cch,把这个地址放到edi中,也就是说,这等同于:

mov edi,ebp-0cch

但以上的mov指令时错误的,因为mov不支持后一个操作数写成寄存器减去数字。而lea支持,因此可以用lea来代替它。

 

Stos指令:

mov ecx, 30h

mov eax,0CCCCCCCCh

rep stos dword ptr es:[edi]

 

stos是串存储指令,它的功能是将eax中的数据放入edi所指的地址中,同时,edi会增加4(字节数)。rep时指令重复执行ecx中填写的次数。方括弧表示存储器,这个地址实际上就是edi的内容所指向的地址。这里的stos其实对应的是stosd,其他还有stosb、stosw,分别对应于处理4、1、2个字节。

上面代码中对堆栈30h*4(=0c0h)个字节初始化为0CCh(也就是int3指令的机器码),这样发生意外时执行堆栈里面的内容会引发调试中断。

 

==============lost的分割线===============

C函数的参数传递过程:

1)C语言程序通过堆栈把参数从函数外部传入到函数内部,同时,在堆栈中划分区域来容纳函数的内部变量。对于C语言默认的调用方式,函数调用方把参数反序(从右到左)地压入堆栈中,被调用方把堆栈复原。这些参数对齐到机器字长,16位、32位、64位CPU下分别对齐到2、4、8个字节。

 

2)函数调用规则指的是调用者和被调用者函数间传递参数及返回参数的方法,在Windows上,常用的有Pascal方式、WINAPI方式(_stdcall)、C方式(_cdecl)。

 

_cdecl调用规则:

(1)参数从右到左进入堆栈;

(2)在函数返回后,调用者要负责清除堆栈,所以这个调用常会生成较大的可执行文件。

 

_stdcall又称为WINAPI,其调用规则:

(1)参数从右到左入栈;

(2)被调用的函数在返回前自行清理堆栈,所以生成的代码比cdecl下。

 

Pascal调用规则:

(1)参数从左到右入栈;

(2)被调用参数在返回前自行清理堆栈;

(3)不支持可变参数的函数调用。

 

此外,在Windows内核中还常见有快速调用方式(_fastcall);在C++编译的代码中有this call方式(_thiscall)。

 

3)以如下函数作为例子分析:

void ACEFunction(int a, int b)

{

       int c = a + b;

}

 

int _tmain(int argc, _TCHAR* argv[])

{

       int a = 1;

       int b = 2;

       ACEFunction(a, b);

       return 0;

}

标准的C函数调用方式(_cdecl):

(1)调用者把参数反序地压入堆栈中;

(2)调用函数;

(3)调用者负责把堆栈清理复原。

 

注意:在Windows中,不管哪种调用方式都是返回值放在eax中,然后返回。外部从eax中得到返回值。

 

_cdecl方式下被调用函数需要做以下的事情:

(1)保存ebp。ebp总是被我们用来保存这个函数执行之前的esp的值,执行完毕后,我们用ebp恢复esp;同时,调用此函数的上层函数也用ebp做同样的事情,所以先把ebp压入堆栈,函数返回之前弹出,避免ebp被我们改动。

(2)保存esp到ebp中。

上面两步的代码如下:

;保存ebp,并把esp放入ebp中,此时ebp和esp同

;都是这次函数调用时的栈顶

00411360  push        ebp 

00411361  mov         ebp,esp 

 

(3)在堆栈中腾出一个区域用来保存局部变量,这就是常说的所谓局部变量时保存在栈空间中的。方法是:把esp减少一个数值,这样就等于压入了一堆变量。恢复时,只有把esp恢复成ebp中保存的数据就行。

(4)保存ebx、esi、edi到堆栈中,函数调用完后恢复。

上面两步对应代码如下:

;把esp往下移动一个范围,等于在堆栈中放出一片新

;的空间来保存局部变量

00411363  sub         esp,0CCh 

00411369  push        ebx 

0041136A  push        esi 

0041136B  push        edi 

 

(5)把局部变量区域初始化成全0CCCCCCCCh。0CCh实际上是int3指令的机器码,这是一个断点中断指令。因为局部变量不可能被执行,如果执行了,必然程序出错,这时发生中断来提示开发者。这时VC编译Debug版本的特有操作:

0041136C  lea         edi,[ebp-0CCh] 

00411372  mov         ecx,33h 

00411377  mov         eax,0CCCCCCCCh 

0041137C  rep stos    dword ptr es:[edi] 

 

(6)然后做函数里应该做的事情。参数的获取是ebp+12字节为第二个参数,ebp+8字节为第一个参数(反序入栈),依次增加。最后ebp+4字节处是要返回的地址。

 

(7)恢复ebx、esi、edi、esp、ebp,最后返回:

00411387  pop         edi 

00411388  pop         esi 

00411389  pop         ebx 

0041138A  mov         esp,ebp 

0041138C  pop         ebp 

0041138D  ret 

 

用VS2010编译Debug版本,完整的反汇编代码如下:

--- g:/acecore/acecore/acecore.cpp ---------------------------------------------

// ACECore.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

 

void ACEFunction(int a, int b)

{

00411360  push   ebp  ;保存ebp,并把esp放入ebp中。此时ebp与esp相同

00411361  mov   ebp,esp  ;都是这次函数调用时的栈顶

00411363  sub   esp,0CCh  ;把esp往上移动一个范围,等于在堆栈中放出一片新

                                     ;的空间用来存储局部变量

00411369  push   ebx  ;下面保存三个寄存器:ebx、esi、edi

0041136A  push   esi 

0041136B  push   edi 

0041136C  lea   edi,[ebp-0CCh] ;原本是想使用“mov edi, ebp-0CCh”,但是mov不支持

                                        ;“-”操作,所以先对ebp-0CCh取内容(即[ebp-0CCh]),

                                        ;再利用lea把[ebp-0CCh]的地址也就是ebp-0CCh放到edi中

                                        ;目的是把保存局部变量的区域(即ebp-0CCh开始的区域)

                                        ;初始化成全部为0CCCCCCCCh。

00411372  mov   ecx,33h 

00411377  mov   eax,0CCCCCCCCh 

0041137C  rep stos    dword ptr es:[edi]  ;写入0CCh指令(中断)

         int c = a + b;

0041137E  mov   eax,dword ptr [a]  ;加法操作,从堆栈中取得从外部传入的参数。

00411381  add   eax,dword ptr [b]  ;通过ida反汇编可以看到,其实这两天指令是:

                                               ;mov eax, [ebp+8]

                                               ;add eax, [ebp+0Ch]

                                               ;参数是通过ebp从堆栈中取得的。这里看到的是

;VC调试器的显示结果,是为了方便阅读,

;直接加上了参数名

00411384  mov  dword ptr [c],eax 

}

00411387  pop         edi  ;恢复edi、dsi、ebx

00411388  pop         esi 

00411389  pop         ebx 

0041138A  mov         esp,ebp  ;恢复原来的ebp和esp,让上一级调用的

0041138C  pop         ebp  ; 函数可以正常使用

0041138D  ret 

 

主程序中对这个函数的调用方式是:

004123DC  mov         eax,dword ptr [b]  ;把b, a两个参数压入堆栈

004123DF  push        eax 

004123E0  mov         ecx,dword ptr [a]  

004123E3  push        ecx 

004123E4  call        ACEFunction (411014h)  ;调用函数ACEFunction

004123E9  add         esp,8  ;恢复堆栈

 

 

 

 

 

 

 

 

 


 

C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照 C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照下面进行详细步骤说明,感兴趣的同学可以看一下: 1简单示例(一条线): 2.数据源随着时间不断变化,进度条变化 。多条线: 3.看在整段时期内的数据大体图(消去或出现)进度条: 4.后台将时刻记录变化记录到一个txt文本里以供详细校验: 话不多说上码: using System; using Sys... 阅读详情

相关推荐

从零到一:如何用YOLOv8和PyQt5打造你的第一个花卉识别桌面应用

本文详细介绍了如何使用YOLOv8和PyQt5从零开始构建一个花卉识别桌面应用。涵盖环境搭建、数据准备、模型训练、界面设计、模型集成与性能优化等全流程,帮助开发者快速掌握深度学习目标识别技术的实际应用。

weixin_29048775的博客 453

《Windows核心编程》---执行可执行文件

<br />方法一:Shell调用:<br />Win32中可以通过WinExec和ShellExecute函数来执行另一个可执行程序。<br />WinExec函数原型如下:<br />UINT WINAPI WinExec(<br />  __in  LPCSTR lpCmdLine, //包含可执行文件名和命令行参数<br />  __in  UINT uCmdShow //指定窗口的显示方式,如果有窗口的话<br />);<br />如果文件被成功执行,那么函数返回一个大于31的值。使用WinExe

ASCE1885 2527

手把手教你配置微信商户平台IP白名单:企业付款到零钱必备步骤

本文详细解析了微信商户平台IP白名单的配置原理与实操步骤,这是实现企业付款到零钱功能的关键安全环节。文章从理解IP白名单的安全逻辑出发,指导开发者精准定位服务器公网IP,并提供了在商户平台后台的详细配置流程与常见问题排查指南,帮助开发者高效完成配置,确保企业付款API的顺利调用。

weixin_29326909的博客 736

汇编入门指令汇总(复习篇 | 完整易懂)

在学习汇编前需要掌握一定的C/C++编程基础,计算机组成原理、操作系统等课程知识。 此文为复习所总结,主要介绍和总结汇编的常用指令,参考教材为《新概念汇编语言》。

weixin_58219093的博客 1万+

国家医保移动支付国密算法SM2签名验签、SM4加解密DLL

DLL,非.net开发,所以无需安装配置,直接程序引用开发即可,支持各类开发语言。已知省份有广西、贵州、安徽、河北、黑龙江、湖南、吉林、江苏、四川、新疆等各地方。国家医保移动支付国密算法SM2签名验签、SM4加解密DLL。//SM4加密与解密。支持医保移动支付(国家统一版),//SM2签名与验签。

4263

研制过程评审活动(三)工程研制阶段

工程研制阶段主要任务、及评审活动

Abel的博客 2387

Windows内核解析-代码段执行过程

汇编代码在CPU中的执行过程如下: 一、拆分段选择子 RPL:请求特权级别 TI: TI=0查GDT表 TI=1查LDT表(Windows没有使用) INDEX: 处理器将索引值乘以8再加上GDT表的基址,就是要加载的段描述符 二、查表得到段描述符 根据段选择子的TI值为0,查询GDT表 根据段选择子的INDEX的值,找到对应的段描述符 三、权限检查 如果是非一致代码段,要求:C...

蜡笔小新的博客 373

【脑电信号】脑电信号EEG形态学滤波处理【含Matlab源码 4023期】

脑电信号EEG形态学滤波处理 完整的代码,包运行;运行操作视频见优快云资源!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 823

【Windows源码分析】(一)初始化内核与执行体子系统

标 题: 【Windows源码分析】(一)初始化内核与执行体子系统作 者: 北极星2003时 间: 2008-03-22,23:59链 接: http://bbs.pediy.com/showthread.php?t=61749对于那么没有相关经验的朋友,在阅读本文时最好对照windows源码来看,否则光看着这么多数据结构就足以头大。对于这篇文章,严格来说,应该是属于学习笔记型

求索 2317

热更新方案 HybridCLR 学习教程 |(一)原理及准备工作

前面文章介绍了热更新相关的知识,包括使用xLua实现热更新实战等 那本文就来介绍一下 热更新方案 HybridCLR(代号wolong,原huatuo)和基本使用方法。 若是想了解更多关于HybridCLR的东西也可以去 官网 详细查阅。

努力前行,总会成为自己心中的那道光 2万+

Claude Code(1):手把手教你安装配置 Claude Code

Claude Code 是一款强大的 AI 编程助手工具,能够帮助开发者提升编码效率。本文将详细介绍如何在不同操作系统上安装和配置 Claude Code,让你快速上手这款工具。

blues_C的博客 752

windows 核心编程(进程)

<br />1、进程:一个正在运行的程序的实例,它由两部分组成:<br />(1) 一个内核对象,操作系统用它来管理进程。内核对象也是系统保存进程统计信息的地方。<br />(2) 一个地址空间,其中包含所有可执行文件或DLL模块的代码和数据,此外,它还包含动态分配内存,比如线程堆栈和堆的分配。<br />2、windows应用程序必须有一个入口点函数,应用程序开始运行时,这个函数会被调用。操作系统实际并不调用我们所写的入口点函数。相反,它会调用由C/C++运行库实现并在链接时使用-entry:命令行选项来

wangsifu2009的专栏 799

❤️爆肝十二万字《python从零到精通教程》,从零教你变大佬❤️(建议收藏)

文章目录强烈推荐系列教程,建议学起来!!一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置4.2手动添加镜像源4.3永久配置镜像源五.插件安装(比如汉化?)5.1自动补码神器第一款5.2汉化pycharm5.3其它插件六.美女背景七.自定义脚本开头八、这个前言一定要看九、python入门十、python缩进十一、Python注释1.单行注释2.多行注释十二、Python 变量1.变量定义理解2. 变量名命名3. 分

全栈川川 26万+

《Windows内核编程》の基本汇编指令 .

1)用VS2010新建Win32 Console Application,工程名为ACECore,工程建立完成后得到打开文件ACECore.cpp,代码如下: #include"stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { return 0; }   2)用VS2010查看汇编代码的方法: 1. VC必须处于debug状态才能看到

happylife1527的专栏 610

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

《Windows核心编程》のWindows时间

<br />Windows时间的获取和设置:<br />在Win32编程中,常用的获取系统时间的函数是有两个,即GetLocalTime和GetSystemTime:<br />void WINAPI GetLocalTime(<br />  __out  LPSYSTEMTIME lpSystemTime<br />);<br />void WINAPI GetSystemTime(<br />  __out  LPSYSTEMTIME lpSystemTime<br />);<br />这两个函数的区别

ASCE1885 2278

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

OpenArk:Windows系统安全分析的终极完整指南

OpenArk是一款开源的Windows反Rootkit(ARK)工具,专为系统安全分析和恶意软件检测设计。作为下一代ARK工具,它不仅能帮助开发者进行逆向工程和编程辅助,还能让普通用户轻松发现操作系统中隐藏的恶意程序。本文将全面介绍这款强大工具的核心功能、安装方法和实用技巧,让你快速掌握Windows系统安全分析的关键技能。 ## 🚀 为什么选择OpenArk? 在当今复杂的网络安全环境中

gitblog_01136的博客 1146

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

《Windows核心编程》---获得内存的当前状态のGlobalMemoryStatusEx

Win32系统中,一个进程可寻址的地址空间是4GB,用户可使用的地址空间是大概是2GB,但这不是说用户可以申请2GB的内存,因为这2GB只是可以使用的“地址”空间,而不是可以使用的“内存”空间,可分配内存的大小还受制于物理内存和磁盘交换文件的大小。因为物理内存和磁盘交换文件是供整个系统和所有用户程序使用的,所有系统内核、当前执行的所用用户程序的代码、数据,以及分配的内存总量并不能超过物理内存和磁盘交换文件的总和。当设计一个可能需要申请大量内存的程序时,我们就需要预先得知系统的配置情况,这时可以使用Globa

ASCE1885 3408

【JokerのZYNQ7020】LINUX_ETHERNET_MTU_9K。

软件环境:vivado 2017.4 硬件平台:XC7Z035 在上一篇的基础上,这篇主要说下LINUX这边巨型帧(JUMBO FRAME)9K的包怎么跑通。 底图相对前一篇稍微做了点修改,加上了DMA的LOOP回环,倒不是因为ETHERNET_9K需要这样搞,而是为了后面做LINUX这边跑AXI_DMA时候,底图就不用做修改了而已,如果只想做ETHERNET_9K实验的话,...

Joker_是小王的博客 1836

Windows+vm双机调试内核

参考链接 编写通用 Hello World 驱动程序 (KMDF) - Windows drivers | Microsoft Docs https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/writing-a-very-small-kmdf–driver 调试环境 通常,在测试和调试驱动程序时,调试程序和...

博客 489

TCP/UDP底层实现(c实现)の四

linux下多线程服务和windows多线程

jack的博客 2647
上一篇: 认清C++语言之《模板特化specialization》
下一篇: Tree Recovery---POJ--2255
ACE1985
博客等级 码龄17年 1307粉丝 308原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值