题目


分析过程

是一个无壳,64位的文件

丢到IDA里面,找到main函数

 1 int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
2 {
3 __int64 v3; // rdx
4 char *v4; // [rsp+20h] [rbp-18h]
5
6 qword_140004618 = (__int64)malloc(16ui64); // "ui64"表示无符号的64位整数
7 qword_140004620 = qword_140004618;
8 *(_QWORD *)(qword_140004618 + 8) = 0i64; // *(_QWORD *) 作为一个整体,通常用于将一个地址(或其他整数)转换为一个指向64位无符号整数的指针,并获取该地址上的值。
9 // i64表示64位带符号整数
10 sub_140001020("请输入正确的数字:\n");
11 sub_140001080("%lld"); // %lld是对应 long long
12 sub_1400010E0(v4, v3);
13 }

代码还是很好理解的,我们继续看看sub_1400010E0函数

 1 void __fastcall __noreturn sub_1400010E0(char *input, __int64 a2)
2 {
3 int v2; // er9
4 __int64 input_int64; // r8
5 char *v4; // r10
6 char v5; // al
7 __int64 v6; // rbx
8 char v7; // cl
9 char v8; // [rsp+1Fh] [rbp-3F9h]
10 char v9; // [rsp+20h] [rbp-3F8h] BYREF
11
12 v2 = 0;
13 input_int64 = (__int64)input;
14 if ( input )
15 {
16 v4 = &v9; // v4存放v9字符串的地址,是一个指针
17 do
18 {
19 ++v4; // 将指针往后移动
20 ++v2; // 记录循环次数
21 v5 = a4890572163qwe[input_int64 + -26 * (input_int64 / 26)];// )(*&^%489$!057@#><:2163qwe
22 input_int64 /= 26i64;
23 *(v4 - 1) = v5; // 因为之前+1了,-1又移动回去,就是存放在原来的地址
24 }
25 while ( input_int64 );
26 }
27 v6 = v2;
28 while ( v6 )
29 {
30 v7 = *(&v8 + v6--);
31 sub_1400011E0(v7 ^ 7);
32 }
33 sub_140001220();
34 }
35 /* Orphan comments:
36 )(*&^%489$!057@#><:2163qwe
37 */

提取出最难理解的一部分

v5 = a4890572163qwe[input_int64 + -26 * (input_int64 / 26)];
input_int64 /= 26i64;

)(*&^%489$!057@#><:2163qwe——刚好26个字符

括号里面举例子更好去理解

  • 假设input_int64是8:
  • 8+ -16*(8/26)=8+ -26*0=8
  • 8/26=0——结束循环
  • 假设input_int64=28:
  • 28+ -26*(28/26)=28+ -26*1=2
  • 28/26=1
  • 1+ -26*(1/26)=1+ -26*0=1
  • 1/16=0——结束循环

你可以看作这是一个26位的循环,我们要找到input_int64在循环中对应的位置,也就是数组的索引

v7 = *(&v8 + v6--);

这里突然出现一个v8,还是取v8的地址,我们看看栈

发现v8就在v9上面,这行代码就是取出v9中的数赋值给v7,为后面的异或操作做准备

接着看看sub_1400011E0函数

 1 _QWORD *__fastcall sub_1400011E0(char a1)
2 {
3 _QWORD *result; // rax
4 __int64 v3; // rdx
5
6 result = malloc(16ui64);
7 v3 = qword_140004618;
8 qword_140004618 = (__int64)result;
9 *(_QWORD *)(v3 + 8) = result; // 将result存储到v3 + 8地址处,也就是qword_140004618 + 8地址处
10 *(_BYTE *)v3 = a1; // 将a1的值存储到v3地址处,也就是qword_140004618地址处
11 result[1] = 0i64; // 将result的第二个_QWORD大小的元素设置为0
12 return result;
13 }

这个函数的作用是动态分配了16字节的内存空间

接着看看sub_140001220函数

可以输出成功的局部声明在while循环里面,v7判断关键

一开始我遗漏了条件,不知道qword_140004620里面放的是什么 (我有预感是异或操作结果,但是我们需要找到证据)

在main函数中:qword_140004620 = qword_140004618;

在sub_1400011E0函数中:*(_BYTE *)v3 = a1;

a1就是经过异或操作的结果,v3地址就是qword_140004618地址

所以qword_140004620里面放的就是异或操作的结果

两个if就是判断异或结果与字符串的比较结果是否相同

判断结果将影响v4与v7的值,而从打印结果

这个循环直到(v2 < 14)条件不成立结束


逆向脚本

从最后一个sub_140001220函数往前推,将 /..v4p$$!>Y59- 与7异或,得到sub_1400010E0函数中的v7,也就是v9字符串,最重要的是可以得出其在 )(*&^%489$!057@#><:2163qwe 中对应的索引值

思路大概就是这样,写脚本吧

 1 str1 = ')(*&^%489$!057@#><:2163qwe'
2 str2 = '/..v4p$$!>Y59-'
3 v7 = ''
4 a = []
5
6 # 对 str2 中的每个字符进行异或运算,并将结果存储在 v7 中
7 for i in range(len(str2)):
8 v7 += chr(ord(str2[i]) ^ 7)
9
10 # 对于 v7 中的每个字符,找到其在 table 中的索引并存储在列表 a 中
11 for j in v7:
12 a.append(str1.index(j))
13
14 flag = 0
15 # 将 a 中的索引转换为 26 进制数字,并存储在 flag 中
16 for z in range(len(a)):
17 flag *= 26
18 flag += a[z]
19
20 print(flag)

flag

flag{2484524302484524302}

CTFshow Reverse 逆向4 学习记录的更多相关文章

  1. Java设计模式学习记录-迭代器模式

    前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...

  2. Git 教程 -- 基于自己学习记录

    Git 教程 -- 基于自己学习记录 1. 引言 由于学校布置了一项熟悉 git 和 svn 操作的实验,所以自己重新温习了下 git,记录过程在这. 2. 注册登录 GitHub. 3. 选择一个仓 ...

  3. JavaScript学习记录二

    title: JavaScript学习记录二 toc: true date: 2018-09-13 10:14:53 --<JavaScript高级程序设计(第2版)>学习笔记 要多查阅M ...

  4. Python学习记录:括号配对检测问题

    Python学习记录:括号配对检测问题 一.问题描述 在练习Python程序题的时候,我遇到了括号配对检测问题. 问题描述:提示用户输入一行字符串,其中可能包括小括号 (),请检查小括号是否配对正确, ...

  5. 前端学习记录 week 1

    前端学习记录 week 1 基础知识 CSS盒模型 所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用.CSS盒模型本质上是一个盒子,封 ...

  6. Quartz 学习记录1

    原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...

  7. Java 静态内部类与非静态内部类 学习记录.

    目的 为什么会有这篇文章呢,是因为我在学习各种框架的时候发现很多框架都用到了这些内部类的小技巧,虽然我平时写代码的时候基本不用,但是看别人代码的话至少要了解基本知识吧,另外到底内部类应该应用在哪些场合 ...

  8. Apache Shiro 学习记录4

    今天看了教程的第三章...是关于授权的......和以前一样.....自己也研究了下....我觉得看那篇教程怎么说呢.....总体上是为数不多的精品教程了吧....但是有些地方确实是讲的太少了.... ...

  9. UWP学习记录12-应用到应用的通信

    UWP学习记录12-应用到应用的通信 1.应用间通信 “共享”合约是用户可以在应用之间快速交换数据的一种方式. 例如,用户可能希望使用社交网络应用与其好友共享网页,或者将链接保存在笔记应用中以供日后参 ...

  10. UWP学习记录11-设计和UI

    UWP学习记录11-设计和UI 1.输入和设备 通用 Windows 平台 (UWP) 中的用户交互组合了输入和输出源(例如鼠标.键盘.笔.触摸.触摸板.语音.Cortana.控制器.手势.注视等)以 ...

随机推荐

  1. flutter3-winchat桌面端聊天实例|Flutter3+Dart3+Getx仿微信Exe程序

    首发原创flutter3+bitsdojo_window+getx客户端仿微信exe聊天Flutter-WinChat. flutter3-dart3-winchat 基于flutter3+dart3 ...

  2. 小程序开发:接入腾讯云的人像动漫化api接口

    接口如下: 图片的传参方式有两种,一种是传图片的base64,一种是图片url: 我打算免费版使用base64,如果付费用户支持永久存储历史的图片记录(图片存储到腾讯云对象存储中). 前端框架我用的u ...

  3. (二)Git 学习之基础篇

    一.理论基础 1.1 Git 记录的是什么? Git 和其它版本控制系统(如 SVN)的主要差别在于 Git 对待数据的方式. 1.1.1 SVN 记录差异比较 从概念上来说,SVN 以文件变更列表的 ...

  4. ContextMenuManager右键z 右键菜单

    常用软件 下载 https://files.cnblogs.com/files/pengchenggang/ContextMenuManager右键z-右键菜单.rar?t=1664158084

  5. 替换掉Chrome浏览器的新标签页【已做好自己的插件,并提供下载】

    https://jingyan.baidu.com/article/fc07f9891b256312ffe5190a.html 我做好了自己的 Chrome 新插件 https://files.cnb ...

  6. Dreamweaver基础教程:系列介绍

    目录 前言 Dreamweaver 软件介绍 软件安装 学习支持 相关资料 前言 我一直对前端的一些技术比较感兴趣,之前有用过GitHub上的开源项目部署了自己的导航网站猿导航,但并没有系统的去深入学 ...

  7. 专访惠众科技|元宇宙应用如何借助3DCAT实时云渲染实现流畅大并发呈现?

    当前互联网流量红利已经逐渐消失,营销同质化愈发严重.在这样的背景下,催生了以元宇宙为焦点的虚拟产业经济.元宇宙在各行各业中以不同形式快速萌生.成长,呈现出多元化的应用场景.尤其是众多品牌,将元宇宙视为 ...

  8. CSS(语义化标签、多媒体标签、新表单元素、属性选择器、结构伪类选择器、伪元素选择器、盒子模型、滤镜、calc函数、过渡)

    一.HTML5新特性 概述 HTML5 的新增特性主要是针对于以前的不足,增加了一些新的标签.新的表单和新的表单属性等. 这些新特性都有兼容性问题,基本是 IE9+ 以上版本的浏览器才支持,如果不考虑 ...

  9. Linux快速入门(二)Linux基础操作

    绝对路径和相对路径 Linux中绝对路径指从根目录开始,即/目录. 相对路径是指相对于当前路径开始,即./ 目录,../表示上一级目录路径. pwd pwd命令用于查看当前所在目录. gubeiqin ...

  10. 记录一次报错,程序启动,MySql自动关闭

    关于初级程序员,对于安装mysql,以及配置可能会报几次错 有时候虽然进行第二次安装成功,但是第一次的残留文件还在,可能引起报错 在这里记录一次我的报错 程序启动导致Mysql自动断开,需要手动打开 ...