攻防世界逆向刷题

阅读须知:

探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失,均由使用者
本人负责,作者不为此承担任何责任,如有侵权烦请告知,我们会立即删除并致歉,创作不易转载请标明出处.感谢!

波克比QWQ师傅

原文出处: https://blog.csdn.net/yjh_fnu_ltn?type=blog

题目

题目地址:polyre

  1. 拿到题目后无壳,直接拖入ida反汇编,从start函数直接跳到main函数:
  2. 明显的虚假控制流平坦化,这里简单讲一下什么是平坦化,平坦化就是将原本嵌套多层的语句,改为只用1个switch加while循环来实现,下面使用python语句来表现一个循环语句平坦化:
#原程序
res=[1,-1,2,-2,3,-3]
for i in range(len(res)):
    if res[i] < 0:
        res[i]<<=1
        res[i]+=10
        if res[1]&1==1:
            res[i]*=2
    else :
        res[i]^=13
        res[i]*=4
        # if res[1]
print(res)

res=[1,-1,2,-2,3,-3]
#手动添加平坦换后
i=0
while i<len(res):
    b=(int(res[i]<0)^1)+1
    while True:
        match b:
            case 0:
                break
            case 1:
                res[i]<<=1
                b=3
                
            case 2:
                res[i]^=13
                b=4
                
            case 3:
                res[i]+=10
                b=(res[i]&1)*5
                
            case 4:
                res[i]*=4
                break
                
            case 5:
                res[i]*=2
                break
    i+=1
print(res)


4. 其实现的功能仍然是一样的,只不过将一个循环里的多个语句放在了不同的子模块中,再通过子模块之间的相互控制,来达到原有程序的效果。详细的平坦换请看下面这篇文章:控制流平坦化
5. 知道控制流平坦化后,可以使用符号化执行来简化程序,使程序的可读性增强,便于反汇编,使用deflat.py脚本即可去除平坦化:命令如下
6. -f后是文件名,–addr后是要平坦化的函数首地址,执行后效果如下:汇编视图
7. 这里可以看到,去平坦化后的程序刻度性增强,不过其中还有一些出题人塞进去的虚假指令(恒真/假),永远不会执行。
8. 例如:第一个if语句后面的 ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0条件就永远为假**(n*(n-1))&1这个结果恒等于0,所以前面的条件恒假,即if语句里面的程序根本不会执行,类似的虚指令后面还有16个,需要清除:
9. 这里使用idapython脚本来快速去除,这里
脚本的逻辑**:将jnz指令的条件跳转修改为直接跳转,因为后面的jmp语句永远不会执行,后面的while循环同理,只会执行一次,因此利用脚本将jnz的条件跳转直接改为jmp进行直接跳转(顺跳),源程序相当于:

st = 0x0000000000400620 #main开始
end = 0x0000000000402144 #main结束
 
def patch_nop(start,end):
    for i in range(start,end):
        ida_bytes.patch_byte(i, 0x90)		#修改指定地址处的指令  0x90是最简单的1字节nop
 
def next_instr(addr):
    return addr+idc.get_item_size(addr)		#获取指令或数据长度,这个函数的作用就是去往下一条指令
    
 
 
addr = st
while(addr<end):
    next = next_instr(addr)
    if "ds:dword_603054" in GetDisasm(addr):	#GetDisasm(addr)得到addr的反汇编语句
        while(True):
            addr = next
            next = next_instr(addr)
            if "jnz" in GetDisasm(addr):
                dest = idc.get_operand_value(addr, 0)		#得到操作数,就是指令后的数
                ida_bytes.patch_byte(addr, 0xe9)     #0xe9 jmp后面的四个字节是偏移
                ida_bytes.patch_byte(addr+5, 0x90)   #nop第五个字节
                offset = dest - (addr + 5)  #调整为正确的偏移地址 也就是相对偏移地址 - 当前指令后的地址
                ida_bytes.patch_dword(addr + 1, offset) #把地址赋值给jmp后
                print("patch bcf: 0x%x"%addr)
                addr = next
                break
    else:
        addr = next
  1. 利用脚本修改后的汇编指令,反编译程序如下,去除掉后面16个虚指令:
  2. 前期准备结束,正式开始分析函数实现的功能,第一个循环的逻辑是将最后输入的回车符"\n"转化为0,第二个循环:将输入的字符串每8个一组(共64个bit)进行一下处理,大于零则左移1位(乘2),小于零则左移1位后与0xB0004B7679FA26B3异或。这里由于变量v4是64位的有符号数,左移根据其最高位来判定符号,1为负数,0为正数:
  3. 最后,Jami后的字符串与程序给定的数据相比较,因为8个字节一组,所以将程序给定的48个字节分为6组整合到一起:
  4. 最后解密脚本如下,脚本里面使用到的逻辑:原先的正数(最高位的符号位为0)左移1后一定是偶数(左移后低位自动用0补充),而原先的负数(最高位的符号位为1)左移1后(变为偶数)再与0xB0004B7679FA26B3(奇数)异或,结果一定是奇数,也就是说,最后结果(加密一次)里面的偶数原先一定是正数,而结果里面的奇数原先一定是负数,所以根据每次结果奇偶性即可判定上一次该值是否为正或者负,如果是负数则需要给最高位(第64为)补上1(补上因为加密是左移而溢出的1),为正数不用补(加密是左移溢出的是0,相当于没有溢出):
a=[0xBC8FF26D43536296,0x520100780530EE16,0x4DC0B5EA935F08EC,0x342B90AFD853F450,
0x8B250EBCAA2C3681,0x55759F81A2C68AE4]
key=0xB0004B7679FA26B3
for res in a:
    for j in range(64): #循环64次
        tmp=res&1
        if tmp == 1:#判定是否为奇数(为奇数则上轮加密是为负数),在二进制下最低为为1则是奇数
            res ^= key
        res>>=1
        if tmp==1:
            res+=0x8000000000000000 #如果该次加密前是负数(),把左移漏掉的最高位1补回来

    #输出,大小端续转化输出
    k=0
    while k<8:
        print(chr(res&0xff),end="")
        res>>=8
        k+=1
#flag{6ff29390-6c20-4c56-ba70-a95758e3d1f8}

总结:控制流平坦换的题需要将程序还原,增强程序的可读性,程序中存在永真(或永假)指令时可以利用idapython将条件跳转(jz,jnz)修改为直接跳转(jmp),进一步增强可读性。

题目 :maze

题目地址 :maze

  1. 查壳无,直接使用ida打开,这应该时一道迷宫的题,打开后如下。在这里插入图片描述
  2. 分析,发现这是一道直线迷宫的题,解这类题目只需要找到该直线迷宫,分析键盘输入对应的移动操作即可,迷宫如下:
  3. 在主循环中分析输入的flag对应的移动操作,可以看到0 后退1=79,前进1=111,后退8=46,前进8=48,由cmp函数可以看见只能停留在空格#
  4. 分析出输入对应的移动操作后,即可走完迷宫,操作对应如下,代码附上:
'  *******   *  **** * ****  * ***  *#  *** *** ***     *********'
# 0 后退1=79
# 1 前进1=111
# 2 后退8=46
# 3 前进8=48
key=[79,111,46,48]
#    0 , 1 , 2,3
res=[1,3,1,1,3,3,0,3,3,3,1,1,1,1,2,2,0,0]
for i in range(len(res)):
    print(chr(key[res[i]]),end="")
flag="o0oo00O000oooo..OO"
print(len(flag))

最后flag=nctf{o0oo00O000oooo…OO}

题目:easy_go

题目地址:easy_go

  1. 无壳,直接ida打开:=
  2. 能看到的关键信息由一个字符串 “tGRBtXMZgD6ZhalBtCUTgWgZfnkTgqoNsnAVsmUYsGtCt9pEtDEYsql3”,外加一个encode_base64的加密函数,看到了base64直接去找base64表,字符串里面直接看,搜索abcdefgABCDEFG…,查询base64表:
  3. 其中发现三个比较像的字符串,三个字符串一个一个用脚本(网站)试一下,最后真正的base64表是6789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345
  4. 总结:有关于base64的题目都可以直接去找base64表和密文。

题目:polyre

题目地址:polyre

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32学习笔记(7_2)- ADC模数转换器代码

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 本期开…

PHP全自动采集在线高清壁纸网站源码

源码简介 集合360壁纸&#xff0c;百度壁纸&#xff0c;必应壁纸&#xff0c;简单方便。非常高清,支持全屏支持2K. 每天自动采集&#xff0c;自动更新&#xff0c;非常不错。 搭建环境 php5.6 Nginx 安装教程 上传源码压缩包到网站目录并解压即可 首页截图 源码下载 P…

深度学习基础入门:从数学到实现

I. 引言 A. 深度学习的背景 深度学习是机器学习的一个重要分支&#xff0c;是一种基于神经网络的算法&#xff0c;被广泛应用于计算机视觉、自然语言处理、语音识别等领域。与传统机器学习算法相比&#xff0c;深度学习具有更高的容错性、复杂性和精度&#xff0c;需要庞大的…

【Redis】Redis 介绍Redis 为什么这么快?Redis数据结构Redis 和Memcache区别 ?为何Redis单线程效率也高?

目录 Redis 介绍 Redis 为什么这么快&#xff1f; Redis数据结构 Redis 和Memcache区别 &#xff1f; 为何Redis单线程效率也高&#xff1f; Redis 介绍 Redis 是一个开源&#xff08;BSD 许可&#xff09;、基于内存、支持多种数据结构的存储系统&#xff0c;可以作为数据…

大白话扩散模型(无公式版)

背景 传统的图像生成模型有GAN&#xff0c;VAE等&#xff0c;但是存在模式坍缩&#xff0c;即生成图片缺乏多样性&#xff0c;这是因为模型本身结构导致的。而扩散模型拥有训练稳定&#xff0c;保持图像多样性等特点&#xff0c;逐渐成为现在AIGC领域的主流。 扩散模型 正如…

python第三次作业

1、求一个十进制的数值的二进制的0、1的个数 def count_0_1_in_binary(decimal_num):binary_str bin(decimal_num)[2:]count_0 binary_str.count(0)count_1 binary_str.count(1)return count_0, count_1decimal_number int(input("十进制数&#xff1a;")) zero…

linux 外部GPIO Watchdog驱动适配

前言 文章描述&#xff0c; 利用外部gpio看门狗芯片驱动芯片的复位功能。 芯片&#xff1a;RK3568 平台&#xff1a; Linux ubuntu.lan 4.19.232 #27 SMP Sat Sep 23 13:43:49 CST 2023 aarch64 aarch64 aarch64 GNU/Linux 硬件接线图示 看门狗芯片采用GPIO喂狗&#xff0c;W…

PTA L2-037 包装机

一种自动包装机的结构如图 1 所示。首先机器中有 N 条轨道&#xff0c;放置了一些物品。轨道下面有一个筐。当某条轨道的按钮被按下时&#xff0c;活塞向左推动&#xff0c;将轨道尽头的一件物品推落筐中。当 0 号按钮被按下时&#xff0c;机械手将抓取筐顶部的一件物品&#x…

unity 横版过关单向通行实现(PlatformEffector2D)

目录 前言一、什么是 PlatformEffector2D&#xff1f;二、使用步骤1.创建模型2.创建jump脚本3.PlatformEffector2D组件 三、效果总结 前言 在 2D 游戏中&#xff0c;处理角色与平台之间的交互是一个常见但复杂的任务。为了简化这一过程&#xff0c;Unity 提供了 PlatformEffec…

五分钟,零基础也能入门 Python 图像文字识别

一. 前言 最近在研究 Python 的一些功能 &#xff0c; 也尝试了一些有趣实现&#xff0c; 这一篇就从实践的角度来研究一下 Python 如何实现图片识别。 众所周知 &#xff0c; Python 的库真的老多了&#xff0c;其中在图像识别上比较突出的就是 OpenCV. 那么基于这个库我们…

有效三角形的个数【双指针】

1.优化版暴力求解 如果能构成三⻆形&#xff0c;需要满⾜任意两边之和要⼤于第三边。实际上只需让较⼩的两条边之和⼤于第三边即可。将原数组排序&#xff0c;从⼩到⼤枚举三元组&#xff0c;这样三层 for 循环枚举出的三元组只需判断较⼩的两条边之和是否⼤于第三边。 class…

新一代酒店智能客控方案亮相上海酒店展:力合微PLC技术推动酒店智能化升级

3月26日&#xff0c;2024上海国际酒店及商业空间博览会&#xff08;以下简称&#xff1a;上海酒店展&#xff09;于上海新国际博览中心开幕。作为行业领先的物联网通信芯片企业&#xff0c;22年专注于PLC&#xff08;电线通信&#xff09;技术及芯片&#xff0c;&#xff08;股…

代理与 XLogin 集成

代理与 XLogin 集成 通过将 Smartdaili 住宅代理与强大的 XLogin 反检测浏览器相匹配来解锁网络数据。 什么是 XLogin&#xff1f; XLogin 是一款防关联浏览器&#xff0c;具有多重指纹保护技术&#xff0c;可通过 Selenium 网络驱动程序实现任务自动化&#xff0c;并为每个…

变量,前世你也许是个过客!

很多书中喜欢将变量比喻成一个容器&#xff0c;比如盒子、碗之类的。但老金认为这个比喻有失妥当。按字面意思理解&#xff0c;变量只是一个可以改变的量&#xff0c;就像函数中的自变量x、因变量y一样。变量本身并不具有存储功能&#xff0c;有存储功能的是内存&#xff0c;所…

rmvb怎么转换为mp4?最简单方法!

各种文件格式层出不穷&#xff0c;而RMVB&#xff08;RealMedia Variable Bitrate&#xff09;格式作为一种独特的视频文件格式&#xff0c;其起源可以追溯到上世纪90年代。当时&#xff0c;随着数字视频的崛起&#xff0c;RealNetworks公司迎来了一项重要任务&#xff1a;提供…

【LVGL-平铺视图部件(lv_tileview)】

LVGL-平铺视图部件&#xff08;lv_tileview&#xff09; ■ LVGL-平铺视图部件&#xff08;lv_tileview&#xff09;■ 示例一&#xff1a;添加到行列中的位置&#xff08;1,0&#xff09;表示第1列第0行■ 示例二&#xff1a;滑动方向LV_DIR_RIGHT &#xff0c;LV_DIR_LEFT■ …

Web Components初探

组件化&#xff0c;标签语义化&#xff0c;是前端发展的趋势。现在流行的组件化框架有React、Vue等&#xff0c;标签语义化在H5中添加的article、dialog等。 Web Components 就是类似的一套技术&#xff0c;允许您创建可重用的定制元素&#xff0c;并且在您的web应用中使用它们…

cesium 创建实体

1、 entity 1.1 entity类型整理 Entity分类 1.2 entity添加 椭圆 const ellipse new Cesium.Entity({position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 100),ellipse: {semiMinorAxis: 30000, //椭圆的短半轴semiMajorAxis: 40000, //椭圆的长半轴extrudedHeight: 0…

如何使用Fiddler对手机进行弱网测试?(干货教程)

1.首先&#xff0c;fiddler连接手机 1)Tools->Options->Connections->设置端口8888&#xff0c;勾选Allow remote computers to connect 2)配置手机 注&#xff1a;手机和电脑需要在同一局域网下 手机进入网络详情&#xff0c;将代理改为手动 设置主机名、端口 主机…

Python中的变量与常量

变量&#xff1a;在程序运行过程中&#xff0c;值会发生变化的量&#xff0c; 常量&#xff1a;在程序运行过程中&#xff0c;值不会发生变化的量。 无论是变量还是常量&#xff0c;在创建时都会在内存中开辟一块空间&#xff0c;用于保存它的值。 Python 中的变量不需要声明…