BUUCTF Mysterious

Posted chneft

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BUUCTF Mysterious相关的知识,希望对你有一定的参考价值。



通过题目简介和下载得到的文件格式分析,该题需要对该文件进行逆向分析

BUUCTF Mysterious

查壳

逆向第一步分析文件格式,以及查看是否加壳,本例用exeinfoPE进行以上操作

可知该程序大概率是vc6.0编译的32位程序,可以用od分析(od只能分析32位程序),并且没有加壳。

IDA静态分析

方法一:通过WinMain函数分析

用ida打开该程序

从函数名称表里能看到非常显眼的WinMain函数,熟悉windows sdk的同学肯定马上就能反应过来这是窗口程序,而不是控制台程序。
tips:其实直接打开这个程序也能看出。
附图:

一般的win32程序就是用WinMain函数作为主函数,通过操作系统调用回调函数,对用户的操作做出对应的反馈。
于是我们可以直接双击这个WinMain函数,对其进行反编译。

反编译后得到下图

再双击这个返回值(这里有点套娃的意思,return WinMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd)这个函数就是winmain函数,但是却把他写成返回值,我不知道这里是ida的问题还是别的什么问题)

发现是一个DialogBoxParamA函数,也就是对话框函数。

给出一个msdn上对DialogBoxParamA函数的解释
链接: https://learn.microsoft.com/zh-CN/windows/win32/api/winuser/nf-winuser-dialogboxparama
之前我们讲了,既然要知道我输入数值之后程序做出了什么样的反应。那就必须要找回调函数。



DialogFunc便是指向对话框过程的指针,这个对话框过程便是一个回调函数。双击这个这个函数查看他的代码

再双击这个返回值(为什么函数体就是一个孤独的返回值呢,其实这里是一个间接调用,sub_401090这个函数它其实就是DialogFunc()这个回调函数),这样就看到这个回调函数的内容了,接下来就一条代码一条代码分析咯

方法二:通过string window取巧分析

有的同学对windows sdk不熟悉,想不到WinMain函数这个切入点,那么可以抛开上面的分析思路,打开ida后快捷键shift+F12直接打开string window。
立马就能发现well done这个非常可疑的字符串。

双击这个字符串查看他在内存中的位置

双击后边的sub_401090函数,查看调用这个字符串的函数,来到汇编图形界面,按f5反编译。


这样就来到了这个关键函数(回调函数)了。
这两种方法都可以达到相同的目的。

接下来分析这个回调函数
分享一个msdn对DialogFunc的解释
链接: https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nc-winuser-dlgproc


和我们分析的函数int __stdcall sub_401090(HWND hWnd, int a2, int a3, int a4)进行比对,可知hwnd是句柄,a2便是消息,a3,a4是其他消息。

接着分析

用memset函数把string为首地址的0x104个内存空间的值都置0。

前面说了a2是消息,那么16对应的应该是WM_CLOSE这个宏定义,273对应的应该是用户按下确认键之类的吧(这里我不确定具体是什么,因为目前我对对话框过程也不是很了解,也是边学边做,说的不对的见谅)。
a3(wparam)是一个附带的消息,往往是坐标值之类的东西。

附上该函数的msdn链接: https://learn.microsoft.com/zh-CN/windows/win32/api/Winuser/nf-winuser-getdlgitemtexta

可知,该函数把输入框里的值复制到&string指向的缓冲区。

得到string的字符个数,如果大于6就结束该程序。
下面是解题的关键——v10

在回调函数的顶部我们知道了v10是一个int变量,而atoi()函数是用来将ascii(char型)转化为integer(int型)
转载一个链接链接: https://blog.csdn.net/u010806950/article/details/105505540?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166562775916782417052552%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166562775916782417052552&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-105505540-null-null.142v53control,201v3control&utm_term=atoi&spm=1018.2226.3001.4187
可知v10的值是将string字符串 转化为int型之后加1的值

从if的判断条件可以反推,v10=atoi(&string)+1=123
,atoi(&string)=122,所以sting的值为"122xxx",即开头三个数为122,但总共有几个字符暂不可知。接下来把v12,v13,v14转化成ascii码看看

接着往下看

于是Text=“flag”,然后是置零操作

itoa()函数的功能是将integer转化为ascii,第一个参数是要转化的值,第二个参数是转化后值的储存地址,第三个数是要转化的值的进制,这里为10进制。
大家可能纳闷,v5是一个char变量,&v5是什么意思,&v5取地址,把要转化的值存到以v5为首地址的数组中,ida中将v5定义为一个char变量,但这并不代表他就是char,他有可能是char[]数组。
接下来

第一条代码使Text=“flag”,接着第二条指令使Text=“flag123”,到最后Text=“flag123_Buff3r_0v3rf|0w”
接着是一个messagebox,well done是标题,Text是内容

得到flag:flag123_Buff3r_0v3rf|0w

OD动态分析

但是得到了flag还不够,想知道我在文本框里输入什么值可以使程序输出messagebox。于是用od打开这个程序,定位到GetDlgItemTextA(hWnd, 1002, &String, 260);这个函数的汇编指令。该怎么做呢。
先在ida汇编图形界面中找到GetDlgItemTextA(hWnd, 1002, &String, 260);这个函数

发现了在这里

按空格进入文本界面
得到这条指令的VA(虚拟地址)为40113e
于是就定位到了这条指令的位置,在od中跳转到这个地址,并在push eax处下断点(根据右边的注释我们可以看到这里eax的值是输入框中字符串存放的首地址)

运行程序,我们之前说了sting的值为"122xxx",我们只能确定前三个数是122,后边的不确定,因此我们在输入框中输入122,接着程序运行到断点,,此时发现eax的值为19f5dc,于是在数据窗口中跳转到19f5dc这个地址

选定第一个19f5dc这个字节进行跟随

接着我们单步步过(f8),运行完40113e处的GetDlgItemTextA函数

发现‘31’32‘’32‘也就是122传进了19f5dc这个地址处,我们接着单步步过往下执行,运行到4011a7处

这个指令对应的就是v10== 123


我们接着往下走,运行到4011b4处

4011b4处这条指令把一个字节大小的值以补零的方式(movsx)传给eax,接着4011bb处将eax和0x78(’x‘)作比较

我们可以注意到这个字节大小的值的地址是19f5df,正好在’31‘32‘‘32’(19f5dc–19f5de)的后边一个字节,而19f5dc不正好就是输入框中字符串存放的首地址吗!于是便能联想到

这个if判断里v12,v13,v14也是文本框中输入值的一部分,那么理性推测文本框中的值也就是string=“122xyz”。那我们把这个值输到文本框里运行程序试一下

果然得到了正确答案,flag显现出来了,证明我们之前的推理正确。
最后再提一下

在ida界面中仔细观察string,v12,v13,v14的地址分别是esp+25c,esp+25f,esp+260,esp+261,会发现他们是连起来的(25ch–261h),正好6个字节,string虽然被ida判定为char类型,但不代表源代码中string便是char类型,实际上它应该是char string[6],之所以被判定为char类型,是ida的判断而已,不代表一定正确,这样就能解释的清string与v12,v13,v14之间的关系了,事实上这个小细节在reverse赛题中经常遇到,做题时多留意留意变量之间的地址关系,会有意想不到的收获。这道题就讲到这,有些地方思路比较绕弯,说的不对还请指正,谢谢。

Mysterious Light

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 int main()
 5 {
 6     ll i,j,k,m,n,x;
 7     ll sum;
 8     ll a,b;
 9     int flag=1;
10     cin>>n>>x;
11     a=x,b=n-x;
12     sum=n;
13     while(flag)
14     {
15         if(a>b)
16         {
17             ll y=a/b;
18             if(a%b==0)
19                 y--;
20             a=a-y*b;
21             sum+=2*y*b;
22         }
23         else if(a<b)
24         {
25             ll y=b/a;
26             if(b%a==0)
27                 y--;
28             b=b-y*a;
29             sum+=2*y*a;
30         }
31         else
32         {
33             sum+=a;
34             flag=0;
35         }
36     }
37     cout<<sum<<endl;
38     return 0;
39 }
View Code

题目描述

Snuke is conducting an optical experiment using mirrors and his new invention, the rifle of Mysterious Light.

Three mirrors of length N are set so that they form an equilateral triangle. Let the vertices of the triangle be a,b and c.

Inside the triangle, the rifle is placed at the point p on segment ab such that ap=X. (The size of the rifle is negligible.) Now, the rifle is about to fire a ray of Mysterious Light in the direction of bc.

The ray of Mysterious Light will travel in a straight line, and will be reflected by mirrors, in the same ways as "ordinary" light. There is one major difference, though: it will be also reflected by its own trajectory as if it is a mirror! When the ray comes back to the rifle, the ray will be absorbed.

The following image shows the ray‘s trajectory where N=5 and X=2.
技术分享图片
It can be shown that the ray eventually comes back to the rifle and is absorbed, regardless of the values of N and X. Find the total length of the ray‘s trajectory.

Constraints
2≦N≦1012
1≦X≦N?1
N and X are integers.
Partial Points
300 points will be awarded for passing the test set satisfying N≦1000.
Another 200 points will be awarded for passing the test set without additional constraints.

输入

The input is given from Standard Input in the following format:N X

输出

Print the total length of the ray‘s trajectory.

样例输入

5 2

样例输出

12

提示

Refer to the image in the Problem Statement section. The total length of the trajectory is 2+3+2+2+1+1+1=12.

就是一个不停减转化为除的过程。


















以上是关于BUUCTF Mysterious的主要内容,如果未能解决你的问题,请参考以下文章

BUUCTF | [GXYCTF2019]BabySQli

Buuctf | BUU SQL COURSE 1

BUUCTF-MISC-图片隐藏的秘密

buuctf 刷题记录 [第一章 web入门]afr_2

[BUUCTF 2018]Online Tool

[BUUCTF 2018]Online Tool