逆向入门(1)

article/2025/8/12 11:46:55

前言:

本篇文章面向想入门逆向的新手小白。

NSSCTF和BUUCTF是两个刷题网站,知识点下面会有对应的题,大家可以自己试着做一下

NSSCTF:https://www.nssctf.cn/problem

BUUCTF:https://buuoj.cn/challenges

1.看exe模式(位数)

把一个exe程序拖到DetectItEasy或者exeinfope里面看这个exe的位数(一般是64位有的时候也可能是32位)(后期脱壳也会用到这个工具)这决定是把exe拖到ida-32里面还是拖到ida-64里面。

这个exe程序就是64位的

2.IDA Pro的使用快捷键

题:BUU--easyre

先看位数

64位的程序,拖到ida-64

然后点yes

当然你也可以ctrl+f 查找main函数 然后再F5反汇编查看函数

ctrl+c将flag复制下来然后提交

3.位运算

符号

描述

运算规则

&

两个位都为1时,结果才为1

|

两个位都为0时,结果才为0

^

异或

两个位相同为0,相异为1

~

取反

0变1,1变0

<<

左移

各二进位全部左移若干位,高位丢弃,低位补0

>>

右移

各二进位全部右移若干位,对无符号数,高位补0;有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

1.&

清零

如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。

取一个数的指定位

比如取数 X=1010 1110 的低4位,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行按位与运算(X&Y=0000 1110)即可得到X的指定位。

判断奇偶

只要根据最未位是0还是1来决定,为0就是偶数,为1就是奇数。因此可以用if ((a & 1) == 0)代替if (a % 2 == 0)来判断a是不是偶数。

2.|

常用来对一个数据的某些位设置为1

比如将数 X=1010 1110 的低4位设置为1,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行按位或运算(X|Y=1010 1111)即可得到。

3.~ (取反)

使一个数的最低位为零

使a的最低位为0,可以表示为:

a & ~1

~1的值为 1111 1111 1111 1110,再按"与"运算,最低位一定为0。因为" ~"运算符的优先级比算术运算符、关系运算符、逻辑运算符和其他运算符都高。

4.^ (异或) 相同为0,不同为1

翻转指定位

比如将数 X=1010 1110 的低4位进行翻转,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行异或运算(X^Y=1010 0001)即可得到。

与0相异或值不变

例如:1010 1110 ^ 0000 0000 = 1010 1110

3)交换两个数

void Swap(int &a, int &b){

if (a != b){

a ^= b;

b ^= a;

a ^= b;

}

}

5.>>

操作数每右移一位,相当于该数除以2。

6.<<

若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。

4.移位

[SWPUCTF 2021 新生赛]简简单单的逻辑

list[i]>>4,就是将当前列表元素向右移4位,即当i=0时 值为47 >>4 是将47的二进制 高位向右移动四位 也就是 0010111向右移动4位 00000010=2。

(list[i] & 0xf)<<4,就是先与0xf进行按位运算,保留低4位,然后左移4位。&0xf <<4 是将 47的二进制值00101111跟16的二进制值(1111)进行与运算,也就是当两个位置的数都为1时 与运算的结果才为1 否则都是0,00101111&00001111=00001111再将其移动到高位 因为有个<<4 =240

然后将两个值相加。

 
#include <stdio.h>
#include <string.h>int main() {char result[] = "bcfba4d0038d48bd4b00f82796d393dfec";char flag[100] = {0};int list[] = {47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25};int len = sizeof(list) / sizeof(list[0]);int i, key;for (i = 0; i < len; i++) {key = (list[i] >> 4) + ((list[i] & 0xf) << 4);int hex_value = 0;sscanf(result + 2 * i, "%2x", &hex_value);flag[i] = (char)(hex_value ^ key);}flag[len] = '\0';printf("%s\n", flag);return 0;
}

5.替换

直接看题

拖进ida-64里面

但这不是真正的flag

那我们再来分析一下函数

也就是把flag里面的o替换成0

(如果你的是数字的话,那你就按R转成字符)

所以flag就是{hell0_w0rld}

6.异或(Xor)

基本概念

1.1 符号

异或是一种二进制的 位运算,符号以 XOR 或 ^ 表示。

1.2 运算规则

相同为0,不同为1,即

1 ^ 1 = 0

0 ^ 0 = 0

1 ^ 0 = 1

由运算规则可知,任何二进制数与零异或,都会等于其本身,即 A ^ 0 = A。

1.3 异或性质

(1)交换律:A ^ B = B ^ A

(2)结合律:(A ^ B)^ C = A ^ ( B ^ C )

(3)自反性:A ^ B ^ B = A (由结合律可推:A ^ B ^ B = A ^ ( B ^ B ) = A ^ 0 = A)

异或运算的性质

(1)0^N=N, N^N=0;

(2)异或运算满足交换律和结合律,a^b=b^a (a^b)^c=a^(b^c)

放入ida64

左边ctrl+f寻找main函数,然后f5反汇编

分析代码(首先这是一个c语言)

一般for循环都是重要内容,所所以我们直接从for循环开始看

循环的条件是i<33,也就是从索引 1 开始到 32(因为条件是 i < 33),在每次循环中,它将当前字符 __b[i] 与前一个字符 __b[i - 1] 进行按位异或(^)操作,并将结果重新赋值给当前字符 __b[i]

在for循环下面还有一个if语句,如果if括号里面的东西为真,就输出“success”,这就要求strncmp(__b, global, 0x21uLL)这个条件为假,因为前面有个!(非)

strncmp(__b, global, 0x21uLL)这个语句是比较_b和global的前32个字符

我们看一下global的内容

发现了主要内容,shift+e导出

用c语言写解密函数

#include <stdio.h>
int main()
{int arr[33]={ 0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,0x78, 0x80, 0x5A, 0x38, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,0x76, 0x22, 0x40, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,0x47, 0x32, 0x4F,};char flag[33]={0};int i;flag[0] = 0x66;for(i=1;i<33;i++){flag[i]=arr[i] ^ arr[i-1];}for(i=0;i<33;i++)printf("%c",flag[i]);
}
return 0;

就得到了flag

7.Base家族(换表)

我建议你积累一下换表base的脚本

不换表base

拖入ida

S1里面没东西,看看s2

用在线解base网站:https://www.toolhelper.cn/EncodeDecode/Base64

当然你也可以用工具

换表base

找main函数

点开看看

Base64的编码方式

所以密文就是 5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8==

退回 f5反汇编

看一下这个函数

把61换成字符型,61的ASCII码是=

再看一下aQvejafhmuyjbac

所以base换表就是 qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD

就得到了flag

还可以使用在线网站

ctfer必备厨子:https://gchq.github.io/CyberChef/

就得到了flag

总结:

base64与base64换表

标准的base64加解密所用表是【ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/】刚好64个字符

如果对标准表中的字符进行顺序替换,称之为base64换表

  • 对于标准表的base64,可以直接用编程语言提供的解密函数直接解密或者使用在线网站解密等

  • 对于换表base64,需要多做一步映射,将换表的字符映射回标准表,然后再进行解密

怎么映射呢?拿本题来举例,换表是【qvEJAfHmUYjBac+u8Ph5n9Od17FrCL/X0gVtM4Qk6Tz3wNSsyoebilxWKGZpRD】

密文是【5Mc58bPHLiAx7J8ocJllaVUxaJvMcoYMaoPMaOfg15c475tschfM/8==】

密文中第一个字符是5,在换表中的索引(下标)为19,而在标准表中,索引19处的字符为【T】

密文中第二个字符是M,在换表中的索引(下标)为37,而在标准表中,索引19处的字符为【I】

以此类推,完成映射

映射可以通过自写循环来实现,也可以直接使用字符串函数translate。

自写循环映射
import base64 #导入base64模块用于解密
s1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' #标准表
s2 = 'qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD' #base64换表
en_text = '5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8==' #密文map_text = '' #用于存放密文通过换表映射回标准表的字符
for i in en_text:if(i != '='): #注意密文中存在等号的情况下,不需要替换!idx = s2.index(i) #获取每个密文的字符在换表中的索引map_text += s1[idx] #取出标准表中的该索引的字符,就是正常base64加密的密文else:map_text += i
print(map_text) #可以先看看标准表base64加密的密文
print(base64.b64decode(map_text)) #直接使用提供的base64解密函数,获得明文,就是flag
库函数映射
import base64 #导入base64模块用于解密
s1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' #标准表
s2 = 'qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD' #base64换表
en_text = '5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8==' #密文map = str.maketrans(s2, s1) #用str类中的maketrans建立映射,注意第一个参数是需要映射的字符串,第二个参数是映射的目标(将换表的字符映射回标准表)
map_text = en_text.translate(map) #映射实现替换密文,替换前是base64换表加密,替换后则是base64标准表加密
print(map_text) #可以先看看标准表加密的密文
print(base64.b64decode(map_text)) #直接使用提供的base64解密函数,获得明文,就是flag

8.脱upx壳

首先要查壳,可以用exeinfope工具,把exe文件拖进去

无壳

有壳

对于有壳的文件你就得脱壳(注意要把你要脱壳的文件放在upx工具里面)保持路径一致

在脱upx壳的工具里面cmd打开终端

输入命令

upx -d 你要脱壳的exe名称

这就脱完了

不信你再检查一下

这就完了


http://www.hkcw.cn/article/aTPyZCZdvv.shtml

相关文章

经典算法回顾之最小生成树

最小生成树&#xff08;Minimum Spanning Tree&#xff0c;简称MST&#xff09;是图论中的一个重要概念&#xff0c;主要用于解决加权无向图中连接所有顶点且总权重最小的树结构问题。本文对两种经典的算法即Prim算法和Kruskal算法进行回顾&#xff0c;并对后者的正确性给出简单…

Java八股文智能体——Agent提示词(Prompt)

这个智能体能够为正在学习Java八股文的同学提供切实帮助&#xff1a;不仅可以帮你优化答案表述&#xff0c;还能直接解答八股文相关问题——它会以面试者的视角&#xff0c;给出贴合求职场景的专业回答。 将以下内容发送给任何一个LLM&#xff0c;他会按照你提示词的内容&…

VScode编译调试debug,gpu的cuda程序,Nsight

进行下面操作的前提是&#xff0c;我们的环境已经能跑简单的CUDA程序了。 一、安装Nsight 二、创建launch.json文件 {"version": "0.2.0","configurations": [{"name": "CUDA C: Launch","type": "cuda-gdb…

飞牛fnNAS存储空间模式详解

目录 一、NAS的存储空间 二、多硬盘对NAS速度的提升原理 三、多硬盘对数据安全的提升原理 四、多硬盘对容量的提升原理 五、磁盘阵列模式 六、飞牛NAS支持的存储模式 七、具体如何选择存储空间模式 在数字化时代,数据是个人和企业发展的核心资产,但面临硬盘损坏、病毒…

vue3: baidusubway using typescript

项目结构&#xff1a; <!--npm install -D tailwindcss-3d BaiduSubwayMap.vue npm install -D tailwindcss postcss autoprefixer--> <template><div class"relative w-full h-screen"><!-- 地图容器 --><div id"subway-container…

【递归、搜索与回溯】专题二、二叉树中的深搜

文章目录 1.计算布尔二叉树的值1.1 题目1.2 思路1.3 代码 2.求根节点到叶节点数字之和2.1 题目2.2 思路2.3 代码 3.二叉树剪枝3.1 题目3.2 思路3.3 代码 4.验证二叉搜索树4.1 题目4.2 思路4.3 代码 5.二叉搜索树中第K小的元素5.1 题目5.2 思路5.3 代码 6.二叉树的所有路径6.1 题…

Windows商店中的免费扫雷游戏应用

《扫雷》是一款经典的单人益智小游戏&#xff0c;1992年微软发布的Windows 3.1中加入该游戏&#xff0c;从此风靡全世界。游戏目标是通过逻辑推理&#xff0c;在最短的时间内根据点击格子出现的数字找出所有非雷格子&#xff0c;同时避免踩雷。 此Windows应用实现了经典扫雷的…

无法运用pytorch环境、改环境路径、隔离环境

一.未建虚拟环境时 1.创建新项目后&#xff0c;直接运行是这样的。 2.设置中Virtualenv找不到pytorch环境&#xff1f;因为此时没有创建新虚拟环境。 3.选择conda环境&#xff08;全局环境&#xff09;时&#xff0c;是可以下载环境的。 运行结果如下&#xff1a; 是全局环境…

古老的传说(Player、Stage)是否还能在蓝桥云课ROS中重现-250601(失败)

古老的传说是否还能在蓝桥云课ROS中重现-250601 经典复现何其难&#xff0c;百分之二就凉凉&#xff01; 古老的传说 那是很久很久以前的故事……上个世纪的一个机器人项目 Player、Stage这个项目最早起源于1999年&#xff0c;由美国南加州大学机器人研究实验室开发&#xff0…

机器学习:逻辑回归与混淆矩阵

本文目录&#xff1a; 一、逻辑回归Logistic Regression二、混淆矩阵&#xff08;一&#xff09;精确率precision&#xff08;二&#xff09;召回率recall&#xff08;三&#xff09;F1-score&#xff1a;了解评估方向的综合预测能力&#xff08;四&#xff09;Roc曲线&#xf…

Spring是如何实现属性占位符解析

Spring属性占位符解析 核心实现思路1️⃣ 定义占位符处理器类2️⃣ 处理 BeanDefinition 中的属性3️⃣ 替换具体的占位符4️⃣ 加载配置文件5️⃣ Getter / Setter 方法 源码见&#xff1a;mini-spring 在使用 Spring 框架开发过程中&#xff0c;为了实现配置的灵活性&#xf…

继承与多态

继承与多态的分析 继承继承与访问限定比较派生类和基类关系派生类的构造顺序基类对象&#xff08;指针&#xff09;派生类对象&#xff08;指针&#xff09;的转换重载和隐藏 虚函数静态绑定与动态绑定指针调用其他调用的绑定方式虚函数实现的依赖 多态 继承 继承的本质&#…

API异常信息如何实时发送到钉钉

#背景 对于一些重要的API&#xff0c;开发人员会非常关注API有没有报错&#xff0c;为了方便开发人员第一时间获取错误信息&#xff0c;我们可以使用插件来将API报错实时发送到钉钉群。 接下来我们就来实操如何实现 #准备工作 #创建钉钉群 如果已有钉钉群&#xff0c;可以跳…

Amazon GameLift实战指南:低成本构建高并发全球游戏服务器架构

一、为什么游戏服务器需要GameLift&#xff1f; 行业痛点 传统自建服务器&#xff1a;扩容慢、DDoS防御弱、全球延迟不均 开源解决方案&#xff08;如Agones&#xff09;&#xff1a;运维成本高、需K8s深度知识 云虚拟机手动扩缩容&#xff1a;响应延迟导致玩家流失 GameLi…

2025安装与配置archlinux很详细

不知不觉&#xff0c;距离上次安装archlinux已经2年多了。我又打算把archlinux作为主力机使用了。 以前也写过一些类似的文章&#xff0c;有一些不变的内容&#xff0c;我直接从原来的文章中复制了&#xff08;包括截图&#xff09;。 《2021年vmware安装archlinux》 https:/…

字节golang后端二面

前端接口使用restful格式&#xff0c;post与get的区别是什么&#xff1f; HTTP网络返回的状态码有哪些&#xff1f; go语言切片与数组的区别是什么&#xff1f; MySQL实现并发安全避免两个事务同时对一个记录写操作的手段有哪些&#xff1f; 如何实现业务的幂等性&#xff08;在…

MyBatis03——SpringBoot整合MyBatis

目录 一、springboot整合mybatis 二、搭建环境 1、引入jar包 2、配置文件 3、准备控制层、业务层、持久层 4、SQLMapper文件 ​编辑 三、动态sql 四、分页 4.1逻辑分页 4.2物理分页 4.2.1引入分页插件在pom.xml 4.2.2使用分页插件 五、事务 编程式事务 声明式事…

【linux】知识梳理

操作系统的分类 1. 桌⾯操作系统: Windows/macOS/Linux 2. 移动端操作系统: Android(安卓)/iOS(苹果) 3. 服务器操作系统: Linux/Windows Server 4. 嵌⼊式操作系统: Android(底层是 Linux) Liunx介绍 liunx系统:服务器端最常见的操作系统类型 发行版:Centos和Ubuntu 远程连接操…

计算机网络第1章(上):网络组成与三种交换方式全解析

目录 一、计算机网络的概念二、计算机网络的组成和功能2.1 计算机网络的组成2.2 计算机网络的功能 三、电路交换、报文交换、分组交换3.1 电路交换&#xff08;Circuit Switching&#xff09;3.2 报文交换&#xff08;Message Switching&#xff09;3.3 分组交换&#xff08;Pa…

经典面试题:一文了解常见的缓存问题

在面试过程中&#xff0c;面试官的桌子上摆放着很多高频的面试题&#xff0c;能否顺利回答决定了你面试通过的概率。其中缓存问题就是其中的一份&#xff0c;可以说掌握缓存问题及解决方法是面试前必须准备的内容。那么缓存有什么典型的问题&#xff0c;出现的原因是什么&#…