【茶余饭后-源于学校布置的父亲节礼物】此文章归类为:茶余饭后。
最近龙河河畔的著名学府布置了一项任务:
设计一个“礼物”,藏在家里。让爸爸在父亲节当天想办法寻找并“获取”这个“礼物”内容。
考虑到我爸做程序猿若干年,我直接设计一手父亲节闯关任务,放在U盘,藏起来,作为这个“礼物”
不太清楚我爸的逆向水平(应该不是逆向方面工作者),不敢设计特别麻烦的题目,一点难度都不敢上,都是比较基础的内容,又怕做不出来,所以依托看雪平台,我个人把全部题解和流程发在这里,作为“参考答案”。
第零关
设计思路:网易我的世界在没有进行公开预告的时候,在我的世界官网的源代码里藏了一个小彩蛋,表示会更新1.19和1.20双版本。所以,相关信息藏在网页的源代码里。
解题步骤:
①F12
②COPY
③SUCCESS
本题源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <!DOCTYPE html>
<html lang = "en" >
<head>
<meta charset = "UTF-8" >
<meta http - equiv = "X-UA-Compatible" content = "IE=edge" >
<meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
<title>网页里好像藏着什么东西< / title>
<style>
body {
display: flex;
justify - content: center;
align - items: center;
height: 100vh ;
margin: 0 ;
background - color:
font - family: Arial, sans - serif;
overflow: hidden;
}
h1 {
font - size: 3rem ;
animation: fadeIn 2s ease - out;
}
@keyframes fadeIn {
0 % {
opacity: 0 ;
}
100 % {
opacity: 1 ;
}
}
< / style>
< / head>
<body>
<h1>网页里好像藏着什么东西< / h1>
<! - - Hidden information - - >
<p style = "display: none;" >看到这串文字意味着通过了入门关卡,请访问不愿意透漏姓名的url下载剩余题目.< / p>
< / body>
< / html>
|
第一关
设计思路:C++20是一次很重要的特性更新,正确识别C++20代码,就可以做出部分本题。C++中类的继承,以及相关设计模式是发挥C++面向对象特性的重要一部分,考察基本功。代码审查,检查有无后门代码是很重要的一个环节。
解题步骤:
①尝试运行该程序
②切换为C++20 可以解决关于transform ranges的报错
③Wrapper以纯虚方式声明了Info函数,但是在class ConsoleLog : public Wrapper 并没有给出实现,所以无法实例化抽象类
可以补写Info函数:
1 2 3 4 5 6 | void ConsoleLog::Info(const char * format , ...) {
va_list args;
va_start(args, format );
Log( "[INFO]: " , format , args);
va_end(args);
}
|
也可以直接删掉Wrapper中关于Info函数的声明
④全部修复好后 再次尝试运行 直接喜提锁屏套餐
看来代码有地方藏了“后门”
这里折叠起来的代码有猫腻
对相关代码进行删除即可
⑤再次运行 正确输出:
1 2 | [RUN]: Thread: 0x4d54
本题目的Key是:不愿意透漏姓名的前半个Keye97df5bb41f79e90bea61b0fb693ff
|
⑥也可以直接通过执行这部分代码实现Key的获取 但这不是题目设计的本意
1 2 3 4 5 6 7 8 9 10 11 12 | char key = 'K' ;
auto encryptDecryptChar = [key](char c) { return c ^ key; };
std::string original = "{y/z.{-|)z)*z}s-y|*xx)x-|*}|zx(}~.r|/-~))z-|r.r{).*}z){-)}rx--" ;
std::string encrypted = original;
std::ranges::transform(original, encrypted.begin(), encryptDecryptChar);
std::cout << "本题目的Key是:" << encrypted << std::endl;
|
第二关
设计思路:考察基本windows逆向功底,可以通过替换dll,hook sleep,hook 导出函数等多重方式解决本道题,也可以直接用工具查看内存明文字符串,等也不失为一种办法,大概需要十五个小时就可以等完了。
解题步骤:
①观察发现给出了目标函数的具体写法,甚至把函数放到dll作为导出函数使用,这种方式这道题难度就很低了。
②先点击执行,尝试删除dll,发现dll被占用
大概就可以推测出来写法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | typedef void(__stdcall * ReturnMethod)();
HMODULE hModule = LoadLibraryA( "test_002_dll.dll" );
if (hModule = = NULL) {
MessageBoxA(NULL, "Failed to load DLL." , "Error" , MB_ICONERROR);
return ;
}
/ / 获取returnMethod函数地址
ReturnMethod returnMethod = (ReturnMethod)GetProcAddress(hModule, "returnMethod" );
if (returnMethod = = NULL) {
MessageBoxA(NULL, "Failed to get function address." , "Error" , MB_ICONERROR);
FreeLibrary(hModule);
return ;
}
/ / 执行returnMethod函数 100 万次
for ( int i = 0 ; i < 10000 ; + + i) {
returnMethod();
}
|
③由于使用的是dll的导出函数 直接踩用最简单的替换dll,新建一个dll项目文件
1 2 3 | extern "C" void __declspec(dllexport) returnMethod() {
return ;
}
|
编译 替换掉test_002_dll.dll
④直接重新执行,没有了Sleep,很快得到了答案
⑤可以直接hook Sleep函数 直接retrun它 也可以达到相同的效果,也可以对导出函数进行hookreturn。这里不再赘述。
使用秘钥获得结果
最后访问这个网页,就可以看到祝福了。
题目还是超级简单的哦 大概率用不上这份题解吧 我觉得~
全部源码已上传附件
更多【茶余饭后-源于学校布置的父亲节礼物】相关视频教程:www.yxfzedu.com