Reverse入门[不断记录]

news2024/9/24 3:28:44

文章目录

  • 前言
  • 一、[SWPUCTF 2021 新生赛]re1
  • 二、[SWPUCTF 2021 新生赛]re2
  • 三、[GFCTF 2021]wordy[花指令]
  • 四、[NSSRound#3 Team]jump_by_jump[花指令]
  • 五、[NSSRound#3 Team]jump_by_jump_revenge[花指令]


前言

心血来潮,想接触点Reverse,感受下Reverse,于是从CTF的简单题目中慢慢入门


提示:以下是本篇文章正文内容,下面案例可供参考

一、[SWPUCTF 2021 新生赛]re1

1、工具:IDA
直接使用IDA将exe反编译,得到一堆代码。
在这里插入图片描述

使用Ctrl+X,查看编译流程,然后使用F5,查看代码。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Str2[1008]; // [rsp+20h] [rbp-60h] BYREF
  char Str1[1000]; // [rsp+410h] [rbp+390h] BYREF
  int i; // [rsp+7FCh] [rbp+77Ch]

  _main();
  strcpy(Str2, "{34sy_r3v3rs3}");
  printf("please put your flag:");
  scanf("%s", Str1);
  for ( i = 0; i <= 665; ++i )
  {
    if ( Str1[i] == 101 )
      Str1[i] = 51;
  }
  for ( i = 0; i <= 665; ++i )
  {
    if ( Str1[i] == 97 )
      Str1[i] = 52;
  }
  if ( strcmp(Str1, Str2) )
    printf("you are wrong,see again!");
  else
    printf("you are right!");
  system("pause");
  return 0;
}

将输入的字符,ascii为101的变成51,97的变成52,然后与str2对比,一致则成功。

s = '{34sy_r3v3rs3}'
r = ''
for i in s:
    if ord(i) ==51:
        r += chr(101)
    elif ord(i) == 52:
        r += chr(97)
    else:
        r += i
print(r)

得到flag

二、[SWPUCTF 2021 新生赛]re2

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Str2[64]; // [rsp+20h] [rbp-90h] BYREF
  char Str[68]; // [rsp+60h] [rbp-50h] BYREF
  int v7; // [rsp+A8h] [rbp-8h]
  int i; // [rsp+ACh] [rbp-4h]

  _main();
  strcpy(Str2, "ylqq]aycqyp{");
  printf(Format);
  gets(Str);
  v7 = strlen(Str);
  for ( i = 0; i < v7; ++i )
  {
    if ( (Str[i] <= 96 || Str[i] > 98) && (Str[i] <= 64 || Str[i] > 66) )
      Str[i] -= 2;
    else
      Str[i] += 24;
  }
  if ( strcmp(Str, Str2) )
    printf(asc_404024);
  else
    printf(aBingo);
  system("pause");
  return 0;
}
s = 'ylqq]aycqyp{'
l = []
for i in s:
    l.append(ord(i))
# print(l)
l = [121, 108, 113, 113, 93, 97, 121, 99, 113, 121, 112, 123]
r = ''
for i in l:
    if (i <= 94 or i > 96) and (i <= 62 or i > 64):
        r += chr(i + 2)
    else:
        r += chr(i - 24)
print(r)

得到的结果进行caser,并且猜一下,得到{nss_caesar}

三、[GFCTF 2021]wordy[花指令]

  1. 花指令实质就是一串垃圾指令,它与程序本身的功能无关,并不影响程序本身的逻辑。在软件保护中,花指令被作为一种手段来增加静态分析的难度,花指令也可以被用在病毒或木马上,通过加入花指令改变程序的特征码,躲避杀软的扫描,从而达到免杀的目的。
  2. 花指令是让反编译器无法反编译起到混淆租用的指令,一般最常见的就是在机器码中加入 E8,E8 加入后会将汇编代码改变为 CALL,而后续的机器码代表的东西是没有意义的,不是一个函数,所以 CALL 之后反编译器无法识别。

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

存在大量jmp跳转,导致程序无法正常编译,尝试将跳转nop掉,即将其转换成空指令。

startaddr = 0x1135
endaddr = 0x3100

for i in range(startaddr,endaddr):
    if get_wide_byte(i) == 0xEB:
        if get_wide_byte(i+1) == 0xFF:
            patch_byte(i,0x90)
            print("[+] Addr {} is patched".format(hex(i)))

起始地址是main函数的0x1135到结束,通过遍历byte,判断是否和EB FF,即jmp的机械码,是则改成90,即nop。
在这里插入图片描述
看到flag为GFCTF{u_are2wordy}

四、[NSSRound#3 Team]jump_by_jump[花指令]

  1. 先找主函数入口,即main
    在这里插入图片描述

可以看到0041188C处有call,并且爆红,可以判断为花指令,因此要消除即变成nop,选中41188C,按快捷键D,将其转换为数据。

在这里插入图片描述

然后将0E8h改成0x90即nop机器码

在这里插入图片描述

快捷键C,将数据再次转换成指令,并将下面黄色的部分依次使用C转换成指令。

在这里插入图片描述

最后往上选中main入口,快捷键P生成函数,然后F5,获得函数代码。

int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  int i; // [esp+D0h] [ebp-2Ch]
  char v5[28]; // [esp+DCh] [ebp-20h] BYREF

  strcpy(v5, "NSSCTF{Jump_b9_jump!}");
  for ( i = 0; i < 21; ++i )
    v5[i] = (v5[i] + v5[(i * i + 123) % 21]) % 128;
  sub_4110CD("%s", (char)v5);
  return 0;
}

发现flag根本没被加密,直接开始Shift+F12就可以看到字符串。

五、[NSSRound#3 Team]jump_by_jump_revenge[花指令]

在这里插入图片描述

跟上面一样,将爆红那里改成空指令,P+F5得到伪代码。

int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  int i; // [esp+D0h] [ebp-40h]
  char Str1[36]; // [esp+E8h] [ebp-28h] BYREF

  sub_411037("%s", (char)Str1);
  for ( i = 0; i < 29; ++i )
    Str1[i] = (Str1[i] + Str1[(i * i + 123) % 21]) % 96 + 32;
  if ( !j_strcmp(Str1, "~4G~M:=WV7iX,zlViGmu4?hJ0H-Q*") )
    puts("right!");
  else
    puts("nope!");
  return 0;
}

将flag打乱了,并且进行了变换,逆向解密。

a = ['~', '4', 'G', '~', 'M', ':', '=', 'W', 'V', '7', 'i', 'X', ',', 'z', 'l', 'V', 'i', 'G', 'm', 'u', '4', '?', 'h',
     'J', '0', 'H', '-', 'Q', '*']

for i in range(28, -1, -1):
    k = (i * i + 123) % 21
    for j in range(5):
        x = (ord(a[i]) - 32 + j * 96 - ord(a[k]))
        if 33 <= x <= 126:
            a[i] = chr(x)
            break
print("".join(a))

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

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

相关文章

网络编程(一)

网络编程 文章目录网络编程前置概念1- 字节序高低地址与高低字节高低地址&#xff1a;高低字节字节序大端小端例子代码判断当前机器是大端还是小端为何要有字节序字节序转换函数需要字节序转换的时机例子一例子二2- IP地址转换函数早期(不用管)举例现在与字节序转换函数相比:**…

模块化热更思路

title: 模块化热更思路 categories: Others tags: [热更, 模块化, 分包] date: 2023-02-18 01:04:57 comments: false mathjax: true toc: true 模块化热更 浅浅的记录一下访问破 200w (But, I don’t care about this.) 前篇 只谈思路, 不贴实现代码. 需求 游戏类型属于合集…

Linux(十三)设计模式——单例模式

设计模式——针对典型场景所设计出来的特别的处理方案 单例模式&#xff1a;一个类只能实例化一个对象&#xff08;所以叫单例&#xff09; 场景&#xff1a; 1、资源角度&#xff1a;资源在内存中只占有一份 2、数据角度&#xff1a;如果只有一个对象&#xff0c;那么该对象在…

2019蓝桥杯真题质数(填空题) C语言/C++

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 我们知道第一个质数是 2、第二个质数是 3、第三个质数是 5…… 请你计算第 2019 个质数是多少&#xff1f; 运行限制 最大运行时间&#xff1a;1s 最大运行内存: 128M…

Mac下安装Tomcat以及IDEA中的配置

安装brew 打开终端输入以下命令&#xff1a; /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 搜索tomcat版本&#xff0c;输入以下命令&#xff1a; brew search tomcat 安装自己想要的版本&#xff0c;例…

JDK版本区别

1. 泛型 ArrayList listnew ArrayList()------>ArrayList<Integer>listnew ArrayList<Integer>(); 2 自动装箱/拆箱 nt ilist.get(0).parseInt();-------->int ilist.get(0);原始类型与对应的包装类不用显式转换 3 for-each i0;i<a.length;i------------&…

解析从Linux零拷贝深入了解Linux-I/O(上)

本文将从文件传输场景以及零拷贝技术深究 Linux I/O 的发展过程、优化手段以及实际应用。前言 存储器是计算机的核心部件之一&#xff0c;在完全理想的状态下&#xff0c;存储器应该要同时具备以下三种特性&#xff1a; 速度足够快&#xff1a;存储器的存取速度应当快于 CPU …

JWT安全漏洞以及常见攻击方式

前言 随着web应用的日渐复杂化&#xff0c;某些场景下&#xff0c;仅使用Cookie、Session等常见的身份鉴别方式无法满足业务的需要&#xff0c;JWT也就应运而生&#xff0c;JWT可以有效的解决分布式场景下的身份鉴别问题&#xff0c;并且会规避掉一些安全问题&#xff0c;如CO…

python+vue微信小程序的线上服装店系统

服装行业是一个传统的行业。根据当前发展现状,网络信息时代的全面普及,服装行业也在发生着变化,单就服饰这一方面,利用手机购物正在逐步进入人们的生活。传统的购物方式,不仅会耗费大量的人力、时间,有时候还会出错。小程序系统伴随智能手机为我们提供了新的方向。手机线上服装…

JavaEE|套接字编程之UDP数据报

文章目录一、DatagramSocket API构造方法常用方法二、DatagramPacket API构造方法常用方法E1:回显服务器的实现E2:带有业务逻辑的请求发送一、DatagramSocket API 在操作系统中&#xff0c;把socket对象当成了一个文件处理。等价于是文件描述符表上的一项。 普通的文件&#xf…

vbs简单语法及简单案例

文章目录一、简单语法1、变量2、输入3、输出4、选择语句5、循环二、用记事本编译中文乱码问题三、制作一个简单vbs脚本表白一、简单语法 1、变量 语法&#xff1a; dim 变量名例&#xff1a; dim a,b a1 b2 msgbox ab运行&#xff1a; 2、输入 语法&#xff1a;InputBox(…

【ip neigh】管理IP邻居( 添加ARP\NDP静态记录、删除记录、查看记录)

一、邻居管理存在状态 1、NUD_NONE&#xff1a; 初始状态。当一个新的路由缓存条目被创建时&#xff0c;arp_bind_neighbour()函数被调用.如果找不到相匹配的ARP缓存条目, neigh_alloc()将创建一个新的ARP缓存条目并设置状态为NUD_NONE. 2、NUD_INCOMPLETE&#xff1a;未完成状…

设计模式之适配器模式与桥接模式详解和应用

目录1 适配器模式1.1 定义1.2 应用场景1.3 适配器角色1.4 类适配器1.5 对象适配器1.5 接口适配器1.6 实战1.7 源码1.8 适配器与装饰器的对比1.9 适配器模式的优缺点1.10 总结2 桥接模式2.1 原理解析2.2 角色2.3 通用写法2.4 应用场景2.5 业务场景中的运用2.6 源码2.7 桥接模式优…

指针笔记(指针数组和指向数组的指针,数组中a和a的区别等)

指针数组和指向数组的指针 int *p[4]和int (*p)[4]有何区别&#xff1f; 前者是一个指针数组&#xff0c;数组大小为4&#xff0c;每一个元素都是一个指向int的指针 后者是指向int[4]类型数组的指针 以上代码若运行会报如下错误 main函数中定义的a数组本质是一个指向int[2]的…

内网渗透(三十八)之横向移动篇-pass the key 密钥传递攻击(PTK)横向攻击

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

从0到1一步一步玩转openEuler--18 openEuler 管理服务-简介

文章目录18 管理服务简介18.1 概念介绍18 管理服务简介 systemd是在Linux下&#xff0c;与SysV和LSB初始化脚本兼容的系统和服务管理器。systemd使用socket和D-Bus来开启服务&#xff0c;提供基于守护进程的按需启动策略&#xff0c;支持快照和系统状态恢复&#xff0c;维护挂…

java基础学习 day41(继承中成员变量和成员方法的访问特点,方法的重写)

继承中&#xff0c;成员变量的访问特点 a. name前什么都不加&#xff0c;name变量的访问采用就近原则&#xff0c;先在局部变量中查找&#xff0c;若没找到&#xff0c;继续在本类的成员变量中查找&#xff0c;若没找到&#xff0c;继续在直接父类的成员变量中查找&#xff0c…

Mel Frequency Cepstral Coefficients (MFCCs)

wiki里说 在声音处理中&#xff0c;梅尔频率倒谱( MFC ) 是声音的短期功率谱的表示&#xff0c;基于非线性梅尔频率标度上的对数功率谱的线性余弦变换。 倒谱和MFC 之间的区别在于&#xff0c;在 MFC 中&#xff0c;频带在梅尔尺度上等距分布&#xff0c;这比正常频谱中使用的线…

Windows10 安装ElasticStack8.6.1

一、安装ElasticSearch8.6.1 1.官网下载ElasticSearch8.6.1压缩包后解压 2.安装为服务 elasticsearch-service.bat install 3.运行 elasticsearch-service.bat start 4.通过浏览器访问 http://localhost:9200/ 提示需要登录&#xff0c;但不知密码是啥。 5.重置密码 ela…

操作系统(day12)-- 基本分段存储,段页式存储

基本分段存储管理方式 不会产生内部碎片&#xff0c;会产生外部碎片 分段 按照程序自身的逻辑关系划分为 若干个段&#xff0c;每个段都有一个段名&#xff0c;每段从0开始编址 分段存储管理方式中一个段表项由段号&#xff08;隐含&#xff09;、段长、基地址 分段的段表项固…