2020西湖论剑 re-Cellular
本帖最后由 三年三班三井寿 于 2020-10-12 15:35 编辑没有什么花里胡哨的东西,进去之后逻辑很清晰
```
int __cdecl main(int argc, const char **argv, const char **envp)
{
Honeycomb *v3; // ebx
char *Format; //
int i; //
Honeycomb *v7; //
char v8; //
_alloca((size_t)Format);
__main();
memset(&v8, 0, 0x1Au);
v3 = (Honeycomb *)operator new(8u);
Honeycomb::Honeycomb(v3);
v7 = v3;
for ( i = 0; i <= 4; ++i )
Honeycomb::IncDepth(v7);
printf("Path:");
scanf("%25s", &v8);
if ( (unsigned __int8)Honeycomb::CheckFlag(v7, &v8) )
{
puts("Congrulations!");
puts("The flag is md5(Path)!");
}
else
{
puts("Wrong~");
}
system("pause");
return 0;
}
```
通过CheckFlag将输入的"%25s"与之前构建的数据结构判断。
输入按字节循环,‘L'或’R‘进行左旋或右旋操作,其他均为无效输入。
```
signed int __cdecl Honeycomb::CheckFlag(Honeycomb *this, char *Str)
{
signed int v3; //
char str_i; //
size_t i; //
_DWORD *v7; //
v7 = *(_DWORD **)this;
for ( i = 0; i < strlen(Str); ++i )
{
str_i = Str;
if ( str_i == 76 )
{
if ( *(_DWORD **)this == v7 )
{
if ( !(unsigned __int8)Honeycomb::RotateL(this, (Hexagon **)&v7, 0) )
return 0;
}
else if ( !(unsigned __int8)Honeycomb::Clockwise(this, (Hexagon **)&v7) )
{
return 0;
}
}
else if ( str_i == 82 )
{
if ( *(_DWORD **)this == v7 )
{
if ( !(unsigned __int8)Honeycomb::RotateR(this, (Hexagon **)&v7, 0) )
return 0;
}
else if ( !(unsigned __int8)Honeycomb::Counterclockwise(this, (Hexagon **)&v7) )
{
return 0;
}
}
}
v3 = 0;
if ( *v7 == 0x23 && Honeycomb::CheckUseCount(this) == 0x5E )
v3 = 1;
return v3;
}
```
数据中初始化生成,每个节点长度为0x14。操作后需要找到0x23(#)的节点,所有节点的值存在一个全局数组中char map[] = "*-----++++--++--------------------------------+++-#-----------++-------------------+++++++++----+++---++++++++---++++---+------+++++++++++++++++++---+";
本来想画出结构再去解,后来实在是弄不下去了。三个指针的逻辑也不是父左右子节点。有师傅知道的告知一下,我也不是ctfer,很多基础估计也不知道。
最后只能扣代码实现爆破。因为其输入的限制,爆破起来也很快。
直接扣出相关代码
```
char map[] = "*-----++++--++--------------------------------+++-#-----------++-------------------+++++++++----+++---++++++++---++++---+------+++++++++++++++++++---+";
BYTE pathL[] = { 01, 01, 01, 01, 01, 02, 01, 01,03, 02, 01, 01, 03, 02, 03, 01,03, 02, 03, 02, 03, 02, 03, 02,01, 02, 03, 02, 01, 01, 03, 02,01 ,01, 03, 02 ,01, 03, 02, 01,01, 03, 02, 01, 03, 03, 02, 01,03, 02, 00, 00, 00, 00, 00, 00,00, 00, 00, 00 };
BYTE pathR[] = {02,02,02,02,02,01,02,02,03,01,02,02,03,01,03,02,03,01,03,01,03,01,03,01,02,01,03,01,02,02,03,01,02,02,03,01,02,03,01,02,02,03,01,02,03,03,01,02,03,01,00,00,00,00,00,00,00,00,00,00 };
int g_num = 0;
_DWORD* InsertHexagon(_DWORD arg1, _DWORD arg2) {
int v2; // esi
_DWORD *v3; // ebx
int v4; // esi
_DWORD *v5; // ebx
int v6; // esi
_DWORD *v7; // ebx
int v8; // esi
_DWORD *v9; // ebx
int v10; // esi
_DWORD *v11; // ebx
_DWORD *result; // eax
int j; //
signed int i; //
_DWORD *v15; //
_DWORD *v16; //
_DWORD *arg2a; //
_DWORD *arg2c; //
_DWORD *arg2d; //
_DWORD *arg2b; //
_DWORD *arg2e; //
v15 = 0;
while (*((_DWORD *)arg2 + 4))
arg2 = (_DWORD)(*(_DWORD **)(*((_DWORD *)arg2 + 4) + 8));
for (i = 0; i <= 5; ++i) {
v16 = (_DWORD *)*((_DWORD *)arg2 + 3);//*NEXT
v2 = map;
v3 = (_DWORD *) new char{ 0 };
*(_DWORD *)v3 = v2;
*((_DWORD *)arg2 + 4) = (_DWORD)v3;
*((_DWORD *)v3 + 4) = arg2;
arg2a = v3;
if (v15) {
*((_DWORD *)v3 + 3) = (_DWORD)v15;
*((_DWORD *)v15 + 3) = (_DWORD)v3;
}
v4 = map;
v5 = (_DWORD *) new char{ 0 };
*(_DWORD *)v5 = v4;
*((_DWORD *)arg2a + 2) = (_DWORD)v5;
*((_DWORD *)v5 + 2) = (_DWORD)arg2a;
arg2c = v5;
v6 = map;
v7 = (_DWORD *) new char{ 0 };
*(_DWORD *)v7 = v6;
*((_DWORD *)arg2c + 3) = (_DWORD)v7;
*((_DWORD *)v7 + 2) = (_DWORD)arg2c;
v15 = v7;
for (j = 0; *((_DWORD *)arg1 + 1) > 1 && *((_DWORD *)arg1 + 1) - 1 > j; ++j)
{
arg2d = v16;
v16 = *(_DWORD **)(*((_DWORD *)v16 + 3) + 8);
v8 = map;
v9 = (_DWORD *) new char{ 0 };
*(_DWORD *)v9 = v8;
*((_DWORD *)arg2d + 4) = (_DWORD)v9;
*((_DWORD *)v9 + 4) = (_DWORD)arg2d;
arg2b = v9;
if (v15)
{
*((_DWORD *)v9 + 3) = (_DWORD)v15;
*((_DWORD *)v15 + 3) = (_DWORD)v9;
}
v10 = map;
v11 = (_DWORD *) new char{ 0 };
*(_DWORD *)v11 = v10;
*((_DWORD *)arg2b + 2) = (_DWORD)v11;
*((_DWORD *)v11 + 2) = (_DWORD)arg2b;
v15 = v11;
}
if (*((_DWORD *)v16 + 4)) {
arg2e = (_DWORD *)*((_DWORD *)v16 + 4);
*((_DWORD *)arg2e + 3) = (_DWORD)v15;
*((_DWORD *)v15 + 3) = (_DWORD)arg2e;
break;
}
arg2 = (_DWORD)v16;
}
result = (_DWORD*)arg1;
++*((_DWORD *)result + 1);
return result;
}
signed int IncDepth(char* arg) {
int v1; // esi
int v3;
char* v4;
if (*(_DWORD *)arg) {
return (unsigned int)InsertHexagon((DWORD)arg, *(DWORD*)arg);
}
v1 = map;
char* v2= new char{ 0 };
*(_DWORD *)v2 = v1;
*(_DWORD *)arg = (_DWORD)v2;
*(_DWORD *)(*(_DWORD *)arg + 4) = 1;
_DWORD * v8 = *(_DWORD **)arg;
for (signed int i = 0; i <= 4; ++i) {
v3 = map;
v4 = new char{ 0 };
*(_DWORD *)v4 = v3;
*((_DWORD *)v8 + 3) = (_DWORD)v4;
*((_DWORD *)v4 + 2) = (_DWORD)v8;
v8 = (_DWORD*)v4;
}
*(_DWORD *)(*(_DWORD *)arg + 8) = (_DWORD)v8;
*((_DWORD *)v8 + 3) = *(_DWORD *)arg;
++*((_DWORD *)arg + 1);
return 1;
}
signed int __cdecl RotateL(_DWORD *this_, _DWORD **a2, int a3)
{
char v4; //
signed int i; //
_DWORD *v7; //
_DWORD *v8; //
_DWORD *v9; //
for (i = 0; i <= 4; ++i)
{
v9 = (_DWORD *)*((_DWORD *)*a2 + 2);
v8 = (_DWORD *)*((_DWORD *)*a2 + 3);
v7 = (_DWORD *)*((_DWORD *)*a2 + 4);
v4 = pathL;
if (v4 == 2)
{
if (*(_DWORD *)v8 == 43)
return 0;
if ((*(_DWORD *)v8 != 45 || *((_DWORD *)v8 + 1)) && *(_DWORD *)v9 != 35)
{
if (*((_DWORD *)v8 + 1) == 1)
return 1;
}
else
{
*a2 = v8;
*((_DWORD *)*a2 + 1) = 1;
}
}
else if (v4 > 2)
{
if (v4 == 3)
{
if (v7==0||*(_DWORD *)v7 == 43)
return 0;
if ((*(_DWORD *)v7 != 45 || *((_DWORD *)v7 + 1)) && *(_DWORD *)v9 != 35)
{
if (*((_DWORD *)v7 + 1) == 1)
return 1;
}
else
{
*a2 = v7;
*((_DWORD *)*a2 + 1) = 1;
}
}
}
else if (v4 == 1)
{
if (*(_DWORD *)v9 == 43)
return 0;
if ((*(_DWORD *)v9 != 45 || *((_DWORD *)v9 + 1)) && *(_DWORD *)v9 != 35)
{
if (*((_DWORD *)v9 + 1) == 1)
return 1;
}
else
{
*a2 = v9;
*((_DWORD *)*a2 + 1) = 1;
}
}
}
return 1;
}
signed int __cdecl RotateR(_DWORD *this_, _DWORD **a2, int a3) {
char v4; //
signed int i; //
_DWORD *v7; //
_DWORD *v8; //
_DWORD *v9; //
for (i = 0; i <= 4; ++i)
{
v9 = (_DWORD *)*((_DWORD *)*a2 + 2);
v8 = (_DWORD *)*((_DWORD *)*a2 + 3);
v7 = (_DWORD *)*((_DWORD *)*a2 + 4);
v4 = pathR;
if (v4 == 2)
{
if (*(_DWORD *)v8 == 43)
return 0;
if ((*(_DWORD *)v8 != 45 || *((_DWORD *)v8 + 1)) && *(_DWORD *)v9 != 35)
{
if (*((_DWORD *)v8 + 1) == 1)
return 1;
}
else
{
*a2 = v8;
*((_DWORD *)*a2 + 1) = 1;
}
}
else if (v4 > 2)
{
if (v4 == 3)
{
if (v7==0||*(_DWORD *)v7 == 43)
return 0;
if ((*(_DWORD *)v7 != 45 || *((_DWORD *)v7 + 1)) && *(_DWORD *)v9 != 35)
{
if (*((_DWORD *)v7 + 1) == 1)
return 1;
}
else
{
*a2 = v7;
*((_DWORD *)*a2 + 1) = 1;
}
}
}
else if (v4 == 1)
{
if (*(_DWORD *)v9 == 43)
return 0;
if ((*(_DWORD *)v9 != 45 || *((_DWORD *)v9 + 1)) && *(_DWORD *)v9 != 35)
{
if (*((_DWORD *)v9 + 1) == 1)
return 1;
}
else
{
*a2 = v9;
*((_DWORD *)*a2 + 1) = 1;
}
}
}
return 1;
}
intDirectionL(_DWORD *this_, _DWORD **a2, int a3, int a4, int a5) {
int v7; //
int v8; //
int v9; //
v9 = *((_DWORD *)*a2 + 2);
v8 = *((_DWORD *)*a2 + 3);
v7 = *((_DWORD *)*a2 + 4);
if (*(_DWORD *)(v9 + 4) == 1 && *(_DWORD *)(v8 + 4) == 1)
return (unsigned __int8)RotateL(this_, a2, a3);
if (*(_DWORD *)(v9 + 4) == 1 && *(_DWORD *)(v7 + 4) == 1)
return (unsigned __int8)RotateL(this_, a2, a4);
if (*(_DWORD *)(v8 + 4) != 1 || *(_DWORD *)(v7 + 4) != 1)
return 0;
return (unsigned __int8)RotateL(this_, a2, a5);
}
intDirectionR(_DWORD *this_, _DWORD **a2, int a3, int a4, int a5) {
int v7; //
int v8; //
int v9; //
v9 = *((_DWORD *)*a2 + 2);
v8 = *((_DWORD *)*a2 + 3);
v7 = *((_DWORD *)*a2 + 4);
if (*(_DWORD *)(v9 + 4) == 1 && *(_DWORD *)(v8 + 4) == 1)
return (unsigned __int8)RotateR(this_, a2, a3);
if (*(_DWORD *)(v9 + 4) == 1 && *(_DWORD *)(v7 + 4) == 1)
return (unsigned __int8)RotateR(this_, a2, a4);
if (*(_DWORD *)(v8 + 4) != 1 || *(_DWORD *)(v7 + 4) != 1)
return 0;
return (unsigned __int8)RotateR(this_, a2, a5);
}
intClockwise(_DWORD *this_, _DWORD **a2) {
int v2; // ST20_4
int v5; //
int v6; //
int v7; //
int v8; //
v8 = *((_DWORD *)*a2 + 2);
v7 = *((_DWORD *)*a2 + 3);
v2 = *((_DWORD *)*a2 + 4);
v6 = *(_DWORD *)(*((_DWORD *)*a2 + 3) + 8);
v5 = *(_DWORD *)(*((_DWORD *)*a2 + 2) + 12);
if (*(_DWORD *)v8 == 42 || *(_DWORD *)v7 == 42)
return (unsigned __int8)RotateL(this_, a2, 6);
if (*(_DWORD **)(*(_DWORD *)(v6 + 12) + 12) == *a2 && *(_DWORD **)(*(_DWORD *)(v5 + 8) + 8) == *a2)
return (unsigned __int8)DirectionL(this_, a2, 4, 1, 8);
if (*(_DWORD **)(v8 + 12) == *a2 && *(_DWORD **)(v7 + 12) == *a2)
return (unsigned __int8)DirectionL(this_, a2, 6, 7, 2);
if (*(_DWORD **)(v7 + 8) == *a2 && *(_DWORD **)(v8 + 8) == *a2)
return (unsigned __int8)DirectionL(this_, a2, 9, 5, 3);
if (*(_DWORD **)(*(_DWORD *)(v6 + 12) + 12) == *a2)
return (unsigned __int8)DirectionL(this_, a2, 9, 1, 8);
if (*(_DWORD **)(*(_DWORD *)(v5 + 8) + 8) == *a2)
return (unsigned __int8)DirectionL(this_, a2, 4, 7, 8);
return (unsigned __int8)DirectionL(this_, a2, 9, 7, 8);
}
intCounterclockwise(_DWORD *this_, _DWORD **a2) {
int v4; //
int v5; //
int v6; //
int v7; //
v7 = *((_DWORD *)*a2 + 2);
v6 = *((_DWORD *)*a2 + 3);
v5 = *(_DWORD *)(*((_DWORD *)*a2 + 3) + 8);
v4 = *(_DWORD *)(*((_DWORD *)*a2 + 2) + 12);
if (*(_DWORD *)v7 == 42 || *(_DWORD *)v6 == 42)
return (unsigned __int8)RotateR(this_, a2, 6);
if (*(_DWORD **)(*(_DWORD *)(v5 + 12) + 12) == *a2 && *(_DWORD **)(*(_DWORD *)(v4 + 8) + 8) == *a2)
return (unsigned __int8)DirectionR(this_, a2, 4, 8, 1);
if (*(_DWORD **)(v7 + 12) == *a2 && *(_DWORD **)(v6 + 12) == *a2)
return (unsigned __int8)DirectionR(this_, a2, 9, 3, 5);
if (*(_DWORD **)(v6 + 8) == *a2 && *(_DWORD **)(v7 + 8) == *a2)
return (unsigned __int8)DirectionR(this_, a2, 6, 2, 7);
if (*(_DWORD **)(*(_DWORD *)(v5 + 12) + 12) == *a2)
return (unsigned __int8)DirectionR(this_, a2, 4, 8, 7);
if (*(_DWORD **)(*(_DWORD *)(v4 + 8) + 8) == *a2)
return (unsigned __int8)DirectionR(this_, a2, 9, 8, 1);
return (unsigned __int8)DirectionR(this_, a2, 9, 8, 7);
}
intCheckUseCount(_DWORD *this_) {
_DWORD *v1; // ST10_4
int l; //
int j; //
signed int k; //
int i; //
_DWORD *v7; //
_DWORD *v8; //
int v9; //
v9 = 0;
v1 = *(_DWORD **)this_;
for (i = 0; *((_DWORD *)this_ + 1) > i; ++i)
{
v8 = *(_DWORD **)this_;
for (j = 0; j < i; ++j)
v8 = *(_DWORD **)(v8 + 8);
if (*(_DWORD **)this_ != v8 && *(_DWORD *)(v8 + 4) == 1)
++v9;
v7 = v8;
for (k = 0; k <= 5; ++k)
{
if (v8 == 1)
++v9;
v8 = (_DWORD *)v8;
for (l = 0; l < i; ++l)
{
if (v8 == 1)
++v9;
v8 = (_DWORD *)v8;
if ((_DWORD *)v8 == v7)
break;
if (v8 == 1)
++v9;
v8 = (_DWORD *)v8;
}
}
}
return v9;
}
int CheckFlag(_DWORD*arg1, char* Str) {
signed int v3; //
char v4; //
size_t i; //
_DWORD *v7; //
v7 = *(_DWORD **)arg1;
int dep = 0;
for (i = 0; i < strlen(Str); ++i) {
v4 = Str;
if (v4 == 76)
{
if (*(_DWORD **)arg1 == v7)
{
if (!(unsigned __int8)RotateL(arg1, (_DWORD **)&v7, 0))
return dep;
}
else if (!(unsigned __int8)Clockwise(arg1, (_DWORD **)&v7))
{
return dep;
}
dep++;
}
else if (v4 == 82)
{
if (*(_DWORD **)arg1 == v7)
{
if (!(unsigned __int8)RotateR(arg1, (_DWORD **)&v7, 0))
return dep;
}
else if (!(unsigned __int8)Counterclockwise(arg1, (_DWORD **)&v7))
{
return dep;
}
dep++;
}
}
//v3 = 0;
if (*v7 == 35 && CheckUseCount(arg1) == 94) {
//v3 = 1;
dep = -1;
}
if (dep == strlen(Str)) {
dep = strlen(Str)-1;
}
return dep;
}
```
而爆破的思路也很简单。我们将CheckFlag稍做修改,使其返回正确或检测发生错误时的下标。初始输入全为L,“LLLLLLLLLLLLLLLLLLLLLLLLL”当检测出错下标值为L时,替换为R。当为R时,则向前找最近的一个L变为R,后面再全置为L。以及一个标识记录检测正确的位数。
最后通过递归实现爆破
```
int find_lastL(char* input,int err_index) {
while (input == 'R') {
err_index--;
}
return err_index;
}
void new_input(char*input, int R_index) {
input = 'R';
for (int i = R_index+1; i < 25; i++) {
input = 'L';
}
}
int m_check(char* input,int right_count) {
char* v3 = new char{ 0 };
char*v7 = v3;
for (int i = 0; i <= 4; ++i) {
IncDepth(v7);
}
g_num = 0;
int err_index = CheckFlag((_DWORD*)v7, input);
if (err_index != -1) {//=-1为正确
if (input == 'L') {
input = 'R';
}
else {
int lastL = find_lastL(input, err_index);
if (right_count <= lastL) {
new_input(input, lastL);
if (right_count == lastL ) {
right_count++;
}
}
}
return m_check(input, right_count);
}
return 1;
}
int main()
{
char input[] = "LLLLLLLLLLLLLLLLLLLLLLLLL";
m_check(input, 0);
printf("%s", input);
return 0;
}
```
虽然我看不懂代码,但我知道西湖论剑主办方是杭州安恒{:1_893:} 硬核,看不懂! 完全看不懂啊,要多学习才行了
杭州安恒{:1_926:}{:1_926:} 可惜小白的我,看的有点懵 啥东西都是代码看不明白 卧槽牛逼,直接爆破出来!
学习了!谢谢! 本帖最后由 ghostsang 于 2020-10-13 16:41 编辑
大佬代码是IDA直接反编译扣出来的吗, 我做的时候也想着爆破,不会整,直接手动输入爆破{:1_909:}
页:
[1]
2