reverse方向入门过程
声明:因为懒,所以懒得从头开始做,基本都是看着wp复现的,其中大部分的wp都来源于
https://blog.csdn.net/palmer9/category_9607326.html
然后直接开始做题
BUU部分
最简单的题目(直接搜索字符串就能看到flag的)
1.[BJDCTF 2nd]guessgame
打开IDA,F12搜索字符串就能看到
xor
一个64位的文件,直接F5看main函数
其中重要的语句为
if ( strlen(v6) != 33 ) //判断v6的长度是否为33(从上面的程序中可以看出,v6就是我们的输入)
for ( i = 1; i < 33; ++i ) //进行循环异或,从v6的第二位开始将v6的每一位与前一位异或
v6[i] ^= v6[i - 1];
if ( !strncmp(v6, global, 0x21uLL) ) //比较v6与global段处存放的前33位(也就是0x21)是否相同,是如果相同的话输出success,
大致地看完代码之后我们发现进入global段里面写了什么很重要,我们要做的就是将异或后的v6与global段中的数据进行比对,比对完之后相同就能拿到flag(这里的sucess应该是提示你通过了这道题,并且前面有提示input your flag,也就是要我们输入一串字符(就是v6变量)做为答案。)那么我们只要进入global看到的global的内容就是异或后的v6,也就是异或后的flag
双击进入global看到内容。
```python
str1 = ['f', 0x0A, 'k', 0x0C, 'w', '&', 'O', '.', '@', 0x11, 'x', 0x0D, 'Z', ';', 'U', 0x11, 'p', 0x19, 'F', 0x1F, 'v','"', 'M', '#', 'D', 0x0E, 'g', 6, 'h', 0x0F, 'G', '2', 'O']x = 'f'for i in range(1, len(str1)):if (isinstance(str1[i], str)):if (isinstance(str1[i - 1], str)):x += chr(ord(str1[i]) ^ ord(str1[i - 1]))else:x += chr(ord(str1[i]) ^ str1[i - 1])else:x += chr(str1[i] ^ ord(str1[i - 1]))print(x)
新年快乐(最简单的脱壳)
发现放进IDA里有错误报告,应该是加壳了
先用PE查壳(步骤省略)
直接用万能工具查壳,然后点击脱壳就好了
然后得到一个这样的文件,然后就可以放进IDA了,然后看main函数,里面的程序还是相当简单的
输入一个v5,与v4相等即可拿到flag(v4是HappyNewYear!,在上面可以看到)
v5来源于上面的scanf,也就是我们得到输入
emmmmm,其实也就是HappyNewYear!做为flag
所以flag是flag{HappyNewYear!}
SimpleRev
点进去看main函数,发现没什么关键的,下面代码的大致意思就是输入的不为d或者D就退出这次循环
和如果输入的为Q或者q就退出,然后看到有一个Decry函数,点进去
点进Decry函数
其中v9注意按R转换成字符串格式
同时发现有一个join函数,内容如下,大致意思为,
大致意思为将a1的长度赋值给v2
将a2的长度赋值给v3,然后malloc动态分配空间dest给a1和a2 (大小为a1+a2+1)
然后将a1赋值给dest(strcpy函数),将a2拼接到dest后(strcat函数) (。。。。其实整个函数就是将a1和a2,也就是下面的key3和v9连接起来的意思)
unsigned __int64 Decry()
{char v1; // [rsp+Fh] [rbp-51h]int v2; // [rsp+10h] [rbp-50h]int v3; // [rsp+14h] [rbp-4Ch]int i; // [rsp+18h] [rbp-48h]int v5; // [rsp+1Ch] [rbp-44h]char src[8]; // [rsp+20h] [rbp-40h]__int64 v7; // [rsp+28h] [rbp-38h]int v8; // [rsp+30h] [rbp-30h]__int64 v9; // [rsp+40h] [rbp-20h]__int64 v10; // [rsp+48h] [rbp-18h]int v11; // [rsp+50h] [rbp-10h]unsigned __int64 v12; // [rsp+58h] [rbp-8h]v12 = __readfsqword(0x28u);*(_QWORD *)src = 357761762382LL; //(按R变成SLCDN)v7 = 0LL;v8 = 0;v9 = 512969957736LL;v10 = 0LL;v11 = 0;text = (char *)join(key3, &v9); //令text等于key3+v9//key3="kills"(双击点进key3可知)//v9="hadow" //因为小端序存储//则 text= killshadowstrcpy(key, key1); //将key1赋值给key ,key = "ADSFK"(同样双击可知)strcat(key, src); //将src处的字符拼接到key后//key = "ADSFKNDCLS"(小端序)v2 = 0; v3 = 0;getchar();v5 = strlen(key); // v5 = key的长度 v5 = 10for ( i = 0; i < v5; ++i ){if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 ) //如果key中存在大写字母,将其变成小写(asc码加32)(这里的v5是10,对10取余等于个位数,而v3最大只到9,所以可以忽略v5)key[i] = key[v3 % v5] + 32; //key = "adsfkndcls"++v3;}printf("Please input your flag:", src);while ( 1 ){v1 = getchar(); //接受用户的输入赋值给v1if ( v1 == 10 ) // 如果输入的为换行符,则退出(都可以按R转换看到是\n,以下省略省略)break;if ( v1 == 32 ) // 如果输入的为空格,则v2加一{++v2;}else{if ( v1 <= 96 || v1 > 122 ) // 如果输入的v1不为小写字母{if ( v1 > 64 && v1 <= 90 ) // 如果v1为大写字母str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97; // 将v1减去39再减去key中下表为[v3++]位置的字母然后加上97之后求除以26的余数再加上97,然后赋值给str2// str1[v2] = (v1-key[v3]+58)%26 + 97 // 变换后str1[v2]存放小写字母} else{str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97; //如果v1为小写,则同样处理}if ( !(v3 % v5) ) //如果循环到key的最后一位 putchar(32); //打印一个空格++v2;}}if ( !strcmp(text, str2) ) // 如果text和str2存储的相同,则成功puts("Congratulation!\n"); // text = "killshadow"elseputs("Try again!\n");return __readfsqword(0x28u) ^ v12;
}
所以我们的目标就是像str2中存入killshadow,其中要满足输入的每个字符减去39再减去key中下标为[v3++]位置的字母然后加上97对26取余然后再加上97,变为killshadow
根据这个要求,我们来编写脚本,首先赋值出一个代表killshadow的变量和一个代表adsfkndcls的变量,然后从大写字母(因为我们的只有我们的大写字母在经过一系列运算之后加上97还能得到的答案是字母的,虽然在字母表中把小写字母写上也没事)中找到一个字母减去39再减去key中下标为v3的字母的asc值再加上97后对26取余再加上97会得到killshadow
(其中97就是a)
key = "adsfkndcls" //赋值给key
text = "killshadow" //赋值给text
flag = ""
_dict = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" //做字母表
v5 = len(text) //赋值给v5 text的长度
for i in range(v5):for v1 in _dict:if ord(text[i]) == (ord(v1) - 39 - ord(key[i % v5]) + 97) % 26 + 97: //例:flag += v1
print(flag)
//例:将text中的第一个k取出并且转换成asc值107,然后判断是否等于大写字母表中的一个值减去39和字母a的asc码值(也就是97),然后加上97,再对26取余,再加上97那么就是flag,我们时候诸葛亮的知道第一个正确字母是K,也就是75,减去39再减去97再加上97,得36,对26取余得到10,然后再加上97=107(后续答案同样如此得来)
答案KLDQCUDFZO
//ord,返回其asc码值
[ACTF新生赛2020]easyre
事先脱壳(UPX脱壳,用之前的万能脱壳工具即可)
前面都是一些定义变量的东西,然后到scanf,输入变量给v19,并且v19如果不等于ACTF{}这些字符,那么return 0
然后定义v16 17 18(?意义不明)
然后解题的重点就在这个循环,那就是判断*(&v4+i)是否等于byte_402000这个数组中下标为的&v16+i-1的数
我们点进去看到了byte_402000有这些,并且在上面的
循环中我们可以知道flag大概是12位
并且*(&v4+i),意为每次v4的地址加1,也就是v4,v5,v6…这样子,直到v15然后判断是否等于byte-402000
所以如果写脚本的话我们要这样写
先将byte-402000中的值赋值给一个变量,然后将v4到v15的值赋值给另外一个变量,
然后将v4中的值用chr转换成字符,然后检索在byte_402000中的位置,然后把这个位置转换成字符添加到flag变量里
这里要介绍两个函数方法,一个叫做append,作用是将对象添加到末尾
例如
aList = [123, ‘xyz’, ‘zara’, ‘abc’];
aList.append( 2009 );
print "Updated List : ", aList;
结果将会输出Updated List : [123, ‘xyz’, ‘zara’, ‘abc’, 2009],2009被添加到了列表的末尾。
一个叫做find ,作用是检索一个字符串在指定字符串中的位置
例如
str1 = “this is string example…wow!!!”;
str2 = “exam”;
print str1.find(str2);
将会输出15,意为exam这个str2在 str1中的第15个位置开始
其实下面这张图里的这句话这样看,我们会顺眼很多
v4[i]!=byte_402000[flag[i]-1]
# -*- coding:utf-8 -*-v4 = [42,70,39,34,78,44,34,40,73,63,43,64]model = "}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(" + chr(0x27) + r'&%$# !"'pos = []for i in v4:pos.append(model.find(chr(i))+1) //意为将v4中的数字转换成字符+1然后检索在model中的位置,并且把这个位置+1,然后把这个位置(一个数字)添加到pos后面
s = [chr(x + 1) for x in pos] //然后将pos中的每个数字+1转换成字符,然后一个个组成flag
flag = ''.join(s)
print ('flag{'+flag+'}')
举个例子大概就是这样,先从v4中取出第一个字符42,然后将转换成字符,也就是*(星号),然后,然后检索*在model中的位置,是83,加1是84,再加1是85,再转换成字符就是85转换成U
*********为什么要两次加1?
答:第一个chr(i)+1是因为位置加1才是下标(下标从0开始)
第二个chr(x+1)是因为原式子中byte_402000[&v16+i]-1,所以要加1补回去
攻防世界部分
insanity(直接搜索字符串就能得到flag)
Mysterious
满足v10=123,v12=120,v14=122,v13=121
reverse方向入门过程相关推荐
- [BUGKU] [REVERSE] 逆向入门
[BUGKU] [REVERSE] 逆向入门 例行PEID查壳,发现不是有效的PE文件 winhex打开 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA ...
- 基于Altium Designer10的PCB设计入门过程
基于Altium Designer10的PCB设计入门过程 原理图绘制 原理图绘制 ①新建Project(工程) 打开AD10,左上角依次点击File->New->Project-> ...
- 网络安全web方向入门题合集
网络安全web方向入门题合集 [HCTF 2018]WarmUp 验证 [极客大挑战 2019]EasySQL [极客大挑战 2019]Havefun [强网杯 2019]随便注 前期工作 堆叠注入查 ...
- 程序员不同方向入门路线全解
一.程序员分为哪几个方向 随着编程技术在各方面的应用,传统程序员的工作逐渐多样化,衍生出来了很多方面. 一般来说程序员分为 前端.移动开发.后端.测试.运维.数据.硬件.通信.人工智能. 在技术层面这 ...
- 【FPGA】初探FPGA —— 入门过程的分享
#悬崖上的花,越芬芳越无常~ 终于又抽出时间搞这个FPGA入门系列了.这个也是我之前在B站做的视频,关于FPGA入门的过程经验的一个总结,去帮助大家帮助了解FPGA的入门. 南信大电子工程师协会慕课计 ...
- 疑惑即新知——记一次reverse模板实现过程
2019独角兽企业重金招聘Python工程师标准>>> 最近学习C++,在实现reverse模板函数的时候,从一个小问题开始,在对这个问题的旁敲侧击当中带起了更多疑惑,顺藤摸瓜之后, ...
- 简单记录fortran入门过程
寒假给堂弟讲C语言.我自然是轻车熟路,但他对C却是一无所知.不用说函数啊,格式啊,变量了,就连void都会写成viod,不知int为何物.各种格式也是一团乱麻.读者切不可笑,今天初次接触fortran ...
- 机器学习入门开源资料
最近学习的过程中发现了一些不错的开源资源,分享给大家,可以直接通过开源链接下载. 本文作为资料笔记,将长期更新. 公众号:炼丹笔记 机器学习导论 威斯康辛大学的助理教授Sebastian Raschk ...
- sql server 入门_SQL Server中的数据挖掘入门
sql server 入门 介绍 (Introduction) In past chats, we have had a look at a myriad of different Business ...
最新文章
- 网站服务器可以用虚拟主机吗,做网站虚拟主机可以用服务器吗
- android5.0(Lollipop) BLE Peripheral深入理解系统篇之提高篇
- Python函数篇(5)-装饰器及实例讲解
- 基于持久化的wordcount程序 foreachRDD
- 屌丝程序员的那些事(一)-毕业那年
- 别再抱怨 TensorFlow2.0 辣鸡了,会了是“真香”
- LeetCode-数组-三数之和
- Java配置Spring时REQUIRED和REQUIRES_NEW 的区别
- [论文翻译] Visual Saliency Transformer
- IntelliJIdea14 修改默认缓存的位置
- DM8 Out of space,错误码 code = -523问题解决
- android模拟器设置静态ip,安卓模拟器多开挂手游改IP防封号技术讲解
- 计算机无法获取正常的ip地址,教你轻松解决Win7系统经常获取不到IP地址问题
- ★C语言期末课程设计★——教师工资管理系统(详细报告+源代码+详细注释)
- max3232ese_【MAX3232ESE+ PDF数据手册】_中文资料_引脚图及功能_(美信 Maxim Integrated)-采芯网...
- 紫猫安卓按键之其他命令
- 糖尿病会对视网膜造成影响吗?
- 简单制作百度注册页面
- Windows 局域网中文件进行自动同步备份通过synctoy和计划任务实现
- C++边学边用,使用类完成复数运算,可自动识别表达式(详细注释)