microcorruption-Tutorial

Tutorial

目录

本教程将带您了解我们的调试器,并在通关的过程中逐步解释一切是如何工作的。强烈建议您完成它(我们保证不到15分钟),但不是必须的。只要您不刷新页面,就随时可以返回本教程。

请添加图片描述

欢迎
世界各地锁着的仓库里散落着装满Cy Yombinator无记名债券的公文包,这些债券可能价值数十亿美元。你会帮忙偷公文包的。
Cy Yombinator巧妙地用Lockitall电子锁设备保护了仓库。Lockitall锁可以通过应用程序解锁。我们在每个仓库附近都安排了特工;每个人都在等着你通过解开锁来成功解锁仓库。
Lockitall设备通过接受来自Lockitall LockIT Pro应用程序的蓝牙连接来工作。我们已经为您做了艰苦的工作:我们花了15000美元购买了一个开发工具包,其中包括可供您练习的远程控制锁,并对其进行了逆向工程,以构建一个原始调试器。
使用调试器,您将能够单步调试代码,设置断点,检查内存。您将使用调试器来找到一个解锁测试锁的输入,然后将其重播为一个真正的锁。

简而言之, 就是你现在在用调试器调试一个智能锁,试着解开这个锁吧。

请添加图片描述

汇编代码窗口

这是反汇编的对象文件。
它包含LockIT Pro将执行的所有汇编指令。使用鼠标滚轮查看说明。

请添加图片描述

调试控制台

这是调试器的输入。
在此处输入命令。首先键入“help”

可以看到代码的回显,最下方输入框是输入命令的地方,我们先输入一个help

请添加图片描述

这是调试器控制台。
它包含您输入的命令的输出。向后滚动并阅读帮助。

请添加图片描述

启动程序

运行程序。
键入“continue”或“c”以启动。

请添加图片描述

这是IO控制台。
在这里我们可以看到锁的输出。现在,它希望我们输入密码。

这里是输入密码的地方,与刚刚的调试控制台不同,这里输入的内容会被当成数据来交互,而不是命令

请添加图片描述

输入密码

你可以在这里进行输入,然后锁会识别你的输入,现在输入test然后点击send提交

请添加图片描述

c启动

请添加图片描述

CPU输出也在这里。
注意,这里也显示了CPU的输出。此时,您输入的密码不正确

这里提示 我们输入的密码不正确

请添加图片描述

这意味着程序已结束执行

请添加图片描述

重置CPU

重置CPU
让我们再试一次,但这次我们要通过CPU查看发生了什么,输入reset来重置cpu状态

请添加图片描述

设置断点

设置一个断点
为了 了解发生了什么,我们将设置一个断点。当到达特定位置时,这将停止CPU执行。现在,输入“break-main”来中断名为“main”的函数。

输入break-main,可以使cpu在运行到main函数的时候进入暂停状态。

请添加图片描述

然后再输入c 可以发现cpu会停在主函数上

请添加图片描述

CPU已暂停。
您可以看到蓝色背景设置了一个断点。通过单击指令删除断点,这样下次运行程序时,CPU就不会停在这里。您可以通过单击指令来添加任何断点(但在本教程中不可以)。

可以看到现在代码停在了主函数上,我们单击一下,就可以取消掉它(但在本关教程无法取消)

请添加图片描述

寄存器

这里是寄存器
他们显示此时cpu的状态

请添加图片描述

这个是 pc (Program counter)
它以16进制 展示了当前执行命令的地址。(在debug调试中 所有数字都是16进制)

请添加图片描述

这里是当前的指令
pc指向的内存的值展示在这里,你也可以在左侧的 汇编代码窗口看到这条指令。

请添加图片描述

继续执行程序

让我们单步运行程序,输入step or s

输入s执行单步操作

请添加图片描述

我们运行了一个指令
我们正在执行的指令(红色指令)位于设置断点的位置之后。我们前进了一步。

可以看到我们只运行了一行命令,我们的断点在4438,现在单步执行完,cpu停在了443c

请添加图片描述

多次 单步操作
单步调试的方式,太缓慢了。键入step 5a以执行一系列指令。记住:这个数字是16进制的——我们实际上要执行90行指令。

s 5a 或者 step 5a 执行90次单步操作(如果没遇到断点或代码结束,则会执行到当前行后的90行)

请添加图片描述

INT函数

这是INT函数(interrupt)
这是锁与用户交互的方式。通过发出中断,可以回显字符、请求输入或执行其他任何操作。

请添加图片描述

部分输出
程序的部分输出如图所示。

请添加图片描述

再次继续
输入continue来运行到需要输入密码为止

请添加图片描述

你仍然不知道密码
但让我们再次输入test来看看程序究竟发生了什么吧

请添加图片描述

从函数里走出去

您可以通过输入out退出当前函数。它一直运行到遇到下一个ret(return)指令。所有函数都以“ret”指令结束,将它们返回给调用者。

请添加图片描述

您还没有退出到main函数,out可以缩写为f表示finish:请使用它。

请添加图片描述

再来一次

请添加图片描述

check_password函数

这个 check_password 函数看起来很有趣

请添加图片描述

设置断点

让我们在哪儿停下
输入break check_password来设置这个检查密码函数的断点

请添加图片描述

运行到断点
输入ccontinue

请添加图片描述

分析函数指令

这看起来很像。。。
看起来是在检查你的密码是否正确

请添加图片描述

分析指令中
接下来要执行的指令是`mov.b @r15,r14`
这条命令的意思是 将r15指向内存的值逐字节的传给r14,注意看r15

请添加图片描述

在内存中查找r15的值(它的位置是0x439c)。注意到您输入的密码是如何存在的吗?

请添加图片描述

输入s执行单步操作来看cpu将值传给r14

请添加图片描述

注意看r14的值已被更改。0x74是字母t的16进制

请添加图片描述

现在再输入一个 s ,看看下一条指令,这会让r15的值增加 1

请添加图片描述

注意看r15的值已被增加

请添加图片描述

接下来的命令是让r12的值加1,输入s看它这样做

请添加图片描述

注意看r12的值也增加了1

请添加图片描述

test指令(如果不是零,则进行测试)
测试函数将r14中的值与常数0进行比较。然后,它将相应地在状态寄存器中设置flag 0。

请添加图片描述

输入s,看看比较的结果

请添加图片描述

jnz指令 (非零跳转指令)
这是一个条件跳转,它将在未设置flag 0时移动程序计数器pc向回跳了8个字节。

非0跳,如果寄存器中sr不是0, 则会将当前指令地址向上跳8字节 (448c-8=4484 4484是检查密码函数的起始地址)也就是再次执行检查密码函数

请添加图片描述

将鼠标悬停在sr上面可以查看已设置的标志。‘c’表示设置了Carry flag(进位)。如果最后一条指令的执行结果为0,则会设置flag 0。但事实并非如此。

请添加图片描述

输入s,让我们看看这个跳转

请添加图片描述

我们回到了起点
但别忘了,我们现在已经处理了一个字节的输入,并且使r12增加了1

虽然我们又回到了函数开头,但我们之前执行的那些指令结果不会撤销掉。

请添加图片描述

循环终将结束。
当r14为0时,跳转不会发生,我们将在地址0x448e处结束。用`break 448e`在那里设置一个断点。请注意,这是一个以16进制的地址。在调试器中输入的所有数字都是16进制

循环总是会结束的,这个循环的结束条件就是让jnz不执行跳转。

理一下逻辑:

  1. 想让jnz不跳转,那就要让jnz执行时,寄存器sr值为 0.
  2. tst指令控制了sr,如果tst r14执行成功(判断r14为0),则sr为0
  3. r14的值是从r15传来的,而r15的值是一个地址,在每次循环时都增加1,也就是向后读取一个字节

总结:函数会逐字节读取字符串写入r14中,在当前读取的字符为0x00时,tst r14会将sr设为0,jnz也就不会跳转,循环就终止了。

请添加图片描述

取消断点
您还需要取消设置其他断点。输入unbreak check_password

输入unbreak check_password取消掉 检查密码函数 的断点,方便我们查看调试结果。

请添加图片描述

输入c

请添加图片描述

我们不再需要这个断点了,输入unbreak 448e取消掉

因为这里没有循环,所以要不要这个断点都没有意义了。

请添加图片描述

cmp指令(比较两个值)。

比较指令将r12中的值与常数9进行比较。请注意,r12现在是5。这是因为我们输入了一个4个字符的密码,其中一个额外的字符用于空字节。

请添加图片描述

jeq/jz指令(如果相等则跳转/如果为零则跳转)

如果比较为true(如果r12为9),则此函数将向前跳过4个字节。如果相等则跳转和如果零则跳转指令实际上是等效的:这是因为“cmp”在值相等时设置零标志。

请添加图片描述

没有设置flag0,所以跳转不会发生
输入 `s`

请添加图片描述

如果我们跳转成功会怎么样
来看看如果我们跳转成功会发生什么吧

请添加图片描述

改变pc的值
输入let pc=4498来改变pc指针

如果4492的jz语句跳转成功则会跳到4498,我们作弊一下看看成功跳转会发生什么

请添加图片描述

输入outf看看接下来会发生什么

请添加图片描述

我们再次执行了test指令,它会检查r15是否为非0,并设置相应的状态标志

请添加图片描述

输入s继续

请添加图片描述

继续s``r15是1,是非零的,所以现在能够触发jnz指令的跳转,我们再次输入s

请添加图片描述

完成!

我们正在移动授予访问权限的字符串,然后调用put,然后调用unlock_door。这意味着我们完成了开锁动作。

请添加图片描述

输入c让CPU继续执行

请添加图片描述

门已解锁

耶!
但别忘了,我们作弊了,我们将pc修改到了我们想要执行的位置。现在,让我们重新再来一次,但这次我们要输入正确的密码。

请添加图片描述

输入reset重置CPU

请添加图片描述

输入c继续运行

请添加图片描述

中断请求还有其他选项。
此复选框允许您输入十六进制编码的值,以便在需要输入特殊字符时使用。举个例子,当你想输入“test”的时候,必须输入“74657374”而不是“test”。

请添加图片描述

中断请求还有其他选项。
此按钮允许您关闭弹出窗口并返回调试器进行更多调查。您可以用“继续”来恢复CPU,这将返回此弹出窗口。

请添加图片描述

开始破解

现在让我们来解决它。我们知道如何使密码正确!
还记得r12需要是9吗?它为我们键入的每个字符增加一次,为结尾的空字节增加一次?所以我们只需要输入一个8个字符的密码。尝试将“password”作为输入。

请添加图片描述

在你提交了你的输入后,CPU会自动中断。这样可以更容易地调试正在发生的事情。(以前每次都会发生这种情况。)

请添加图片描述

继续,让我们看看一切是如何工作的

请添加图片描述

耶!
请记住,这是在调试器锁上。现在让我们对真正的锁做同样的事情,让我们的特工进入第一个仓库。

请添加图片描述

去干掉真正的锁
现在我们要在真正的锁上执行它。键入“solve”结束教程并执行此操作。您将无法运行任何调试命令,只需输入解决方案即可。

意思就是说,你不再可以单步运行,或是操作寄存器,你仅能够完成输入密码操作。

请添加图片描述

输入password

请添加图片描述

成功通关教程关卡

请添加图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值