首页 > 其他分享 >XP版扫雷官方作弊彩蛋分析

XP版扫雷官方作弊彩蛋分析

时间:2024-01-21 14:46:16浏览次数:23  
标签:触发 函数 事件处理 彩蛋 注解 XP 作弊

概述

Minesweeper(扫雷)是一款由微软于1992年发行的小游戏。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。该游戏在推出后预装到Windows系统中,随后逐渐风靡全球,经久不衰。

本次分析主要是对XP版本的扫雷游戏中官方预置的彩蛋进行分析。该彩蛋已知的触发行为是:关闭输入法,先依次输入XYZZY五个字母,随后按下shift键即开启作弊。作弊开启后,当指针划过游戏区时,屏幕左上角的像素点颜色可以提示玩家该区域是否存在雷。若为黑色像素点,则玩家指针所指的区域即为雷,反之亦然。

本次分析将采用动态分析和静态分析相结合的方式,旨在确定该官方彩蛋的触发方式、作弊功能具体的实现方式等内容,并尝试确定是否有其他开启彩蛋的方法。

确定分析位置

首先打开OllyDbg,对软件进行加载。运行后观察函数相关调用,寻找与彩蛋有关的线索。已知彩蛋开启后的表现是在桌面左上角绘制一个黑色像素点,过程中可能需要调用相关绘制函数。

确认该程序在01002158地址处调用了gdi32.SetPixel函数,该函数可以用于将设备上下文中指定坐标处的像素设置为指定颜色。该调用前后还有获取和释放设备上下文的调用。

image-20240104152348372

对其下断点,调试运行,触发彩蛋条件并尝试作弊,确认是否与该调用有关。经确认,在开启彩蛋后,指针划过扫雷游戏区能够触发断点,且继续运行可以发现屏幕左上角像素点颜色发生变化。

继续运行程序,可以发现最终进入了消息处理循环之中。

image-20240104154001366

可以确认,该窗体应用程序采用了经典的基于消息的事件驱动的程序设计模式。总体流程为:系统发生事件->Windows把事件翻译成消息,然后放入消息队列->应用程序接收到消息,并放在Msg记录中->窗口过程响应该消息并处理。

在本部分主要确认了程序彩蛋中具体的作弊调用位置(地址01002158),确认了该程序是基于Windows基于消息的事件驱动的窗体应用程序,且确定了消息处理主进程(地址01002379)。下面将基于这些信息展开进一步的分析和讨论。

彩蛋作弊流程分析

使用IDA Pro分析工具打开可执行文件,跳到SetPixel所在位置(地址01002158),反编译后观察逻辑。

image-20240104170905162

可以看到此处上方有一个标签LABEL_102。该部分为主要的作弊逻辑。具体逻辑简述如下:首先对鼠标指针指向的扫雷游戏区的坐标进行计算(通过v4变量,在上方通过消息lParam获得),得到扫雷游戏区的逻辑坐标,然后判断是否合法。若逻辑坐标合法,读取对应该位置对应的内存,判断若内存值<0时绘制黑色像素点,>=0时绘制白色像素点。接下来执行到return语句,该部分处理流程结束。以下是作弊部分的流程图。

image-20240104170835475

本部分主要对彩蛋的作弊流程进行了分析。该部分内容首先依赖了上面部分已经保存了的lParam参数以获得鼠标的指向位置,并利用计算转换为了逻辑坐标,最后依照内存中的值(相关内存中的值在<0时为雷)在设备上下文中绘制像素点。过程中巧妙地利用了位运算提升了计算效率,节约了机器资源。

彩蛋触发流程分析

继续阅读代码段,追踪作弊主要逻辑所在函数的调用,发现该函数在窗体运行函数中被作为WNDCLASSW结构的lpfnWndProc成员,即指向窗口过程的指针。必须使用CallWindowProc函数来调用窗口过程。

image-20240105134132506

很显然,包含作弊主要逻辑的函数为窗口消息的响应函数,故将sub_1001BC9重命名为EventProess函数。

在注册事件处理函数后,该函数还会进行创建窗口、判断等操作,随后进入事件处理循环。事件循环结束后,进入后处理环节(用于销毁环境、释放资源等),最后该函数结束。

image-20240105135106466

在事件到来时,窗体运行函数会将消息先转换后,通过DispatchMessage自动地将有关事件消息转发到刚刚注册的EventProcess函数。由于其功能,将注册响应函数的sub_10021F0函数重命名为RunWindow。而RunWindow又进一步被start函数(程序起始点)所调用。以下是窗体运行时的相关流程示意图。

image-20240105144845550

进一步对EventProcess事件处理函数进行分析,会发现整体上是一个大型if-elif-else形式/switch-case形式的结构,接收到翻译后的消息后,按照Msg内容,分配到不同的逻辑中进行处理,并按需使用消息中所含的wParamlParam

进一步对逻辑进行整理,要使得EventProcess事件处理函数在处理事件时能够判断是否开启作弊流程、是否跳转到作弊流程,需要满足几个条件,如图和注解所示。(为清晰展示,其它无关逻辑被简化,不再在图中体现。请按照注解顺序观看本图。)

image-20240105165737839
  • 注解1:Msg==0x200时,事件名WM_MOUSEMOVE,描述为“移动鼠标”。Y分支即当事件处理函数接收到鼠标移动事件时执行对应操作。

  • 注解2:Msg==0x100时,事件名WM_KEYDOWN,描述为“按下一个键”。Y分支即当事件处理函数接收到按下键盘事件时执行对应操作。

  • 注解3:在WM_KEYDOWN事件前提下,wParam事件参数代表着按下了哪个键。由于本次分析主要关注Shift键(见注解5),其余判断逻辑由于无关,均省略。

  • 注解4:此处经编辑后的源代码如图所示。

    image-20240105163904052

    alreadyInputDigits为变量A,password为触发彩蛋序列(地址01005034),wParam在事件前提下代表用户按下的键。本段主要逻辑为:逐次对比用户的输入是否符合password序列,若符合序列则变量A+1,不符合则将变量A置0。最终正确输入序列后变量A应为5。由于采用了事件编程,这里巧妙地利用了int型变量A(alreadyInputDigits)来存储匹配序列的状态。

    同时,结合ollydbg动态分析查看password处(地址01005034)的序列信息,可以看到XYZZY序列,与预计的触发序列一致。

    image-20240105164408764

  • 注解5:在事件前提下,wParam若为0x10则代表用户本次按下了Shift键。

  • 注解6:若按下了Shift键后,变量A大于等于5时,代表要么已经输入完毕还未开启(A5),或是已经被开启(A11)。

  • 注解7:此处巧妙利用异或运算,当输入完毕时还未开启(A5),执行XOR 0x14u操作后A变为11;而当已开启时(A11),执行XOR 0x14u操作后A变为5。

  • 注解8:wParam二进制第四位是否为1,在源代码中操作如图。

    image-20240105170234393

    wParam & 8 != 0该语句为真则执行Y分支跳转到作弊主要流程。由于有注解1的移动鼠标事件前提,其事件的wParam参数用于指示各种虚拟键是否已按下。 在这种情况下,只有MK_CONTROL键(值为0x0008)能够满足该条件。故本次后门彩蛋分析发现了一个新的触发方式,在输入触发序列后,还没有按下Shift键开启前,按住Ctrl键不放使用鼠标指向雷区可以实现同样的作弊功能。经过实验,用这种新发现的方式也成功地触发了彩蛋作弊功能。

  • 注解9:当变量A>5时,代表着作弊功能已被开启(A==11),直接跳转进入彩蛋作弊主要流程。

本部分主要对彩蛋触发的流程进行了详细分析。彩蛋主要是通过对事件的响应来实现对应的操作。而实现的过程中采用了许多巧妙的方法,如使用变量A存储用户彩蛋字符的输入状态,节约内存空间。进一步地,开发者还采取了异或计算的技巧,更巧妙地复用了该变量状态,使得一个变量能够为整个功能提供支撑,极大的节约了运行内存资源。可以说,整个彩蛋的触发和执行过程主要依赖于变量A的状态。最后,通过分析还找到了一种新型的采用Ctrl键触发彩蛋的方法。

总结

至此,针对XP版扫雷游戏的后门彩蛋分析就基本完成了。

在调试与分析扫雷二进制文件的过程中,不难发现颇有早期程序员简约、节约的风格。其中调用的一部分win32 API有一些已经不再推荐使用,或有更新的实现,但旧版仍被保留了下来,让XP时代的程序在Win11时代仍能运行;程序逻辑中有一些设计和技巧十分巧妙(也不排除是编译器自动优化的结果),如利用位运算简洁计算所指的游戏区逻辑位置,利用单变量存储用户输入状态以及利用异或计算来复用变量的操作都十分令人惊叹。

本次分析利用了动态调试与静态调试结合的方法,工具主要使用了OllyDbg以及IDA Pro。从彩蛋的表现入手,利用动态调试确定其调用的win32 API、地址信息以及程序的设计模式,随后对二进制文件进行静态分析,阅读程序逻辑,理顺事件处理函数与逻辑,最终形成本次报告。除分析了常规的利用Shift键开启彩蛋作弊的触发流程、事件处理流程以及作弊的核心代码之外,还发现了一个全新的利用Ctrl键的触发方式。

标签:触发,函数,事件处理,彩蛋,注解,XP,作弊
From: https://www.cnblogs.com/framelinker/p/17977837/xp-minesweeper-cheat

相关文章

  • ValueError: Found array with dim 4. None expected <= 2.
     Traceback(mostrecentcalllast): File"train.py",line109,in<module>   out,eval_res=tasks.eval_forecasting(model,data,train_slice,valid_slice,test_slice,scaler,pred_lens,n_covariate_cols,args.max_train_length-1) Fil......
  • spring boot一个奇怪的错误(There was an unexpected error (type=Internal Server Err
    今天运行springboot的时候爆了这个错(Therewasanunexpectederror(type=InternalServerError,status=500).Exceptionparsingdocument:template=“index”,line6-column3)说什么无法解析文档,昨天还运行的好好的,看一下控制台说什么meta标签没关闭,我可是用idea自己创......
  • Process Explorer高级技巧
    ProcessExplorer是一款功能丰富的进程系统工具,远比windows自带的任务管理器强大。  还原线程堆栈 点击菜单Options--ConfigureSymbols... 配置Symbol符号表:srv*D:\Symbols\sys*http://msdl.microsoft.com/download/symbols;D:\Symbols\MyGame然后把MyTest1-Win6......
  • 前端歌谣-第六十五课-express之服务端渲染和客户端渲染
    前言我是歌谣微信公众号关注前端小歌谣一起学习前端知识今天继续给大家讲解服务端渲染和客户端渲染静态资源的讲解案列index.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,init......
  • hyperexpress框架/使用uwebsockets.js核心
    import{scheduleJob}from'node-schedule';//定时任务functionsetupScheduledTasks(){//每6秒执行一次setInterval(()=>{taskEverySixSeconds();},6000);//每33分钟执行一次setInterval(()=>{taskEve......
  • 提速40%!江波龙推出XP2200系列M.2 2280规格SSD:疾速7100MB/s
    江波龙FORESEEXP2200系列PCIeSSD推出M.22280规格。产品搭载主流232层3DTLC闪存颗粒,并采用基于12nm工艺的4通道高性能主控芯片,支持HMB主机高速缓冲技术,能够提供高达2400MT/s的I/O速率,进一步释放产品潜能。产品所用的主控芯片减少了一半的读写通道数量,从而显著降低25%的功耗并......
  • Nexpose v6.6.233 for Linux & Windows - 漏洞扫描
    Nexposev6.6.233forLinux&Windows-漏洞扫描Rapid7VulnerabilityManagement,ReleaseJan17,2024请访问原文链接:https://sysin.org/blog/nexpose-6/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org您的本地漏洞扫描程序搜集通过实时覆盖整个网络,随......
  • [论文阅读] Progressive Domain Expansion Network for Single Domain Generalization
    ProgressiveDomainExpansionNetworkforSingleDomainGeneralization3.Method本文提出的PDEN用于单域泛化。假设源域为\(\mathcal{S}=\left\{x_i,y_i\right\}_{i=1}^{N_S}\),目标域为\(\mathcal{T}=\left\{x_i,y_i\right\}_{i=1}^{N_T}\),其中\(x_i,y_i\)分别表示第......
  • Google的Jax框架的JAX-Triton目前只能成功运行在TPU设备上(使用Pallas为jax编写kernel
    使用Pallas为jax编写kernel扩展,需要使用JAX-Triton扩展包。由于Google的深度学习框架Jax主要是面向自己的TPU进行开发的,虽然也同时支持NVIDIA的GPU,但是支持力度有限,目前JAX-Triton只能在TPU设备上正常运行,无法保证在GPU上正常运行。该结果使用kaggle上的TPU和GPU进行测试获得。......
  • 前端歌谣-第陆拾叁课-express获取请求参数
    前言我是歌谣微信公众号关注前端小歌谣一起学习前端知识今天继续给大家讲解获取express获取请求采参数的讲解案例index.jsconstexpress=require("express")constapp=express()constIndexRouter=require("./router/indexRouter")//应用app.use(function(req,res,next)......