【Writeup】i春秋网络安全领域专项技能赛_Reverse_srcleak

【Writeup】i春秋网络安全领域专项技能赛_Reverse_srcleak

​ 本题给了一个cpp文件,其内容如下:

#include<iostream>
using namespace std;

typedef unsigned int uint;



template <bool Flag, class MaybeA, class MaybeB> class IfElse;

template <class MaybeA, class MaybeB>
class IfElse<true, MaybeA, MaybeB> {
public:
	using ResultType = MaybeA;
};

template <class MaybeA, class MaybeB>
class IfElse<false, MaybeA, MaybeB> {
public:
	using ResultType = MaybeB;
};

template <uint N, uint L, uint R> struct func1 {
	enum { mid = (L + R + 1) / 2 };

	using ResultType = typename IfElse<(N < mid * mid),
		func1<N, L, mid - 1>, func1<N, mid, R> >::ResultType;

	enum { result = ResultType::result };
};

template <uint N, uint L> struct func1<N, L, L> { enum { result = L }; };

template <uint N> struct _func1 { enum { result = func1<N, 1, N>::result }; };









template<size_t Input>
constexpr size_t func2 = (Input % 2) + func2< (Input / 2) >;

template<>
constexpr size_t func2<0> = 0;









template<size_t num>
constexpr size_t func3 = num % 2;









template<uint n, uint m>struct NEXTN {
	const static uint value = ((n % m != 0) * n);
};
template<uint n, uint m>struct NEXTM {
	const static uint value = (m * m <= n ? (m + 1) : 0);
};
template<uint n, uint m>struct TEST {
	const static uint value = TEST<NEXTN<n, m>::value, NEXTM<n, m>::value>::value;
};
template<uint m>struct TEST<0, m> {
	const static uint value = 0;
};
template<uint n>struct TEST<n, 0> {
	const static uint value = 1;
};
template<uint n>struct func4 {
	const static uint value = TEST<n, 2>::value;
};
template<>struct func4<1> {
	const static uint value = 0;
};
template<>struct func4<2> {
	const static uint value = 1;
};











int main(int argc, char**argv) {
	//input 5 uint numbers ,x1,x2,x3,x4,x5
	//the sum of them should be MIN


	cout << func3< func2<x1> > << endl;
	cout << func3< func2<x2> > << endl;
	cout << func3< func2<x3> > << endl;
	cout << func3< func2<x4> > << endl;
	cout << func3< func2<x5> > << endl;

	// output: 1 1 1 1 1


	cout << _func1<x1>::result << endl;
	cout << _func1<x2>::result << endl;
	cout << _func1<x3>::result << endl;
	cout << _func1<x4>::result << endl;
	cout << _func1<x5>::result << endl;

	//output: 963 4396 6666 1999 3141




	//how many "1" will func4<1>,func4<2>,fun4<3>......fun4<10000> ::value  return?
	x6 = count;


	// your flag is flag{x1-x2-x3-x4-x5-x6}
	// if x1=1,x2=2,x3=3,x4=4,x5=5,x6=6
	// flag is     flag{1-2-3-4-5-6}



	return 0;
}

要求比较明确:读懂源码按条件计算得到x1-x6并以-连接即为flag。

笨一点的方法就是改写一下源码写出python脚本爆破出x1-x5,再计算出x6:

x1-x5:

def func2(x):
	if x == 0:
		return 0
	return (x % 2) + func2(x // 2)

def func3(x):
	return x % 2

def func1(N, L, R):
	if L == R:
		return L
	mid = (L + R + 1) // 2
	if N < mid * mid:
		return func1(N, L, mid - 1)
	else:
		return func1(N, mid, R)

def _func1(x):
	return func1(x, 1, x)



if __name__ == '__main__':
	x1_flag = False
	x2_flag = False
	x3_flag = False
	x4_flag = False
	x5_flag = False
	for i in range(10000000, 100000000):
		if func3(func2(i)) != 1:
			continue
		if _func1(i) == 963 and not x1_flag:
			print("x1:",i)
			x1_flag = True
		if _func1(i) == 4396 and not x2_flag:
			print("x2:",i)
			x2_flag = True
		if _func1(i) == 6666 and not x3_flag:
			print("x3:",i)
			x3_flag = True
		if _func1(i) == 1999 and not x4_flag:
			print("x4:",i)
			x4_flag = True
		if _func1(i) == 3141 and not x5_flag:
			print("x5:",i)
			x5_flag = True

x6:

def nextm(n, m):
	if m*m <= n:
		return m+1
	else:
		return 0

def nextn(n, m):
	return (n % m != 0) * n

def test(n, m):
	if n == 0:
		return 0
	if m == 0:
		return 1
	return test(nextn(n, m), nextm(n, m))

def func4(x):
	if x == 1:
		return 0
	if x == 2:
		return 1
	return test(x, 2)


if __name__ == '__main__':
	x6 = 0
	for i in range(1, 5):
		if func4(i*2-1) == 1:
			x6 += 1
	print(x6)

  快一点的话就是由语义和简单的测试可以得出,_func1的输入值是输出值的平方,即x1-x5可以由output的5个数分别平方获取;而x6是1-10000整数中质数的个数。

​ 最终flag:
flag{927369-19324816-44435556-3996001-9865881-1229}

题目#include <cstdio> #include <cstring> #include <ctype.h> #include <cstdlib> #include <cmath> #include <climits> #include <ctime> #include <iostream> #include <algorithm> #include <deque> #include <vector> #include <queue> #include <string> #include <map> #include <stack> #include <set> #include <numeric> #include <sstream> #include <iomanip> #include <limits> #define CLR(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair <int, int> pii; typedef pair <ll, ll> pll; typedef pair<string, int> psi; typedef pair<string, string> pss; const double PI = 3.14159265358979323846264338327; const double E = exp(1); const double eps = 1e-6; const int INF = 0x3f3f3f3f; const int maxn = 1e6 + 5; const int MOD = 1e9 + 7; int main() { int n; cin >> n; vector <int> v; int num; for (int i = 0; i < n; i++) { scanf("%d", &num;); v.push_back(num); } cin >> n; for (int i = 0; i < n; i++) { scanf("%d", &num;); v.erase(v.begin() + num - 1); } vector <int>::iterator it; for (it = v.begin(); it != v.end(); it++) { if (it != v.begin()) printf(" "); cout << *it; } cout << endl; } --------------------- 作者:Dup4 来源:CSDN 原文:https://blog.csdn.net/dup4plz/article/details/79666083 版权声明:本文为博主原创文章,转载请附上博文链接!#include <cstdio> #include <cstring> #include <ctype.h> #include <cstdlib> #include <cmath> #include <climits> #include <ctime> #include <iostream> #include <algorithm> #include <deque> #include <vector> #include <queue> #include <string> #include <map> #include <stack> #include <set> #include <numeric> #include <sstream> #include <iomanip> #include <limits> #define CLR(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair <int, int> pii; typedef pair <ll, ll> pll; typedef pair<string, int> psi; typedef pair<string, string> pss; const double PI = 3.14159265358979323846264338327; const double E = exp(1); const double eps = 1e-6; const int INF = 0x3f3f3f3f; const int maxn = 1e6 + 5; const int MOD = 1e9 + 7; int main() { int n; cin >> n; vector <int> v; int num; for (int i = 0; i < n; i++) { scanf("%d", &num;); v.push_back(num); } cin >> n; for (int i = 0; i < n; i++) { scanf("%d", &num;); v.erase(v.begin() + num - 1); } vector <int>::iterator it; for (it = v.begin(); it != v.end(); it++) { if (it != v.begin()) printf(" "); cout << *it; } cout << endl; } --------------------- 作者:Dup4 来源:CSDN 原文:https://blog.csdn.net/dup4plz/article/details/79666083 版权声明:本文为博主原创文章,转载请附上博文链接!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值