爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      Windows逆向安全(一)之基础知识(十六)

      首页 知识中心 其他 文章详情页

      Windows逆向安全(一)之基础知识(十六)

      2023-08-03 06:47:48 阅读次数:424

      windows,逆向安全

      指针三

      通过先前指针的学习,了解了指针和地址以及数据的关系,现在结合先前的知识继续学习巩固

      指针遍历数组

      有了先前的基础,再来看看如何用指针遍历数组

      代码

      #include "stdafx.h"
      void function(){
              short arr[5]={1,2,3,4,5};
      
              short* p=&arr[0];
              short* p2=arr;
      
              if(p==p2){
                      printf("equal\n");
              }else{
                      printf("not equal\n");
              }
      
              int i;
              for(i=0;i<5;i++){
                      int j=*(p+i);
                      printf("addr:%x value:%d\n",p+i,j);
              }        
      }
      int main(int argc, char* argv[])
      {
              function();
              return 0;
      }

      代码说明

      稍微说明的一下代码部分

      主要是声明了一个数组,然后用两种方法取得数组的首地址,一种是&arr[0],另一种则直接是arr

      后面则是通过循环配合指针遍历数组成员并输出

      按顺序依次涉及先前指针笔记的知识点:

      1. 取变量地址
      2. 指针赋值
      3. 指针之间的比较
      4. 取地址中存储数据
      5. 指针的加减

      运行结果

      Windows逆向安全(一)之基础知识(十六)

       

      可以看到通过&arr[0]和arr取数组首地址得到的结果是一致的

      并且能够通过指针来输出数组成员的地址和对应的数据

      这里还会观察到数组里的每个地址都相差2(short类型的数据宽度),和先前数组的学习又匹配上了

      反汇编代码

      11:       short arr[5]={1,2,3,4,5};
      0040D7A8   mov         word ptr [ebp-0Ch],offset function+1Ch (0040d7ac)
      0040D7AE   mov         word ptr [ebp-0Ah],offset function+22h (0040d7b2)
      0040D7B4   mov         word ptr [ebp-8],offset function+28h (0040d7b8)
      0040D7BA   mov         word ptr [ebp-6],offset function+2Eh (0040d7be)
      0040D7C0   mov         word ptr [ebp-4],offset function+34h (0040d7c4)
      12:
      13:       short* p=&arr[0];
      0040D7C6   lea         eax,[ebp-0Ch]
      0040D7C9   mov         dword ptr [ebp-10h],eax
      14:       short* p2=arr;
      0040D7CC   lea         ecx,[ebp-0Ch]
      0040D7CF   mov         dword ptr [ebp-14h],ecx
      15:
      16:       if(p==p2){
      0040D7D2   mov         edx,dword ptr [ebp-10h]
      0040D7D5   cmp         edx,dword ptr [ebp-14h]
      0040D7D8   jne         function+59h (0040d7e9)
      17:           printf("equal\n");
      0040D7DA   push        offset string "equal\n" (00422fbc)
      0040D7DF   call        printf (0040d710)
      0040D7E4   add         esp,4
      18:       }else{
      0040D7E7   jmp         function+66h (0040d7f6)
      19:           printf("not equal\n");
      0040D7E9   push        offset string "not equal\n" (00422fb0)
      0040D7EE   call        printf (0040d710)
      0040D7F3   add         esp,4
      20:       }
      21:
      22:       int i;
      23:
      24:       for(i=0;i<5;i++){
      0040D7F6   mov         dword ptr [ebp-18h],0
      0040D7FD   jmp         function+78h (0040d808)
      0040D7FF   mov         eax,dword ptr [ebp-18h]
      0040D802   add         eax,1
      0040D805   mov         dword ptr [ebp-18h],eax
      0040D808   cmp         dword ptr [ebp-18h],5
      0040D80C   jge         function+0A8h (0040d838)
      25:           int j=*(p+i);
      0040D80E   mov         ecx,dword ptr [ebp-18h]
      0040D811   mov         edx,dword ptr [ebp-10h]
      0040D814   movsx       eax,word ptr [edx+ecx*2]
      0040D818   mov         dword ptr [j],eax
      26:           printf("addr:%x value:%d\n",p+i,j);
      0040D81B   mov         ecx,dword ptr [j]
      0040D81E   push        ecx
      0040D81F   mov         edx,dword ptr [ebp-18h]
      0040D822   mov         eax,dword ptr [ebp-10h]
      0040D825   lea         ecx,[eax+edx*2]
      0040D828   push        ecx
      0040D829   push        offset string "addr:%x value%d:\n" (00422f9c)
      0040D82E   call        printf (0040d710)
      0040D833   add         esp,0Ch
      27:       }
      0040D836   jmp         function+6Fh (0040d7ff)
      28:
      29:   }

      反汇编分析

      由于循环和数组等相关的知识在先前的笔记已经详细学习过了,这里就直接看指针相关的代码

      25:           int j=*(p+i);
      0040D80E   mov         ecx,dword ptr [ebp-18h]
      0040D811   mov         edx,dword ptr [ebp-10h]
      0040D814   movsx       eax,word ptr [edx+ecx*2]
      0040D818   mov         dword ptr [j],eax

      1.将ebp-18h里的值赋值给ecx,这里的[ebp-18h]其实对应的就是 i

      0040D80E   mov         ecx,dword ptr [ebp-18h] (i)

      2.将ebp-10h里的值赋值给edx,这里的[ebp-10h]其实对应的是p,即数组首地址

      0040D811   mov         edx,dword ptr [ebp-10h] (p)

      3.movsx是带符号扩展赋值,将edx+ecx2,也就是p+i\数据宽度地址里存储的值赋给eax

      0040D814   movsx       eax,word ptr [edx+ecx*2]

      为什么要使用movsx指令?

      内存对齐的结果,先前的笔记就提到过:char short 在计算时都会转变为dword宽度来进行计算

      4.将前面暂存在寄存器中的值赋给变量j

      0040D818   mov         dword ptr [j],eax

      指针翻转数组

      翻转数组思想

      翻转数组的思想就是从数组两端(数组首部和数组尾部)开始然后逐渐向中间靠拢,相互交换数组中的内容

      Windows逆向安全(一)之基础知识(十六)

      代码

      #include "stdafx.h"
      void function(){
              int arr[5]={1,2,3,4,5};
      
              int* begin=&arr[0];
              int* end=begin+4;
      
              while(begin<end){
                      int tmp=*begin;
                      *begin=*end;
                      *end=tmp;
                      begin++;
                      end--;
              }
      
              int i;
              for(i=0;i<5;i++){
                      printf("%d\n",arr[i]);
              }        
      
      }
      int main(int argc, char* argv[])
      {
              function();
              return 0;
      }

      代码分析

      数组翻转的关键代码是:

      int* begin=&arr[0];
      int* end=begin+4;
      
      while(begin<end){
              int tmp=*begin;
              *begin=*end;
              *end=tmp;
              begin++;
              end--;
      }

      1.获取数组首地址和尾地址

      int* begin=&arr[0];
      int* end=begin+4;

      2.循环直到所有数组成员交换结束

      while(begin<end){
      }

      3.取出begin中的数据放在临时变量中

      int tmp=*begin;

      4.用end里存储的值覆盖begin

      *begin=*end;

      5.将原本备份的begin的变量tmp赋值给end,此时已经完成了交换

      *end=tmp;

      6.继续交换,让指针向数组中间靠拢

      begin++;
      end--;

      运行结果

      Windows逆向安全(一)之基础知识(十六)

      可以看到,数组成功翻转了

      反汇编实现翻转数组

      前面使用指针实现了数组的翻转,为进一步了解其本质,自己手写汇编代码实现翻转数组

      下面的汇编代码中省略了 dword ptr ds:[],默认就是取dword

      代码

      #include "stdafx.h"
      void function(){
              int arr[5]={1,2,3,4,5};        
              int len=sizeof(arr)/sizeof(int)-1;        
              __asm{
                      xor ecx,ecx
      _begin:
                      mov eax,len
                      sub eax,ecx
      
                      lea edx,[arr+ecx*4]        
                      push edx
                      mov edx,[edx]
                      lea ebx,[arr+4*eax]
                      push ebx
                      mov ebx,[ebx]
                      xchg [arr+ecx*4],ebx
                      pop ebx
      
                      mov [ebx],edx
                      pop edx
                      inc ecx
      
                      cmp edx,ebx
                      jb _begin
      
              }
              int i;
              for(i=0;i<5;i++){
                      printf("%d\n",arr[i]);
              }        
      
      }
      int main(int argc, char* argv[])
      {
              function();
              return 0;
      }

      运行结果

      Windows逆向安全(一)之基础知识(十六)

      能够正确地实现相同的功能

      反汇编代码分析

      __asm{
                      xor ecx,ecx
      _begin:
                      mov eax,len
                      sub eax,ecx
      
                      lea edx,[arr+ecx*4]        
                      push edx
                      mov edx,[edx]
                      lea ebx,[arr+4*eax]
                      push ebx
                      mov ebx,[ebx]
                      xchg [arr+ecx*4],ebx
                      pop ebx
      
                      mov [ebx],edx
                      pop edx
                      inc ecx
      
                      cmp edx,ebx
                      jb _begin
      
              }

      1.将ecx清零,初始化ecx,ecx在这里是作为偏移量来使用的(刚开始为首地址的偏移,后来慢慢往中间靠拢)

      xor ecx,ecx

      2.声明一个程序段,后续跳转会用到

      _begin:

      3.将数组的长度减1的值赋给eax,因为数组从0开始,所以要减1

      mov eax,len

      4.用先前的eax减去ecx获得偏移(刚开始为尾地址的偏移,后来慢慢往中间靠拢)

      sub eax,ecx

      5.通过数组首地址加上ecx偏移取得地址,刚开始取得的为首地址,相当于edx=begin

      lea edx,[arr+ecx*4]

      6.将前面获得的地址edx放入堆栈中

      push edx

      7.取出edx中的值,这里相当于edx=*begin=tmp

      mov edx,[edx]

      8.通过数组首地址加上偏移eax取得地址,刚开始取得的为尾地址,相当于ebx=end

      lea ebx,[arr+4*eax]

      9.将前面获得的地址ebx放入堆栈中

      push ebx

      10.取出ebx中的值,这里对相当于ebx=*end

      mov ebx,[ebx]

      11.交换arr+ecx*4(*begin)和ebx(end)里存储的值,这里相当于begin=*end

      xchg [arr+ecx*4],ebx

      12.将先前的push的end的地址恢复到ebx,使得ebx=end

      pop ebx

      13.这里相当于*end=tmp,此时数组中的两个成员就已经交换完毕了

      mov [ebx],edx

      14.将先前push的begin的地址恢复到edx,使得edx=begin

      pop edx

      15.让ecx自增一,这里相当于begin++;end–; 因为这里end的偏移是通过len-begin的偏移得到的

      inc ecx

      16.比较edx和ebx

      jb:jump below,小于则跳转(无符号),这里相当于while(begin<end)中的比较

      如果begin<end则继续跳回去执行

      cmp edx,ebx
      jb _begin

       

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.51cto.com/u_16179749/6632412,作者:私ははいしゃ敗者です,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:Windows逆向安全(一)之基础知识(十)

      下一篇:el-input 输入验证 整数、小数、实数、整数、负数等

      相关文章

      2025-03-24 08:45:46

      windows中CMD快捷命令

      windows中CMD快捷命令

      2025-03-24 08:45:46
      windows , 打开 , 管理器
      2025-02-28 09:28:01

      Pytorch 学习(9):Python C 扩展( C、C++代码-----C so 代码库------python代码调用)

      Pytorch 学习(9):Python C 扩展( C、C++代码-----C so 代码库------python代码调用)

      2025-02-28 09:28:01
      bin , windows , 代码 , 版本
      2025-01-14 09:17:05

      Java竖线分割字符串问题

      Java竖线分割字符串问题

      2025-01-14 09:17:05
      https , Java , windows , 使用 , 分割 , 字符串 , 转义字符
      2025-01-08 08:39:44

      windows系统环境c++(c) socket编程实例代码(含服务端和客户端)

      本代码是windows系统环境c++(c) socket编程实例。包含客户端和服务端,可以实现客户端发送消息,服务端接收消息并写入日志。 server.cpp为服务端。

      2025-01-08 08:39:44
      client , cpp , server , socket , windows , 代码 , 客户端 , 服务端
      2024-12-31 06:01:41

      在windows server 2016中通过dbca创建数据库时,出现DIM-00019告警

      在windows server 2016中通过dbca创建数据库时,出现DIM-00019告警

      2024-12-31 06:01:41
      dbca , server , windows
      2024-11-27 03:26:40

      windows cmake编译报错 “No CUDA toolset found.“

      windows cmake编译报错 “No CUDA toolset found.“

      2024-11-27 03:26:40
      windows , 编译
      2024-10-24 08:33:12

      Windows平台里的grep——1.Borland grep

      grep来自英文词组“global search regular expression and print out the line”的缩写,意思是用于全面搜索的正则表达式,并输出相应行。Unix和Linux都直接提供了grep命令。

      2024-10-24 08:33:12
      c++ , windows
      2024-10-14 06:12:34

      system.exe,alien32.exe,ftsKetNt.7ps,SysKetNt.Sys, iexpe.exe等1

      system.exe,alien32.exe,ftsKetNt.7ps,SysKetNt.Sys, iexpe.exe等1

      2024-10-14 06:12:34
      windows , 代码
      2024-10-09 09:17:25

      解决windows installer 错误一例

      解决windows installer 错误一例

      2024-10-09 09:17:25
      windows , 服务
      2024-09-24 06:31:17

      Windows 计算机加入域和登录域

      客户端计算机必须加入域,才能接受域的统一管理,使用域中的资源。在目前主流的Windows 操作系统中,除Home版外都能添加到域中。

      2024-09-24 06:31:17
      windows , 服务器
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5244022

      查看更多

      最新文章

      windows中CMD快捷命令

      2025-03-24 08:45:46

      windows cmake编译报错 “No CUDA toolset found.“

      2024-11-27 03:26:40

      Windows平台里的grep——1.Borland grep

      2024-10-24 08:33:12

      解决windows installer 错误一例

      2024-10-09 09:17:25

      Windows 防火墙上也有端口映射功能

      2024-08-06 09:37:28

      windows server 2016安装DNS服务,搭建使用,主备恢复

      2024-07-01 01:32:03

      查看更多

      热门文章

      windows刷新dns,查看文件md5值

      2023-03-24 10:33:05

      在Win10中、如何把常用的应用添加到高效工作窗口呢?

      2023-04-27 08:03:06

      如何查看JDK版本信息

      2023-06-15 05:58:45

      windows 脚本 编写

      2023-03-14 11:21:34

      windows cmd 自定义关机,重启,休眠

      2023-06-07 07:27:35

      windows7下vs2008常见错误解决方法汇总

      2023-04-06 06:35:33

      查看更多

      热门标签

      linux java python javascript 数组 前端 docker Linux vue 函数 shell git 节点 容器 示例
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      windows 版 nginx 运行错误的一些解决方法

      windows7下vs2008常见错误解决方法汇总

      windows cmake编译报错 “No CUDA toolset found.“

      Windows逆向安全(一)之基础知识(十一)

      windows任务栏IDEA图标变白色快速解决方法#yyds干货盘点#

      CVE漏洞复现-CVE-2021-36934 Windows 提权漏洞

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号