RCTF2022-MyCarsShowSpeed
做到一道好题,mark一下。
正向分析这一步是可以看看程序具体实现了一个什么逻辑,运行出现一个菜单,并且是多级的。
开始一把游戏
查看信息
拜访商店
切换卡车
输出一句话
退出
其中拜访商店又有一个新的菜单
买东西
卖东西
修车
取车
退回上一级
我们可以去商店买车,买汽油,买安全带(没有实际用处)和flag,当然 flag 比较贵,那么我们一定要寻找赚钱的途径,把车买了再卖了是得到一半的价格。修车根据时间来算价格,增加车的 health,车有 health,fuel,stability这几个属性,fuel是汽油,health 是血条吧可以理解为,另一个查一查单词意思是稳定性,不过也不知道具体是什么意思。
我们修车的时候不能卖车,估计是防止我们通过这个不停地卖车刷钱。
有了车我们可以去跟一个 bot pk,赢了的话得到 10 块钱,但是跑一次会损耗汽油和 health,然后又要去买,而且只赚 10 块,目测不行,但是通过正向的分析我们很浅显地知道了程序大概逻辑,具体实现需要分析它给的源码。
源码分析基本分析看到 .h 文件的一些结构体定义
12345678910111213 ...
C++基础——函数与类模板的一些细节
C++基础——函数模板与类模板的一些细节
这里做一下总结 and 深入吧~
类模板继承这里我们需要知道一点,模板类可以被继承,但是你必须指定类继承,比如你声明了一个
12345class A<T>{public: A(); ~A();}
A 并不是一个类,不能被继承,你只能继承一个 A<int> 类,或者是其它类的一个类实例,或者如果你想让子类也保持为泛型,那么你可以给子类定义一个模板类,然后这里继承的时候给 A<T>。
这里两种继承还是有很大区别的,至少在编译部分就会让你产生写法上的很大的差异,指定实例化的类继承这个我们很好理解,它就相当于直接指定完整了一个类,你把你指定的类用模板类替换上去类型就成了一个具体的类,然后去继承,和直接继承没有任何差别,我们主要关心第二种情况:子类传泛型进去给父类继承。
关注以下的代码:
12345678910111213141516171819202122232425262728293031#include<iostream>template<typenam ...
C++基础——函数与类模板
C++基础——函数模板与类模板
应该就是 C++ 的一个泛型编程了。
泛型编程泛型编程主要是因为这样的一个应用场景:如果我要实现一个数的加法,那么数可以是整数,浮点数,长整数等等等,返回值也可以是这些类的其中一个,排列组合一下可以有很多种组合,但是它们函数内部的功能几乎一模一样,这样的话就会比较繁琐,泛型编程就很好的解决了这一个问题。
比如算竞常用的函数 sort 可以排序,它能排很多种数据类型,只要数据类型支持小于号,那么就可以使用 sort,就算没有小于号我们也可以重载小于号使用。
函数模板123456789101112#include<iostream>#include<string>template<typename T>//古老版本中没有 typename 关键字,用的是 class,效果一样T add(T a, T b) { return a + b;}int main() { std::cout << add(1, 2) << std::endl; std::c ...
C++面向对象基础——函数与对象总结
C++面向对象基础——函数与对象总结
面向对象最后一节课了~
引入例:
12345678910111213141516class A{public: int a; void test(int num) { a += num; }};void test(A* obj, int num) { obj->a += num;}int main() { A obj; obj.test(100); test(&obj, 100);}
效率以上代码中的 A::test 函数和 test 函数实现了相同的功能。这种情况下,效率永远是类内的函数比全局函数的效率高的。这也就是为什么作用域我们会倾向于小的处理,就近原则嘛。
成员函数调用方式这里成员函数的理解就理解为整个类的就行了,它不属于一个个体。
成员函数直接调用实际上跟全局函数调用一模一样,因为在编译器就已经确定了成员函数的位置,用对象无论调用的是虚函数还是非虚函数,结果都是一致的,因为它这里认为你 ...
C++面向对象基础——数据语义学
C++面向对象基础——数据语义学
PS:这节课感觉没有太多东西
歧义的纠正在 C 里面,局部变量和全局变量是可以同名的,但是局部变量会屏蔽全局变量。同样的,在类内也是这样,它会尽量在作用域范围较小的地方找到定义。即使我函数只在类内申明,类外定义,依然是会优先找到类内的定义的,因为成员函数不管在哪里定义,它的作用域都是在类内。
但是呢,跟之前的类一样,重写的方法具有覆盖继承方法的特性,只是因为它优先在本作用域找而已,并不是说就没了,我们想调用依然可以调用,我们在调用成员方法之前使用 FatherClass:: 限定作用域可以去调用父类的成员方法和成员变量。同样,我们如果类内和类外都定义了同名的变量,我们可以加上 :: 标定我们方法全局作用域的变量,这样就可以解决变量屏蔽的问题了。
预处理设置数据对对齐#pragma pack 的主要作用就是改变编译器的内存对齐方式,这个指令在网络报文的处理中有着重要的作用,#pragma pack(n)是他最基本的用法,其作用是改变编译器的对齐方式, 不使用这条指令的情况下,编译器默认采取#pragma pack(8)也就是8字节的默认对齐方式,n值 ...
C++基础——调用约定分析
C++基础——调用约定分析
调用约定其实自己 Pwn 打了两年半了也是比较了解的,但是还是开个具体的笔记去记录吧。
CPU架构常见的 CPU 架构有 x86 架构,ARM 架构和 MIPS 架构。不同的架构能执行的机器指令集是不一样的,比如 ARM 下面编译的程序指定是不能在 x86 架构下面去跑的。
x64 为一个简称,全称是 x86-64 架构,也就是 x86 架构下的 64 位版本,多见于我们的 PC,服务器,笔记本等等。
ARM 架构多见于一系列的水果产品和移动端设备。
MIPS 架构多见于路由器、智能设备等等。
处理器发展史
1971年,Intel推出了世界上第一款微处理器4004,它是一个包含了2300个晶体管的4位cPU。
1978年,Intel公司首次生产出16位的微处理器命名为i8086,同时还生产出与之相配合的数学协处理器i8087。
1978年,Intel还推出了具有16位数据通道、内存寻址能力为1MB、最大运行速度8MHz的8086,并根据外设的需求推出了外部总线为8位的8088,从而有了IBM的XT机。
1979年,Intel公司推出了8088芯片,它是第 ...
C++面向对象基础——虚函数分析
C++面向对象基础——虚函数分析
虚函数调用调用方式指针创建式调用函数(ClassName obj=new ClassName())调用的是虚表当中的函数地址,每个对象是不一样的,而如果是直接创建对象(ClassName obj)调用的函数地址就是同一个,都是类里面的函数。
写一个代码
1234567891011121314151617181920212223242526272829303132333435#include"main.h"class A{public: A() {}; ~A() {}; virtual void testA() { cout << "A::TestA" << endl; } virtual void testB() { cout << "A::TestB" << endl; } ...
C++面向对象基础——构造与拷贝构造函数
C++面向对象基础——对象&构造函数&拷贝构造函数
对象模型的探索占用内存对象所占用的空间至少1个字节,空类也会占用一个字节,这里根结构体是几乎一样的。类也和结构体一样,异构的数据类型就是会存在数据对齐,即当前位置所在的地址不在该类大小的整数倍则需要向后寻找合适的地址。
如果对象有静态变量,则静态变量不计入对象的空间,因为静态变量不属于对象,属于全体类共有,成员方法同理,也属于类,不会占用对象的空间。
如果有虚函数存在,那么对象会额外存一个虚表指针,又多 4 个字节或者是 8 个字节。
内存分布我们先来看一个例子。
123456789101112131415161718192021222324252627282930313233343536373839#pragma once#include<iostream>class A{public: A() {}; ~A() {}; int a; void TestA() { printf("A:%p\r\n" ...
一些关于Ubuntu的东西
写这个完全是因为最近在 Ubuntu 上面踩的坑有点多了。
Ubuntu
Ubuntu 是基于Debian,以桌面应用为主的Linux发行版。Ubuntu有三个正式版本,包括桌面版、服务器版及用于物联网设备和机器人的Core版。前述三个版本既能安装于实体电脑,也能安装于虚拟电脑。从17.10版本开始,Ubuntu以GNOME为默认桌面环境。Ubuntu是著名的Linux发行版之一,也是目前最多用户的Linux版本。Ubuntu每六个月(即每年的四月与十月)发布一个新版本,长期支持(LTS)版本每两年发布一次。普通版本一般只支持9个月,但LTS版本一般能提供5年的支持。
这个一直存在于 wiki 的介绍我现在才仔细地去看了看。
Ubuntu 应该算是我最喜欢用的系统了,连 Windows 都无法撼动它的地位。这里 wiki 也讲了,它主要分三个发行版:桌面版(desktop),服务器版(server),和 Core 版。我们用的最多的应该是前两个,然后就是它版本号的一些说明了,它每半年发布一个小版本(只提供9个月的支持),两年发布一个长期版本(LTS),提供五年支持。
然后每个版本 ...
HITCTF2022题解
打到第三,最后把RSA想到解法了,还行,已知高位攻击分解 p 的方法还可以学学。
附件下载
CryptoCrypto1拿出来是一个16进制,看着像 tar 的文件头,拿到解压,得到 1 文件,文件结构比较乱。看着像base家族,然后拿到 base85转hex之后发现又是熟悉的文件头。
所以可能应该是严重套娃,写个脚本统计字符数,如果发现是 tar 文件头那就直接解压拿文件内容,如果类似 base 家族的信息就 base 解码。
12345678910111213141516171819202122232425262728293031323334import gzipimport base64import base91import base58import base62from collections import Counterwith open('1','rb')as f: text=f.read()def get_count(str1): c=dict(Counter(str1)) return len(c)baseX= ...