buuctf-[网鼎杯 2020 青龙组]singal个人感悟及收获

好久没写博客了。。。真不是懒,我是真的不会做(泪,流了下来

这道别人的博客都说很简单的虚拟机题我做(看题解)了两天半才算大概明白整个题的原理与做法,为了不辜负我这几天的绞尽脑汁,我得写篇题解整理整理思路,顺便加强记忆

下载文件后直接拖到ida32里,进入main函数后反汇编

 

 最上面那个_main里面毫无价值,直接看下面。从memcpy很容易推测出这里v4里存储的是unk_403040的值。进入unk看看情况

由于太长,我直接转到hex页,发现里面用db存了这些东西

 

 由于v4是int整型变量,一个数占四个字节,所以我们可以简化unk里面的值,也就是四个四个的提取出来

得到下面的数(都是16位进制的数)

 

 稍微整理一下后,我们得到下面的数

 

 

长度为456/4=114,正好与下一个函数的第二个传入值相等,证明之前的猜想应该是正确的
点进下面的函数

 

 比较长,这里就不全部截出来了(

a1即是传入的v4,也就是刚刚求出来的数组。

进入函数发现是类似虚拟机的题目。在case 10中发现了一个奇怪的函数,点进去发现是输入值的函数

 

 

 给我们的信息是输入的值放在str里,且str长度为15
回到上一个函数,开始分析

 

 v10大于114时跳出

 

 唯一一个给v4赋值的case

 

 

 

 用输入的str与a1做运算来给v5赋值,且v10一次加2

 

 这个没有实际作用,和continue函数差不多

 

 这个很有意思,因为a1我们是知道的,所以我们可以从这个case推出v4的值,等下再分析

 

 

将v5的值存在str里面

 

 只在最开始出现过,用来输入

 

 用str赋值v5,但此处v10只加1

 

 不是1到12就continue

还算很好理解,现在分析case7

 

 v8最初是0,执行一次case7就加1,a1[v10]是switch里的数,此处意味着v4当前位和a1[v10]后一位相等

我们回头看之前推出来的a1的值

 

 提取出7后面的值,得到v4的值

整个类虚拟机运行的思路大致如下:

 

 1.10只出现一次,对应输入,也就是我们需要求的flag

2.因为只有case 1是给v4赋值,而v4最开始里面啥都莫得,再根据最后一串case7后面紧跟着的v4与a1比较,我们可以推测出:

前面其他的数字都是给v5——即中间变量——做各种各样变换,也是一个加密过程。最后case1是最重要的存储加密完的结果的一个步骤。而且case 1有15个(其中有一个地方1连在一起了算做一个,因为相连代表着v5未作变换,所以后一个1会覆盖掉前一个),7也有15个,刚好一一对应。

综上,整个程序的思路已经差不多出来了。

根据虚拟机逆向的做题思路,此处我们应该写个脚本来反过来推flag

因为我自己第一次做虚拟机,搞不出来这种逆向的脚本,我借鉴了大佬博客里的一段代码  https://www.cnblogs.com/sk2rw/p/14324186.html

在这里讲一下我看了许久才明白的部分吧(

 因为要逆向求原输入,所以把a1和v4都逆向排序了一波,因此此处i等于len(a1)-1时,对应的是最开始的输入,也就是第一个输入的数的变换对应的值,所以我们得加上去。

 

 之前描述了,覆盖的问题

 

 因为这里的几个case都是v10+=2,所以会一次跳两位。假设a1[i]==3,如果他前一位是case 2,5,4的话因为2,5,4一次会进两位,因此会跳过case 3即他本身。自相矛盾,所以要加这些if判断。

好了,似乎。。没什么需要解释的了。

希望看我博客的朋友能看懂我写的这杂乱无章的文章

(我反正看懂了

(koishi赛高

 

posted @ 2021-05-30 21:07  夏男人  阅读(532)  评论(0)    收藏  举报