首先说一下什么叫评测机。在信息学竞赛中,往往是给出一道题目要求选手编写程序完成题目所要求的任务,根据给定的输入文件,计算得出一个输出文件,评测机会将程序的输出文件和标准答案进行对比,返回正确与否的结果。还可限制任务运行的时间、内存、可使用函数等
本文背景及文章内容纯属虚构,旨在分享在开发评测机可能遇到的问题,如有评测机工作原理与本文描述雷同,纯属巧合
任何Hack评测机的行为都是作弊行为,本文里所介绍的方式仅供参考,请不要在实战中运用。上一个在洛谷搞AC自动机的人已经gg了。
这篇文章的作者在github上某个隐蔽的角落找到了某个不知名的小评测机。简单测试发现并没有对穿越目录的行为进行限制,而且可以直接读到答案文件AC,为防止作弊嫌疑,故不在此放出评测机名字。
创建一个比赛,看到生成了一堆文件(夹),在 players
文件夹下放置选手代码,编译后产物在 tmp
文件夹,并在此中执行,评测数据在 examdata
。
评测时会同时从评测数据中复制一个输入数据在 tmp
文件夹中,命名为 {题目名称}.in
选手程序需要读取该文件作为数据并将答案输出到 {题目名称}.out
,随后进行比对。是很原始的文件io。
得知以上运行逻辑便可编写出一段测试(伪)代码:
fs.readFileSync(`../examdata/ ${problemName}${testNo}.ans`)
来读入文件。
这样我们就轻松AC了一个点,那么其他点怎么搞呢。
其实我们读入到给出的输入文件后,可以去评测数据文件夹中遍历查找,然后输出对应的文件。就结束了?没错,就这样就结束了。
修复起来其实也不是什么难事,不过看到上一次commit时间还在N年前就没有维护的欲望了。不过还是在此放出修复方法。
限制权限,单独开用户运行选手代码,不给读取评测数据文件夹的权限
改用标准输入输出,对输出文件进行加密,由评测机解密后比较
[修改于 3年11个月前 - 2020/12/27 03:36:38]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |