逆向(异或)

news2024/10/6 19:29:10

在学习逆向前我们需要掌握一些汇编的基础知识的
同时我们得知道可执行文件的原理
计算机生成可执行文件,我们大致可以简单的这么理解
1.asm源程序文件
2.asm源程序生成obj也就是目标文件
3.由目标文件链接生成可执行文件,Windows的可执行文件通常是EXE,Linux通常是ELF
而在实际的环境中,计算会选择丢弃部分不要重要,或者自己优化一些信息。
逆向就是需要对这些信息进行还原,同时可以进行破译,也就是游戏开外挂,软件正版却有盗版的存在

test1(静态分析)

首先用查壳工具先看看
在这里插入图片描述
64位,ELF文件
查壳的目的:
1.看加了什么保护没
2.看看是多少位的程序,因为IDA有32和64的版本,必须与之分别对应
逆向基本步骤是使用IDA,对源程序进行反汇编,分析其中的代码

IDA

IDA(Interactive Disassembler)是一款强大的逆向工程工具,常用于分析和反汇编计算机程序。它支持各种平台和体系结构,并提供了丰富的功能和工具,可用于深入研究二进制代码的功能、结构和漏洞。
以下是IDA的一些主要特点和功能:
1.反汇编和分析:IDA能够将二进制文件转换为可读的汇编代码,使用户可以更好地理解程序的内部结构和执行逻辑。它提供了丰富的反汇编视图和分析工具,以帮助用户识别代码块、函数、指令和数据。
2.交互式界面:IDA提供了直观且易于使用的图形用户界面,支持用户与反汇编结果进行交互。用户可以浏览代码、跳转到函数或指令,查看和编辑数据以及设置断点等。
3.反编译器:IDA还提供了反编译功能,可以将汇编代码转换为高级语言表示,如C语言。这可以帮助用户更好地理解程序的功能和逻辑,尤其是对于无法获得源代码的情况。
4.插件和脚本支持:IDA支持各种插件和脚本,用户可以根据需要扩展和定制工具。这使得用户可以编写自己的脚本来自动化任务、添加新的功能或与其他工具集成。
总体而言,IDA是一款功能强大且灵活的逆向工程工具。它被广泛用于恶意软件分析、漏洞研究、软件安全评估和逆向工程等领域,并受到安全专家、软件工程师和研究人员的青睐。
同时IDA可以按F5,生成C/C++代码
以Test1为例子
打开IDA左边这一栏代表的是所用到的函数,当然我们知道C语言是从主函数开始的,所以一般我们先会去看看main函数的样子,当函数少的时候,我们可以直接看到,但是当函数多的时候我们就看不到了,此时我们用Ctr+f的方式可以在左边的篮筐进行搜索
在这里插入图片描述由于这题比较简单,突破口就是main函数
这里需要我们有C语言的基础,仔细看好
每一个变量,每一个函数的逻辑关系
当然由于这道题说了考察异或那我们重点观察异或!!(这里其实已经在汇编、离散数学中学过)

什么是异或

异或(XOR)是一种逻辑运算符,常用于计算机科学和电子工程中。异或操作符通常用符号 “^” 表示。
异或操作的定义如下:
当两个操作数的位值不同时,异或结果为1。
当两个操作数的位值相同时,异或结果为0。
例如,对于两个二进制数1和0进行异或操作:
1 XOR 0 = 1
异或操作还具有以下一些重要性质:
1.结合律:(A XOR B) XOR C = A XOR (B XOR C)
2.交换律:A XOR B = B XOR A
3.自反性:A XOR A = 0
4.零元素:A XOR 0 = A
异或操作在计算机科学中广泛应用,包括数据加密、校验和计算、错误检测和纠错编码等领域。在编程中,异或操作也常用于快速交换变量值、判断奇偶性和重复元素的消除等。

为什么要异或?这道题的思路

根据上面我们现在知道,把密码重复异或两次就会出现成本身,那么这道题的思路:
1,找到匹配的数据
2.将匹配的数据进行二次异或
3.最后得到原来的密码,也就是我们所需要的信息

int __cdecl main(int argc, const char **argv, const char **envp)
{
  size_t v3; // rbx
  char s[8]; // [rsp+0h] [rbp-40h] BYREF
  __int64 v6; // [rsp+8h] [rbp-38h]
  __int64 v7; // [rsp+10h] [rbp-30h]
  __int64 v8; // [rsp+18h] [rbp-28h]
  char v9; // [rsp+20h] [rbp-20h]
  int i; // [rsp+2Ch] [rbp-14h]

  *(_QWORD *)s = 0LL;
  v6 = 0LL;
  v7 = 0LL;
  v8 = 0LL;
  v9 = 0;
  puts("Welcome to RE world,Can you solve the problem?");
  printf("Now you should input your flag and i'll tell you if it is right:");
  __isoc99_scanf("%s", s);
  for ( i = 0; ; ++i )
  {
    v3 = i;
    if ( v3 >= strlen(s) )
      break;
    s[i] ^= i;   **重点!!!
  }
  if ( (unsigned int)compare(s) )
    puts("Well done! You find the secret!");**根据这里的提示我们看到如果(unsigned int)compare(s)
    成立==1那就说梦成功了,那这里我们在IDA里面点进这个函数看看
  else
    puts("The flag is wrong! Maybe something run before main");
  return 0;

在这里插入图片描述

__int64 __fastcall compare(const char *a1)
{
  int i; // [rsp+1Ch] [rbp-4h]

  if ( strlen(a1) != 32 )
  {
    puts("The length of flag is Wrong!!");
    exit(0);
  }
  for ( i = 0; i <= 31; ++i )
  {
    if ( final[i] != a1[i] )**这里我们看到我们输入的字符串被传输进入了a1[]里面,然后与fianl[]里面的数做了
    一个对比,那其实就是final[]就是加密后的密码,点击进入查看数据
      return 0LL;
  }
  return 1LL;
}

在这里插入图片描述

.data是什么?

学逆向我们还需要懂得一些文件结构的基础,这里我之前有讲过可以去看看下面这篇我写的博客
https://blog.csdn.net/m0_72827793/article/details/130231662
里面讲了PE文件结构,当然这道题是ELF文件结构,但他们都是类似的,都在COFF的基础上

至于db是汇编语言的知识

可以在我博客上的汇编框里面找找

回到刚才

这些数据就是我们需要破译的密码
这里我们需要提取出来选中这些数据
shift+e
在这里插入图片描述
我们选择十六进制转换
在这里插入图片描述
我们把数据提取出来(0X)表示十六进制
0x66, 0x6D, 0x63, 0x64, 0x7F, 0x56, 0x69, 0x6A, 0x6D, 0x7D,
0x62, 0x62, 0x62, 0x6A, 0x51, 0x7D, 0x65, 0x7F, 0x4D, 0x71,
0x71, 0x73, 0x79, 0x65, 0x7D, 0x46, 0x77, 0x7A, 0x75, 0x73,
0x21, 0x62

解密

这里我们可以C语言,也可以用python等一些语言写一个破译的脚本
这里是我写的
在这里插入图片描述
运行即可
在这里插入图片描述

Test2(动态)

学了上面这些,我们再加深一下理解,同时做一个提升
看一下同类型的test2这道题
同样的方式先找到main函数
在这里插入图片描述解析这段

 if ( Size != 38 )**这里判断了输入的数必须是38goto LABEL_22;
  v5 = 0i64;
  v3 = &Buf1;
  do
  {
    v6 = &Buf1**给数赋值
    v7 = &Buf1;
    if ( (unsigned __int64)qword_7FF7B8B96C68 >= 0x10 )
      v6 = (void **)Buf1;
    if ( (unsigned __int64)qword_7FF7B8B96C68 >= 0x10 )
      v7 = (void **)Buf1;
    *((_BYTE *)v7 + v5) ^= *((_BYTE *)v6 + v5 + 1);**给数组str[i]^=str[i+1],下面的依次类推分析
    v8 = &Buf1;
    v9 = &Buf1;
    if ( (unsigned __int64)qword_7FF7B8B96C68 >= 0x10 )
      v8 = (void **)Buf1;
    if ( (unsigned __int64)qword_7FF7B8B96C68 >= 0x10 )
      v9 = (void **)Buf1;
    *((_BYTE *)v9 + v5 + 1) ^= *((_BYTE *)v8 + v5 + 2);
    v10 = &Buf1;
    v11 = &Buf1;
    if ( (unsigned __int64)qword_7FF7B8B96C68 >= 0x10 )
      v10 = (void **)Buf1;
    if ( (unsigned __int64)qword_7FF7B8B96C68 >= 0x10 )
      v11 = (void **)Buf1;
    *((_BYTE *)v11 + v5 + 2) ^= *((_BYTE *)v10 + v5 + 3);
    ++v5;
    v4 = Size;
  }
  while ( v5 < Size - 3 );

跟上一题的思路类似,那这里我们要怎么去寻找到那个匹配的数呢?看到后面这一段代码

 v12 = &Buf2;**先看明白下面 
 Size != qword_7FF7B8B96C40 || (v13 = memcmp(v3, v12, Size), v14 = "Right!", v13)
 这个判断,再看这个!
 **此时我们我们便可以知道Buf2就是判断的值
  if ( (unsigned __int64)qword_7FF7B8B96C48 >= 0x10 )
    v12 = (void **)Buf2;
  if ( (unsigned __int64)qword_7FF7B8B96C68 >= 0x10 )
    v3 = (void **)Buf1;
  if ( Size != qword_7FF7B8B96C40 || (v13 = memcmp(v3, v12, Size), v14 = "Right!", v13) )
LABEL_22:
    v14 = "Wrong!";
  sub_7FF7B8B62410(v3, v14, v4);
  return 0;

memcmp函数

在这里插入图片描述

Buf2问题

可以当我们点开buf2发现,这里面啥也没有
在这里插入图片描述**所以我们需要动态调试!!**数据节(data section)是程序的一部分,它存储了静态和全局变量的初始化值。在程序执行过程中,这些变量的值可能会被修改或者被其他操作所影响。因此,通过动态调试,在程序运行时可以实时查看这些变量的当前值,而不仅仅是它们的初始化值。
由于动态调试可以在程序运行时观察和修改内存中的数据,因此可能需要使用动态调试来确认 Buf2 的具体值,以便确定判断条件的结果
其实IDA通常不用于动态调试,IDA一般当作地图来使用,我们通常会选用OD或者X64dgb进行动态调试
这里我们还是讲解一些IDA动态调试
设立断点
在这里插入图片描述在这里插入图片描述选择start process
或者直接按F9即可
输入38个字符

在这里插入图片描述
在看到IDA
在这里插入图片描述
F7步入,F8不过
不过这里当我们执行过
v12 = &Buf2;这条语句时,我们会看到这个
在这里插入图片描述
点击小坐标我们进去看看
在这里插入图片描述
会出现这样的画面,同时我们再点击进入下面箭头所指的部分

在这里插入图片描述
跳转到这样的画面
在这里插入图片描述
如果你不清楚,数据是哪里开始的你可以回到刚才上一页的地方
看到这样的画面
在这里插入图片描述
至于结束会出现在这里,也就是0的前面
在这里插入图片描述
我们再次提取数据,用上一道题讲过的方法
0x0A, 0x0B, 0x7D, 0x2F, 0x7F, 0x67, 0x65, 0x30, 0x63, 0x60,
0x37, 0x3F, 0x3C, 0x3F, 0x33, 0x3A, 0x3C, 0x3B, 0x35, 0x3C,
0x3E, 0x6C, 0x64, 0x31, 0x64, 0x6C, 0x3B, 0x68, 0x61, 0x62,
0x65, 0x36, 0x33, 0x60, 0x62, 0x36, 0x1C, 0x7D,

最后进行解密

这里给出了两个语言写的代码,自行研究一下

#include <stdio.h>
#include <stdlib.h>
int  main()
{
	int i=0;
	int str[38]={ 0x0A, 0x0B, 0x7D, 0x2F, 0x7F, 0x67, 0x65, 0x30, 0x63, 0x60, 
   0x37, 0x3F, 0x3C, 0x3F, 0x33, 0x3A, 0x3C, 0x3B, 0x35, 0x3C, 
   0x3E, 0x6C, 0x64, 0x31, 0x64, 0x6C, 0x3B, 0x68, 0x61, 0x62, 
   0x65, 0x36, 0x33, 0x60, 0x62, 0x36, 0x1C, 0x7D};
   int str1[38]={0};
   int str2[38]={0};
   for(i=0;i<38;i++)
   {
   	str1[i]=str[37-i];
   }
    for(i=3;i<38;i++)
    {
    	str1[i - 2] ^= str1[i - 3];
        str1[i - 1] ^= str1[i - 2];
        str1[i] ^= str1[i - 1];
	}
	for(i=0;i<38;i++)
	{
		str2[i]=str1[37-i];
		printf("%c",str2[i]);
	}
	
   return 0;
 } 

Python注意缩进

 k= [
    0x0A, 0x0B, 0x7D, 0x2F, 0x7F, 0x67, 0x65, 0x30, 0x63, 0x60,
    0x37, 0x3F, 0x3C, 0x3F, 0x33, 0x3A, 0x3C, 0x3B, 0x35, 0x3C,
    0x3E, 0x6C, 0x64, 0x31, 0x64, 0x6C, 0x3B, 0x68, 0x61, 0x62,
    0x65, 0x36, 0x33, 0x60, 0x62, 0x36, 0x1C, 0x7D
   ]
s = k[::-1]
for i in range(3, len(s)):
    s[i - 2] ^= s[i - 3]
    s[i - 1] ^= s[i - 2]
    s[i] ^= s[i - 1]

s=s[::-1]
for i in range(len(s)):
    print(chr(s[i]), end='')

结果
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

【运维工程师学习三】shell编程

【运维工程师学习三】shell编程 1、系统中sh命令是bash的软链接2、Shell脚本标准格式之文件后缀3、Shell脚本标准格式之文件内容首行4、Shell脚本的运行方法一、作为可执行程序解释 二、作为解释器&#xff08;bash&#xff09;参数 5、find、grep、xargs、sort、uniq、tr、cut…

MOS、PMOS、NMOS

1、MOS 管 简介 MOS管的英文全称叫 MOSFET(Metal Oxide Semiconductor Field Effect Transistor)&#xff0c;即 金属氧化物半导体型场效应管&#xff0c;属于场效应管中的绝缘栅型。 2、MOS 管工作原理 学习视频链接 &#xff1a; 1、https://www.bilibili.com/video/BV1L54…

代码随想录算法训练营第五十二天|300.最长递增子序列、 674. 最长连续递增序列、 718. 最长重复子数组

最长递增子序列 dp[i]的定义dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度状态转移方程 位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 1 的最大值。 所以&#xff1a;if (nums[i] > nums[j]) dp[i] max(dp[i], dp[j] 1);dp[i]的初始化 每一…

动态地图开发的未来应用场景有哪些?

动态地图开发应用已经成为现代数字世界中不可或缺的一部分。这种技术的灵活性为公司和组织提供了一种简单却强大的方式&#xff0c;以在现实世界地图上显示各种信息。无论是用于自动导航系统、气象预报、实时交通状况或利用商业洞察力获取市场数据&#xff0c;动态地图开发应用…

赛效:视频怎么转音频怎么转

1&#xff1a;先在浏览器中将91ai工具网站给打开&#xff0c;登录账号后从“音视频工具”中选择视频转音频功能&#xff0c;我们就可以进入到视频转音频的功能界面了。 2&#xff1a;点击上传视频文件&#xff0c;需要注意的是非会员不能上传超过5M的视频。 3&#xff1a;输入格…

Maven高级操作--分模块设计、聚合、继承和私服

一、分模块设计与开发 1.1 分模块设计 问题&#xff1a;当项目做大做强的时候&#xff0c;前面的基础Spring开发的框架都无法满足java大型项目的维护和复用&#xff0c;而且团队合作也会造成较大的困难。所以就需要分模块设计&#xff1a;将项目按照功能拆分成若干个子模块&a…

JDK8新特性-下部

文章目录 一、Stream结果收集1.1 结果收集到集合中1.2 结果集收集到数组中1.3 对流中数据做聚合运算1.4 对流中数据做分组操作1.5 对流中的数据做分区操作1.6 对流中的数据做拼接 二、并行的Stream流2.1 串行的Stream流2.2 并行流2.2.1获取并行流2.2.2 并行流操作 2.3 串行流与…

深入探究小程序技术:构建轻巧高效的移动应用

&#x1f482; 个人网站:【海拥】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 1.背景&#xff1a;2. …

SwiftUI async/await 并发代码提示 Non-sendable type cannot cross actor boundary 警告的解决

问题现象 从 Swift 5.5 开始, 为我们引入了新的 async/await 并发模型,使用它我们可以用更简洁的代码来实现复杂的并发功能。 async/await 并发模型同时也对大部分系统框架中的类型做了扩展,让它们在并发上重新“焕发青春”。 不过,我们在用新并发模型撸码的过程中,有…

深度学习训练营之中文文本分类识别

深度学习训练营之中文文本分类识别 原文链接环境介绍前置工作设置环境设置GPU加载数据 构建词典生成数据批次和迭代器模型定义定义实例 定义训练函数和评估函数模型训练模型预测 原文链接 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366;…

SpringBoot(实用开发篇)

SpringBoot实用开发篇 第三方属性bean绑定 ConfigurationProperties 使用ConfigurationProperties为第三方bean绑定属性 配置文件 datasource:driverClassName: com.mysql.jdbc.Driver servers:ipAddress: 192.168.0.1port: 80timeout: -1ServerConfig类&#xff1a; Dat…

PIC16F877A Proteus仿真太阳能市电互补供电系统蓄电池充电 -0051

PIC16F877A Proteus仿真太阳能市电互补供电系统蓄电池充电 -0051 Proteus仿真小实验&#xff1a; PIC16F877A Proteus仿真太阳能市电互补供电系统蓄电池充电 -0051 功能&#xff1a; 硬件组成&#xff1a;PIC16F877A单片机 LCD1602显示器AC220V市电转59V直流蓄电池充电电路…

机器学习讲了什么?如果你看不懂南瓜书和花书,先看看这本机器学习图解书

优达学城创始人Sebastian Thrun作序推荐&#xff0c; 机器学习布道者、Google和Apple前工程师Luis G. Serrano 倾情分享&#xff1a; 以图形的方式讲解机器学习经典算法和技术。 近年来&#xff0c;“人工智能”“机器学习”和“深度学习”蓬勃发展&#xff0c;各种新的技术和…

9-1小波变换 小波分解和重构(matlab程序)

1.简述 一、小波处理信号的一般过程 1&#xff09;取样&#xff1a;这是一个预处理步骤。若信号连续&#xff0c;那么必须以能够捕获原信号必要细节的速率取样。不同的应用决定了不同的取样率。如&#xff1a;原信号的细节频率为20kHz&#xff0c;由Nyquist采样定理&#xff0c…

剑指 Offer !37. 序列化二叉树

剑指 Offer 37. 序列化二叉树 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树。 你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑&#xff0c;你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序…

Day43

思维导图 深拷贝和浅拷贝 1> 如果类中有指针成员时&#xff0c;如果没有显性的定义拷贝构造和拷贝赋值函数&#xff0c;系统默认提供的都只能实现浅拷贝&#xff0c;需要显性定义出深拷贝函数&#xff0c;为了完成指针成员的独立赋值&#xff0c;如果类中没有指针成员&#…

java面向对象之java继承

文章目录 一、java继承总结 一、java继承 继承的概念 继承是java面向对象编程技术的一块基石&#xff0c;因为它允许创建分等级层次的类。 继承就是子类继承父类的特征和行为&#xff0c;使得子类对象&#xff08;实例&#xff09;具有父类的实例域和方法&#xff0c;或子类…

Java之集合Collection

Collection接口有两个子接口&#xff1a;List(链表|线性表)和Set(集) ---|Collection: 单列集合---|List: 有存储顺序, 可重复---|ArrayList: 数组实现, 查找快, 增删慢由于是数组实现, 在增和删的时候会牵扯到数组增容, 以及拷贝元素. 所以慢。数组是可以直接按索引查找, 所以…

less和sass

less和sass 相比于css解决了什么问题&#xff1f; 答案&#xff1a;less和sass可以嵌套&#xff0c;可以使用变量&#xff1b;而css不可以 BEM/CSS modules/Atomic CSS/CSS in JS&#xff0c;这些方案应用于工程化中&#xff0c;解决了的问题是&#xff1a; 多人协同/大规模场…

Leonard ai 画明代皇帝肖像

链接&#xff1a; https://app.leonardo.ai/ai-generations prompt&#xff1a; Highly detailed doodle illustration of a Chinese emperor centered, isometric, mural, doodle, composition, shape, pattern, vector art ready to print Negative Prompt&#xff1a; …