天天看點

re的刷題0

re的刷題

day1 5.5

easyre

拖進ida,shift+F12查找flag

IDA Pro:互動式反彙編器,是典型的遞歸下降反彙編器。

導覽列:

藍色 表示正常的指令函數

黑色 節與節之間的間隙

銀白色 資料内容

粉色 表示外部導入符号

暗黃色 表示ida未識别的内容

IDA主界面:

IDA View三種反彙編視圖:文本視圖、圖表視圖、路徑視圖

Hex View 十六進制視窗

Imports 導入函數視窗

Struceures 結構體視窗

Exports 導出函數視窗

Enums 枚舉視窗

Strings 字元串視窗

常用功能及快捷鍵:

空格鍵:切換文本視圖與圖表視圖

ESC:傳回上一個操作位址

G:搜尋位址和符号

N:對符号進行重命名

冒号鍵:正常注釋

分号鍵:可重複注釋

Alt+M:添加标簽

Ctrl+M:檢視标簽

Ctrl+S:檢視段的資訊

代碼資料切換

C-->代碼/D-->資料/A-->ascii字元串/U-->解析成未定義的内容

X:檢視交叉應用

F5:檢視僞代碼

Alt+T:搜尋文本

Alt+B:搜尋十六進制

導入jni.h分析jni庫函數。

僞C代碼視窗:

右鍵

comment-注釋僞c代碼。

copy to -assembly-把僞c代碼複制到反彙編視窗的彙編代碼。

IDA可以修改so的hex來修改so,edit,然後edit-patchrogram,

在這裡建議使用winhex來實作。

————————————————

版權聲明:本文為CSDN部落客「阿魯巴110」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/qq_30531517/java/article/details/82559428

reverse1

查找flag找到

aThisIsTheRight db \'this is the right flag!\',0Ah,0

接下來尋找什麼時候調用的

loc_140011948:                          ; CODE XREF: sub_1400118C0+61j
.text:0000000140011948                 lea     rcx, aInputTheFlag ; "input the flag:"
.text:000000014001194F                 call    sub_1400111D1
.text:0000000140011954                 lea     rdx, [rbp+130h+Str1]
.text:0000000140011958                 lea     rcx, a20s       ; "%20s"
.text:000000014001195F                 call    sub_14001128F
.text:0000000140011964                 lea     rcx, Str2       ; "{hello_world}"
.text:000000014001196B                 call    j_strlen
.text:0000000140011970                 mov     r8, rax         ; MaxCount
.text:0000000140011973                 lea     rdx, Str2       ; "{hello_world}"
.text:000000014001197A                 lea     rcx, [rbp+130h+Str1] ; Str1
.text:000000014001197E                 call    cs:strncmp
.text:0000000140011984                 test    eax, eax
.text:0000000140011986                 jz      short loc_140011996
.text:0000000140011988                 lea     rcx, aWrongFlag ; "wrong flag\n"
.text:000000014001198F                 call    sub_1400111D1
.text:0000000140011994                 jmp     short loc_1400119A2
.text:0000000140011996 ; ---------------------------------------------------------------------------
.text:0000000140011996
.text:0000000140011996 loc_140011996:                          ; CODE XREF: sub_1400118C0+C6j
.text:0000000140011996                 lea     rcx, aThisIsTheRight ; "this is the right flag!\n"
           

第一次:hello_world,錯誤。

1,所用的寄存器不同于32下的eax,ebx,ecx,edx,esi,edi,esp,ebp等,在64位下是rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,此外又增加了r8,r9,r10,r11,r12,r13,r14,r15等寄存器。但eax,ax,ah,al等依然可用,且增加了spl,bpl等8位寄存器調用,r8等也可以用r8d,r8w,r8b進行32位,16位,8位的調用。

2,函數調用參數傳遞不同于32下的stdcall規範,而采用fastcall,前四個參數為别放入rcx,rdx,r8,r9四個寄存器中,并在堆棧中留出4*8=32個位元組的空間,多于四個的參數放入堆棧。

3,函數調用後,由調用者負責堆棧回收。

僞代碼

int sub_1400118C0()
{
  char *v0; // rdi@1
  signed __int64 i; // rcx@1
  size_t v2; // rax@5
  size_t v3; // rax@9
  char v5; // [sp+0h] [bp-20h]@1
  signed int v6; // [sp+20h] [bp+0h]@4
  char Str1; // [sp+48h] [bp+28h]@9
  unsigned __int64 v8; // [sp+128h] [bp+108h]@5
  unsigned __int64 v9; // [sp+130h] [bp+110h]@4

  v0 = &v5;
  for ( i = 82i64; i; --i )
  {
    *(_DWORD *)v0 = -858993460;
    v0 += 4;
  }
  v9 = (unsigned __int64)&v6 ^ _security_cookie;
  for ( *(&v6 + 1) = 0; ; ++*(&v6 + 1) )
  {
    v8 = *(&v6 + 1);
    v2 = j_strlen(Str2);
    if ( v8 > v2 )
      break;
    if ( Str2[(signed __int64)*(&v6 + 1)] == 111 )
      Str2[(signed __int64)*(&v6 + 1)] = 48;
  }
  sub_1400111D1("input the flag:");
  sub_14001128F("%20s", &Str1);
  v3 = j_strlen(Str2);
  if ( !strncmp(&Str1, Str2, v3) )
    sub_1400111D1("this is the right flag!\n");
  else
    sub_1400111D1("wrong flag\n");
  sub_14001113B(&v5, &unk_140019D00);
  return sub_1400112E9((unsigned __int64)&v6 ^ v9);
}
           
strncmp函數為字元串比較函數,字元串大小的比較是以ASCII 碼表上的順序來決定,此順序亦為字元的值。其函數聲明為int strncmp ( const char * str1, const char * str2, size_t n );功能是把 str1 和 str2 進行比較,最多比較前 n 個位元組,若str1與str2的前n個字元相同,則傳回0;若s1大于s2,則傳回大于0的值;若s1 小于s2,則傳回小于0的值。

111為o,48為0,把str2字元串的o變成0

lea ----取記憶體單元的有效知位址指令,隻用于傳送道地址。

ptr-----是臨時的類型轉換,相當于C語言中的強制類型轉換

reserve2

.data:0000000000601080 ; char flag
.data:0000000000601080 flag            db 7Bh                  ; DATA XREF: main+34r
.data:0000000000601080                                         ; main+44r ...
.data:0000000000601081 aHacking_for_fu db \'hacking_for_fun}\',0
.data:0000000000601081 _data           ends
           

flag:hacking_for_fun}

僞代碼

pid = fork();
  if ( pid )
  {
    argv = (const char **)&stat_loc;
    waitpid(pid, &stat_loc, 0);
  }
  else
  {
    for ( i = 0; i <= strlen(&flag); ++i )
    {
      if ( *(&flag + i) == 105 || *(&flag + i) == 114 )
        *(&flag + i) = 49;
    }
  }
  printf("input the flag:", argv);
  __isoc99_scanf(4196628LL, &s2);
  if ( !strcmp(&flag, &s2) )
    result = puts("this is the right flag!");
  else
    result = puts("wrong flag!");
  v4 = *MK_FP(__FS__, 40LL) ^ v9;
  return result;
}
           

105:i,114:r,49:1

試一試hack1ng_fo1_fun,起飛。

版本不相容,後來點了以相容模式運作

新年快樂

打開有點不對

UPX是一個著名的壓縮殼,主要功能是壓縮PE檔案(比如exe,dll等檔案),有時候也可能被病毒用于免殺.殼upx是一種保護程式。一般是EXE檔案的一種外保護措施,主要用途 :

1、讓正規檔案被保護起來,不容易被修改和破解。

2、使檔案壓縮變小。

3、保護防毒軟體安裝程式,使之不受病毒侵害。

4、木馬,病毒的保護外殼,使之難以為攻破。

  • 技術原理

對于可執行程式資源壓縮,是保護檔案的常用手段. 俗稱加殼,加殼過的程式可以直接運作,但是不能檢視源代碼.要經過脫殼才可以檢視源代碼.

加殼:其實是利用特殊的算法,對EXE、DLL檔案裡的資源進行壓縮。類似WINZIP的效果,隻不過這個壓縮之後的檔案,可以獨立運作,解壓過程完全隐蔽,都在記憶體中完成。解壓原理,是加殼工具在檔案頭裡加了一段指令,告訴CPU,怎麼才能解壓自己。當加殼時,其實就是給可執行的檔案加上個外衣。使用者執行的隻是這個外殼程式。當執行這個程式的時候這個殼就會把原來的程式在記憶體中解開,解開後,以後的就交給真正的程式。

  • 加殼脫殼

程式為了反跟蹤、被人跟蹤調試、防止算法程式被别人靜态分析就需要加殼。使用加殼軟體加密代碼和資料,就可以保護你程式資料的完整性,防止被程式修改和被窺視内幕。

https://blog.csdn.net/dubuqingfenggzy/java/article/details/16881607

happly new year!

day2 5.6

helloworld

apk檔案。

APK是Android作業系統使用的一種應用程式封包件格式,基于 ZIP 檔案格式。

我用jadx打開。

内涵軟體

v3 = (int)"DBAPP{49d3c93df25caad81232130f3d2ebfad}";
  while ( v4 >= 0 )
  {
    printf("距離出現答案還有%d秒,請耐心等待!\n", v4);
    sub_40100A();
    --v4;
  }
  printf("\n\n\n這裡本來應該是答案的,但是粗心的程式員忘記把變量寫進來了,你要不逆向試試看:(Y/N)\n");
  v2 = 1;
  scanf("%c", &v2);
  if ( v2 == 89 )
  {
    printf("OD吾愛破解或者IDA這些逆向軟體都挺好的!");
    result = sub_40100A();
  }
           

内涵

xor

我傻了,沒注意64位。

僞代碼,v7是輸入且33位異或後==global

printf("Input your flag:\n", 0LL);
  get_line(v7, 256LL);
  if ( strlen(v7) != 33 )
    goto LABEL_13;
  for ( i = 1; i < 33; ++i )
    v7[i] ^= v7[i - 1];
  v3 = (signed __int64)global;
  if ( !strncmp(v7, global, 0x21uLL) )
    printf("Success", v3);
           
aFKWO_@XZUPFVMD 
db \'f\',0Ah              
; DATA XREF: __data:_globalo
db \'k\',0Ch,\'w&O.@\',11h,\'x\',0Dh,\'Z;U\',11h,\'p\',19h,\'F\',1Fh,\'v"M#D\',0Eh,\'g\',6,\'h\',0Fh,\'G2O\',0
           
a=[\'f\', \'k\',0xC,\'w&O.@\',0x11,\'x\',0xD,\'Z;U\',0x11,\'p\',0x19,\'F\',0x1F,\'v"M#D\',0x0E,\'g\',6,\'h\',0xF,\'G2O\',0]
#print(len(a))
#print(type(a[2]))
for i in range(len(a)):
    if type(a[i]).__name__ == \'int\':
        a[i]=chr(a[i])
print(a)
a="".join(a)
#print(len(a))
flag=\'f\'
for i in range(1,33):
    flag+=chr(ord(a[i])^ord(a[i-1]))
print(flag)
           

寫的腳本有點問題,得到fg{QianQiuWanDai_YiTongJiangHu}O,應該是flag{QianQiuWanDai_YiTongJiangHu}

guessgame

lea     rax, aBjdS1mple_rev3 ; "BJD{S1mple_ReV3r5e_W1th_0D_0r_IDA}"
           

簽到題

reserve_3

輸入flag

sub_41132F("please enter the flag:", v4);
 sub_411375("%20s", (unsigned int)&Str);
 v0 = j_strlen(&Str);
 v1 = (const char *)sub_4110BE(&Str, v0, &v11);
 strncpy(Dest, v1, 0x28u);
 sub_411127();
 i = j_strlen(Dest);
 for ( j = 0; (signed int)j < (signed int)i; ++j )
    Dest[j] += j;
 v2 = j_strlen(Dest);
 strncmp(Dest, Str2, v2);
 if ( sub_411127() )
    sub_41132F("wrong flag!\n", v4);
 else
    sub_41132F("rigth flag!\n", v4);
 sub_41126C(&savedregs, &dword_415890);
           

sub_41132F輸出,sub_411375輸入。輸入str經過sub_4110BE變成v1,變成Dest,dest裡循環加j,0<j<len(dest),比較str2。

找str2

push    offset Str2     ; "e3nifIH9b_C@n@dH"
           
a="e3nifIH9b_C@n@dH"
flag=""
for i in range(len(a)):
    flag+=chr(ord(a[i])-i )
print(flag)

           

結果:e2lfbDB2ZV95b3V9,錯誤。忘了還有sub_4110BE。sub_411AB0

if ( i == 1 )
        {
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[64];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[64];
        }
        else if ( v4 == 2 )
        {
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[64];
        }
        else if ( v4 == 3 )
        {
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
          *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[byte_41A144[2] & 0x3F];
        }
      }
           
mov     cl, byte ptr ds:aAbcdefghijklmn[edx] ; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"...
           

base64,emmmmmmmmm~~

day3 5.7

不一樣的flag

看到提示我覺得不妙,會不會f5不能用了。

搜尋flag。

call _puts應該是輸出ptr,call _printf

while ( 1 )
  {
    puts("you can choose one action to execute");
    puts("1 up");
    puts("2 down");
    puts("3 left");
    printf("4 right\n:");
    scanf("%d", &v3);
    if ( v3 == 2 )
    {
      ++v1;
    }
    else if ( v3 > 2 )
    {
      if ( v3 == 3 )
      {
        --v2;
      }
      else
      {
        if ( v3 != 4 )
           LABEL_13:
          exit(1);
        ++v2;
      }
    }
    else
    {
      if ( v3 != 1 )
        goto LABEL_13;
      --v1;
    }
    for ( i = 0; i <= 1; ++i )
    {
      if ( *(&v1 + i) < 0 || *(&v1 + i) > 4 )
        exit(1);
    }
    if ( *((_BYTE *)&v5 + 5 * v1 + v2 - 41) == 49 )
      exit(1);
    if ( *((_BYTE *)&v5 + 5 * v1 + v2 - 41) == 35 )
    {
      puts("\nok, the order you enter is the flag!");
      exit(0);
    }
  }
           

v3=1,v1--;

v3=2,v1++;

v3=3,v2--;

v3=4,v2++;

v5+5*v1+v2-41=35(\'#\')!=49(\'1\')

char v0; // [sp+17h] [bp-35h]@1
qmemcpy(&v0, _data_start__, 0x19u);
           
mov     ebx, offset __data_start__ ; "*11110100001010000101111#"
           

想多了,這是一個迷宮

*1111
01000
01010
00010
1111#
           

相當于二維數組,v1v2是坐标,1是可以走的,*頭#尾。

刮開有獎

挂不了,生氣。

GetDlgItemTextA(hDlg, 1000, &String, 0xFFFF);
      if ( strlen(&String) == 8 )
      {
        v7 = 90;
        v8 = 74;
        v9 = 83;
        v10 = 69;
        v11 = 67;
        v12 = 97;
        v13 = 78;
        v14 = 72;
        v15 = 51;
        v16 = 110;
        v17 = 103;
        sub_4010F0(&v7, 0, 10);
        memset(&v26, 0, 0xFFFFu);
        v26 = v23;
        v28 = v25;
        v27 = v24;
        v4 = (const char *)sub_401000(&v26, strlen(&v26));
        memset(&v26, 0, 0xFFFFu);
        v27 = v21;
        v26 = v20;
        v28 = v22;
        v5 = (const char *)sub_401000(&v26, strlen(&v26));
        if ( String == v7 + 34
          && v19 == v11
          && 4 * v20 - 141 == 3 * v9
          && v21 / 4 == 2 * (v14 / 9)
          && !strcmp(v4, "ak1w")
          && !strcmp(v5, "V1Ax") )
          MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
      }
           

看看sub_4010F0對v7-v17做了什麼

int __cdecl sub_4010F0(int a1, int a2, int a3)
{
  int result; // eax@1
  int i; // esi@1
  int v5; // ecx@2
  int v6; // edx@2

  result = a3;
  for ( i = a2; i <= a3; a2 = i )
  {
    v5 = 4 * i;
    v6 = *(_DWORD *)(4 * i + a1);
    if ( a2 < result && i < result )
    {
      do
      {
        if ( v6 > *(_DWORD *)(a1 + 4 * result) )
        {
          if ( i >= result )
            break;
          ++i;
          *(_DWORD *)(v5 + a1) = *(_DWORD *)(a1 + 4 * result);
          if ( i >= result )
            break;
          while ( *(_DWORD *)(a1 + 4 * i) <= v6 )
          {
            ++i;
            if ( i >= result )
              goto LABEL_13;
          }
          if ( i >= result )
            break;
          v5 = 4 * i;
          *(_DWORD *)(a1 + 4 * result) = *(_DWORD *)(4 * i + a1);
        }
        --result;
      }
      while ( i < result );
    }
LABEL_13:
    *(_DWORD *)(a1 + 4 * result) = v6;
    sub_4010F0(a1, a2, i - 1);
    result = a3;
    ++i;
  }
  return result;
}
           
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

int sub(char *a1, int a2, int a3)
{
  int result; // eax@1
  int i; // esi@1
  int v5; // ecx@2
  int v6; // edx@2

  result = a3;
  for ( i = a2; i <= a3; a2 = i )
  {
    v5 = 4 * i;
    v6 = a1[4 * i];
    if ( a2 < result && i < result )
    {
      do
      {
        if ( v6 > a1[4 * result] )
        {
          if ( i >= result )
            break;
          ++i;
          a1[v5] = a1[4 * result];

          if ( i >= result )
            break;
          while ( a1[4 * i] <= v6 )
          {
            ++i;
            if ( i >= result )
              goto LABEL_13;
          }
          if ( i >= result )
            break;
          v5 = 4 * i;
          a1 [4 * result] = a1[4 * i];
        }
        --result;
      }while ( i < result );
    }
LABEL_13:
    a1 [4 * result] = v6;
    sub(a1, a2, i - 1);
    result = a3;
    ++i;
  }
  return result;
}
int main(){
    char a1[11]={90,74,83,69,67,97,78,72,51,110,103};
    sub(a1,0,10);
    for(int i=0;i<=10;i++)
        cout<<a1[i];

return 0;
}

           

JSE aNH ng

淦,我的彙編就是一坨屎

去掉4*。

淦,我的儲存沒了。

string是flag,其中(v4, "ak1w")(v5, "V1Ax")是base64結果。

string = “UJWP1jMp”

day4 5.8

simpleRev

64位。

48-57:0-9

65-90:A-Z

97-122:a-z

Decry()裡

__int64 Decry()
{
  char v1; // [sp+Fh] [bp-51h]@19
  int v2; // [sp+10h] [bp-50h]@1
  signed int v3; // [sp+14h] [bp-4Ch]@1
  signed int i; // [sp+18h] [bp-48h]@1
  signed int v5; // [sp+1Ch] [bp-44h]@1
  char src[8]; // [sp+20h] [bp-40h]@1
  __int64 v7; // [sp+28h] [bp-38h]@1
  int v8; // [sp+30h] [bp-30h]@1
  __int64 v9; // [sp+40h] [bp-20h]@1
  __int64 v10; // [sp+48h] [bp-18h]@1
  int v11; // [sp+50h] [bp-10h]@1
  __int64 v12; // [sp+58h] [bp-8h]@1

  v12 = *MK_FP(__FS__, 40LL);
  *(_QWORD *)src = 357761762382LL;
  v7 = 0LL;
  v8 = 0;
  v9 = 512969957736LL;
  v10 = 0LL;
  v11 = 0;
  text = join(key3, (const char *)&v9);
  strcpy(key, key1);
  strcat(key, src);
  v2 = 0;
  v3 = 0;
  getchar();
  v5 = strlen(key);
  for ( i = 0; i < v5; ++i )
  {
    if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
      key[i] = key[v3 % v5] + 32;
    ++v3;
  }
  printf("Please input your flag:", src);
  while ( 1 )
  {
    v1 = getchar();
    if ( v1 == 10 )
      break;
    if ( v1 == 32 )
    {
      ++v2;
    }
    else
    {
      if ( v1 <= 96 || v1 > 122 )
      {
        if ( v1 > 64 && v1 <= 90 )
          str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
      }
      else
      {
        str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
      }
      if ( !(v3 % v5) )
        putchar(32);
      ++v2;
    }
  }
  if ( !strcmp(text, str2) )
    puts("Congratulation!\n");
  else
    puts("Try again!\n");
  return *MK_FP(__FS__, 40LL) ^ v12;
}
           
char *__fastcall join(const char *a1, const char *a2)
{
  size_t v2; // rbx@1
  size_t v3; // rax@1
  char *dest; // [sp+18h] [bp-18h]@1

  v2 = strlen(a1);
  v3 = strlen(a2);
  dest = (char *)malloc(v2 + v3 + 1);
  if ( !dest )
    exit(1);
  strcpy(dest, a1);
  strcat(dest, a2);
  return dest;
}
           

join就是字元串相連

主要變量:

v9 = 512969957736LL;==hadow

*(_QWORD *)src = 357761762382LL;==NDCLS

int main(){
    long long a = 512969957736LL;
    char buffer[100];
    sprintf(buffer, "%lld", a);
    printf("%s\n", buffer);
    const char *b=(const char *)&a;
    cout<<b;
    return 0;
}

           

text = join(key3, (const char *)&v9);

key3 ; "kills"

key1 ; "ADSFK"

過程:

key=key1+src

//text=killshadow,key=ADSFKNDCLS

key變小寫

//keyt=adsfkndcls

str2變換

最後str2=test

str2[v3] = (v2 - 39 - key[v4++ % v6] + 97) % 26 + 97;

key="adsfkndcls"
text="killshadow"
str2=""
flag=""
import string
print(len(key))
v4 = 9
for i in range(0,10):
    for j in range(65,91):
        zm = chr((j - 39 - ord(key[(v4+1) % 10]) + 97) % 26 + 97)
        if zm==text[i]:
            flag+=chr(j)
            v4=v4+1
            break
print(flag)

           

java逆向解密

package defpackage;

import java.util.ArrayList;
import java.util.Scanner;

/* renamed from: Reverse  reason: default package */
public class Reverse {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.println("Please input the flag :");
        String str = s.next();
        System.out.println("Your input is :");
        System.out.println(str);
        Encrypt(str.toCharArray());
    }

    public static void Encrypt(char[] arr) {
        ArrayList<Integer> Resultlist = new ArrayList<>();
        for (char c : arr) {
            Resultlist.add(Integer.valueOf((c + \'@\') ^ 32));
        }
        int[] KEY = {180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65};
        ArrayList<Integer> KEYList = new ArrayList<>();
        for (int valueOf : KEY) {
            KEYList.add(Integer.valueOf(valueOf));
        }
        System.out.println("Result:");
        if (Resultlist.equals(KEYList)) {
            System.out.println("Congratulations!");
        } else {
            System.err.println("Error!");
        }
    }
}
           

(flag+@)^32==key

KEY = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]
flag=""
for i in range(0,len(KEY)):
    for j in range(32,127):
        if (j+ord(\'@\'))^32==KEY[i]:
            flag+=chr(j)
print(flag)

           

蕪湖!!!

findit

public class MainActivity extends ActionBarActivity {
    /* access modifiers changed from: protected */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView((int) R.layout.activity_main);
        final EditText edit = (EditText) findViewById(R.id.widget2);
        final TextView text = (TextView) findViewById(R.id.widget1);
        final char[] a = {\'T\', \'h\', \'i\', \'s\', \'I\', \'s\', \'T\', \'h\', \'e\', \'F\', \'l\', \'a\', \'g\', \'H\', \'o\', \'m\', \'e\'};
        final char[] b = {\'p\', \'v\', \'k\', \'q\', \'{\', \'m\', \'1\', \'6\', \'4\', \'6\', \'7\', \'5\', \'2\', \'6\', \'2\', \'0\', \'3\', \'3\', \'l\', \'4\', \'m\', \'4\', \'9\', \'l\', \'n\', \'p\', \'7\', \'p\', \'9\', \'m\', \'n\', \'k\', \'2\', \'8\', \'k\', \'7\', \'5\', \'}\'};
        ((Button) findViewById(R.id.widget3)).setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                char[] x = new char[17];
                char[] y = new char[38];
                for (int i = 0; i < 17; i++) {
                    if ((a[i] < \'I\' && a[i] >= \'A\') || (a[i] < \'i\' && a[i] >= \'a\')) {
                        x[i] = (char) (a[i] + 18);
                    } else if ((a[i] < \'A\' || a[i] > \'Z\') && (a[i] < \'a\' || a[i] > \'z\')) {
                        x[i] = a[i];
                    } else {
                        x[i] = (char) (a[i] - 8);
                    }
                }
                if (String.valueOf(x).equals(edit.getText().toString())) {
                    for (int i2 = 0; i2 < 38; i2++) {
                        if ((b[i2] < \'A\' || b[i2] > \'Z\') && (b[i2] < \'a\' || b[i2] > \'z\')) {
                            y[i2] = b[i2];
                        } else {
                            y[i2] = (char) (b[i2] + 16);
                            if ((y[i2] > \'Z\' && y[i2] < \'a\') || y[i2] >= \'z\') {
                                y[i2] = (char) (y[i2] - 26);
                            }
                        }
                    }
                    text.setText(String.valueOf(y));
                    return;
                }
                text.setText("答案錯了腫麼辦。。。不給你又不好意思。。。哎呀好糾結啊~~~");
            }
        });
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
           

b變y,y是flag

for (int i2 = 0; i2 < 38; i2++) {
	if ((b[i2] < \'A\' || b[i2] > \'Z\') && (b[i2] < \'a\' || b[i2] > \'z\')) {
		y[i2] = b[i2];
	} else {
		y[i2] = (char) (b[i2] + 16);
		if ((y[i2] > \'Z\' && y[i2] < \'a\') || y[i2] >= \'z\') {
			y[i2] = (char) (y[i2] - 26);
		}
	}
}
           

凱撒,16位。我不管,爆破

pvkq{m164675262033l4m49lnp7p9mnk28k75}

8086

迷~~

db 0B9h, 22h, 0, 8Dh, 1Eh, 2 dup(0), 8Bh, 0F9h, 4Fh, 80h
db 31h, 1Fh, 0E2h, 0F8h, 8Dh, 16h, 2 dup(0), 0B4h, 9, 0CDh
db 21h, 0C3h
           

c強制轉換代碼

mov     cx, 22h ; \'"\'
lea     bx, aUDuT@Z@wj__Q@g ; "]U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;"
loc_10039:                              ; CODE XREF: seg001:000Fj
mov     di, cx
dec     di
xor     byte ptr [bx+di], 1Fh
loop    loc_10039
lea     dx, aUDuT@Z@wj__Q@g ; "]U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;"
mov     ah, 9
int     21h             ; DOS - PRINT STRING; DS:DX -> string terminated by "$"
retn
           
xor     byte ptr [bx+di], 1Fh
           
a="]U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;"
flag=""
b=0x1f
print(b)

for i in range(len(a)):
    flag+=chr(ord(a[i])^b)
print(flag)

           

rsa

public key:MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY9+7+./AvKr1rzQczdAgMBAAE=

http://tool.chacuo.net/cryptrsakeyparse

key長度: 256
模數: C0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD
指數: 65537 (0x10001)

86934482296048119190666062003494800588905656017203025617216654058378322103517

p=285960468890451637935629440372639283459

q=304008741604601924494328155975272418463

openssl rsa -pubin -text -modulus -in pub.txt
python2 rsatool.py -o private.pem -e 65537 -p 285960468890451637935629440372639283459 -q 304008741604601924494328155975272418463
openssl rsautl -decrypt -in flag.enc -inkey private.pem
           
#coding=utf-8
import math
import sys
from Crypto.PublicKey import RSA
arsa=RSA.generate(1024)
arsa.p=
arsa.q=
arsa.e=
arsa.n=arsa.p*arsa.q
Fn=long((arsa.p-1)*(arsa.q-1))
i=1
while(True):
    x=(Fn*i)+1
    if(x%arsa.e==0):
           arsa.d=x/arsa.e
           break
    i=i+1
private=open(\'private.pem\',\'w\')
private.write(arsa.exportKey())
private.close()
           

day5 5.9

CrackRTF

32位

printf("pls input the first passwd(1): ");
  scanf("%s", &pbData);
  if ( strlen((const char *)&pbData) != 6 )
  {
    printf("Must be 6 characters!\n");
    ExitProcess(0);
  }
           

pw6位

v5 = unknown_libname_1((char *)&pbData);
  if ( v5 < 100000 )
    ExitProcess(0);
  strcat((char *)&pbData, "@DBApp");
           
__int32 __cdecl unknown_libname_1(char *a1)
{
  return atol(a1);
}
           

pw>100000

strcat((char *)&pbData, "@DBApp");
v0 = strlen((const char *)&pbData);
           

pbData=pw+"@DBApp"

v0=12

sub_40100A(&pbData, v0, &String1);
           

好像hash

去搜CryptCreateHash

CryptCreateHash:ALG_ID

sha1

import hashlib
data="@DBApp"
a="6E32D0943418C2C33385BC35A1470250DD8923A9"
for i in range(100000,1000000):
    print(i)
    flag=str(i)+data
    sha1 = (hashlib.sha1(flag).hexdigest()).upper()
    if sha1==a:
        print(flag)
        break
           

跑了好久。。。。

pw=123321@DBApp

if ( !_strcmpi(&String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )
  {
    printf("continue...\n\n");
    printf("pls input the first passwd(2): ");
    memset(&String, 0, 0x104u);
    scanf("%s", &String);
    if ( strlen(&String) != 6 )
    {
      printf("Must be 6 characters!\n");
      ExitProcess(0);
    }
    strcat(&String, (const char *)&pbData);
    memset(&String1, 0, 0x104u);
    v1 = strlen(&String);
    sub_401019((BYTE *)&String, v1, &String1);
    if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", &String1) )
    {
      if ( !(unsigned __int8)sub_40100F(&String) )
      {
        printf("Error!!\n");
        ExitProcess(0);
      }
      printf("bye ~~\n");
    }
  }
           
strcat(&String, (const char *)&pbData);
    memset(&String1, 0, 0x104u);
    v1 = strlen(&String);
    sub_401019((BYTE *)&String, v1, &String1);
    if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", &String1) )
           

string=pw2+"123321@DBApp"

CryptCreateHash裡0x8003u是MD5,查不到。

會不會還是數字,爆破數字。

import hashlib
data="123321@DBApp"
a="27019e688a4e62a649fd99cadaafdb4e"
md5 = hashlib.md5()
for i in range(100000,1000000):
    print(i)
    flag=str(i)+data
    md5.update(flag)
    if md5==a:
        print(flag)
        break
           

看後面吧

hResInfo = FindResourceA(0, (LPCSTR)0x65, "AAA");
  if ( hResInfo )
  {
    nNumberOfBytesToWrite = SizeofResource(0, hResInfo);
    hResData = LoadResource(0, hResInfo);
    if ( hResData )
    {
      lpBuffer = LockResource(hResData);
      sub_401005(lpString, (int)lpBuffer, nNumberOfBytesToWrite);
      hFile = CreateFileA("dbapp.rtf", 0x10000000u, 0, 0, 2u, 0x80u, 0);
           

到這裡,

sub_401019((BYTE *)&String, v1, &String1);

函數sub_401040(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)

memset(&v4, 0xCCu, 0x4Cu);
  v7 = lstrlenA(lpString);
  v6 = lpString;
  for ( i = 0; ; ++i )
  {
    result = i;
    if ( i >= a3 )
      break;
    *(_BYTE *)(i + a2) ^= v6[i % v7];
  }
           

發現lpString進行了異或,a2為lpString首位址。

AAA是啥?我受不了了了,看wp。

{\rtf1\ansi\

。。。。。。。。。。。就這樣吧,累了

day6 5.10

注冊器

char[] x = "dd2940c04462b4dd7c450528835cca15".toCharArray();
                    x[2] = (char) ((x[2] + x[3]) - 50);
                    x[4] = (char) ((x[2] + x[5]) - 48);
                    x[30] = (char) ((x[31] + x[9]) - 48);
                    x[14] = (char) ((x[27] + x[28]) - 97);
                    for (int i = 0; i < 16; i++) {
                        char a = x[31 - i];
                        x[31 - i] = x[i];
                        x[i] = a;
                    }

           
x="dd2940c04462b4dd7c450528835cca15"
b=list(x)
print(b)
b[2] = chr((ord(b[2]) + ord(b[3])) - 50)
b[4] = chr((ord(b[2]) + ord(b[5])) - 48)
b[30] = chr((ord(b[31]) + ord(b[9])) - 48)
b[14] = chr((ord(b[27]) + ord(b[28])) - 97)
for i in range(16):
        a = b[31 - i];
        b[31 - i] = b[i];
        b[i] = a;


print(\'\'.join(b))

           

luck_guy

int __fastcall patch_me(int a1)
{
  int result; // eax@2

  if ( ((((unsigned int)((unsigned __int64)a1 >> 32) >> 31) + (_BYTE)a1) & 1)
     - ((unsigned int)((unsigned __int64)a1 >> 32) >> 31) == 1 )
    result = puts("just finished");
  else
    result = get_flag();
  return result;
}
           

a1最後一位為0

flag=f1+f2

.text:0000000000400845 loc_400845:                             ; DATA XREF: .rodata:0000000000400BC8o
.text:0000000000400845                 mov     edi, offset aOkItSFlag ; "OK, it\'s flag:"
.text:000000000040084A                 call    _puts
.text:000000000040084F                 lea     rax, [rbp+s]
.text:0000000000400853                 mov     edx, 28h        ; n
.text:0000000000400858                 mov     esi, 0          ; c
.text:000000000040085D                 mov     rdi, rax        ; s
.text:0000000000400860                 call    _memset
.text:0000000000400865                 lea     rax, [rbp+s]
.text:0000000000400869                 mov     esi, offset f1  ; "GXY{do_not_"
.text:000000000040086E                 mov     rdi, rax        ; dest
.text:0000000000400871                 call    _strcat
.text:0000000000400876                 lea     rax, [rbp+s]
.text:000000000040087A                 mov     esi, offset f2  ; src
.text:000000000040087F                 mov     rdi, rax        ; dest
.text:0000000000400882                 call    _strcat
.text:0000000000400887                 lea     rax, [rbp+s]
.text:000000000040088B                 mov     rsi, rax
.text:000000000040088E                 mov     edi, offset format ; "%s"
.text:0000000000400893                 mov     eax, 0
.text:0000000000400898                 call    _printf
.text:000000000040089D                 jmp     loc_400975
           

f2=i c u g ` o f 

.text:00000000004008CA loc_4008CA:                             ; DATA XREF: .rodata:0000000000400BE0o
.text:00000000004008CA                 mov     [rbp+s], 0
.text:00000000004008D2                 mov     [rbp+var_28], 0
.text:00000000004008D6                 mov     byte ptr [rbp+s], 69h
.text:00000000004008DA                 mov     byte ptr [rbp+s+1], 63h
.text:00000000004008DE                 mov     byte ptr [rbp+s+2], 75h
.text:00000000004008E2                 mov     byte ptr [rbp+s+3], 67h
.text:00000000004008E6                 mov     byte ptr [rbp+s+4], 60h
.text:00000000004008EA                 mov     byte ptr [rbp+s+5], 6Fh
.text:00000000004008EE                 mov     byte ptr [rbp+s+6], 66h
.text:00000000004008F2                 mov     byte ptr [rbp+s+7], 7Fh
.text:00000000004008F6                 lea     rax, [rbp+s]
.text:00000000004008FA                 mov     rsi, rax        ; src
.text:00000000004008FD                 mov     edi, offset f2  ; dest
.text:0000000000400902                 call    _strcat
.text:0000000000400907                 jmp     short loc_400975
           
.text:0000000000400963 loc_400963:                             ; CODE XREF: get_flag+145j
.text:0000000000400963                 cmp     [rbp+var_38], 7
.text:0000000000400967                 jle     short loc_400912
.text:0000000000400969                 jmp     short loc_400975
           
.text:0000000000400912 loc_400912:                             ; CODE XREF: get_flag+19Cj
.text:0000000000400912                 mov     eax, [rbp+var_38]
.text:0000000000400915                 cdq
.text:0000000000400916                 shr     edx, 1Fh
.text:0000000000400919                 add     eax, edx
.text:000000000040091B                 and     eax, 1
.text:000000000040091E                 sub     eax, edx
.text:0000000000400920                 cmp     eax, 1
.text:0000000000400923                 jnz     short loc_400943
.text:0000000000400925                 mov     eax, [rbp+var_38]
.text:0000000000400928                 cdqe
.text:000000000040092A                 movzx   eax, ds:f2[rax]
.text:0000000000400931                 sub     eax, 2
.text:0000000000400934                 mov     edx, eax
.text:0000000000400936                 mov     eax, [rbp+var_38]
.text:0000000000400939                 cdqe
.text:000000000040093B                 mov     ds:f2[rax], dl
.text:0000000000400941                 jmp     short loc_40095F
           
CDQ 是一個讓很多人感到困惑的指令。 這個指令把 EAX 的第 31 bit 複制到 EDX 的每一個 bit 上。 它大多出現在除法運算之前。它實際的作用隻是把EDX的所有位都設成EAX最高位的值。也就是說,當EAX <80000000, EDX 為00000000;當EAX >= 80000000, EDX 則為FFFFFFFF。

我的f5和wp不一樣,隻能看彙編。頭疼

f2=[0x69,0x63,0x75,0x67,0x60,0x6f,0x66,0x7f]
flag = \'GXY{do_not_\'

for j in range(8):
    if ( j % 2 == 1 ):
        flag+= chr(f2[j] - 2)
    else:
        flag+= chr(f2[j] -1)
    
print(flag)

           

younger_drive

脫殼,32位。

v0是printf傳回值,為1008

sub_41116D(&v5 == &v5, v0);

沒看出什麼

v1=12

v2=flag

int __usercall sub_411E30@<eax>(char a1@<zf>, int result@<eax>)
{
  int v2; // ST18_4@2
  int _0; // [sp+0h] [bp+0h]@2

  if ( !a1 )
  {
    v2 = result;
    sub_4111F9(_0, 0);
    result = v2;
  }
  return result;
}
           

堆棧平衡看看

day7 5.11

pyre

pyc檔案是python編譯後的位元組碼檔案。

在python中,輸入一個子產品相對來說是一個比較費時的事情,是以Python做了一些技巧,以便使輸入子產品更加快一些。一種方法是建立位元組編譯的檔案,這些檔案以.pyc作為擴充名。

當你在下次從别的程式輸入這個子產品的時候,.pyc檔案是十分有用的——它會快得多,因為一部分輸入子產品所需的處理已經完成了。

在你import别的py檔案時(也就是子產品),那個py檔案會被存一份pyc檔案以加速下次裝載。而主檔案因為隻需要裝載一次就沒有存pyc。

https://tool.lu/pyc/

print \'Welcome to Re World!\'
print \'Your input1 is your flag~\'
l = len(input1)
for i in range(l):
    num = ((input1[i] + i) % 128 + 128) % 128
    code += num

for i in range(l - 1):
    code[i] = code[i] ^ code[i + 1]

print code
code = [
    \'\x1f\',
    \'\x12\',
    \'\x1d\',
    \'(\',
    \'0\',
    \'4\',
    \'\x01\',
    \'\x06\',
    \'\x14\',
    \'4\',
    \',\',
    \'\x1b\',
    \'U\',
    \'?\',
    \'o\',
    \'6\',
    \'*\',
    \':\',
    \'\x01\',
    \'D\',
    \';\',
    \'%\',
    \'\x13\']

           
input1=\'\'
code = [\'\x1f\', \'\x12\', \'\x1d\', \'(\', \'0\', \'4\', \'\x01\', \'\x06\', \'\x14\', \'4\', \',\', \'\x1b\', \'U\', \'?\', \'o\', \'6\', \'*\', \':\', \'\x01\', \'D\', \';\', \'%\', \'\x13\']
I=len(code)
print(ord(code[0]))
for i in range(I-2,-1,-1):
    code[i]=chr(ord(code[i])^ord(code[i+1]))
print(code)

for i in range(I):
    input1+=chr( (ord(code[i])-i)%128 )
print(input1)
           

相冊

jadx打開。搜.com,有點弱智。

搜mail,有一個sendMailByJavaMail

m.set_host(C2.MAILHOST);
m.set_port(C2.PORT);
m.set_debuggable(true);
m.set_to(new String[]{mailto});
m.set_from(C2.MAILFROME);
m.set_subject(title);
m.setBody(mailmsg);
           

去c2看看

public static final String CANCELNUMBER = "%23%2321%23";
    public static final String MAILFROME = Base64.decode(NativeMethod.m());
    public static final String MAILHOST = "smtp.163.com";
    public static final String MAILPASS = Base64.decode(NativeMethod.pwd());
    public static final String MAILSERVER = Base64.decode(NativeMethod.m());
    public static final String MAILUSER = Base64.decode(NativeMethod.m());
    public static final String MOVENUMBER = "**21*121%23";
    public static final String PORT = "25";
    public static final String date = "2115-11-1";
    public static final String phoneNumber = Base64.decode(NativeMethod.p());

           
package com.net.cn;
public class NativeMethod {
public static native String m();
public static native String p();
public static native String pwd();
}
           

不知道這是什麼。

一個Native Method就是一個Java調用非java代碼的接口

"A native method is a Java method whose implementation is provided by non-java code."

wp:Java中NativeMethod一般用于調用外部檔案,再用IDA打libcore.so

easyRE

在sub_4009C6()裡有

char v57[36]

if ( (unsigned __int8)(v57[i] ^ i) != *(&v21 + i)

寫個代碼看看

b=a.replace(\' \',\'\')
c=b.replace(\'\n\',\'\')
#c=\'v21=73;v22=111;v23=100;v24=108;v25=62;v26=81;v27=110;v28=98;v29=40;v30=111;v31=99;v32=121;v33=127;v34=121;v35=46;v36=105;v37=127;v38=100;v39=96;v40=51;v41=119;v42=125;v43=119;v44=101;v45=107;v46=57;v47=123;v48=105;v49=121;v50=61;v51=126;v52=121;v53=76;v54=64;v55=69;v56=67\'
fin=re.sub(r\'v..=\', "", c)
num=fin.split(\';\')
print(num)
I=len(num)
s=\'\'
for i in range(I):
    s+=chr(int(num[i])^i)
print(s)
           

Info:The first four chars are

flag

sub_400E44是base64

if ( v9 == 39 )
    {
      v10 = sub_400E44((const __m128i *)&v59);
      v11 = sub_400E44((const __m128i *)v10);
      v12 = sub_400E44((const __m128i *)v11);
      v13 = sub_400E44((const __m128i *)v12);
      v14 = sub_400E44((const __m128i *)v13);
      v15 = sub_400E44((const __m128i *)v14);
      v16 = sub_400E44((const __m128i *)v15);
      v17 = sub_400E44((const __m128i *)v16);
      v18 = sub_400E44((const __m128i *)v17);
      v19 = sub_400E44((const __m128i *)v18);
      v2 = off_6CC090;
      v3 = (char *)v19;
      if ( !sub_400360(v19, off_6CC090) )
           

10次,最後和off_6CC090比:

Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ==

https://bbs.pediy.com/thread-254172.htm

毛線啊神經病

不知道該怎麼下手,看wp

.data:00000000006CC0A0 byte_6CC0A0     db 40h                  ; DATA XREF: sub_400D35+95r
.data:00000000006CC0A0                                         ; sub_400D35+C1r
.data:00000000006CC0A1                 db  35h ; 5
.data:00000000006CC0A2                 db  20h
.data:00000000006CC0A3 byte_6CC0A3     db 56h                  ; DATA XREF: sub_400D35+A6r
.data:00000000006CC0A4                 db  5Dh ; ]
.data:00000000006CC0A5                 db  18h
.data:00000000006CC0A6                 db  22h ; "
.data:00000000006CC0A7                 db  45h ; E
.data:00000000006CC0A8                 db  17h
.data:00000000006CC0A9                 db  2Fh ; /
.data:00000000006CC0AA                 db  24h ; $
.data:00000000006CC0AB                 db  6Eh ; n
.data:00000000006CC0AC                 db  62h ; b
.data:00000000006CC0AD                 db  3Ch ; <
.data:00000000006CC0AE                 db  27h ; \'
.data:00000000006CC0AF                 db  54h ; T
.data:00000000006CC0B0                 db  48h ; H
.data:00000000006CC0B1                 db  6Ch ; l
.data:00000000006CC0B2                 db  24h ; $
.data:00000000006CC0B3                 db  6Eh ; n
.data:00000000006CC0B4                 db  72h ; r
.data:00000000006CC0B5                 db  3Ch ; <
.data:00000000006CC0B6                 db  32h ; 2
.data:00000000006CC0B7                 db  45h ; E
.data:00000000006CC0B8                 db  5Bh ; [
           
v7 = v4;
v9 = BYTE3(v4);
if ( ((unsigned __int8)v4 ^ byte_6CC0A0[0]) == 102 && (v9 ^ (unsigned __int8)byte_6CC0A3) == 103 )
  {
    for ( j = 0; j <= 24; ++j )
    {
      v2 = (unsigned __int8)(byte_6CC0A0[(signed __int64)j] ^ *((_BYTE *)&v7
                                                              + (signed int)(((((unsigned int)((unsigned __int64)j >> 32) >> 30)
                                                                             + (_BYTE)j) & 3)
                                                                           - ((unsigned int)((unsigned __int64)j >> 32) >> 30))));
      sub_410E90(v2);
    }
  }
           

102是f,103是g。byte_6CC0A0應該是flag,先把v7解出來

key = \'\'
enc1 = \'flag\'
dec = \'\'
enc = [0x40,0x35,0x20,0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B]
for i in range(4):
    key += chr(enc[i] ^ ord(enc1[i]))
print (key)

for i in range(len(enc)):
    dec += chr(enc[i] ^ ord(key[i%4]))
print(dec)
           

https://www.cnblogs.com/Mayfly-nymph/p/11869959.html

脫殼

shift+f12字元串表

alt+t搜尋字元串

f5僞代碼

c強制轉換代碼

寫py

day8 5.12

singin

v8 = *MK_FP(__FS__, 40LL);
  puts("[sign in]");
  printf("[input your flag]: ");
  __isoc99_scanf("%99s", &v6);
  sub_96A(&v6, &v7);
  __gmpz_init_set_str(&v5, "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL);
  __gmpz_init_set_str(&v4, &v7, 16LL);
  __gmpz_init_set_str(&v2, "103461035900816914121390101299049044413950405173712170434161686539878160984549", 10LL);
  __gmpz_init_set_str(&v3, "65537", 10LL);
  __gmpz_powm(&v4, &v4, &v3, &v2);
  if ( __gmpz_cmp(&v4, &v5) )
    puts("GG!");
  else
    puts("TTTTTTTTTTql!");
           

v6=flag

sub_96A:v6變v7

size_t __fastcall sub_96A(const char *a1, __int64 a2)
{
  size_t result; // rax@3
  int v3; // [sp+18h] [bp-18h]@1
  int i; // [sp+1Ch] [bp-14h]@1

  v3 = 0;
  for ( i = 0; ; i += 2 )
  {
    result = strlen(a1);
    if ( v3 >= result )
      break;
    *(_BYTE *)(a2 + i) = byte_202010[(char)(a1[v3] >> 4)];
    *(_BYTE *)(a2 + i + 1LL) = byte_202010[a1[v3++] & 0xF];
  }
  return result;
}
           

byte_202010:16進制0-f

db 30h, 31h, 32h, 33h, 34h, 35h, 36h, 37h, 38h, 39h, 61h 62h, 63h, 64h, 65h, 66h
           

__gmpz_init_set_str:

 GMP(The GNU Multiple Precision Arithmetic Library)又叫GNU多精度算術庫,是一個提供了很多操作高精度的大整數,浮點數的運算的算術庫,幾乎沒有什麼精度方面的限制,功能豐富。

__gmpz_powm

gmp_powm()是PHP中的一個内置函數,用于計算以另一個GMP數模數模拟的兩個GMP數的幂。(GNU Multiple Precision:For large number)

沒有查到__gmpz_init_set_str具體幹嘛的,應該是字元串轉數字,gmpz_powm指數模。但是看到65537,rsa。

import binascii
def egcd(a,b):         #擴充歐幾裡得算法
    if a==0:
        return  (b,0,1)
    else:
        g,y,x=egcd(b%a,a)
        return (g,x-(b//a)*y,y)
 
def modinv(a,m):
    g,x,y=egcd(a,m)
    if g!=1:
        raise Exception(\'modular inverse does not exist\')
    else:
        return x%m
c_hex=\'ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35\'
c=int(c_hex,16)
print(c)

n=103461035900816914121390101299049044413950405173712170434161686539878160984549
p=282164587459512124844245113950593348271
q=366669102002966856876605669837014229419
e=65537
fn=(p-1)*(q-1)
d=modinv(e,fn)
m=pow(c,d,n)
print(m)
#m_hex=hex(m)
#print(m_hex)
m_hex=\'73756374667b50776e5f405f68756e647265645f79656172737d\'
print(binascii.a2b_hex(m_hex))

           

原來有gmpy2.mpz

https://www.cnblogs.com/ESHLkangi/p/8576222.html

justre

you dian ji dong.

shift f12看到BJD{%d%d2069a45792d233ac},一定是flag,,,吧

f5不出來,右鍵create f

sprintf(&String, aBjdDD2069a4579, 19999, 0);

這個分值是為什麼啊

ida F5失敗原因1

ida F5失敗原因2

day9 5.13

strngecpp

沒有什麼能阻止我獲得flag,Orz。

puts("Let me have a look at your computer...");
  for ( j = v16; *(_QWORD *)j; j += 8i64 )
  {
    v14 = *(_QWORD *)j;
    sub_140011226("%s\n", v14);
  }
  std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140011127);
  dword_140021190 = SystemInfo.dwNumberOfProcessors;
  sub_140011226("now system cpu num is %d\n", SystemInfo.dwNumberOfProcessors);
  if ( dword_140021190 < 8 )
  {
    puts("Are you in VM?");
    _exit(0);
  }
  if ( GetUserNameA(Str1, &pcbBuffer) )
  {
    LODWORD(v5) = sub_140011172(std::cout, "this is useful");
    std::basic_ostream<char,std::char_traits<char>>::operator<<(v5, sub_140011127);
  }
  LODWORD(v6) = std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140011127);
  LODWORD(v7) = sub_140011172(v6, "ok,I am checking...");
  std::basic_ostream<char,std::char_traits<char>>::operator<<(v7, sub_140011127);
  if ( !j_strcmp(Str1, "cxx") )
  {
    LODWORD(v8) = sub_140011172(std::cout, "flag{where_is_my_true_flag?}");
    std::basic_ostream<char,std::char_traits<char>>::operator<<(v8, sub_140011127);
    _exit(0);
  }
  system("pause");
  sub_1400113E3(&v10, &unk_14001DE50);
  return sub_140011104((unsigned __int64)&v11 ^ v15);
}

           

我覺得flag應該在:

sub_1400113E3((__int64)&v10, (__int64)&unk_14001DE50);
           
int __fastcall sub_140014860(__int64 a1, __int64 a2)
{
  int v2; // ebx@1
  __int64 v3; // rsi@1
  __int64 v4; // rbp@1
  __int64 v5; // rdi@2
  __int64 v6; // rdx@3
  __int64 v7; // rcx@3
  __int64 v8; // rax@4
  void *retaddr; // [sp+28h] [bp+0h]@5

  v2 = 0;
  v3 = a2;
  v4 = a1;
  if ( *(_DWORD *)a2 > 0 )
  {
    v5 = 0i64;
    do
    {
      v6 = *(_QWORD *)(v3 + 8);
      v7 = *(_DWORD *)(v6 + v5);
      if ( *(_DWORD *)(v7 + v4 - 4) != -858993460
        || (v8 = v7 + *(_DWORD *)(v6 + v5 + 4), *(_DWORD *)(v8 + v4) != -858993460) )
        LODWORD(v8) = sub_14001117C(retaddr, *(_QWORD *)(v6 + v5 + 8));
      ++v2;
      v5 += 16i64;
    }
    while ( v2 < *(_DWORD *)v3 );
  }
  return v8;
}
           

unk_14001DE50=10000000

0i64、16i64應該是64位整數。

-858993460是啥0xcccccccc

等等

v15 = (unsigned __int64)&v11 ^ _security_cookie;
return sub_140011104((unsigned __int64)&v11 ^ v15);
           

_security_cookie=47936899621426:i64。好像沒什麼用。

找到一些奇怪的東西

db 26h, 2Ch, 21h, 27h, 3Bh, 0Dh, 4, 75h, 68h, 34h, 28h
db 25h, 0Eh, 35h, 2Dh, 69h, 3Dh
           
int sub_140013580()
{
  __int64 *v0; // rdi@1
  signed __int64 i; // rcx@1
  int result; // eax@4
  __int64 v3; // [sp+0h] [bp-20h]@1
  int v4; // [sp+24h] [bp+4h]@4
  int j; // [sp+44h] [bp+24h]@6
  __int64 v6; // [sp+128h] [bp+108h]@4

  v0 = &v3;
  for ( i = 82i64; i; --i )
  {
    *(_DWORD *)v0 = -858993460;
    v0 = (__int64 *)((char *)v0 + 4);
  }
  v6 = -2i64;
  sub_1400110AA(&unk_140027033);
  result = sub_140011384((unsigned int)dword_140021190);
  v4 = result;
  if ( result == 607052314 && dword_140021190 <= 14549743 )
  {
    for ( j = 0; j < 17; ++j )
    {
      putchar((unsigned __int8)(dword_140021190 ^ byte_140021008[j]));
      result = j + 1;
    }
  }
  return result;
}
           
signed __int64 __fastcall sub_140013890(signed int a1)
{
  __int64 *v1; // rdi@1
  signed __int64 i; // rcx@1
  signed __int64 result; // rax@5
  __int64 v4; // [sp+0h] [bp-20h]@1
  int v5; // [sp+24h] [bp+4h]@4
  int v6; // [sp+44h] [bp+24h]@4
  int v7; // [sp+64h] [bp+44h]@4
  signed int v8; // [sp+160h] [bp+140h]@1

  v8 = a1;
  v1 = &v4;
  for ( i = 82i64; i; --i )
  {
    *(_DWORD *)v1 = -858993460;
    v1 = (__int64 *)((char *)v1 + 4);
  }
  sub_1400110AA(&unk_140027033);
  v5 = v8 >> 12;
  v6 = v8 << 8;
  v7 = (v8 << 8) ^ (v8 >> 12);
  v7 *= 291;
  if ( v7 )
    result = (unsigned int)v7;
  else
    result = 987i64;
  return result;
}
           

dword_140021190通過sub_140013890變成了result

\'\'\'
result = 607052314
for i in range(14549743):
    print(i)
    v8=i
    v7 = (v8 << 8) ^ (v8 >> 12)
    v7 *= 291
    if v70xFFFFFFFF==result:
        print(i)
        break
\'\'\'
result = 123456
a=\'26h, 2Ch, 21h, 27h, 3Bh, 0Dh, 4, 75h, 68h, 34h, 28h,25h, 0Eh, 35h, 2Dh, 69h, 3Dh\'
b=a.replace(\'h\',\'\')
c=b.replace(\' \',\'\')
d=c.split(\',\')
for i in range(len(d)):
    d[i]=\'0x\'+d[i]
print(d)
flag = ""
for i in d:
    flag += chr((result ^ int(i,16))&0xFF) 
print(flag)
import hashlib

md5 = hashlib.md5()
md5.update(\'123456\')
print md5.hexdigest()

           

沒有注意unsigned int和int的我像個弱智跑了好久

day10 5.14

又是元氣滿滿的一天。

我最樂于助人了。

。。。

路由器固件dump檔案,tplink我倒是看到了

binwalk -e 後有個.squashfs、7z壓縮包、證書、空檔案夾

Squashfs是一個隻讀格式的檔案系統,具有超高壓縮率,其壓縮率最高可達34%。當系統啟動後,會将檔案系統儲存在一個壓縮過的檔案系統的檔案中,這個檔案可以使用換回的形式挂載并對其中的檔案進行通路,當程序需要某些檔案時,僅将對應部分的壓縮檔案解壓縮。

  Squashfs檔案系統常用的壓縮格式有GZIP、LZMA、LZO、XZ(LZMA2),在路由器中被普遍采用。路由器的根檔案系統通常會按照Squashfs檔案系統常用壓縮格式中的一種進行打包,形成一個完整的Squashfs檔案系統,然後與路由器作業系統的核心一起形成更新固件。

然後呢。網上查

用unsquashfs指令解壓

去ubuntu試試,不行。

查報錯,。。。算了看wp

firmware-mod-kit工具的功能和binwalk工具的類似,實際上firmware-mod- kitfirm工具在功能上有調用binwalk工具提供的功能以及其他的固件解包工具的整合。下載下傳firmware-mod-kit工具的連結進入到src目錄下就能夠看到firmware-mod-kit工具整合了那些固件提取和檔案系統解壓的工具。firmware-mod-kit工具的功能有固件檔案的解包和打包,固件提取檔案系統的解壓和壓縮,DD-WRT

網頁的修改等,在每個整合的固件分析中工具的源碼檔案夾裡都有相關的使用說明。

sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic
git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make
           

gitclone慢沒什麼用,fq也是

./unsquashfs_all.sh 120200.squashfs
           

emmm手動

day11 5.15

路漫漫其修遠兮,吾将上下而求索!

re

好短,有殼吧。

脫殼。

搜了一波。

找到aInputYourFlag,

sub_40F950((__int64)"input your flag:", 0LL, 0LL, 0LL, 0LL);
sub_40FA80((__int64)"%s", &v4);
if ( (unsigned int)sub_4009AE(&v4, &v4) )
{
v0 = "Correct!";
sub_410350("Correct!");
           
sub_40F950(-92);
  sub_40FA80(-75);
  if ( sub_4009AE(&v2, &v2) )
  {
    v0 = 4855992LL;
    sub_410350(4855992LL);
    result = 0LL;
  }
           

sub_4009ae裡

__int64 __fastcall sub_4009AE(__int64 a1)
{
  __int64 result; // rax@2

  if ( 1629056 * *(_BYTE *)a1 == 166163712 )
  {
    if ( 6771600 * *(_BYTE *)(a1 + 1) == 731332800 )
    {
      if ( 3682944 * *(_BYTE *)(a1 + 2) == 357245568 )
      {
        if ( 10431000 * *(_BYTE *)(a1 + 3) == 1074393000 )
        {
          if ( 3977328 * *(_BYTE *)(a1 + 4) == 489211344 )
          {
            if ( 5138336 * *(_BYTE *)(a1 + 5) == 518971936 )
            {
              if ( 7532250 * *(_BYTE *)(a1 + 7) == 406741500 )
              {
                if ( 5551632 * *(_BYTE *)(a1 + 8) == 294236496 )
                {
                  if ( 3409728 * *(_BYTE *)(a1 + 9) == 177305856 )
                  {
                    if ( 13013670 * *(_BYTE *)(a1 + 10) == 650683500 )
                    {
                      if ( 6088797 * *(_BYTE *)(a1 + 11) == 298351053 )
                      {
                        if ( 7884663 * *(_BYTE *)(a1 + 12) == 386348487 )
                        {
                          if ( 8944053 * *(_BYTE *)(a1 + 13) == 438258597 )
                          {
                            if ( 5198490 * *(_BYTE *)(a1 + 14) == 249527520 )
                            {
                              if ( 4544518 * *(_BYTE *)(a1 + 15) == 445362764 )
                              {
                                if ( 3645600 * *(_BYTE *)(a1 + 17) == 174988800 )
                                {
                                  if ( 10115280 * *(_BYTE *)(a1 + 16) == 981182160 )
                                  {
                                    if ( 9667504 * *(_BYTE *)(a1 + 18) == 493042704 )
                                    {
                                      if ( 5364450 * *(_BYTE *)(a1 + 19) == 257493600 )
                                      {
                                        if ( 13464540 * *(_BYTE *)(a1 + 20) == 767478780 )
                                        {
                                          if ( 5488432 * *(_BYTE *)(a1 + 21) == 312840624 )
                                          {
                                            if ( 14479500 * *(_BYTE *)(a1 + 22) == 1404511500 )
                                            {
                                              if ( 6451830 * *(_BYTE *)(a1 + 23) == 316139670 )
                                              {
                                                if ( 6252576 * *(_BYTE *)(a1 + 24) == 619005024 )
                                                {
                                                  if ( 7763364 * *(_BYTE *)(a1 + 25) == 372641472 )
                                                  {
                                                    if ( 7327320 * *(_BYTE *)(a1 + 26) == 373693320 )
                                                    {
                                                      if ( 8741520 * *(_BYTE *)(a1 + 27) == 498266640 )
                                                      {
                                                        if ( 8871876 * *(_BYTE *)(a1 + 28) == 452465676 )
                                                        {
                                                          if ( 4086720 * *(_BYTE *)(a1 + 29) == 208422720 )
                                                          {
                                                            if ( 9374400 * *(_BYTE *)(a1 + 30) == 515592000 )
                                                              result = 5759124 * *(_BYTE *)(a1 + 31) == 719890500;
                                                            else
                                                              result = 0LL;
                                                          }
                                                          else
                                                          {
                                                            result = 0LL;
                                                          }
                                                        }
                                                        else
                                                        {
                                                          result = 0LL;
                                                        }
                                                      }
                                                      else
                                                      {
                                                        result = 0LL;
                                                      }
                                                    }
                                                    else
                                                    {
                                                      result = 0LL;
                                                    }
                                                  }
                                                  else
                                                  {
                                                    result = 0LL;
                                                  }
                                                }
                                                else
                                                {
                                                  result = 0LL;
                                                }
                                              }
                                              else
                                              {
                                                result = 0LL;
                                              }
                                            }
                                            else
                                            {
                                              result = 0LL;
                                            }
                                          }
                                          else
                                          {
                                            result = 0LL;
                                          }
                                        }
                                        else
                                        {
                                          result = 0LL;
                                        }
                                      }
                                      else
                                      {
                                        result = 0LL;
                                      }
                                    }
                                    else
                                    {
                                      result = 0LL;
                                    }
                                  }
                                  else
                                  {
                                    result = 0LL;
                                  }
                                }
                                else
                                {
                                  result = 0LL;
                                }
                              }
                              else
                              {
                                result = 0LL;
                              }
                            }
                            else
                            {
                              result = 0LL;
                            }
                          }
                          else
                          {
                            result = 0LL;
                          }
                        }
                        else
                        {
                          result = 0LL;
                        }
                      }
                      else
                      {
                        result = 0LL;
                      }
                    }
                    else
                    {
                      result = 0LL;
                    }
                  }
                  else
                  {
                    result = 0LL;
                  }
                }
                else
                {
                  result = 0LL;
                }
              }
              else
              {
                result = 0LL;
              }
            }
            else
            {
              result = 0LL;
            }
          }
          else
          {
            result = 0LL;
          }
        }
        else
        {
          result = 0LL;
        }
      }
      else
      {
        result = 0LL;
      }
    }
    else
    {
      result = 0LL;
    }
  }
  else
  {
    result = 0LL;
  }
  return result;
}
           

32位a1。

crackMe

32位。

while ( 1 )
  {
    do
    {
      do
      {
        printf("user(6-16 letters or numbers):");
        scanf("%s", &v10);
        v0 = (FILE *)sub_4024BE();
        sub_4022E7(v0);
      }
      while ( !(unsigned __int8)sub_401000(&v10) );
      printf("password(6-16 letters or numbers):");
      scanf("%s", &v8);
      v1 = (FILE *)sub_4024BE();
      sub_4022E7(v1);
    }
    while ( !(unsigned __int8)sub_401000(&v8) );
    sub_401090(&v10);
    v6 = 0;
    memset(&v7, 0, 0xFFu);
    v4 = 0;
    memset(&v5, 0, 0xFFu);
    v3 = ((int (__cdecl *)(char *, char *))loc_4011A0)(&v6, &v4);
    if ( (unsigned __int8)sub_401830(&v10, &v8) )
    {
      if ( v3 )
        break;
    }
    printf(&v4);
  }
  printf(&v6);
  return 0;
           

sub_4020E5==printf

sub_402194==scanf

sub_401000應該是判斷使用者存在。。是判斷輸入合法

char __cdecl sub_401000(const char *a1)
{
  char result; // al@3
  unsigned int v2; // [sp+8h] [bp-10h]@1
  signed int i; // [sp+Ch] [bp-Ch]@4

  v2 = strlen(a1);
  if ( (signed int)v2 >= 6 || (signed int)v2 <= 16 )
  {
    for ( i = 0; i < (signed int)v2; ++i )
    {
      if ( !isalnum(a1[i]) )
        return 0;
    }
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}
           

關鍵應該是sub_401830,它同時調用user和password

bool __usercall sub_401830@<al>(signed int ebx0@<ebx>, int a1, const char *a2)
{
  signed int v4; // [sp+18h] [bp-22Ch]@1
  unsigned int v5; // [sp+1Ch] [bp-228h]@1
  unsigned int v6; // [sp+28h] [bp-21Ch]@1
  unsigned int v7; // [sp+30h] [bp-214h]@1
  char v8; // [sp+36h] [bp-20Eh]@14
  char v9; // [sp+37h] [bp-20Dh]@4
  char v10; // [sp+38h] [bp-20Ch]@1
  char v11; // [sp+39h] [bp-20Bh]@1
  char v12; // [sp+3Ah] [bp-20Ah]@1
  char v13; // [sp+3Bh] [bp-209h]@14
  int v14; // [sp+3Ch] [bp-208h]@21
  char v15; // [sp+40h] [bp-204h]@1
  char v16; // [sp+41h] [bp-203h]@1
  char v17; // [sp+140h] [bp-104h]@1
  char v18; // [sp+141h] [bp-103h]@1

  v5 = 0;
  v6 = 0;
  v12 = 0;
  v11 = 0;
  v17 = 0;
  memset(&v18, 0, 0xFFu);
  v15 = 0;
  memset(&v16, 0, 0xFFu);
  v10 = 0;
  v7 = 0;
  v4 = 0;
  while ( v7 < strlen(a2) )
  {
    if ( isdigit(a2[v7]) )
    {
      v9 = a2[v7] - 48;
    }
    else if ( isxdigit(a2[v7]) )
    {
      if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(48) + 24) + 12) != 2 )
        a2[v7] = 34;
      v9 = (a2[v7] | 0x20) - 87;
    }
    else
    {
      v9 = ((a2[v7] | 0x20) - 97) % 6 + 10;
    }
    v10 = v9 + 16 * v10;
    /***
    選a2偶數位的數值給v15
    ***/
    if ( !((signed int)(v7 + 1) % 2) )
    {
      *(&v15 + v4++) = v10;
      ebx0 = v4;
      v10 = 0;
    }
    ++v7;
  }
  while ( (signed int)v6 < 8 )
  {
    ++v12;
    v11 += byte_416050[(unsigned __int8)v12];
    v13 = byte_416050[(unsigned __int8)v12];
    v8 = byte_416050[(unsigned __int8)v11];
    byte_416050[(unsigned __int8)v11] = v13;
    byte_416050[(unsigned __int8)v12] = v8;
    if ( *(_DWORD *)(__readfsdword(48) + 104) & 0x70 )
      v13 = v11 + v12;
    /***
    v17有8位,byte_416050[不知道什麼鬼]^v15。(v5=v6)
    ***/
    *(&v17 + v6) = byte_416050[(unsigned __int8)(v8 + v13)] ^ *(&v15 + v5);
    if ( *(_DWORD *)(__readfsdword(48) + 2) & 0xFF )
    {
      v11 = -83;
      v12 = 43;
    }
    sub_401710((int)&v17, (const char *)a1, v6++);
    v5 = v6;
    if ( v6 >= strlen(&v15) )
      v5 = 0;
  }
  v14 = 0;
  sub_401470(ebx0, (int)&v17, (int)&v14);
  return v14 == 43924;
}
           

sub_401470,傳v17,使v14=43924

sub_401470裡發現多個 if ( *(_BYTE *)a2 == \'字元\' ),v17=dbappsec。

byte_416050在sub_401090(user)生成。不不不感謝https://www.cnblogs.com/basstorm/p/12662023.html。

繞過三個if反調試(__readfsdword)

v = [0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd]
a =\'dbappsec\'
ps=\'\'
for i in range(8):
    ps+=hex(ord(a[i])^v[i])[2:]
print(ps)
           

可以說這是我目前為止遇到最難的,結合wp搞了一下午。反調試看了https://www.cnblogs.com/Crisczy/p/7575521.html,簡單了解了一下。

day12 5.16

[GUET-2019]re

掐指一算有殼。

根據sub_4009AE寫腳本。

這裡可以用Z3限制器,也可以用515592000//9374400直接求a1。

#!/usr/bin/python
# -*- coding: utf-8 -*-
from z3 import *

from z3 import*
#申明未知量
a1 = [0]*32
for i in range(32):
    a1[i] = Int(\'a1[\'+str(i)+\']\')
s=Solver() # 建立限制求解器

# 添加限制條件
s.add( 1629056 * a1[0] == 166163712 )
s.add( 6771600 * a1[1] == 731332800 )
s.add( 3682944 * a1[2] == 357245568 )
s.add( 10431000 * a1[3] == 1074393000 )
s.add( 3977328 * a1[4] == 489211344 )
s.add( 5138336 * a1[5] == 518971936 )
s.add( 7532250 * a1[7] == 406741500 )
s.add( 5551632 * a1[8] == 294236496 )
s.add( 3409728 * a1[9] == 177305856 )
s.add( 13013670 * a1[10] == 650683500 )
s.add( 6088797 * a1[11] == 298351053 )
s.add( 7884663 * a1[12] == 386348487 )
s.add( 8944053 * a1[13] == 438258597 )
s.add( 5198490 * a1[14] == 249527520 )
s.add( 4544518 * a1[15] == 445362764 )
s.add( 3645600 * a1[17] == 174988800 )
s.add( 10115280 * a1[16] == 981182160 )
s.add( 9667504 * a1[18] == 493042704 )
s.add( 5364450 * a1[19] == 257493600 )
s.add( 13464540 * a1[20] == 767478780 )
s.add( 5488432 * a1[21] == 312840624 )
s.add( 14479500 * a1[22] == 1404511500 )
s.add( 6451830 * a1[23] == 316139670 )
s.add( 6252576 * a1[24] == 619005024 )
s.add( 7763364 * a1[25] == 372641472 )
s.add( 7327320 * a1[26] == 373693320 )
s.add( 8741520 * a1[27] == 498266640 )
s.add( 8871876 * a1[28] == 452465676 )
s.add( 4086720 * a1[29] == 208422720 )
s.add( 9374400 * a1[30] == 515592000 )
s.add(5759124 * a1[31] == 719890500)
# 檢查是否有解
if s.check()!="sat":
    print( "unsat")

m=s.model()
for d in m.decls():   # decls()傳回model包含了所有符号的清單
    print("%s = %s" % (d.name(),m[d]))
print(515592000//9374400)
           

a1[6]沒有。沒想到爆破。1

day13 5.17

CSre

有殼。Eazfuscator.NET http://github.com/0xd4d/de4dot

什麼亂七八糟的東西。

dnspy真好看,class3.method_0是sha1。

public static string smethod_0(string string_0)
	{
		byte[] bytes = Encoding.UTF8.GetBytes(string_0);
		byte[] array = SHA1.Create().ComputeHash(bytes);
		StringBuilder stringBuilder = new StringBuilder();
		foreach (byte b in array)
		{
			stringBuilder.Append(b.ToString("X2"));
		}
		return stringBuilder.ToString();
           

314159

return

去掉39re

day14 5.18

[ACTF新生賽2020]easyre

upx脫殼

LOWORD()得到一個32bit數的低16bit

HIWORD()得到一個32bit數的高16bit

LOBYTE()得到一個16bit數最低(最右邊)那個位元組

HIBYTE()得到一個16bit數最高(最左邊)那個位元組

__main();
  v4 = 42;
  v5 = 70;
  v6 = 39;
  v7 = 34;
  v8 = 78;
  v9 = 44;
  v10 = 34;
  v11 = 40;
  v12 = 73;
  v13 = 63;
  v14 = 43;
  v15 = 64;
  printf("Please input:");
  scanf("%s", &v19);
  if ( (_BYTE)v19 == \'A\' && HIBYTE(v19) == \'C\' && v20 == \'T\' && v21 == \'F\' && v22 == \'{\' && v26 == \'}\' )
  {
    v16 = v23;
    v17 = v24;
    v18 = v25;
    for ( i = 0; i <= 11; ++i )
    {
      if ( *(&v4 + i) != _data_start__[*((_BYTE *)&v16 + i) - 1] )
        return 0;
    }
    printf("You are correct!");
    result = 0;
  }
           
.data:00402000 __data_start__  db 7Eh                  ; DATA XREF: _main+ECr
.data:00402001 aZyxwvutsrqponm db \'}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=\'
.data:00402001                 db \'<;:9876543210/.-,+*)(\',27h,\'&%$# !"\',0
           
data=\'~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\\'&%$# !"\'
print(data)
v4 = [42,70,39,34,78,44,34,40,73,63,43,64]
flag=\'\'

for n in v4:
    flag+=chr(data.find(chr(n))+1)
print flag
           

起飛

[FlareOn4]login

<!DOCTYPE Html />
<html>
    <head>
        <title>FLARE On 2017</title>
    </head>
    <body>
        <input type="text" name="flag" id="flag" value="Enter the flag" />
        <input type="button" id="prompt" value="Click to check the flag" />
        <script type="text/javascript">
            document.getElementById("prompt").onclick = function () {
                var flag = document.getElementById("flag").value;
                var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
                if ("[email protected]" == rotFlag) {
                    alert("Correct flag!");
                } else {
                    alert("Incorrect flag, rot again");
                }
            }
        </script>
    </body>
</html>

           
JavaScript fromCharCode() 方法将 Unicode 編碼轉為一個字元:
var n = String.fromCharCode(65);
n 
輸出結果:A
charCodeAt() 方法可傳回指定位置的字元的 Unicode 編碼
           
\'\'\'
    (c <= "Z"? 90 : 122) >= (c + 13)
    ? c+13 : c - 13
\'\'\'
#M77 m109
ef=\'[email protected]\'
flag=\'\'

for i in ef:
    if i<\'A\' or i>\'z\' or \'Z\'<i<\'a\':
        flag+=i
        continue
    if \'Z\'>=i>\'M\' or \'z\'>=i>\'m\':
        flag+=chr(ord(i)-13)
    else:
        flag+=chr(ord(i)+13)
print flag
           

一開始條件沒寫全。

day15 5.19

[BJDCTF2020]easy

沒殼。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [sp+10h] [bp-3F0h]@1
  struct tm *v5; // [sp+3FCh] [bp-4h]@1

  __main();
  time((time_t *)&v4);
  v5 = localtime((const time_t *)&v4);
  puts("Can you find me?\n");
  system("pause");
  return 0;
}
           

找,感覺和時間有關。v5是目前時間tm類。

字元串什麼的都沒有,再找可疑的資料。

int ques()
{
  int v0; // edx@2
  int result; // eax@16
  int v2[50]; // [sp+20h] [bp-128h]@2
  int v3; // [sp+E8h] [bp-60h]@1
  int v4; // [sp+ECh] [bp-5Ch]@1
  int v5; // [sp+F0h] [bp-58h]@1
  int v6; // [sp+F4h] [bp-54h]@1
  int v7; // [sp+F8h] [bp-50h]@1
  int v8; // [sp+FCh] [bp-4Ch]@1
  int v9; // [sp+100h] [bp-48h]@1
  int v10; // [sp+104h] [bp-44h]@1
  int v11; // [sp+108h] [bp-40h]@1
  int v12; // [sp+10Ch] [bp-3Ch]@1
  int j; // [sp+114h] [bp-34h]@7
  __int64 v14; // [sp+118h] [bp-30h]@2
  int v15; // [sp+124h] [bp-24h]@2
  int v16; // [sp+128h] [bp-20h]@2
  int i; // [sp+12Ch] [bp-1Ch]@1

  v3 = 2147122737;
  v4 = 140540;
  v5 = -2008399303;
  v6 = 141956;
  v7 = 139457077;
  v8 = 262023;
  v9 = -2008923597;
  v10 = 143749;
  v11 = 2118271985;
  v12 = 143868;
  for ( i = 0; i <= 4; ++i )
  {
    memset(v2, 0, sizeof(v2));
    v16 = 0;
    v15 = 0;
    v0 = *(&v4 + 2 * i);
    LODWORD(v14) = *(&v3 + 2 * i);
    HIDWORD(v14) = v0;
    while ( SHIDWORD(v14) > 0 || SHIDWORD(v14) >= 0 && (_DWORD)v14 )
    {
      v2[v16++] = ((SHIDWORD(v14) >> 31) ^ (((unsigned __int8)(SHIDWORD(v14) >> 31) ^ (unsigned __int8)v14)
                                          - (unsigned __int8)(SHIDWORD(v14) >> 31)) & 1)
                - (SHIDWORD(v14) >> 31);
      v14 /= 2LL;
    }
    for ( j = 50; j >= 0; --j )
    {
      if ( v2[j] )
      {
        if ( v2[j] == 1 )
        {
          putchar(42);
          ++v15;
        }
      }
      else
      {
        putchar(32);
        ++v15;
      }
      if ( !(v15 % 5) )
        putchar(32);
    }
    result = putchar(10);
  }
  return result;
}
           

define SHIDWORD(x) (*((int32*)&(x)+1))

_ques裡。為什麼呢

修改eip位址跳轉

HACKIT4FUN

wp上:函數視窗可以發現一個叫ques的未被調用的函數。

完全看找不找得到。

[GXYCTF2019]simple CPP

無殼64.

字元串裡有,要繞過反調試

函數有個std::_Lockit::~_Lockit(void)沒看出什麼

int sub_140001290()
{
  bool v0; // si@1
  __int64 v1; // rax@1
  void *v2; // rax@2
  void *v3; // rbx@2
  int v4; // er10@5
  __int64 v5; // r11@6
  void *v6; // r9@7
  void **v7; // r8@9
  __int64 v8; // rdi@12
  __int64 v9; // r15@12
  __int64 v10; // r12@12
  __int64 v11; // rbp@12
  signed int v12; // ecx@13
  void *v13; // rdx@14
  __int64 v14; // rdi@15
  void *v15; // r14@27
  __int64 v16; // rbp@29
  __int64 v17; // r13@29
  void *v18; // rdi@29
  __int64 v19; // r12@32
  __int64 v20; // r15@32
  __int64 v21; // rbp@32
  __int64 v22; // rdx@32
  __int64 v23; // rbp@32
  __int64 v24; // rbp@34
  __int64 v25; // r10@34
  __int64 v26; // rdi@34
  __int64 v27; // r8@34
  bool v28; // dl@34
  __int64 v29; // rax@40
  void *v30; // rdx@40
  __int64 v31; // rax@42
  __int64 v32; // rax@44
  void *v33; // rcx@46
  __int64 v35; // [sp+0h] [bp-88h]@50
  __int64 v36; // [sp+20h] [bp-68h]@29
  void *v37; // [sp+28h] [bp-60h]@29
  void *Memory; // [sp+30h] [bp-58h]@1
  unsigned __int64 v39; // [sp+40h] [bp-48h]@1
  unsigned __int64 v40; // [sp+48h] [bp-40h]@1
  __int64 v41; // [sp+50h] [bp-38h]@50

  v0 = 0;
  v39 = 0i64;
  v40 = 15i64;
  LOBYTE(Memory) = 0;
  v1 = sub_1400019C0((__int64)std::cout, (__int64)"I\'m a first timer of Logic algebra , how about you?");
  std::basic_ostream<char,std::char_traits<char>>::operator<<(v1, sub_140001B90);
  sub_1400019C0((__int64)std::cout, (__int64)"Let\'s start our game,Please input your flag:");
  sub_140001DE0((__int64)std::cin, (__int64)&Memory);
  std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140001B90);
  if ( v39 - 5 > 0x19 )
  {
    v32 = sub_1400019C0((__int64)std::cout, (__int64)"Wrong input ,no GXY{} in input words");
    std::basic_ostream<char,std::char_traits<char>>::operator<<(v32, sub_140001B90);
    goto LABEL_45;
  }
  v2 = sub_1400024C8(0x20ui64);
  v3 = v2;
  if ( v2 )
  {
    *(_QWORD *)v2 = 0i64;
    *((_QWORD *)v2 + 1) = 0i64;
    *((_QWORD *)v2 + 2) = 0i64;
    *((_QWORD *)v2 + 3) = 0i64;
  }
  else
  {
    v3 = 0i64;
  }
  v4 = 0;
  if ( v39 > 0 )
  {
    v5 = 0i64;
    do
    {
      v6 = &Memory;
      if ( v40 >= 0x10 )
        v6 = Memory;
      v7 = &Dst;
      if ( (unsigned __int64)qword_140006060 >= 0x10 )
        v7 = (void **)Dst;
      *((_BYTE *)v3 + v5) = *((_BYTE *)v6 + v5) ^ *((_BYTE *)v7 + v4++ % 27);
      ++v5;
    }
    while ( v4 < v39 );
  }
  v8 = 0i64;
  v9 = 0i64;
  v10 = 0i64;
  v11 = 0i64;
  if ( (signed int)v39 > 30 )
    goto LABEL_28;
  v12 = 0;
  if ( (signed int)v39 <= 0 )
    goto LABEL_28;
  v13 = v3;
  do
  {
    v14 = *(_BYTE *)v13 + v8;
    ++v12;
    v13 = (char *)v13 + 1;
    if ( v12 == 8 )
    {
      v11 = v14;
      goto LABEL_24;
    }
    if ( v12 == 16 )
    {
      v10 = v14;
      goto LABEL_24;
    }
    if ( v12 == 24 )
    {
      v9 = v14;
LABEL_24:
      v14 = 0i64;
      goto LABEL_25;
    }
    if ( v12 == 32 )
    {
      sub_1400019C0((__int64)std::cout, (__int64)"ERRO,out of range");
      exit(1);
    }
LABEL_25:
    v8 = v14 << 8;
  }
  while ( v12 < (signed int)v39 );
  if ( v11 )
  {
    v15 = sub_1400024C8(0x20ui64);
    *(_QWORD *)v15 = v11;
    *((_QWORD *)v15 + 1) = v10;
    *((_QWORD *)v15 + 2) = v9;
    *((_QWORD *)v15 + 3) = v8;
    goto LABEL_29;
  }
LABEL_28:
  v15 = 0i64;
LABEL_29:
  v36 = *((_QWORD *)v15 + 2);
  v16 = *((_QWORD *)v15 + 1);
  v17 = *(_QWORD *)v15;
  v18 = sub_14000223C(0x20ui64);
  v37 = v18;
  if ( IsDebuggerPresent() )
  {
    sub_1400019C0((__int64)std::cout, (__int64)"Hi , DO not debug me !");
    Sleep(0x7D0u);
    exit(0);
  }
  v19 = v16 & v17;
  *(_QWORD *)v18 = v16 & v17;
  v20 = v36 & ~v17;
  *((_QWORD *)v18 + 1) = v20;
  v21 = ~v16;
  v22 = v36 & v21;
  *((_QWORD *)v18 + 2) = v36 & v21;
  v23 = v17 & v21;
  *((_QWORD *)v18 + 3) = v23;
  if ( v20 != 1176889593874i64 )
  {
    *((_QWORD *)v18 + 1) = 0i64;
    v20 = 0i64;
  }
  v24 = v20 | v19 | v22 | v23;
  v25 = *((_QWORD *)v15 + 1);
  v26 = *((_QWORD *)v15 + 2);
  v27 = v22 & *(_QWORD *)v15 | v26 & (v19 | v25 & ~*(_QWORD *)v15 | ~(v25 | *(_QWORD *)v15));
  v28 = 0;
  if ( v27 == 577031497978884115i64 )
    v28 = v24 == 4483974544037412639i64;
  if ( (v24 ^ *((_QWORD *)v15 + 3)) == 4483974543195470111i64 )
    v0 = v28;
  if ( (v20 | v19 | v25 & v26) != (~*(_QWORD *)v15 & v26 | 0xC00020130082C0Ci64) || v0 != 1 )
  {
    sub_1400019C0((__int64)std::cout, (__int64)"Wrong answer!try again");
    j_j_free(v3);
  }
  else
  {
    v29 = sub_1400019C0((__int64)std::cout, (__int64)"Congratulations!flag is GXY{");
    v30 = &Memory;
    if ( v40 >= 0x10 )
      v30 = Memory;
    LODWORD(v31) = sub_140001FD0(v29, v30, v39);
    sub_1400019C0(v31, (__int64)"}");
    j_j_free(v3);
  }
LABEL_45:
  if ( v40 >= 0x10 )
  {
    v33 = Memory;
    if ( v40 + 1 >= 0x1000 )
    {
      v33 = (void *)*((_QWORD *)Memory - 1);
      if ( (unsigned __int64)((_BYTE *)Memory - (_BYTE *)v33 - 8) > 0x1F )
      {
        invalid_parameter_noinfo_noreturn();
        __debugbreak();
      }
    }
    j_j_free(v33);
  }
  return sub_140002210((unsigned __int64)&v35 ^ v41);
}
           

v3=flag^Dst

v3分割後滿足一系列條件

flag條件:

(v20 | v19 | v25 & v26) == (~*(_QWORD *)v15 & v26 | 0xC00020130082C0Ci64)

v0==1

v36=v26=v15[2]
v17=v15[0]
v16=v25=v15[1]
v19 = v16 & v17=v15[0]&v15[1]
v21 = ~v16=~v15[1]
v22 = v36 & v21=v15[2]&(~v15[1])
v23 = v17 & v21=v15[0]&(~v15[1])

v20 = v15[2] & ~v15[0]
== 1176889593874
    
v24 = v20 | (v15[1] & v15[0]) | (v15[2] & (~v15[1])) | (v15[0]&(~v15[1]));
==4483974544037412639
    
    
v27 =v15[2]&(~v15[1])& v15[0] |v15[2]& ( (v15[0]&v15[1]) | v15[1] & ~v15[0] | ~(v15[1] | v15[0]) );
==577031497978884115
    
4483974544037412639 ^ v15[3] == 4483974543195470111

(v20 | (v15[0]&v15[1]) | v15[1] & v15[2]) == v15[0] & v15[2] | 0xC00020130082C0C
           

給爺爬!!!!

#!/usr/bin/python
# -*- coding: utf-8 -*-
from z3 import *

from z3 import*
#申明未知量
v15 = [0]*4
for i in range(4):
    v15[i] = BitVec(\'v15[\'+str(i)+\']\',64)
s=Solver() # 建立限制求解器

# 添加限制條件
s.add(((v15[2]&~v15[1])&v15[0]|v15[2]&((v15[1]&v15[0])|v15[1]&~v15[0]|~(v15[1]|v15[0])))==577031497978884115)
s.add(4483974544037412639 ^ v15[3] == 4483974543195470111)
s.add(v15[2] & ~v15[0]== 1176889593874)
s.add(1176889593874 | (v15[1] & v15[0]) | (v15[2] & (~v15[1])) | (v15[0]&(~v15[1]))==4483974544037412639)
s.add((1176889593874 | (v15[0]&v15[1]) | v15[1] & v15[2]) == ~v15[0] & v15[2] | 864693332579200012)
# 檢查是否有解
if s.check()!=sat:
    print( "unsat")

m=s.model()
for d in m.decls():   # decls()傳回model包含了所有符号的清單
    print("%s = %s" % (d.name(),m[d]))

           
v15[3] = 842073600
v15[2] = 577031497978884115
v15[0] = 4483973367147818765
v15[1] = 864693332579200012
           
do
    {
      v6 = &Memory;
      if ( v40 >= 0x10 )
        v6 = Memory;
      v7 = &Dst;
      if ( (unsigned __int64)qword_140006060 >= 0x10 )
        v7 = (void **)Dst;
      *((_BYTE *)v3 + v5) = *((_BYTE *)v6 + v5) ^ *((_BYTE *)v7 + v4++ % 27);
      ++v5;
    }
    while ( v4 < v39 );
           
v15=[0]*4
v15[0] = 4483973367147818765
v15[2] = 577031497978884115
v15[1] = 864693332579200012
v15[3] = 842073600
for i in range(4):
    v15[i]=hex(v15[i])
    v15[i]=v15[i].replace(\'L\',\'\')
    v15[i]=v15[i].replace(\'0x\',\'\')
print v15
s=\'\'
for i in v15:
    s+=str(i)
print s
flag=\'\'
dst="i_will_check_is_debug_or_not"
n=0
for j in range(0,len(s),2):
    flag+=chr(int(s[j]+s[j+1],16)^ord(dst[n%27]))
    n+=1
print flag
           

We1l_D0n╡Cx_氤梖bu`Yo|@nho。emmm有點問題。

看過wp後發現v15[1]錯了。我淦,把v15全換成xyzw,一個一個比。

我淦,每個wp v15[1]好像都不一樣。

s="3e3a460533286f00000000000000000008020717153e3013323106"

We1l_D0check_is_lgebra_am_i

比賽給了二部分e!P0or_a

我逆了一下,應該是0d44335b301b2c3e80,這樣會10進制244722044838787956352轉的話沒有第一個0。

day16 5.20

xxor

應該在sub_400856裡

__int64 sub_400856()
{
  signed int i; // [sp+8h] [bp-68h]@1
  signed int j; // [sp+Ch] [bp-64h]@4
  __int64 v3; // [sp+10h] [bp-60h]@1
  __int64 v4; // [sp+18h] [bp-58h]@1
  __int64 v5; // [sp+20h] [bp-50h]@1
  __int64 v6; // [sp+28h] [bp-48h]@1
  __int64 v7; // [sp+30h] [bp-40h]@1
  __int64 v8; // [sp+40h] [bp-30h]@4
  __int64 v9; // [sp+48h] [bp-28h]@4
  __int64 v10; // [sp+50h] [bp-20h]@4
  __int64 v11; // [sp+58h] [bp-18h]@4
  __int64 v12; // [sp+60h] [bp-10h]@4
  __int64 v13; // [sp+68h] [bp-8h]@1

  v13 = *MK_FP(__FS__, 40LL);
  puts("Let us play a game?");
  puts("you have six chances to input");
  puts("Come on!");
  v3 = 0LL;
  v4 = 0LL;
  v5 = 0LL;
  v6 = 0LL;
  v7 = 0LL;
  for ( i = 0; i <= 5; ++i )
  {
    printf("%s", 4197072LL, (unsigned int)i);
    __isoc99_scanf(4197083LL, (char *)&v3 + 4 * i);
  }
  v8 = 0LL;
  v9 = 0LL;
  v10 = 0LL;
  v11 = 0LL;
  v12 = 0LL;
  for ( j = 0; j <= 4; j += 2 )
  {
    dword_601078 = *((_DWORD *)&v3 + j);
    dword_60107C = *((_DWORD *)&v3 + j + 1);
    sub_400686(6295672LL, 6295648LL);
    *((_DWORD *)&v8 + j) = dword_601078;
    *((_DWORD *)&v8 + j + 1) = dword_60107C;
  }
  if ( (unsigned int)sub_400770((__int64)&v8) != 1 )
  {
    puts("NO NO NO~ ");
    exit(0);
  }
  puts("Congratulation!\n");
  puts("You seccess half\n");
  puts("Do not forget to change input to hex and combine~\n");
  puts("ByeBye");
  return 0LL;
}
           

輸入6個數字放在v3,v8還是v3,sub_400770(v8)==1

signed __int64 __fastcall sub_400770(__int64 a1)
{
  signed __int64 result; // rax@7

  if ( *(_DWORD *)(a1 + 8) - *(_DWORD *)(a1 + 12) != 2225223423LL
    || *(_DWORD *)(a1 + 12) + *(_DWORD *)(a1 + 16) != 4201428739LL
    || *(_DWORD *)(a1 + 8) - *(_DWORD *)(a1 + 16) != 1121399208LL )
  {
    puts("Wrong!");
    result = 0LL;
  }
  else if ( *(_DWORD *)a1 != -548868226 || *(_DWORD *)(a1 + 20) != -2064448480 || *(_DWORD *)(a1 + 4) != 550153460 )
  {
    puts("Wrong!");
    result = 0LL;
  }
  else
  {
    puts("good!");
    result = 1LL;
  }
  return result;
}
           

上z3

#!/usr/bin/python
# -*- coding: utf-8 -*-
from z3 import *
v8 = [0]*6

#申明未知量
v8 = [0]*6
for i in range(6):
    v8[i] = BitVec(\'v8[\'+str(i)+\']\',64)
s=Solver() # 建立限制求解器

# 添加限制條件
s.add(v8[2]-v8[3]==2225223423)
s.add(v8[3]+v8[4]==4201428739)
s.add(v8[2]-v8[4]==1121399208)
s.add(v8[0]==0xDF48EF7E)
s.add(v8[5]==0x84F30420)
s.add(v8[1]== 550153460)
# 檢查是否有解
if s.check()!=sat:
    print( "unsat")

m=s.model()
for d in m.decls():   # decls()傳回model包含了所有符号的清單
    print("%s = %s" % (d.name(),m[d]))
"""
v8[4] = 2652626477
v8[1] = 550153460
v8[5] = 2230518816
v8[0] = 3746099070
v8[2] = 3774025685
v8[3] = 1548802262
"""
           

之後因為python整數範圍原因位運算出錯

#include <iostream>

#pragma warning(disable:4996)
using namespace std;

int main()
{
    __int64 a[6] = { 3746099070, 550153460, 3774025685, 1548802262, 2652626477, 2230518816 };
    unsigned int a2[4] = { 2,2,3,4 };
    unsigned int v3, v4;
    int v5;
    for (int j = 0; j <= 4; j += 2) {
        v3 = a[j];
        v4 = a[j + 1];
        v5 = 1166789954*0x40;
        for (int i = 0; i <= 0x3F; ++i) {
            v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
            v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
            v5 -= 1166789954;
        }
        a[j] = v3;
        a[j + 1] = v4;
    }
    for (int i = 0; i < 6; ++i) {
        cout<<hex<<a[i];
    }
    cout<<endl;
    

    for (int i = 0; i < 6; ++i) {
        cout << *((char*)&a[i] + 2) << *((char*)&a[i] + 1) <<  * ((char*)&a[i]);
    }

    return 0;
}
//https://www.cnblogs.com/Mayfly-nymph/p/12669358.html
           

day17 5.21

[BJDCTF2020]BJD hamburger competition

也許世上沒有老八,也去人人都是老八。

ida打開後搜BJD沒有。

unity是用C#開發。C#是微軟公司釋出的一種由C和C++衍生出來的面向對象的程式設計語言、運作于.NET Framework和.NET Core(完全開源,跨平台)之上的進階程式設計語言。

dnSpy 是一款針對 .NET 程式的逆向工程工具。

if (ButtonSpawnFruit.Sha1(str) == "DD01903921EA24941C26A48F2CEC24E0BB0E8CC7")
{
	this.result = "BJDCTF{" + ButtonSpawnFruit.Md5(str) + "}";
	Debug.Log(this.result);
}
           

1001

b8c37e33defde51cf91e1e03e51657da

b8c37e33defde51cf91e

萬萬沒想到是大寫困擾了我。

day18 5.22

EPIC,永遠的神

usualcrypt

32位

sub_403CF8是printf

sub_401080看着是base64,flag base64後傳到v5

byte_40E0E4:

.data:0040E0E4 byte_40E0E4     db 7Ah                  ; DATA XREF: _main+5Cr
.data:0040E0E4                                         ; _main:loc_401238o
.data:0040E0E5 aMxhz3tignxlxjh db \'MXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9\',0
           

MXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9

base64那應該改了

在sub_401000裡

signed int sub_401000()
{
  signed int result; // eax@1
  char v1; // cl@2

  result = 6;
  do
  {
    v1 = byte_40E0AA[result];
    byte_40E0AA[result] = byte_40E0A0[result];
    byte_40E0A0[result++] = v1;
  }
  while ( result < 15 );
  return result;
}
           
#include <stdio.h>
#include <iostream>
using namespace std;

int main(){
    char A0[100]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    signed int result; // eax@1
    char v1; // cl@2
    result = 6;
    do
    {
        v1 = A0[result+10];
        A0[result+10] = A0[result];
        A0[result] = v1;
        result++;
    }
    while ( result < 15 );
    cout<<A0<<endl;

    return 0;

}
           

注意byte_40E0A0和byte_40E0AA是挨着的。[byte_40E0AA]就是[byte_40E0A0+10]

ABCDEFQRSTUVWXYPGHIJKLMNOZabcdefghijklmnopqrstuvwxyz0123456789+/

sub_401030裡大小寫轉換

if ( v2 < 97 || v2 > 122 )                // 97-122小寫
                                                // 
      {
        if ( v2 < 65 || v2 > 90 )
          goto LABEL_9;
        LOBYTE(result) = result + 32;
      }
      else
      {
        LOBYTE(result) = result - 32;
      }
           

是以flag,base64--byte_40E0AA--大小寫

MXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9

import base64
n="ABCDEFQRSTUVWXYPGHIJKLMNOZabcdefghijklmnopqrstuvwxyz0123456789+/"
o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
dic=dict(zip(n,o))
#print dic
flag=\'\'
a="zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9"
f=list(a)
for i in range(len(f)):
    if f[i]<\'a\' or f[i]>\'z\':
        if f[i]>\'A\' and f[i]<\'Z\':
            f[i]=chr(ord(f[i])+32)
    else:
        f[i]=chr(ord(f[i])-32)
for i in f:
    flag+=dic[i]
print base64.b64decode(flag)

           

真好flag{bAse64_2Y_a_Surprise}

為什麼不對???

我的大小寫好像有問題

if f[i]>\'A\' and f[i]<\'Z\': #沒=
           

day19 5.23

[FlareOn4]IgniteMe

void __noreturn start()
{
  DWORD NumberOfBytesWritten; // [sp+0h] [bp-4h]@1

  NumberOfBytesWritten = 0;
  hFile = GetStdHandle(0xFFFFFFF6);
  dword_403074 = GetStdHandle(0xFFFFFFF5);
  WriteFile(dword_403074, aG1v3M3T3hFl4g, 0x13u, &NumberOfBytesWritten, 0);
  sub_4010F0();
  if ( sub_401050(NumberOfBytesWritten) )
    WriteFile(dword_403074, aG00dJ0b, 0xAu, &NumberOfBytesWritten, 0);
  else
    WriteFile(dword_403074, aN0tT00H0tRWe_7, 0x24u, &NumberOfBytesWritten, 0);
  ExitProcess(0);
}
           

sub_4010F0把flag放到byte_403078

signed int sub_401050()
{
  int v0; // ST04_4@1
  int i; // [sp+4h] [bp-8h]@1
  unsigned int j; // [sp+4h] [bp-8h]@4
  char v4; // [sp+Bh] [bp-1h]@1

  v0 = sub_401020(byte_403078);
  v4 = sub_401000();
  for ( i = v0 - 1; i >= 0; --i )
  {
    byte_403180[i] = v4 ^ byte_403078[i];
    v4 = byte_403078[i];
  }
  for ( j = 0; j < 0x27; ++j )
  {
    if ( byte_403180[j] != (unsigned __int8)byte_403000[j] )
      return 0;
  }
  return 1;
}
           

v0是flag長度

v4:

__int16 sub_401000()
{
  int v0; // eax@1

  v0 = __ROL4__(-2147024896, 4);
  return (unsigned __int16)v0 >> 1;
}
           

ROL4沒查到,但v4可以調出來,為4

byte_403000裡

.data:00403000 byte_403000     db 0Dh                 
.data:00403001                 db  26h ; &
.data:00403002                 db  49h ; I
.data:00403003                 db  45h ; E
.data:00403004                 db  2Ah ; *
.data:00403005                 db  17h
.data:00403006                 db  78h ; x
.data:00403007                 db  44h ; D
.data:00403008                 db  2Bh ; +
.data:00403009                 db  6Ch ; l
.data:0040300A                 db  5Dh ; ]
.data:0040300B                 db  5Eh ; ^
.data:0040300C                 db  45h ; E
.data:0040300D                 db  12h
.data:0040300E                 db  2Fh ; /
.data:0040300F                 db  17h
.data:00403010                 db  2Bh ; +
.data:00403011                 db  44h ; D
.data:00403012                 db  6Fh ; o
.data:00403013                 db  6Eh ; n
.data:00403014                 db  56h ; V
.data:00403015                 db    9
.data:00403016                 db  5Fh ; _
.data:00403017                 db  45h ; E
.data:00403018                 db  47h ; G
.data:00403019                 db  73h ; s
.data:0040301A                 db  26h ; &
.data:0040301B                 db  0Ah
.data:0040301C                 db  0Dh
.data:0040301D                 db  13h
.data:0040301E                 db  17h
.data:0040301F                 db  48h ; H
.data:00403020                 db  42h ; B
.data:00403021                 db    1
.data:00403022                 db  40h ; @
.data:00403023                 db  4Dh ; M
.data:00403024                 db  0Ch
.data:00403025                 db    2
.data:00403026                 db  69h ; i
.data:00403027                 db    0
           
b= [0x0D,0x26,0x49,0x45,0x2A,0x17,0x78,0x44,0x2B,0x6C,0x5D,0x5E,0x45,0x12,0x2F,0x17,0x2B,0x44,0x6F,0x6E,0x56,0x09,0x5F,0x45,0x47,0x73,0x26,0x0A,0x0D,0x13,0x17,0x48,
0x42,0x01,0x40,0x4D,0x0C,0x02,0x69]
v=4
flag=\'\'

for i in range(0x27-1,-1,-1):
    flag+=chr(v^b[i])
    v=v^b[i]
print flag[-1::-1]
           

rome

32位無殼

falg16位,變換

for ( i = 0; i <= 15; ++i )
              {
                if ( *((_BYTE *)&v1 + i) > \'@\' && *((_BYTE *)&v1 + i) <= \'Z\' )
                  *((_BYTE *)&v1 + i) = (*((_BYTE *)&v1 + i) - 51) % 26 + 65;
                if ( *((_BYTE *)&v1 + i) > \'`\' && *((_BYTE *)&v1 + i) <= \'z\' )
                  *((_BYTE *)&v1 + i) = (*((_BYTE *)&v1 + i) - 79) % 26 + 97;
              }
           

後為

v15 = 81;
  v16 = 115;
  v17 = 119;
  v18 = 51;
  v19 = 115;
  v20 = 106;
  v21 = 95;
  v22 = 108;
  v23 = 122;
  v24 = 52;
  v25 = 95;
  v26 = 85;
  v27 = 106;
  v28 = 119;
  v29 = 64;
  v30 = 108;
           

day20 5.24

gkctf的簽到

day21 5.25

[19紅帽]xx

無殼64

sub_1400011A0

code是qwertyuiopasdfghjklzxcvbnm1234567890

v3=len(code)=19

v4=sub_140001620(5) molloc(5)

v5 = *(_QWORD *)&::Code;

v6 = v4

v7 = 0;

v8 = v4

最下面的的比較

v24 = (_BYTE *)v19 - (_BYTE *)&v30;

if ( *((_BYTE *)&v30 + v25) != *((_BYTE *)&v30 + v25 + v24) )

是以&v30=&v19

異或

for ( *((_BYTE *)v19 + 23) = *((_BYTE *)v18 + 21); v20 < v17; ++v21 )
  {
    v22 = 0i64;
    if ( v20 / 3 > 0 )
    {
      v23 = *(_BYTE *)v21;
      do
      {
        v23 ^= *((_BYTE *)v19 + v22++);
        *(_BYTE *)v21 = v23;
      }
      while ( v22 < v20 / 3 );
    }
  ++v20;
  }
           

sub_140001AB0裡是xxtea

*(v34 - 1) += ((v27 ^ v38) + (v29 ^ v18[v39])) ^ ((16 * v29 ^ (v38 >> 3)) + ((v29 >> 5) ^ 4 * v38));
           

和下面一樣

#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
           

知識點裡xxtea是純數字的,後來找到了https://blog.csdn.net/cserchen/article/details/8238641 python實作的字元串加解密。

import binascii
result = \'CEBC406B7C3A95C0EF9B202091F70235231802C8E75656FA\'

data=[0]*(len(result)/2)
for i in range(0,len(result),2):
    data[i/2]=int((\'0x\'+result[i]+result[i+1]),16)
#print len(data)

for i in range(len(data)-1,-1,-1):
    for j in range(i//3):
        data[i] ^= data[j]

h = [2,0,3,1,6,4,7,5,10,8,11,9,14,12,15,13,18,16,19,17,22,20,23,21]
c = [1]*24
for i in range(24):
    c[h[i]] = data[i]
print(c)
cc=\'\'
for i in c:
    #確定兩位
    if i<16:
        cc+=\'0\' 
    cc+=str(hex(i)).replace(\'0x\',\'\')

print cc
print len(cc)
strc=binascii.a2b_hex(cc) 
   
############################################################  
#                                                          #  
# The implementation of PHPRPC Protocol 3.0                #  
#                                                          #  
# xxtea.py                                                 #  
#                                                          #  
# Release 3.0.0                                            #  
# Copyright (c) 2005-2008 by Team-PHPRPC                   #  
#                                                          #  
# WebSite:  http://www.phprpc.org/                         #  
#           http://www.phprpc.net/                         #  
#           http://www.phprpc.com/                         #  
#           http://sourceforge.net/projects/php-rpc/       #  
#                                                          #  
# Authors:  Ma Bingyao <[email protected]>                  #  
#                                                          #  
# This file may be distributed and/or modified under the   #  
# terms of the GNU Lesser General Public License (LGPL)    #  
# version 3.0 as published by the Free Software Foundation #  
# and appearing in the included file LICENSE.              #  
#                                                          #  
############################################################  
#  
# XXTEA encryption arithmetic library.  
#  
# Copyright (C) 2005-2008 Ma Bingyao <[email protected]>  
# Version: 1.0  
# LastModified: Oct 5, 2008  
# This library is free.  You can redistribute it and/or modify it.  
  
import struct  
  
_DELTA = 0x9E3779B9  
  
def _long2str(v, w):  
    n = (len(v) - 1) << 2  
    if w:  
        m = v[-1]  
        if (m < n - 3) or (m > n): return \'\'  
        n = m  
    s = struct.pack(\'<%iL\' % len(v), *v)  
    return s[0:n] if w else s  
  
def _str2long(s, w):  
    n = len(s)  
    m = (4 - (n & 3) & 3) + n  
    s = s.ljust(m, "\0")  
    v = list(struct.unpack(\'<%iL\' % (m >> 2), s))  
    if w: v.append(n)  
    return v  
  
def encrypt(str, key):  
    if str == \'\': return str  
    v = _str2long(str, True)  
    k = _str2long(key.ljust(16, "\0"), False)  
    n = len(v) - 1  
    z = v[n]  
    y = v[0]  
    sum = 0  
    q = 6 + 52 // (n + 1)  
    while q > 0:  
        sum = (sum + _DELTA) & 0xffffffff  
        e = sum >> 2 & 3  
        for p in xrange(n):  
            y = v[p + 1]  
            v[p] = (v[p] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff  
            z = v[p]  
        y = v[0]  
        v[n] = (v[n] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[n & 3 ^ e] ^ z))) & 0xffffffff  
        z = v[n]  
        q -= 1  
    return _long2str(v, False)  
  
def decrypt(str, key):  
    if str == \'\': return str  
    v = _str2long(str, False)  
    k = _str2long(key.ljust(16, "\0"), False)  
    n = len(v) - 1  
    z = v[n]  
    y = v[0]  
    q = 6 + 52 // (n + 1)  
    sum = (q * _DELTA) & 0xffffffff  
    while (sum != 0):  
        e = sum >> 2 & 3  
        for p in xrange(n, 0, -1):  
            z = v[p - 1]  
            v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff  
            y = v[p]  
        z = v[n]  
        v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffff  
        y = v[0]  
        sum = (sum - _DELTA) & 0xffffffff  
    return _long2str(v, True)  
  

key = \'flag\'
flag = decrypt(strc, key)
print flag


           

day22 5.27

[MRCTF2020]Transform

64無殼

簡單的轉換

__int64 sub_401530()
{
  char Str[104]; // [sp+20h] [bp-70h]@1
  int j; // [sp+88h] [bp-8h]@7
  int i; // [sp+8Ch] [bp-4h]@4

  sub_402230();
  printf("Give me your code:\n");
  scanf("%s", Str);
  if ( strlen(Str) != 33 )
  {
    printf("Wrong!\n");
    system("pause");
    exit(0);
  }
  for ( i = 0; i <= 32; ++i )
  {
    byte_414040[i] = Str[dword_40F040[i]];
    byte_414040[i] ^= LOBYTE(dword_40F040[i]);
  }
  for ( j = 0; j <= 32; ++j )
  {
    if ( byte_40F0E0[j] != byte_414040[j] )
    {
      printf("Wrong!\n");
      system("pause");
      exit(0);
    }
  }
  printf("Right!Good Job!\n");
  printf("Here is your flag: %s\n");
  system("pause");
  return 0i64;
}
           

輸入str,33位

byte_414040[i] = Str[dword_40F040[i]];

byte_414040[i] ^= LOBYTE(dword_40F040[i]);

LOBYTE()得到一個16bit數最低(最右邊)那個位元組,用&0xff就好。

.data:000000000040F040 dword_40F040    dd 9, 0Ah, 0Fh, 17h, 7, 18h, 0Ch, 6, 1, 10h, 3, 11h, 20h
.data:000000000040F040                                         ; DATA XREF: sub_401530+79o
.data:000000000040F040                                         ; sub_401530+B8o
.data:000000000040F040                 dd 1Dh, 0Bh, 1Eh, 1Bh, 16h, 4, 0Dh, 13h, 14h, 15h, 2, 19h
.data:000000000040F040                 dd 5, 1Fh, 8, 12h, 1Ah, 1Ch, 0Eh, 8 dup(0)
           
.data:000000000040F0E0 byte_40F0E0     db 67h, 79h, 7Bh, 7Fh, 75h, 2Bh, 3Ch, 52h, 53h, 79h, 57h
.data:000000000040F0E0                                         ; DATA XREF: sub_401530+EFo
.data:000000000040F0E0                 db 5Eh, 5Dh, 42h, 7Bh, 2Dh, 2Ah, 66h, 42h, 7Eh, 4Ch, 57h
.data:000000000040F0E0                 db 79h, 41h, 6Bh, 7Eh, 65h, 3Ch, 5Ch, 45h, 6Fh, 62h, 4Dh
.data:000000000040F0E0                 db 3Fh dup(0)
           
a=\'9, 0Ah, 0Fh, 17h, 7, 18h, 0Ch, 6, 1, 10h, 3, 11h, 20h,1Dh, 0Bh, 1Eh, 1Bh, 16h, 4, 0Dh, 13h, 14h, 15h, 2, 19h,5, 1Fh, 8, 12h, 1Ah, 1Ch, 0Eh, 0\'
eflag=\'67h, 79h, 7Bh, 7Fh, 75h, 2Bh, 3Ch, 52h, 53h, 79h, 57h,5Eh, 5Dh, 42h, 7Bh, 2Dh, 2Ah, 66h, 42h, 7Eh, 4Ch, 57h,79h, 41h, 6Bh, 7Eh, 65h, 3Ch, 5Ch, 45h, 6Fh, 62h, 4Dh\'
flag=[0]*33

base=a.split(\',\')
for i in range(len(base)):
    base[i]=int((\'0x\'+base[i]).replace(\'h\',\'\').replace(\' \',\'\'),16)
print len(base)

ef=eflag.split(\',\')
for i in range(len(ef)):
    ef[i]=int((\'0x\'+ef[i]).replace(\'h\',\'\').replace(\' \',\'\'),16)
print len(ef)


for i in range(33):
    flag[base[i]]=ef[i]^base[i]
s=\'\'
for i in flag:
    s+=chr(i)
print s

           

[HDCTF2019]Maze

Maze迷宮,junk是廢物垃圾,感覺是要找東西。

有殼

迷宮是

*******+********* ******    ****   ******* **F******    **************
           

後面寫了7,是以要嗎7要麼10

maze=\'*******+********* ******    ****   ******* **F******    **************\'
print len(maze)
a=0
f=\'\'
for i in maze:
    a+=1
    if i==\' \':
        f+=\'=\'
    else:
        f+=i
    if a%10==0:
        f+=\'\n\'
print f

           
70
*******+**
*******=**
****====**
**===*****
**=**F****
**====****
**********
           

下下左左左下左左下下右右右上

emmmm,flag{ssaaasaassdddw}

main函數奇怪資料強制轉換

.text:0040102C                 jnz     short near ptr byte_40102F
.text:0040102C ; ---------------------------------------------------------------------------
.text:0040102E                 db 0E8h
.text:0040102F byte_40102F     db 58h                  ; CODE XREF: .text:0040102Cj
.text:00401030                 dd 0EC45C7h
.text:00401034                 db 2 dup(0)
.text:00401036 ; ---------------------------------------------------------------------------
.text:00401036                 add     bl, ch
.text:00401038
.text:00401038 loc_401038:                             ; CODE XREF: .text:loc_4010B4j
           
花指令是,由設計者特别構思,希望使反彙編的時候出錯,讓破解者無法清楚正确地反彙程式設計式的内容,迷失方向。經典的是,目标位置是另一條指令的中間,這樣在反彙編的時候便會出現混亂。花指令有可能利用各種指令:jmp, call, ret的一些堆棧技巧,位置運算,等等。
for ( i = 0; i <= 13; ++i )
  {
    switch ( v5[i] )
    {
      case \'w\':
        ++dword_40807C;
        break;
      case \'s\':
        --dword_40807C;
        break;
      case \'a\':
        --dword_408078;
        break;
      case \'d\':
        ++dword_408078;
        break;
      default:
        continue;
    }
  }
           

od nop

儲存檔案。

洗衣服啊啊啊。

day23 5.29

[WUSTCTF2020]level1

有個output

stream = fopen("flag", "r");
  fread(ptr, 1uLL, 0x14uLL, stream);
  fclose(stream);
  for ( i = 1; i <= 19; ++i )
  {
    if ( i & 1 )
      printf("%ld\n", (unsigned int)(ptr[i] << i));
    else
      printf("%ld\n", (unsigned int)(i * ptr[i]));
  }
           

flag19位

a=\'\'\'222
198
232
816
200
1536
300
6144
984
51200
570
92160
1200
565248
756
1474560
800
6291456
1782
65536000
\'\'\'
b=a.split(\'\n\')
flag=\'\'
for i in range(1,20):
    print b[i]
    if i&1:
        print ("aa",int(b[i],10)>>i)
        flag+=chr(int(b[i],10)>>i)
    else:
        print("bb",int(b[i],10)//i)
        flag+=chr(int(b[i],10)//i)
print flag
           

觀察一下資料,随便填一個數。

[安洵杯 2019]crackMe

Hook 技術又叫做鈎子函數,在系統沒有調用該函數之前,鈎子程式就先捕獲該消息,鈎子函數先得到控制權,這時鈎子函數既可以加工處理(改變)該函數的執行行為,還可以強制結束消息的傳遞。

比較

if ( !j_strcmp(Str1, Str2) )
  {
    v0 = printf("right\n");
    sub_4111A4(&v3 == &v3, v0);
  }
           

找到str、str1、str2

Str             db \'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\'
Str2            db \'1UTAOIkpyOSWGv/mOYFY4R!!\'
           
for ( i = 0; ; i += 2 )
    {
      v1 = j_strlen(Str2);
      if ( i >= v1 )
        break;
      v4 = Str2[i];
      Str2[i] = Str2[i + 1];
      Str2[i + 1] = v4;
    }
           

str2奇偶交換

Str1 = (char *)sub_41126C(byte_41A180);
           

sub_41126C應該是base64。

我想着是flag base64後奇偶交換變成str2。然而并不是。再看看。

搜hooked

首先Str大小寫轉換

for ( i = 0; ; ++i )
  {
    v4 = j_strlen(Str);
    if ( i >= v4 )
      break;
    v10 = Str[i] >= 97;
    v9 = Str[i] <= 122;
    if ( v9 & v10 )
    {
      Str[i] -= 32;
    }
    else
    {
      v10 = Str[i] >= 65;
      v9 = Str[i] <= 90;
      if ( v9 & v10 )
        Str[i] += 32;
    }
  }
           

然後AddVectoredExceptionHandler,這是什麼

向量化異常處理(Vectored Exception Handling)

向量化異常處理(VEH)是結構化異常處理的一個擴充,它在Windows XP中被引入。

你可以使用AddVectoredExceptionHandler()函數添加一個向量化異常處理器,VEH的缺點是它隻能用在WinXP及其以後的版本,是以需要在運作時檢查AddVectoredExceptionHandler()函數是否存在。

要移除先前安裝的異常處理器,可以使用RemoveVectoredExceptionHandler()函數。

VEH允許檢視或處理應用程式中所有的異常。為了保持後向相容,當程式中的某些部分發生SEH異常時,系統依次調用已安裝的VEH處理器,直到它找到有用的SEH處理器。

VEH的一個優點是能夠連結異常處理器(chain exception handlers),是以如果有人在你之前安裝了向量化異常處理器,你仍然能截獲這些異常。

當你需要像調試器一樣監事所有的異常時,使用VEH是很合适的。問題是你需要決定哪個異常需要處理,哪個異常需要跳過。 In program\'s code, some exceptions may be intentionally guarded by __try{}__except(){} construction, and handling such exceptions in VEH and not passing it to frame-based SEH handler, you may introduce bugs into application logics.

VEH目前沒有被CrashRpt所使用。SetUnhandledExceptionFilter()更加适用,因為它是top-level SEH處理器。如果沒有人處理異常,top-level SEH處理器就會被調用,并且你不用決定是否要處理這個異常。

翻譯的。

v6 = (int)AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)Handler);
           

Handler進去提示where_are_you_now後一個

sub_411172

while ( v8 < 0x20 )
  {
    v13[v8] = *(&v9 + v8) ^ sub_4114E0(dword_417A78[v8] ^ *(&v12 + v8) ^ *(&v11 + v8) ^ *(&v10 + v8));
    *(_DWORD *)(a1 + 4 * v8) = v13[v8];
    v4 = v8++ + 1;
  }
           

看了wp後知道sm4,。。。我好像學了

key就是where_are_you_now?

那個base64最後有一個return (a1 + 24) % 64;

from pysm4 import *
import base64
import binascii
key="where_are_u_now?"
key= binascii.b2a_hex(key)
print key
b64 = \'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\'
a="1UTAOIkpyOSWGv/mOYFY4R!!"
ba64=\'\'
for i in range(len(b64)):
    x=b64[(i+24)%64]
    if \'a\'<=x<=\'z\':
        ba64+=x.upper()
    elif \'A\'<=x<=\'Z\':
        ba64+=x.lower()
    else:
        ba64+=x
print ba64

b=list(a)
cflag=\'\'
for i in range(0,len(b)-2,2):
    cflag+=b64[ba64.find(b[i+1])]
    cflag+=b64[ba64.find(b[i])]
cflag+=\'==\'
print cflag

cc= base64.b64decode(cflag)
c=\'\'
for i in cc:
    if ord(i)<=0xf:
        c+=\'0\'
    c+=str(hex(ord(i))).replace("0x",\'\')
print c


c = 0x59d095290df2400614f48d276906874e
key=0x77686572655f6172655f755f6e6f773f
          
flag = decrypt(c, key)
flag=hex(flag)[2:].replace(\'L\', \'\')
print binascii.a2b_hex(str(flag))

           

寫的我吐了。各種格式啊什麼東西的

其中pysm4,要看看他的使用

day24 5.30

eqution

看源代碼解JSfuck

本來想http://ctf.ssleye.com/jsfuck.html解密的,但它的代碼是部分部分加密的,一個一個找眼都瞎啦。去找代碼。本來想搞個python爬蟲,結果burpsuit用不了。

<script>
function deEquation(str) {
  for (let i = 0; i <= 1; i++) {
  str = str.replace(/l\[(\D*?)](\+l|-l|==)/g, (m, a, b) => \'l[\' + eval(a) + \']\' + b);
  }
  str = str.replace(/==(\D*?)&&/g, (m, a) => \'==\' + eval(a) + \'&&\');
  return str;
}
s="l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+[]]]+l[!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]==+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[+!+[]]])&&l[!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+[]]]+l[+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+[]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]]+l[+[]]==+(+!+[]+[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]])&&l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]])&&l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+[]]-l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==+(!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(+!+[]+[+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]])&&l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]==+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]-l[!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]]+l[!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==+(!+[]+!+[]+!+[]+!+[]+[+!+[]+[!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]]-l[+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]==+(+!+[]+[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+[]]==-+(!+[]+!+[]+!+[]+[+!+[]+[!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+[]]]+l[!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+[]]+l[!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]])&&l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]]+l[+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]==+(!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+[]]+l[+!+[]+[!+[]+!+[]]]+l[+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(+!+[]+[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]]+l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]]])&&l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+[]]]-l[+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[+!+[]]-l[!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+[]]+l[!+[]+!+[]+!+[]+[+!+[]]]==+(+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+[]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]==+(+!+[]+[+[]+[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]])&&l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]==+(!+[]+!+[]+!+[]+[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]]+l[!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[+[]]]==-+(+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]==+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[])&&l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+[]]-l[!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]]==-+(!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[+[]]])&&l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+[+!+[]+[!+[]+!+[]+!+[]]])&&l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+[]]+l[!+[]+!+[]+!+[]]==-+(!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]-l[+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]+l[+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]==+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]])&&l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]+l[+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]]+l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+[+!+[]+[!+[]+!+[]]])&&l[+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]-l[+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]])&&l[!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]]-l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]-l[+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[+!+[]]]-l[+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]]-l[+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]==+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[+!+[]]])&&l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]+l[+[]]+l[!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==+(+!+[]+[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]])&&l[+!+[]+[!+[]+!+[]+!+[]]]+l[+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]==-+(+!+[]+[!+[]+!+[]+[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]])&&l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[+!+[]]]+l[+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]==-+(+!+[]+[+!+[]+[!+[]+!+[]+!+[]+!+[]]])&&l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+[]]]+l[+!+[]+[+!+[]]]+l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]+l[+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]==+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+[+[]]])&&l[+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]-l[+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]]+l[+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+!+[]+[+!+[]+[!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]+l[!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[+[]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+!+[]+[+[]+[!+[]+!+[]]])&&l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]==+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]])&&l[+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+[]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[+!+[]]-l[!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(!+[]+!+[]+!+[]+!+[]+!+[]+[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]])&&l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+!+[]]]-l[!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[+[]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]-l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]+l[!+[]+!+[]+[+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]==-+(+!+[]+[!+[]+!+[]])&&l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+[+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]]]-l[+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]]]-l[!+[]+!+[]+!+[]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]-l[!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]]]+l[+!+[]]-l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+[+!+[]]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[+!+[]+[+[]]]-l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+[!+[]+!+[]]]+l[!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]+l[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+l[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]-l[!+[]+!+[]+!+[]+[+!+[]]]==+(!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+[+!+[]])";
ss=deEquation(s);
document.write(ss);
</script>
           

day25 5.31

[WUSTCTF2020]level2

有殼,指令行upx -d脫殼,不知道為什麼圖形界面不行。

wctf2020{Just_upx_-d}

好,這題目,好。

[FlareOn6]Overlong

無殼。找東西。

提示i nerver broke the encoding.

unk_402008有奇怪的資料,可能是flag

v4 = sub_401160((int)Text, (int)&qiguai, 28u);
           

28位。

text128位。

a3是28。

for ( i = 0; ; ++i )
  {
    if ( i < a3 )
    {
      a2 += sub_401000(a1, a2);
      v3 = *(_BYTE *)a1++;
      if ( v3 )
        continue;
    }
    break;
  }
           

結合提示,去改a3.

.text:004011C9                 push    1Ch
           

改成qiguai的長度,20b6-2008+1=af

在od改1c為af時改了很多次,發現如果要改成兩位數字或一位數字+一位字母可以,而兩位字母不可以,加0後如果:

push 0aa

00CC11C9     68 AA000000    PUSH 0AA
           

push 0a1a

00CC11D3     68 1A0A0000    PUSH 0A1A
           

push 0ffffffaf

00CC1205     6A AF          PUSH -51
           

day26 6.1+6.2

[GWCTF 2019]re3

correct引用下面有奇怪的資料。

void __noreturn sub_402126()
{
  signed int i; // [sp+8h] [bp-48h]@4
  char s; // [sp+20h] [bp-30h]@1
  __int64 v2; // [sp+48h] [bp-8h]@1

  v2 = *MK_FP(__FS__, 40LL);
  __isoc99_scanf(4204480LL, &s);
  if ( (unsigned int)strlen(&s) != 32 )
  {
    puts("Wrong!");
    exit(0);
  }
  mprotect((void *)0x400000, 0xF000uLL, 7);
  for ( i = 0; i <= 223; ++i )
    *((_BYTE *)sub_402219 + i) ^= 0x99u;
  sub_40207B(6304112LL, 61440LL);
  sub_402219(&s);
}
           

flag32位

在Linux中,mprotect()函數可以用來修改一段指定記憶體區域的保護屬性。

函數原型如下:

#include <unistd.h>
#include <sys/mmap.h>
int mprotect(const void *start, size_t len, int prot);
           

mprotect()函數把自start開始的、長度為len的記憶體區的保護屬性修改為prot指定的值。

prot可以取以下幾個值,并且可以用“|”将幾個屬性合起來使用:

1)PROT_READ:表示記憶體段内的内容可寫;

2)PROT_WRITE:表示記憶體段内的内容可讀;

3)PROT_EXEC:表示記憶體段中的内容可執行;

4)PROT_NONE:表示記憶體段中的内容根本沒法通路。

這裡7是和chmod一樣可讀可寫可執行。

sub_402219還原idc腳本

#include <idc.idc>

static main()
{
    auto addr = 0x402219;
    auto i = 0;
    for(i=0;i<224;i++)
    {
        PatchByte(addr+i,Byte(addr+i)^0x99);
    }
}
           

auto聲明變量

PatchByte(long addr, long val)設定虛拟位址addr處的一個位元組值。

c強制轉換,p生成函數。

主函數先進入sub_40207B。

unsigned __int64 __fastcall sub_40207B(__int64 a1)
{
  char v2; // [rsp+10h] [rbp-50h]
  __int64 v3; // [rsp+20h] [rbp-40h]
  __int64 v4; // [rsp+30h] [rbp-30h]
  __int64 v5; // [rsp+40h] [rbp-20h]
  unsigned __int64 v6; // [rsp+58h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  sub_401CF9(&unk_603120, 64LL, &v2);
  sub_401CF9(&unk_603100, 20LL, &v3);
  sub_401CF9(&unk_6030C0, 53LL, &v4);
  sub_401CF9(&dword_4025C0, 256LL, &v5);
  sub_401CF9(&v2, 64LL, a1);
  return __readfsqword(0x28u) ^ v6;
}
           

__readfsqword從相對于 FS 段開頭的偏移量指定的位置讀取記憶體。

sub_401CF9是md5, 從 v6 = 0x67452301v7 = 0xEFCDAB89;v8 = 0x98BADCFE; v9 = 0x10325476;可以看出來。其中起到作用的是

sub_401CF9(&unk_603120, 64LL, &v2);
sub_401CF9(&v2, 64LL, a1);
           

unk_603120是base64表,a1是unk_603170位址,結果就是base64表兩次md5傳回unk_603170。

base64表兩次md5不行,可能改了什麼,用od結果為cb8d493521b47a4cc1ae7e62229266ce。

看過feng_2016的wp發現sub_40207B中4個md5的關系

import hashlib
s1 = b\'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\'
s2 = b\'\x00\x00\x00\x00\x96\x30\x07\x77\x2C\x61\x0E\xEE\xBA\x51\x09\x99\x19\xC4\x6D\x07\'
s3 = b\'\x03\x05\x07\x0B\x0D\x11\x13\x17\x1D\x1F\x25\x29\x2B\x2F\x35\x3B\x3D\x43\x47\x49\x4F\x53\x59\x61\x65\x67\x6B\x6D\x71\x7F\x83\x89\x8B\x95\x97\x9D\xA3\xA7\xAD\xB3\xB5\xBF\xC1\xC5\xC7\xD3\xDF\xE3\xE5\xE9\xEF\xF1\xFB\'
s4 = b\'\x78\xA4\x6A\xD7\x56\xB7\xC7\xE8\xDB\x70\x20\x24\xEE\xCE\xBD\xC1\xAF\x0F\x7C\xF5\x2A\xC6\x87\x47\x13\x46\x30\xA8\x01\x95\x46\xFD\xD8\x98\x80\x69\xAF\xF7\x44\x8B\xB1\x5B\xFF\xFF\xBE\xD7\x5C\x89\x22\x11\x90\x6B\x93\x71\x98\xFD\x8E\x43\x79\xA6\x21\x08\xB4\x49\x62\x25\x1E\xF6\x40\xB3\x40\xC0\x51\x5A\x5E\x26\xAA\xC7\xB6\xE9\x5D\x10\x2F\xD6\x53\x14\x44\x02\x81\xE6\xA1\xD8\xC8\xFB\xD3\xE7\xE6\xCD\xE1\x21\xD6\x07\x37\xC3\x87\x0D\xD5\xF4\xED\x14\x5A\x45\x05\xE9\xE3\xA9\xF8\xA3\xEF\xFC\xD9\x02\x6F\x67\x8A\x4C\x2A\x8D\x42\x39\xFA\xFF\x81\xF6\x71\x87\x22\x61\x9D\x6D\x0C\x38\xE5\xFD\x44\xEA\xBE\xA4\xA9\xCF\xDE\x4B\x60\x4B\xBB\xF6\x70\xBC\xBF\xBE\xC6\x7E\x9B\x28\xFA\x27\xA1\xEA\x85\x30\xEF\xD4\x05\x1D\x88\x04\x39\xD0\xD4\xD9\xE5\x99\xDB\xE6\xF8\x7C\xA2\x1F\x65\x56\xAC\xC4\x44\x22\x29\xF4\x97\xFF\x2A\x43\xA7\x23\x94\xAB\x39\xA0\x93\xFC\xC3\x59\x5B\x65\x92\xCC\x0C\x8F\x7D\xF4\xEF\xFF\xD1\x5D\x84\x85\x4F\x7E\xA8\x6F\xE0\xE6\x2C\xFE\x14\x43\x01\xA3\xA1\x11\x08\x4E\x82\x7E\x53\xF7\x35\xF2\x3A\xBD\xBB\xD2\xD7\x2A\x91\xD3\x86\xEB\'
s =\'\'
a = [s1,s2,s3,s4]
for i in a:
    md5 = hashlib.md5()
    md5.update(i)
    s += md5.hexdigest()
#以上步驟得到s,下面是我把它提取出來轉化為二進制了
s = b\'\x78\x45\xf7\xea\xde\x89\x33\x8a\xda\xbf\xef\x89\xbd\x6e\x9a\x5b\xe8\x4f\xed\xef\x50\x67\xcf\x85\xf5\xe4\x7f\x4f\x4b\x59\x47\xa3\xc8\x38\xba\xe0\x2e\x07\xae\x0c\x27\x6d\xfb\x2e\x53\x30\x04\xc8\x7a\xc5\xfb\xac\x91\x1f\x3b\x36\x78\x41\xf8\xdc\xec\xc9\xdb\x46\'
md5 = hashlib.md5()
md5.update(s)
print(md5.hexdigest()
#得到cb8d493521b47a4cc1ae7e62229266ce
————————————————
版權聲明:本文為CSDN部落客「feng_2016」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/feng_2016/article/details/106358117
           

接下來就是sub_402219

看到

.rodata:00000000004023A0 ; char byte_4023A0[256]
.rodata:00000000004023A0 byte_4023A0     db 63h                  ; DATA XREF: sub_4007C6+17A↑r
.rodata:00000000004023A0                                         ; sub_4007C6+18D↑r ...
.rodata:00000000004023A1                 db  7Ch ; |
.rodata:00000000004023A2                 db  77h ; w
.rodata:00000000004023A3                 db  7Bh ; {
.rodata:00000000004023A4                 db 0F2h
.rodata:00000000004023A5                 db  6Bh ; k
.rodata:00000000004023A6                 db  6Fh ; o
           

是AES的s盒。

看看aes加密後和誰比,解密flag。

from Crypto.Cipher import AES

key=\'CB8D493521B47A4CC1AE7E62229266CE\'.decode(\'hex\')
c=\'BC0AADC0147C5ECCE0B140BC9C51D52B46B2B9434DE5324BAD7FB4B39CDB4B5B\'.decode(\'hex\')
aes = AES.new(key, AES.MODE_ECB)
print(aes.decrypt(c))

           

day27 6.3

[GUET-CTF2019]number_game

__int64 v3; // ST08_8
  __int64 v5; // [rsp+10h] [rbp-30h]
  __int16 v6; // [rsp+18h] [rbp-28h]
  __int64 v7; // [rsp+20h] [rbp-20h]
  __int16 v8; // [rsp+28h] [rbp-18h]
  char v9; // [rsp+2Ah] [rbp-16h]
  unsigned __int64 v10; // [rsp+38h] [rbp-8h]

  v10 = __readfsqword(0x28u);
  v5 = 0LL;
  v6 = 0;
  v7 = 0LL;
  v8 = 0;
  v9 = 0;
  __isoc99_scanf("%s", &v5, a3);
  if ( (unsigned int)sub_4006D6(&v5) )
  {
    v3 = sub_400758(&v5, 0LL, 10LL);
    sub_400807(v3, &v7);
    v9 = 0;
    sub_400881(&v7);
    if ( (unsigned int)sub_400917() )
    {
      puts("TQL!");
      printf("flag{");
      printf("%s", &v5);
      puts("}");
    }
           

main函數裡判斷

  • 首先對輸入sub_4006D6
if ( strlen(a1) == 10 )
  {
    for ( i = 0; i <= 9; ++i )
    {
      if ( a1[i] > 52 || a1[i] <= 47 )
      {
        puts("Wrong!");
        return 0LL;
      }
    }
    result = 1LL;
  }
  else
  {
    puts("Wrong!");
    result = 0LL;
  }
  return result;
           

輸入v5 10位且47<v5[i]<=52,那就是01234

  • 接下來sub_400758
v6 = a3;
  v7 = *(_BYTE *)(a2 + a1);
  if ( v7 == \' \' || v7 == \'\n\' || a2 >= a3 )
    return 0LL;
  v4 = malloc(0x18uLL);
  v5 = v4;
  *(_BYTE *)v4 = v7;
  v4[1] = sub_400758(a1, 2 * a2 + 1, v6);
  v5[2] = sub_400758(a1, 2 * (a2 + 1), v6);
  return v5;
           

v3指派

  • sub_400807
__int64 __fastcall sub_400807(__int64 a1, __int64 a2)
{
  __int64 result; // rax

  result = a1;
  if ( a1 )
  {
    sub_400807(*(_QWORD *)(a1 + 8), a2);
    *(_BYTE *)(a2 + dword_601080++) = *(_BYTE *)a1;
    result = sub_400807(*(_QWORD *)(a1 + 16), a2);
  }
  return result;
}
           

v7 dword_601080指派v3[3]、[2]、[1]、[0](int 64)

  • sub_400881((char *)&v7);
__int64 __fastcall sub_400881(char *a1)
{
  __int64 result; // rax

  byte_601062 = *a1;
  byte_601067 = a1[1];
  byte_601069 = a1[2];
  byte_60106B = a1[3];
  byte_60106E = a1[4];
  byte_60106F = a1[5];
  byte_601071 = a1[6];
  byte_601072 = a1[7];
  byte_601076 = a1[8];
  result = (unsigned __int8)a1[9];
  byte_601077 = a1[9];
  return result;
}
           

将v7分别指派

  • sub_400917判斷
__int64 sub_400917()
{
  unsigned int v1; // [rsp+0h] [rbp-10h]
  signed int i; // [rsp+4h] [rbp-Ch]
  signed int j; // [rsp+8h] [rbp-8h]
  int k; // [rsp+Ch] [rbp-4h]

  v1 = 1;
  for ( i = 0; i <= 4; ++i )
  {
    for ( j = 0; j <= 4; ++j )
    {
      for ( k = j + 1; k <= 4; ++k )
      {
        if ( *((_BYTE *)&unk_601060 + 5 * i + j) == *((_BYTE *)&unk_601060 + 5 * i + k) )
          v1 = 0;
        if ( *((_BYTE *)&unk_601060 + 5 * j + i) == *((_BYTE *)&unk_601060 + 5 * k + i) )
          v1 = 0;
      }
    }
  }
  return v1;
}
           

數獨解出來v7=0,4,2,1,4,2,1,4,3,0

linux ida遠端調試,我行你也行。(注意版本)

day28 6.5

[2019紅帽杯]childRE

31位

sub_140001080("%s", &v13);
  v0 = -1i64;
  do
    ++v0;
  while ( *((_BYTE *)&v13 + v0) );
  if ( v0 != 31 )
  {
    while ( 1 )
      Sleep(0x3E8u);
  }
           

注意

.rdata:0000000140003438 a55565653255552 db \'55565653255552225565565555243466334653663544426565555525555222\',0
.rdata:0000000140003477                 align 8
.rdata:0000000140003478 a46200860044218 db \'(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&\',0
           
do
    {
      v11 = outputString[v10];
      v12 = v11 % 23;
      if ( a1234567890Qwer[v12] != *(_BYTE *)(v10 + 0x140003478i64) )
        _exit(v9);
      if ( a1234567890Qwer[v11 / 23] != *(_BYTE *)(v10 + 0x140003438i64) )
        _exit(v9 * v9);
      ++v9;
      ++v10;
    }
    while ( v9 < 62 );
           

相當于

a[o[i]%23]=str78[i]
a[o[i]/23] =str38[i]
0<i<62
           
"""
a[o[i]%23]=str78[i]
a[o[i]/23] =str38[i]
"""
o=""
str38="55565653255552225565565555243466334653663544426565555525555222"
str78="(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&"
a="1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;"+chr(0x27)+"A"
for i in range(62):
    m=a.find(str78[i]) 
    n =a.find(str38[i])
    o+=chr(n*23+m)
print(o) 
#private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
           

看UnDecorateSymbolName,看了百度看不懂,C++ 符号修飾和函數簽名

UnDecorateSymbolName(v2, outputString, 0x100u, 0);
           
UnDecorateSymbolName 函數反修飾指定已修飾的 C++ 符号名。
DWORD WINAPI UnDecorateSymbolName(
  _In_ PCTSTR DecoratedName,
  _Out_ PTSTR UnDecoratedName,
  _In_ DWORD UndecoratedLength,
  _In_ DWORD Flags
);
           

DecoratedName [輸入]

已修飾的 C++ 符号名。此名稱能以始終為問号 (?) 的首字元鑒别。

UnDecoratedName [輸出]

指向字元串緩沖區的指針,該緩沖區接收未修飾的名字。

UndecoratedLength [輸入]

UnDecoratedName 緩沖區的大小,為字元數。

Flags [輸入]

用于反修飾已修飾名稱的方式的選項。此參數能為零或更多個下列值

現在要v2的值,C++編譯時函數名修飾約定規則(很具體),MFC提供的宏,extern "C"的作用

?My_Aut0_PWN@R0Pxx@@AAEPADPAE

用x64dbg調試

寫腳本把字元串轉一下得到flag,再md5.

看别人的wp中UnDecorateSymbolName可以這樣,其中注意是char* My_Aut0_PWN不是char My_Aut0_PWN

wp

#include<iostream>
#include <stdio.h>
using namespace std;

class ROPxx {
public:
    ROPxx() {
        unsigned char a;
        My_Aut0_PWN(&a);
    }

private:
    char* My_Aut0_PWN(unsigned char*) {
        printf("%s", __FUNCDNAME__);
        return 0;
    }
};
int main() {
    new ROPxx();
    getchar();
    return 0;
}
           

day29 6.6

[MRCTF2020]Xor

ida編碼格式改utf-8,一開始英文亂碼。

sub_401020輸出

sub_401050輸入

byte_4212C0輸入,27位

比較函數

v1 = 0;
  do
  {
    if ( ((unsigned __int8)v1 ^ (unsigned __int8)byte_4212C0[v1]) != byte_41EA08[v1] )
      goto LABEL_6;
    ++v1;
  }
  while ( v1 < 0x1B );
  printf((int)"Right!\n");
           

((unsigned int8)v1 ^ (unsigned int8)byte_4212C0[v1]) != byte_41EA08[v1]

byte_41EA08是

.rdata:0041EA08 byte_41EA08     db \'M\'                  
.rdata:0041EA09 aSawbFxzJTqjNBp db \'SAWB~FXZ:J:`tQJ"N@ bpdd}8g\',0
           
s="MSAWB~FXZ:J:`tQJ\"N@ bpdd}8g"
flag=""
for i in range(27):
    flag+=chr(ord(s[i])^i)
print flag

           

findKey

全p一下,flag字元串位置

void __usercall __noreturn sub_401A37(int a1@<ebp>)
{
  SetWindowTextA(*(HWND *)(a1 + 8), "flag{}");
  MessageBoxA(*(HWND *)(a1 + 8), "Are you kidding me?", "^_^", 0);
  ExitProcess(0);
}
           

看一下sub_401A37的調用,。。。無。有點問題。

看了wp才知道問題所在,兩個push,nop一個,p一下。

.text:00401918                 push    offset byte_428C54
.text:0040191D
.text:0040191D loc_40191D:                             ; CODE XREF: .text:0040193D↓j
.text:0040191D                 push    offset byte_428C54
           
  • 1
strcpy(&v21, "0kk`d1a`55k222k2a776jbfgd`06cjjb");
strcpy(v17, "SS");
sub_401005(v17, (int)&v21, v9);
           
//sub_401005--異或
unsigned int __cdecl sub_401590(LPCSTR lpString, int a2, int a3)
{
  unsigned int result; // eax
  unsigned int i; // [esp+4Ch] [ebp-Ch]
  unsigned int v5; // [esp+54h] [ebp-4h]

  v5 = lstrlenA(lpString);
  for ( i = 0; ; ++i )
  {
    result = i;
    if ( i >= a3 )
      break;
    *(_BYTE *)(i + a2) ^= lpString[i % v5];
  }
  return result;
}
           
v21="0kk`d1a`55k222k2a776jbfgd`06cjjb"
r=""
for i in v21:
    r += chr(ord(i)^ord(\'S\'))
print r
#c8837b23ff8aaa8a2dde915473ce0991
           
  • 2
_strcmpi((const char *)&String1, &v21)
           

v21是c8837b23ff8aaa8a2dde915473ce0991,找string1是什麼

發現string1結構CryptCreateHash。在附件找到0x8003u是md5

CryptCreateHash(phProv, 0x8003u, 0, 0, &phHash)
           

解密123321

  • 3

最後有一個

memcpy(&v16, &unk_423030, 0x32u);
v10 = strlen(&v16);
sub_401005(&v25, (int)&v16, v10);
           

v25是string1未加密的,就是123321

a=[0x57 ,0x5E ,0x52 ,0x54,0x49 ,0x5F,1,0x6D ,0x69,0x46 ,2,0x6E,0x5F,2,0x6C ,0x57 ,0x5B,0x54 ,0x4C]
b="123321"
flag=""
for i in range(len(a)):
    flag+=chr(ord(b[i%6])^a[i])
print flag

           

day30 6.9

打了學校的awd,專注拿flag,沒有攪屎,以至于後期flag少了很多。還是沒什麼經驗。

[WUSTCTF2020]level3

看字元串是變換的base64

這是加密後的flag

d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD==
           

進入base64_encode檢視

base64_table是正常的

emmm,再找找。肯定對base64_table做了變換,x一下找到

__int64 O_OLookAtYou()
{
  char v0; // ST03_1
  __int64 result; // rax
  signed int i; // [rsp+2h] [rbp-4h]

  for ( i = 0; i <= 9; ++i )
  {
    v0 = base64_table[i];
    base64_table[i] = base64_table[19 - i];
    result = 19 - i;
    base64_table[result] = v0;
  }
  return result;
}
           

換位置。

#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
    char base64_table[100]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    char v0; // ST03_1
    int result; // rax
    signed int i; // [rsp+2h] [rbp-4h]

    for ( i = 0; i <= 9; ++i )
    {
        v0 = base64_table[i];
        base64_table[i] = base64_table[19 - i];
        result = 19 - i;
        base64_table[result] = v0;
    }
    cout<<base64_table<<endl;
    return result;
}
//TSRQPONMLKJIHGFEDCBAUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
           
import base64
eflag="d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD=="
be64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
base64="TSRQPONMLKJIHGFEDCBAUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
flag=\'\'
for i in eflag:
    if i =="=":
        flag+="="
    else:
        flag+=be64[base64.find(i)]
print flag
print base64.b64decode(flag)
#d2N0ZjIwMjB7QmFzZTY0X2lzX3RoZV9zdGFydF9vZl9yZXZlcnNlfQ==
           

不知道為什麼python報錯\'str\' object has no attribute \'b64decode\'

day31 6.23

放假了,emm。好久沒刷題了

[MRCTF2020]hello_world_go

打開看就很奇怪,字元串一堆讓人眼花缭亂。

其中runtime_staticbytes是包含ascii表,看引用runtime_intstring。emm

看main函數裡unk_4D3C58找到flag

day32 7.1

[FlareOn5]Minesweeper Championship Registration

掃雷錦标賽注冊,emm

Welcome to the Fifth Annual Flare-On Challenge! The Minesweeper World Championship is coming soon and we found the registration app. You weren\'t officially invited but if you can figure out what the code is you can probably get in anyway. Good luck!

Hint:本題解出相應字元串後請用flag{}包裹,形如:flag{[email protected]}

java的逆向,百度一下下一個jd-gui,官網打不開,去github

[網鼎杯 2020 青龍組]singal

無殼32位,輸入字元串

read

函數限定15位

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+18h] [ebp-1D4h]

  __main();
  qmemcpy(&v4, &unk_403040, 0x1C8u);
  vm_operad(&v4, 114);
  puts("good,The answer format is:flag {}");
  return 0;
}
           

主要就是

vm_operad

int __cdecl vm_operad(int *a1, int a2)
{
  int result; // eax
  char v3[100]; // [esp+13h] [ebp-E5h]
  char v4[100]; // [esp+77h] [ebp-81h]
  char v5; // [esp+DBh] [ebp-1Dh]
  int v6; // [esp+DCh] [ebp-1Ch]
  int v7; // [esp+E0h] [ebp-18h]
  int v8; // [esp+E4h] [ebp-14h]
  int v9; // [esp+E8h] [ebp-10h]
  int v10; // [esp+ECh] [ebp-Ch]

  v10 = 0;
  v9 = 0;
  v8 = 0;
  v7 = 0;
  v6 = 0;
  while ( 1 )
  {
    result = v10;
    if ( v10 >= a2 )
      return result;
    switch ( a1[v10] )                          // v10 是a1坐标
    {
      case 1:
        v4[v7] = v5;                            // v7 是v4坐标
        ++v10;
        ++v7;
        ++v9;
        break;                                  // v9 是v3坐标,v3是輸入
      case 2:
        v5 = a1[v10 + 1] + v3[v9];
        v10 += 2;
        break;
      case 3:
        v5 = v3[v9] - LOBYTE(a1[v10 + 1]);
        v10 += 2;
        break;
      case 4:
        v5 = a1[v10 + 1] ^ v3[v9];
        v10 += 2;
        break;
      case 5:
        v5 = a1[v10 + 1] * v3[v9];
        v10 += 2;
        break;
      case 6:
        ++v10;
        break;
      case 7:
        if ( v4[v8] != a1[v10 + 1] )
        {
          printf("what a shame...");
          exit(0);
        }
        ++v8;
        v10 += 2;
        break;
      case 8:
        v3[v6] = v5;
        ++v10;
        ++v6;
        break;
      case 10:
        read(v3);
        ++v10;
        break;
      case 11:
        v5 = v3[v9] - 1;
        ++v10;
        break;
      case 12:
        v5 = v3[v9] + 1;
        ++v10;
        break;
      default:
        continue;
    }
  }
}
           

unk_403040

第一個數就是10,執行了

read

我淦,我的儲存呢,隻有未完成的了

from z3 import*
n=0
def tf(flag):
	global n
	if flag==0:
		return \'rflag[\'+str(n)+\']\'
	else:
		return \'\'
a=\'\'\'
0A 00 00 00 04 00 00 00  10 00 00 00 08 00 00 00
03 00 00 00 05 00 00 00  01 00 00 00 04 00 00 00
20 00 00 00 08 00 00 00  05 00 00 00 03 00 00 00
01 00 00 00 03 00 00 00  02 00 00 00 08 00 00 00
0B 00 00 00 01 00 00 00  0C 00 00 00 08 00 00 00
04 00 00 00 04 00 00 00  01 00 00 00 05 00 00 00
03 00 00 00 08 00 00 00  03 00 00 00 21 00 00 00
01 00 00 00 0B 00 00 00  08 00 00 00 0B 00 00 00
01 00 00 00 04 00 00 00  09 00 00 00 08 00 00 00
03 00 00 00 20 00 00 00  01 00 00 00 02 00 00 00
51 00 00 00 08 00 00 00  04 00 00 00 24 00 00 00
01 00 00 00 0C 00 00 00  08 00 00 00 0B 00 00 00
01 00 00 00 05 00 00 00  02 00 00 00 08 00 00 00
02 00 00 00 25 00 00 00  01 00 00 00 02 00 00 00
36 00 00 00 08 00 00 00  04 00 00 00 41 00 00 00
01 00 00 00 02 00 00 00  20 00 00 00 08 00 00 00
05 00 00 00 01 00 00 00  01 00 00 00 05 00 00 00
03 00 00 00 08 00 00 00  02 00 00 00 25 00 00 00
01 00 00 00 04 00 00 00  09 00 00 00 08 00 00 00
03 00 00 00 20 00 00 00  01 00 00 00 02 00 00 00
41 00 00 00 08 00 00 00  0C 00 00 00 01 00 00 00
07 00 00 00 22 00 00 00  07 00 00 00 3F 00 00 00
07 00 00 00 34 00 00 00  07 00 00 00 32 00 00 00
07 00 00 00 72 00 00 00  07 00 00 00 33 00 00 00
07 00 00 00 18 00 00 00  07 00 00 00 A7 FF FF FF
07 00 00 00 31 00 00 00  07 00 00 00 F1 FF FF FF
07 00 00 00 28 00 00 00  07 00 00 00 84 FF FF FF
07 00 00 00 C1 FF FF FF  07 00 00 00 1E 00 00 00
07 00 00 00 7A 00 00 00  00 00 00 00 00 00 00 00
\'\'\'

listcz= a.replace(\'00\',\'\').replace(\'\n\',\' \').split()
print listcz
enflag=[]
for i in range(len(listcz)):
	if listcz[i]==\'07\':
		enflag.append(listcz[i+1])
print enflag
print len(enflag)
print tf(0)

cz=[\'04\', \'10\', \'08\', \'03\', \'05\', \'01\', \'04\', \'20\', \'08\', \'05\', \'03\', \'01\', \'03\', \'02\', \'08\', \'0B\', \'01\', \'0C\', \'08\', \'04\', \'04\', \'01\', \'05\', \'03\', \'08\', \'03\', \'21\', \'01\', \'0B\', \'08\', \'0B\', \'01\', \'04\', \'09\', \'08\', \'03\', \'20\', \'01\', \'02\', \'51\', \'08\', \'04\', \'24\', \'01\', \'0C\', \'08\', \'0B\', \'01\', \'05\', \'02\', \'08\', \'02\', \'25\', \'01\', \'02\', \'36\', \'08\', \'04\', \'41\', \'01\', \'02\', \'20\', \'08\', \'05\', \'01\', \'01\', \'05\', \'03\', \'08\', \'02\', \'25\', \'01\', \'04\', \'09\', \'08\', \'03\', \'20\', \'01\', \'02\', \'41\', \'08\', \'0C\', \'01\']
rflag = [0]*15
\'\'\'
for i in range(15):
    rflag[i] = BitVec(\'rflag[\'+str(i)+\']\',64)
s=Solver() 
\'\'\'
str1=\'s.add(\'
i=0
print len(cz)
flag=0

while i==0:

	print i
	if cz[i]==\'04\':
		str1+=tf(flag)+\'^\'+\'0x\'+cz[i+1]
		flag=1
		i+=2
	elif cz[i]==\'02\':
		str1+=tf(flag)+\'+\'+\'0x\'+cz[i+1]
		flag=1
		i+=2
	elif cz[i]==\'03\':
		str1+=tf(flag)+\'+\'+\'0x\'+cz[i+1]
		flag=1
		i+=2
	elif cz[i]==\'05\':
		str1+=tf(flag)+\'*\'+\'0x\'+cz[i+1]
		flag=1
		i+=2
	elif cz[i]==\'0c\':
		str1+=tf(flag)+\'+\'+cz[i+1]
		flag=1
		i+=2
	elif cz[i]==\'0B\':
		str1+=tf(flag)+\'-\'+cz[i+1]
		flag=1
		i+=2
	elif cz[i]==\'08\':
		i+=1
	elif cz[i]==\'01\':
		print n
		str1+=\')\'
		print str1 
		#eval(str)
		n+=1
		flag=0
		str1=str1[:6]

           
re的刷題0

angr

https://blog.csdn.net/Breeze_CAT/article/details/106139253

import angr

p = angr.Project(\'./signal.exe\')   #指定angr跑的程式
state = p.factory.entry_state()    #建立一個SimState的對象,得到一個初始化到二進制入口函數的SimState對象。
simgr = p.factory.simgr(state)   #建立simulation manager,angr的主要入口

simgr.explore(find=0x004017A5 ,avoid=0x004016E6)  #争取跑到輸出成功的位址,避免跑到輸出wrong的位址
flag = simgr.found[0].posix.dumps(0)[:15]     #得到flag
print(flag)

           

day33 7.2

[MRCTF2020]PixelShooter

像素射手

安卓逆向

内容入口 含義解釋
AndroidManifest.xml 二進制xml檔案,提供裝置運作應用程式所需的各種資訊
classes.dex 以dex格式編譯的應用程式代碼
resources.arsc 包含預編譯應用程式資源的二進制XML檔案
res/ 此檔案夾中包含未編譯到resources.arsc檔案中的資源
assets/ 此檔案夾包含應用程式的原始資源,由AssetManager提供對這些資産檔案的通路
META-INF/ 它包含MANIFEST.MF檔案,該檔案存儲有關JAR内容的中繼資料。APK簽名也存儲在此檔案夾中
lib/ 此檔案夾包含已編譯的代碼,例如本地代碼庫

進去打飛機。

unity召喚dnspy,找到Assembly-CSharp,gameover

[RoarCTF2019]polyre

[root@lalala re]# ./attachment
Input:flag
Wrong!
           

ida裡看一下,wdf

看wp知道是控制流平坦化,angr環境配半天,docker國内鏡像沒有,慢的一p

day34 7.3

[GKCTF2020]Chelly\'s identity

hi.Are you know of chelly?
Can you speak chelly\'s identity?
if you can, I will give you flag.
Give your answer:
my wife
bad long!
請按任意鍵繼續. . .
           

題目錯了

flag是16位,可以通過ida看出來或手動試試

  • 對輸入(v43)動手腳
for ( i = 0; ; ++i )
  {
    v17 = sub_631771(&v43);
    if ( v17 == sub_6311D6(&v42) )
      break;
    v40 = *(char *)sub_631528(i);
    sub_6315D2(&v40);
  }
           

sub_631771

sub_6311D6

最後都調用了

sub_6314DD

先看判斷

sub_411852

sub_4112F8

應該是開辟空間的

day35 7.8

challenge1

v6 = "x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q";
  WriteFile(hFile, "Enter password:\r\n", 0x12u, &NumberOfBytesWritten, 0);
  ReadFile(v7, &Buffer, 0x80u, &NumberOfBytesWritten, 0);
  v5 = sub_401260((int)&Buffer, NumberOfBytesWritten - 2);
  if ( !strcmp(v5, v6) )
    WriteFile(hFile, "Correct!\r\n", 0xBu, &NumberOfBytesWritten, 0);
  else
    WriteFile(hFile, "Wrong password\r\n", 0x11u, &NumberOfBytesWritten, 0);
           

sub_401260

很明顯是一個base64,換表

import base64
eflag="x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q"
be64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
base64="ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/"
flag=""
for i in eflag:
    if i =="=":
        flag+="="
    else:
        flag+=be64[base64.find(i)]
print flag
flag= base64.b64decode(flag)
print flag
           

[Zer0pts2020]easy strcmp

main函數很簡單,就是輸入strcmp zer0pts{********CENSORED********}

找到對輸入操作的函數

__int64 __fastcall sub_6EA(__int64 a1, __int64 a2)
{
  int i; // [rsp+18h] [rbp-8h]
  int v4; // [rsp+18h] [rbp-8h]
  int j; // [rsp+1Ch] [rbp-4h]

  for ( i = 0; *(_BYTE *)(i + a1); ++i )
    ;
  v4 = (i >> 3) + 1;
  for ( j = 0; j < v4; ++j )
    *(_QWORD *)(8 * j + a1) -= qword_201060[j];
  return qword_201090(a1, a2);
}
           
qword_201060    dq 0, 410A4335494A0942h, 0B0EF2F50BE619F0h, 4F0A3A064A35282Bh
           

第一個for循環獲得輸入位數,第二個for循環将輸入分為8位一組減去一個數,是以zer0pts{-0還是zer0pts{。

寫腳本

import binascii
enflag="********CENSORED********"
num=[0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B]
print len(enflag)

flag=\'\'
for i in range(3):
	print i
	print enflag[8*i:8*i+8][::-1]
	t = binascii.b2a_hex(enflag[8*i:8*i+8][::-1])
	a=hex(num[i]+int(t,16))
	flag+= binascii.a2b_hex(str(a).replace(\'0x\',\'\').replace(\'L\',\'\'))[::-1]
	
print flag
           

一開始沒有考慮大小端問題,中間CENSORED出錯了。

day36 7.13

[安洵杯 2019]game

控制流平坦化,惡心

[ACTF新生賽2020]Universe_final_answer

判斷語句

if ( sub_860(&v5) )
  {
    sub_C50(&v5, &v4);
    __printf_chk(1LL, "Judgement pass! flag is actf{%s_%s}\n", &v5);
  }
           

函數

sub_860

一大堆判斷

if ( -85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613 )
  {
    v11 = a1[9];
    if ( 30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400
      && -103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (v6 << 6) - 120 * v9 == -10283
      && 71 * v6 + (v7 << 7) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855
      && 5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944
      && -54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222
      && -83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258
      && 81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559
      && 101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308 )
    {
      result = 99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697;
    }
  }
           

z3求一下

#!/usr/bin/python
# -*- coding: utf-8 -*-
from z3 import *

#申明未知量
v1 = BitVec(\'v1\',10)
v2 = BitVec(\'v2\',10)
v3 = BitVec(\'v3\',10)
v4 = BitVec(\'v4\',10)
v5 = BitVec(\'v5\',10)
v6 = BitVec(\'v6\',10)
v7 = BitVec(\'v7\',10)
v8 = BitVec(\'v8\',10)
v9 = BitVec(\'v9\',10)
v11 = BitVec(\'v11\',10)
s=Solver() # 建立限制求解器

# 添加限制條件
s.add( -85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613 )
s.add( 30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400 )
s.add( -103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (v6 << 6) - 120 * v9 == -10283 )
s.add( 71 * v6 + (v7 << 7) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855 )
s.add( 5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944 )
s.add( -54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222 )
s.add( -83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258 )
s.add( 81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559 )
s.add( 101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308 )
s.add( 99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697 )

# 檢查是否有解

print s.check()

m=s.model()
for d in m.decls():   # decls()傳回model包含了所有符号的清單
    print("%s = %s" % (d.name(),m[d]))
           

注意位置,這是一半:F0uRT_y7w@

淦,裡面還有6、7位置

第二部分就是9異或字元串

再将數字變為字元串

f1=\'F0uRTy_7w@\'
f2=9
for i in f1:
	f2^=ord(i)
print f1+\'_\'+str(f2)
           

day37 7.31

[ACTF新生賽2020]Oruga

tell me the flag

printf("Tell me the flag:", 0LL);
  scanf("%s", s);
  strcpy(s2, "actf{");
  LODWORD(v4) = 0;
  while ( (signed int)v4 <= 4 )
  {
    *((_BYTE *)&v4 + (signed int)v4 + 4) = s[(signed int)v4];
    LODWORD(v4) = v4 + 1;
  }
  v8 = 0;
  if ( !strcmp((const char *)&v4 + 4, s2) )
  {
    if ( (unsigned __int8)sub_78A(s, s2) )
      printf("That\'s True Flag!", v6);
    else
      printf("don\'t stop trying...", v7);
    result = 0LL;
  }
  else
  {
    printf("Format false!", s2, v5);
    result = 0LL;
  }
           

其中

if ( !strcmp((const char *)&v4 + 4, s2) )

就是判斷flag格式是否為

actf{

,然後進入

sub_78A

看到

if ( *(_BYTE *)(v3 + a1) != \'W\' || v4 == -16 )
    {
      if ( *(_BYTE *)(v3 + a1) != \'E\' || v4 == 1 )
      {
        if ( *(_BYTE *)(v3 + a1) != \'M\' || v4 == 16 )
        {
          if ( *(_BYTE *)(v3 + a1) != \'J\' || v4 == -1 )
            return 0LL;
          v4 = -1;
        }
        else
        {
          v4 = 16;
        }
      }
      else
      {
        v4 = 1;
      }
    }
    else
    {
      v4 = -16;
    }
           

這樣子就感覺是個迷宮,W上,E右,M下,J左。把byte_201020資料提取,一行16個。奇怪的是一組判斷

while ( !byte_201020[v2] )
    {
      if ( v4 == -1 && !(v2 & 0xF) )
        return 0LL;
      if ( v4 == 1 && v2 % 16 == 15 )
        return 0LL;
      if ( v4 == 16 && (unsigned int)(v2 - 240) <= 15 )
        return 0LL;
      if ( v4 == -16 && (unsigned int)(v2 + 15) <= 30 )
        return 0LL;
      v2 += v4;
    }
           

前4個if應該是判斷出界,後面v2+=v4就是當byte_201020[v2]==0時可以繼續走。

走到21h結束

00 00 00 00 23 00 00 00 00 00 00 00 23 23 23 23
    00 00 00 23 23 00 00 00 4F 4F 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 4F 4F 00 50 50 00 00 00
    00 00 00 4C 00 4F 4F 00 4F 4F 00 50 50 00 00 00
    00 00 00 4C 00 4F 4F 00 4F 4F 00 50 00 00 00 00
    00 00 4C 4C 00 4F 4F 00 00 00 00 50 00 00 00 00
    00 00 00 00 00 4F 4F 00 00 00 00 50 00 00 00 00
    23 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 23 00 00 00
    00 00 00 00 00 00 4D 4D 4D 00 00 00 23 00 00 00
    00 00 00 00 00 00 00 4D 4D 4D 00 00 00 00 45 45
    00 00 00 30 00 4D 00 4D 00 4D 00 00 00 00 45 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 45 45
    54 54 54 49 00 4D 00 4D 00 4D 00 00 00 00 45 00
    00 54 00 49 00 4D 00 4D 00 4D 00 00 00 00 45 00
    00 54 00 49 00 4D 00 4D 00 4D 21 00 00 00 45 45

           

flag{MEWEMEWJMEWJM}

day38 8.1

[FlareOn5]Ultimate Minesweeper

You hacked your way into the Minesweeper Championship, good job. Now its time to compete. Here is the Ultimate Minesweeper binary. Beat it, win the championship, and we\'ll move you on to greater challenges.

Hint:本題解出相應字元串後請用flag{}包裹,形如:flag{[email protected]}

900個格子,897個雷,好玩。這是net程式,用dnspy打開,這個題目應該是讓我們去修改雷個數或什麼東西。

getkey

裡有個數組很像flag

private string GetKey(List<uint> revealedCells)
		{
			revealedCells.Sort();
			Random random = new Random(Convert.ToInt32(revealedCells[0] << 20 | revealedCells[1] << 10 | revealedCells[2]));
			byte[] array = new byte[32];
			byte[] array2 = new byte[]
			{
				245,
				75,
				65,
				142,
				68,
				71,
				100,
				185,
				74,
				127,
				62,
				130,
				231,
				129,
				254,
				243,
				28,
				58,
				103,
				179,
				60,
				91,
				195,
				215,
				102,
				145,
				154,
				27,
				57,
				231,
				241,
				86
			};
			random.NextBytes(array);
			uint num = 0U;
			while ((ulong)num < (ulong)((long)array2.Length))
			{
				byte[] array3 = array2;
				uint num2 = num;
				array3[(int)num2] = (array3[(int)num2] ^ array[(int)num]);
				num += 1U;
			}
			return Encoding.ASCII.GetString(array2);
		}
           

random.NextBytes(array);

有随機數,放棄。

AllocateMemory

是生成雷區

private void AllocateMemory(MineField mf)
		{
			for (uint num = 0U; num < MainForm.VALLOC_NODE_LIMIT; num += 1U)
			{
				for (uint num2 = 0U; num2 < MainForm.VALLOC_NODE_LIMIT; num2 += 1U)
				{
					bool flag = true;
					uint r = num + 1U;
					uint c = num2 + 1U;
					if (this.VALLOC_TYPES.Contains(this.DeriveVallocType(r, c)))
					{
						flag = false;
					}
					mf.GarbageCollect[(int)num2, (int)num] = flag;
				}
			}
		}
           

if (this.VALLOC_TYPES.Contains(this.DeriveVallocType(r, c)))

改成

if ((r == 1U && c == 1U) || (r == 1U && c == 2U) || (r == 1U && c == 3U))

後安全區改為(1.1)(1.2)(1.3)但最後輸出flag錯誤,這是因為

random.NextBytes(array);

随機數用到了安全坐标。

再看

getkey

的引用

private void SquareRevealedCallback(uint column, uint row)
{
	if (this.MineField.BombRevealed)
	{
		this.stopwatch.Stop();
		Application.DoEvents();
		Thread.Sleep(1000);
		new FailurePopup().ShowDialog();
		Application.Exit();
	}
	this.RevealedCells.Add(row * MainForm.VALLOC_NODE_LIMIT + column);
	if (this.MineField.TotalUnrevealedEmptySquares == 0)
	{
		this.stopwatch.Stop();
		Application.DoEvents();
		Thread.Sleep(1000);
		new SuccessPopup(this.GetKey(this.RevealedCells)).ShowDialog();
		Application.Exit();
	}
}
           

很明顯兩個判斷,第一個是雷。先改程式,把第一個

Thread.Sleep(1000);new FailurePopup().ShowDialog();Application.Exit();

删了就可以找三個點。

但是這樣還是很麻煩,需要一個一個點,根據Harmonica_11可以在AllocateMemory添加

Console.Write(r);
Console.Write(c);//斷點下在這
           

[安洵杯 2019]game

主要函數

while ( 1 )
  {
    while ( 1 )
    {
      while ( v7 == -2071121728 )
      {
        v4 = blank_num((int (*)[9])sudoku);
        v5 = (signed int *)mem_alloc(v4);
        trace((__int64)sudoku, v5, v4);
        check((int (*)[9])sudoku);
        check1(&v8);
        check3(&v8);
        v9 = 0;
        v7 = -303742386;
      }
      if ( v7 != -1804515313 )
        break;
      v3 = -2071121728;
      if ( v10 )
        v3 = 664169471;
      v7 = v3;
    }
    if ( v7 == -303742386 )
      break;
    if ( v7 == 664169471 )
    {
      printf("error");
      check((int (*)[9])sudoku);
      v9 = 0;
      v7 = -303742386;
    }
  }
           

進入

blank_num

,理清流程

v6 = 0;
  v8 = 0;
  v5 = 1046773218;
  while ( 1 )
  {
    while ( v5 == -1892951115 )
    {
      v7 = 0;
      v5 = -1048142948;
    }
    if ( v5 == -1585203536 )                    // 退出
      break;
    switch ( v5 )
    {
      case -1237447983:
        v5 = 1058605341;
        break;
      case -1048142948:
        v2 = -1237447983;                       // 2.
                                                // v7>9 ++v8 回到1
        if ( v7 < 9 )                           // v7<9 進入3
          v2 = 1501457574;
        v5 = v2;
        break;
      case -1026222996:
        ++v7;
        v5 = -1048142948;
        break;
      case -516195663:
        ++v6;
        v5 = 710936108;
        break;
      case 710936108:
        v5 = -1026222996;
        break;
      case 1046773218:                          // 1.
        v1 = -1585203536;                       // v8>9 退出
        if ( v8 < 9 )                           // v8<9 設v7=0,進入2
          v1 = -1892951115;
        v5 = v1;
        break;
      case 1058605341:
        ++v8;
        v5 = 1046773218;
        break;
      case 1501457574:                          // 3.
        v3 = 710936108;                         // sudoku[9*v8+v7]!=0 ++v7 回到2
        if ( !(*a1)[9 * v8 + v7] )              // sudoku[9*v8+v7] =0 ++v6 ++v7 回到2
          v3 = -516195663;
        v5 = v3;
        break;
    }
  }
  return v6;
           

其實到最後就是

if ( !(*a1)[9 * v8 + v7] )

然後傳回了數獨數組中0的個數,動調後發現傳回值為40。

trace((__int64)sudoku, v5, v4);

check((int (*)[9])sudoku);

感覺沒用,一來它們的傳回值沒有用,二沒有改變sudoku,pass。(這個不清楚)

check1

while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            while ( 1 )
            {
              while ( 1 )
              {
                while ( v10 == -2084833488 )
                {
                  v8 = strlen(a1);
                  v9 = -67245798;
                  if ( v12 < v8 )               // v12<flag長度
                    v9 = 1974939745;
                  v10 = v9;
                }
                if ( v10 != -1988665894 )
                  break;
                v12 = 0;
                v10 = -2084833488;
              }
              if ( v10 != -1393133668 )
                break;
              v5 = strlen(a1);
              v6 = -1988665894;                 // v12>flag長度 v12=0 進入4
              if ( v12 < v5 )
                v6 = -1018472136;
              v10 = v6;
            }
            if ( v10 != -1018472136 )
              break;
            v7 = a1[v12];
            a1[v12] = a1[v12 + 1];
            a1[v12 + 1] = v7;
            v10 = -146751883;
          }
          if ( v10 != -831482631 )
            break;
          ++v12;
          v10 = -2084833488;
        }
        if ( v10 != -291294424 )
          break;
        ++v11;
        ++v12;
        v10 = 1519002972;
      }
      if ( v10 != -146751883 )
        break;
      v12 += 2;
      v10 = -1393133668;
    }
    result = (unsigned int)(v10 + 67245798);
    if ( v10 == -67245798 )
      break;
    switch ( v10 )
    {
      case 75381312:                            // 2.
        v4 = a1[v12];                           // flag[v11] [v12]互換 (前後部分)
        a1[v12] = a1[v11];
        a1[v11] = v4;
        v10 = -291294424;                       // ++v11 ++v12 回1
        break;
      case 1519002972:                          // 1.
        v2 = strlen(a1);                        // v2=flag長度
        v3 = 1555725255;                        // v11>flag長度一半 v12=0 進入3
        if ( v11 < v2 >> 1 )                    // v11<flag長度一半 進入2
          v3 = 75381312;
        v10 = v3;
        break;
      case 1555725255:                          // 3.
        v12 = 0;                                // flag[v12][v12+1]互換,v12+=2...... 當全部換完後進入4 v12=0
        v10 = -1393133668;
        break;
      case 1974939745:                          // 4.
        a1[v12] = (a1[v12] & 0xF3 | ~a1[v12] & 0xC) - 20;
        v10 = -831482631;
        break;
    }
  }
           

是以check1将flag先前後互換、兩位互換,最後a1[v12] = (a1[v12] & 0xF3 | ~a1[v12] & 0xC) - 20;

check3

沒什麼用,隻有裡面

check2

有用

s = a1;
  v13 = 0;
  v12 = 1;
  v15 = 0;
  v11 = -2671583;
  while ( 1 )                                   // 1.
  {
    while ( 1 )
    {
      while ( 1 )                               // 3.
      {
        while ( 1 )
        {
          while ( 1 )
          {
            while ( 1 )
            {
              while ( 1 )                       // 4.
              {
                while ( 1 )
                {
                  while ( 1 )
                  {
                    while ( 1 )
                    {
                      while ( 1 )
                      {
                        while ( 1 )
                        {
                          while ( 1 )
                          {
                            while ( 1 )
                            {
                              while ( 1 )
                              {
                                while ( v11 == -2119125118 )
                                {
                                  ++v15;
                                  v11 = -94879051;
                                }
                                if ( v11 != -1998111552 )
                                  break;
                                v6 = 396170963;
                                if ( v15 < 9 )
                                  v6 = -512482015;
                                v11 = v6;
                              }
                              if ( v11 != -1695072055 )
                                break;
                              ++v15;
                              v11 = -1998111552;
                            }
                            if ( v11 != -1658909923 )
                              break;
                            v8 = -1129833658;
                            if ( D0g3[9 * v15 + v14] != sudoku[9 * v15 + v14] )
                              v8 = -528396247;
                            v11 = v8;
                          }
                          if ( v11 != -1613667829 )
                            break;
                          v11 = -2119125118;
                        }
                        if ( v11 != -1369143226 )
                          break;
                        v14 = 0;
                        v11 = -740861019;
                      }
                      if ( v11 != -1244045086 )
                        break;
                      D0g3[9 * v15 + v14] = v16[v13++];
                      v11 = 1611237474;
                    }
                    if ( v11 != -1129833658 )
                      break;
                    v11 = -90011013;
                  }
                  if ( v11 != -740861019 )
                    break;                      // 4.
                  v4 = -1613667829;             // v14>9 ++v15 回3.
                  if ( v14 < 9 )                // v14<9 進入5
                    v4 = 705300330;
                  v11 = v4;
                }
                if ( v11 != -528396247 )
                  break;
                v12 = 0;
                v11 = 1954800504;
              }
              if ( v11 != -512482015 )
                break;
              v14 = 0;
              v11 = 564268595;
            }
            if ( v11 != -334121999 )
              break;
            v15 = 0;
            v11 = -1998111552;
          }
          if ( v11 != -94879051 )
            break;                              // 3.
          v3 = -334121999;
          if ( v15 < 9 )                        // v15<9 v14=0 進入4
            v3 = -1369143226;
          v11 = v3;
        }
        if ( v11 != -90011013 )
          break;
        ++v14;
        v11 = 564268595;
      }
      if ( v11 != -2671583 )
        break;                                  // 1.
      v1 = strlen(s);
      v2 = 2101131376;                          // v15>flag v15=0 列印回車 進入3.
      if ( v15 < v1 )                           // v15<flag 進入2.
        v2 = 441246003;
      v11 = v2;
    }
    if ( v11 == 396170963 )
      break;
    switch ( v11 )
    {
      case 430996436:
        ++v15;
        v11 = -2671583;
        break;
      case 441246003:                           // 2.
        v16[v15] = s[v15] - 232084296 + 232084248;// v16[v15]=s[v15]-48
        v11 = 430996436;                        // ++v15 回1.
        break;
      case 564268595:
        v7 = 1954800504;
        if ( v14 < 9 )
          v7 = -1658909923;
        v11 = v7;
        break;
      case 705300330:                           // 5.
        v5 = 1611237474;                        // D0g3[9 * v15 + v14]!=0 進入6
        if ( !D0g3[9 * v15 + v14] )             // D0g3[9 * v15 + v14]=0 D0g3[9 * v15 + v14] = v16[v13++]; 進入6
          v5 = -1244045086;
        v11 = v5;
        break;
      case 1611237474:                          // 6.
        v11 = 2119231421;                       // ++v14 回4
        break;
      case 1908623879:
        v11 = -1695072055;
        break;
      case 1954800504:
        v9 = 1908623879;
        if ( !v12 )
          v9 = 2014359934;
        v11 = v9;
        break;
      case 2014359934:
        v11 = 396170963;
        break;
      case 2101131376:
        v15 = 0;
        v11 = -94879051;
        printf("\n");
        break;
      case 2119231421:
        ++v14;
        v11 = -740861019;
        break;
    }
  }
           

流程:dog3=flag-48==sudoku

現在需要知道前後的sudoku,動調。不知道為什麼dd變db了

re的刷題0
re的刷題0
sudoku = [1, 4, 5, 3, 2, 7, 6, 9, 8, 8, 3, 9, 6, 5, 4, 1, 2, 7, 6, 7, 2, 8, 1, 9, 5, 4, 3, 4, 9, 6, 1, 8, 5, 3, 7, 2, 2, 1, 8, 4, 7, 3, 9, 5, 6, 7, 5, 3, 2, 9, 6, 4, 8, 1, 3, 6, 7, 5, 4, 2, 8, 1, 9, 9, 8, 4, 7, 6, 1, 2, 3, 5, 5, 2, 1, 9, 3, 8, 7, 6, 4]
dog3   = [1, 0, 5, 3, 2, 7, 0, 0, 8, 8, 0, 9, 0, 5, 0, 0, 2, 0, 0, 7, 0, 0, 1, 0, 5, 0, 3, 4, 9, 0, 1, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, 0, 9, 0, 6, 7, 0, 3, 2, 9, 0, 4, 8, 0, 0, 6, 0, 5, 4, 0, 8, 0, 9, 0, 0, 4, 0, 0, 1, 0, 3, 0, 0, 2, 1, 0, 3, 0, 7, 0, 4]
flag = []
for i in range(81):
    if dog3[i] == 0:
        num = ord(str(sudoku[i])) + 20
        flag.append( num&0xf3 | ~num&0xc )

for i in range(0,40,2):
    (flag[i], flag[i+1]) = (flag[i+1], flag[i])
	
for i in range(20):
    (flag[i],flag[i+20]) = (flag[i+20], flag[i])
	
for i in range(40):
    print chr(flag[i]),
           

day39 8.3

[網鼎杯 2020 青龍組]jocker

堆棧不平衡,在00401833搞一下,f5看main函數

puts("please input you flag:");
  if ( VirtualProtect(encrypt, 0xC8u, 4u, &flOldProtect) == 0 )
    exit(1);
  scanf("%40s", &Source);
  v7 = strlen(&Source);
  if ( v7 != 24 )
  {
    puts("Wrong!");
    exit(0);
  }
  strcpy(&Dest, &Source);
  wrong(&Source);
  omg(&Source);
  for ( i = 0; i <= 186; ++i )
    *((_BYTE *)encrypt + i) ^= 0x41u;
  if ( encrypt(&Dest) != 0 )
    finally(&Dest);
           

VirtualProtect

處理程式的虛拟位置空間裡,變更認可頁面區域上的保護。

flag24位

wrong

char *__cdecl wrong(char *a1)
{
  char *result; // eax
  signed int i; // [esp+Ch] [ebp-4h]

  for ( i = 0; i <= 23; ++i )
  {
    if ( i & 1 )
    {
      result = &a1[i];
      a1[i] -= i;
    }
    else
    {
      result = &a1[i];
      a1[i] ^= i;
    }
  }
  return result;
}
           

傳回值為flag,i為奇數flag[i]-=i,i為偶數flag[i]^=i

omg

int __cdecl omg(char *a1)
{
  int result; // eax
  int v2[24]; // [esp+18h] [ebp-80h]
  int i; // [esp+78h] [ebp-20h]
  int v4; // [esp+7Ch] [ebp-1Ch]

  v4 = 1;
  qmemcpy(v2, &unk_4030C0, sizeof(v2));
  for ( i = 0; i <= 23; ++i )
  {
    if ( a1[i] != v2[i] )
      v4 = 0;
  }
  if ( v4 == 1 )
    result = puts("hahahaha_do_you_find_me?");
  else
    result = puts("wrong ~~ But seems a little program");
  return result;
}
           

v2=fkcd,7fh,agd;Vka{&;Pc_MZq,0ch,7f

有一個假的flag,為什麼呢

在這裡

for ( i = 0; i <= 186; ++i )
    *((_BYTE *)encrypt + i) ^= 0x41u;
  if ( encrypt(&Dest) != 0 )
    finally(&Dest);
           

如果現在去看

encrypt

,現在是加密過的

.text:00401500                     public __Z7encryptPc
.text:00401500     __Z7encryptPc   proc far                ; CODE XREF: _main+10D↓p
.text:00401500                                             ; DATA XREF: _main+3C↓o ...
.text:00401500 000                 adc     al, 0C8h
.text:00401502 000                 movsb
.text:00401503 000                 push    ss
.text:00401504 004                 pop     ss
.text:00401505 000                 adc     al, dl
.text:00401507 000                 lodsd
.text:00401508 000                 cmp     eax, 40A10486h
.text:0040150D 000                 inc     ecx
.text:0040150E 000                 inc     ecx
.text:0040150F 000                 inc     ecx
.text:00401510 000                 int     3               ; Trap to Debugger
.text:00401511 000                 add     al, 0D5h
.text:00401513 000                 cli
.text:00401514 000                 add     [ecx+1], esi
.text:00401517 000                 inc     ecx
.text:00401518 000                 sti
.text:00401519 000                 push    edx
.text:0040151A 004                 inc     ecx
.text:0040151B 004                 inc     ecx
.text:0040151C 004                 inc     ecx
.text:0040151D 004                 enter   0FFFFC886h, 9Fh
.text:00401521 -36F6               enter   0FFFFB290h, 0E4h
.text:00401525 -8452               xchg    al, ds:41414141h
.text:0040152C -8452               stosb
.text:0040152D -8452               or      dl, cl
.text:0040152F -8452               adc     al, 0A5h
.text:00401531 -8452               retf    4904h
.text:00401531     __Z7encryptPc   endp ; sp-analysis failed
           

看一下引用

.text:00401830 0AC                 mov     [esp+0A8h+Str], eax
.text:00401833 0AC                 call    near ptr __Z7encryptPc ; encrypt(char *)
           

用od在00401833下斷點再olldump

真正的

encrypt

int __cdecl start(int a1)
{
  int v2[19]; // [esp+1Ch] [ebp-6Ch]
  int v3; // [esp+68h] [ebp-20h]
  int i; // [esp+6Ch] [ebp-1Ch]

  v3 = 1;
  qmemcpy(v2, &unk_403040, sizeof(v2));
  for ( i = 0; i <= 18; ++i )
  {
    if ( (char)(*(_BYTE *)(i + a1) ^ aHahahahaDoYouF[i]) != v2[i] )
    {
      puts("wrong ~");
      v3 = 0;
      exit(0);
    }
  }
  if ( v3 == 1 )
    puts("come here");
  return v3;
}
           
v2=[14, 13, 9, 6, 19, 5, 88, 86, 62, 6, 12, 60, 31, 87, 20, 107, 87, 89, 13]
aHa="hahahaha_do_you_find_me?"
flag=""
for i in range(18):
	flag+=chr(v2[i]^ord(aHa[i]))
print flag
           

flag{d07abccf8a410

還差一點在

sub_40159A

int __cdecl sub_40159A(_BYTE *a1)
{
  unsigned int v1; // eax
  int result; // eax
  char v3; // [esp+13h] [ebp-15h]
  char v4; // [esp+14h] [ebp-14h]
  char v5; // [esp+15h] [ebp-13h]
  char v6; // [esp+16h] [ebp-12h]
  char v7; // [esp+17h] [ebp-11h]
  int v8; // [esp+18h] [ebp-10h]
  int v9; // [esp+1Ch] [ebp-Ch]

  v3 = 37;
  v4 = 116;
  v5 = 112;
  v6 = 38;
  v7 = 58;
  v1 = time(0);
  srand(v1);
  v9 = rand() % 100;
  v8 = 0;
  if ( (*a1 != 37) == v9 )
    result = puts("Really??? Did you find it?OMG!!!");
  else
    result = puts("I hide the last part, you will not succeed!!!");
  return result;
}
           

最後看wp知道flag最後是},}^58=71,再用異或

對比函數加密前後發現加密是^41,可以對16進制進行修改

re的刷題0

hxd中

re的刷題0

或者idc腳本

#include <idc.idc>
static main()
{
auto addr = 0x401500;
auto i = 0;
for(i=0;i!=186;i++)
{
PatchByte(addr+i,Byte(addr+i)^0x41);
}
}
           

day40 8.4

[WUSTCTF2020]level4

[root@lalala re]# ./level4
Practice my Data Structure code.....
Typing....Struct.....char....*left....*right............emmmmm...OK!
Traversal!
Traversal type 1:2f0t02T{hcsiI_SwA__r7Ee}
Traversal type 2:20f0Th{2tsIS_icArE}e7__w
Traversal type 3:    //type3(&x[22]);   No way!
           

main函數主要代碼,問題在type1、2上

printf("Traversal type 1:");
  type1(&unk_601290);
  printf("\nTraversal type 2:");
  type2(&unk_601290);
  printf("\nTraversal type 3:");
  puts("    //type3(&x[22]);   No way!");
  puts(&byte_400A37);
           

type1

__int64 __fastcall type1(char *a1)
{
  __int64 result; // rax

  if ( a1 )
  {
    type1(*((_QWORD *)a1 + 1));
    putchar(*a1);
    result = type1(*((_QWORD *)a1 + 2));
  }
  return result;
}
           

type2

int __fastcall type2(char *a1)
{
  int result; // eax

  if ( a1 )
  {
    type2(*((_QWORD *)a1 + 1));
    type2(*((_QWORD *)a1 + 2));
    result = putchar(*a1);
  }
  return result;
}
           

這不是樹的周遊嗎

中序:2f0t02T{hcsiI_SwA__r7Ee}

後序:20f0Th{2tsIS_icArE}e7__w

re的刷題0

漏了一個下劃線

day41 8.5

[網鼎杯 2020 青龍組]bang

pkid查殼

re的刷題0

drizzleDumpe脫殼失敗

dumpsys package | grep how_debug

[GKCTF2020]EzMachine

虛拟機:定義一套指令,在程式中能有一套函數和結構解釋自己定義的指令并執行功能。

16f0 173b 17c1 1811 1842 1940 1580

動調找到

.text:0040158E                     cmp     eax, ecx
.text:00401590                     jnz     short near ptr loc_401594+1
.text:00401592                     jz      short near ptr loc_401594+1
.text:00401594
.text:00401594     loc_401594:                             ; CODE XREF: .text:00401590↑j
.text:00401594                                             ; .text:00401592↑j ...
.text:00401594                     mov     eax, 1B8h
.text:00401599                     add     [ebp-74AF8B40h], al
           
re的刷題0
re的刷題0

堆棧不平衡調一下

void __usercall sub_401588(int a1@<ebp>)
{
  sub_4014F0();
  while ( 1 )
  {
LABEL_2:
    *(_BYTE *)(a1 - 1) = byte_4449A0[dword_445BD8];
    for ( *(_DWORD *)(a1 - 8) = 0; ; *(_DWORD *)(a1 - 8) += 2 )
    {
      if ( *(_DWORD *)(a1 - 8) >= 0x58u )
        goto LABEL_2;
      if ( byte_4448F0[4 * *(_DWORD *)(a1 - 8)] == *(_BYTE *)(a1 - 1) )
        break;
    }
    *(_DWORD *)(a1 - 12) = off_4448F4[*(_DWORD *)(a1 - 8)];
    (*(void (**)(void))(a1 - 12))();
  }
}
           

byte_4448F0

dd offset sub_401070
.data:00444908                     db    3
.data:00444909                     db    0
.data:0044490A                     db    0
.data:0044490B                     db    0
.data:0044490C                     dd offset sub_401030
.data:00444910                     db    4
.data:00444911                     db    0
.data:00444912                     db    0
.data:00444913                     db    0
.data:00444914                     dd offset sub_4010A0
.data:00444918                     db    5
.data:00444919                     db    0
.data:0044491A                     db    0
.data:0044491B                     db    0
           

存放着opcode對應操作的函數,4449A0處為虛拟機代碼起始位址,dword_445BD8為ip,off_4427FC處儲存有四個寄存器的位址,dword_445BAC為棧的起始位址,dword_445BC8為esp。wp

分析opcode

op=0:ip++

op=1:mov

op=2:

day42 8.6

[UTCTF2020]basic-re

[root@lalala re]# ./basic-re
Enter an operator (+, -, *,): -
Enter two operands: 2 3
2.0 - 3.0 = -1.0
           

程式完成兩個數運算,測試發現還有/,運算符報錯

Error! operator is not correct

,輸入字元預設為0。

ida,。。。flag get。。。果然basic

day43 8.8

[MRCTF2020]EasyCpp

通過for循環可知flag9位

對輸入判斷是在while循環裡

vector容器,當成數組

// 定義一個vector

std::vector c;

c.pop_back() 删除最後一個資料。

c.push_back(elem) 在尾部加入一個資料。

c.size() 回容器中實際資料的個數。

c.begin() 傳回指向容器第一個元素的疊代器

c.end() 傳回指向容器最後一個元素的疊代器

std::vector<int,std::allocator<int>>::push_back(&v21, &v18);

将輸入指派數組

Lambda

表達式用于定義并建立匿名的函數對象,以簡化程式設計工作。
[函數對象參數] (操作符重載函數參數) mutable 或 exception 聲明 -> 傳回值類型 {函數體}
           

std::for_each<__gnu_cxx::__normal_iterator<int*,std::vector<int,std::allocator<int>>>,main::{lambda(int &)#1}>(v5,v6,v5);

實作異或1。

depart(v26, (__int64)&v15, v3);

v7 = a1;
  for ( i = 2; ; ++i )
  {
    std::sqrt<int>((unsigned int)a1);
    if ( a3 < (double)i )
      break;
    if ( !(a1 % i) )
    {
      v7 = i;
      depart((unsigned int)(a1 / i), a2);
      break;
    }
  }
           

emmm,看不出來先看後面的

{lambda(std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> &)#1}::operator()((__int64)&func,(__int64)&v16);

v25 = \'O\';
  v26 = \'0\';
  v2 = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::end(a2);
  v3 = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::begin(a2);
  std::replace<__gnu_cxx::__normal_iterator<char *,std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>>,char>(
    v3,
    v2,
    &v26,
    &v25);
           

替換,将0-9以及空格替換成字母

搜尋字元串

num=["=zqE=z=z=z","=lzzE","=ll=T=s=s=E","=zATT","=s=s=s=E=E=E","=EOll=E","=lE=T=E=E=E","=EsE=s=z","=AT=lE=ll"]
for i in num:
	a=i.replace("O","0").replace("l","1").replace("z","2").replace("E","3").replace("A","4").replace("s","5").replace("G","6").replace("T","7").replace("B","8").replace("q","9").replace("="," ")
	print a
           
re的刷題0

回到

depart

,測試三個數

def depart(a1,a2,a3):
	v7=a1
	for i in range(2,100):
		if a3 < i:
			break
		if a1 % i==0:
			v7 = i;
			print a1 / i,i
			depart(a1 / i, a2, a3)
			break

print "122"
depart(122,0,20)
print \'\n\'

print "27"
depart(27,0,20)
print \'\n\'

print "5"
depart(5,0,20)
print \'\n\'
           
re的刷題0

蕪湖,

depart

,除除除

num=["=zqE=z=z=z","=lzzE","=ll=T=s=s=E","=zATT","=s=s=s=E=E=E","=EOll=E","=lE=T=E=E=E","=EsE=s=z","=AT=lE=ll"]
flagnum=[]
for i in num:
	a=i[1:].replace("O","0").replace("l","1").replace("z","2").replace("E","3").replace("A","4").replace("s","5").replace("G","6").replace("T","7").replace("B","8").replace("q","9").replace("="," ")
	num=a.split(\' \')
	print num
	b=1
	for j in num:
		b*=int(j)
	flagnum.append(b^1)
print flagnum
           

[WUSTCTF2020]funnyre

建立main函數

JUMPOUT(*v5, \'f\', sub_4005B6);
    JUMPOUT(v5[1], \'l\', sub_4005B6);
    JUMPOUT(v5[2], \'a\', sub_4005B6);
    JUMPOUT(v5[3], \'g\', sub_4005B6);
    JUMPOUT(v5[4], \'{\', sub_4005B6);
    JUMPOUT(v5[37], \'}\', sub_4005B6);
           

sub_4005B6堆棧平衡,傳回1。由此可知flag38位

JUMPOUT(1, (char *)&loc_40061A + 1);
JUMPOUT(0, (char *)&loc_40061A + 1);
           
.text:0000000000400616 008                 jz      short near ptr loc_40061A+1
.text:0000000000400618 008                 jnz     short near ptr loc_40061A+1
.text:000000000040061A
.text:000000000040061A     loc_40061A:                             ; CODE XREF: main+66↑j
.text:000000000040061A                                             ; main+68↑j
.text:000000000040061A 008                 call    near ptr 0FFFFFFFF810037AFh
.text:000000000040061F 008                 jz      short near ptr loc_400621+2
.text:0000000000400621
.text:0000000000400621     loc_400621:                             ; CODE XREF: main+6F↑j
.text:0000000000400621 008                 add     eax, 0C08348CDh
.text:0000000000400626 008                 add     [rax-7Dh], ecx
           
re的刷題0
re的刷題0

後來發現其實沒必要

觀察發現

v12 = 0LL;
    do
      *(_BYTE *)(v9 + v12++ + 5) ^= 0x6Au;
    while ( v12 != 32 );
    v13 = 0LL;
    do
      *(_BYTE *)(v9 + v13++ + 5) ^= 0x59u;
    while ( v13 != 32 );
    v14 = 0LL;
    do
      *(_BYTE *)(v9 + v14++ + 5) ^= 0xAu;
    while ( v14 != 32 );
           

這就是加密,去除flag{}的32位不斷加密

寫正則提取資料

#str =\'*(_BYTE *)(v93 + v121++ + 5) ^= 0x1Cu;\'
pattern = re.compile(r\'do\s*.*?[)]\s(.*?);\s*while\',re.S)
#pattern = re.compile(r\'[)]\s(.*?);\',re.S)
result = pattern.findall(str1)
#print result
for i in result:
	if len(i) == 4 or len(i) == 5 or len(i) == 8:
		continue
	else:
		del result[result.index(i)]
print result
print len(result)
print \'\n\'
result.reverse()
print result
print \'\n\'
           
num=[0xD9, 0x2C, 0x27, 0xD6, 0xD8, 0x2A, 0xDA, 0x2D, 0xD7, 0x2C, 0xDC, 0xE1, 0xDB, 0x2C, 0xD9, 0xDD,0x27, 0x2D, 0x2A, 0xDC,0xDB, 0x2C, 0xE1, 0x29, 0xDA, 0xDA, 0x2C, 0xDA, 0x2A, 0xD9, 0x29, 0x2A]

flag=\'\'
print len(result)
for n in num:
	tmp=str(n)
	for i in range(len(result)):
		#print tmp,result[i]
		if result[i] == \'~\':
			tmp=str(~int(tmp))
			print tmp
		elif result[i] == \'-=128\':
			tmp=str(eval(tmp+\'+128\'))
		else:
			op = result[i].replace(\'+\',\'-\').replace(\'u\',\'\').replace(\'=\',\'\').replace(\' \',\'\')
			tmp=str(eval(tmp+op))
	#print tmp
           

發現最後結果全是負數,淦,少了一個取反。淦,還是少了。。。

flag{1dc20f6e3d497d15cef47d9a66d6f1af}

day43 8.9

[NPUCTF2020]Baby Obfuscation

re的刷題0

虛假控制流

通過在目前基本塊之前添加一個基本塊,來修改函數調用流程圖。新添加的基本塊包含一個不透明的謂語,然後再跳轉到原來的基本塊。

// Before :
//                       entry
//                         |
//                   ______v______
//                  |   Original  |
//                  |_____________|
//                         |
//                         v
//                       return
//
// After :
//                       entry
//                         |
//                     ____v_____
//                    |condition*| (false)
//                    |__________|----+
//                   (true)|          |
//                         |          |
//                   ______v______    |
//              +-->|   Original* |   |
//              |   |_____________| (true)
//              |   (false)|    !-----------> return
//              |    ______v______    |
//              |   |   Altered   |<--!
//              |   |_____________|
//              |__________|
//
//  * The results of these terminator\'s branch\'s conditions are always true, but these predicates are
//    opacificated. For this, we declare two global values: x and y, and replace the FCMP_TRUE
//    predicate with (y < 10 || x * (x + 1) % 2 == 0) (this could be improved, as the global
//    values give a hint on where are the opaque predicates)
           
(angr) angr@788e0ac062a9:/test$ python debogus.py -f BabyObfuscation.exe --addr 0x4015ff
           

day44 8.13

[ACTF新生賽2020]SoulLike

輸入flag,報錯Try another time...

printf("input flag:", a2, a3);
  scanf("%s", v11);
  v9 = \'ftca\';
  v10 = \'{\';
  v5 = 1;
  for ( i = 0; i <= 4; ++i )
  {
    if ( *((_BYTE *)&v9 + i) != v11[i] )
    {
      v5 = 0;
      goto LABEL_6;
    }
  }
  if ( !v5 )
    goto LABEL_19;
LABEL_6:
  for ( j = 0; j <= 11; ++j )
    v8[j] = v11[j + 5];
  v3 = (unsigned __int8)sub_83A(v8) && v12 == 125 ? 1 : 0;
  if ( v3 )
  {
    printf("That\'s true! flag is %s", v11);
    result = 0LL;
  }
           

第一個for循環判斷格式actf{,第二個for循環判斷flag

wrong on #0

逐位元組爆破

import subprocess
from string import *
table =printable
flag=\'actf{\'
for i in range(12):
	for j in table:
		tmp=flag+j
		obj =  subprocess.Popen(["./SoulLike"],stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		obj.stdin.write(tmp.encode())
		obj.stdin.close()
		out=obj.stdout.read()
		#print(out)
		obj.stdout.close()
		"""
		out,err = obj.communicate()
		"""
		#print(str(i)+\':\'+j+\':\'+out.decode())	
		#print(out.decode())
		wrong=\'#\'+str(i)

		if wrong not in out.decode():
			print(j)
			flag+=j
			break
print (flag)
           

一開始少了tmp=flag+j,怎麼都不對淦。

day45 8.15

[FlareOn1]Bob Doge

密碼:malware

壓縮包沒有密碼,這應該是個提示。

安裝軟體後一串字元串被解密成亂碼。dnspy打開,找到decode

private void btnDecode_Click(object sender, EventArgs e)
		{
			this.pbRoge.Image = Resources.bob_roge;
			byte[] dat_secret = Resources.dat_secret;
			string text = "";
			foreach (byte b in dat_secret)
			{
				text += (char)((b >> 4 | ((int)b << 4 & 240)) ^ 41);
			}
			text += "\0";
			string text2 = "";
			for (int j = 0; j < text.Length; j += 2)
			{
				text2 += text[j + 1];
				text2 += text[j];
			}
			string text3 = "";
			for (int k = 0; k < text2.Length; k++)
			{
				char c = text2[k];
				text3 += (char)((byte)text2[k] ^ 102);
			}
			this.lbl_title.Text = text3;
		}
           

動調

re的刷題0

Dig the way

國際開發協會(互動式反彙程式設計式) ,該程式反彙編可執行檔案( 。EXE )為低級彙編語言代碼建立的檔案,存儲在一個壓縮格式的拆卸後的資料,在探索可執行檔案的過程中使用,往往揭示潛在的安全威脅或剝削的路線。

當IDB檔案在IDA打開,資料解壓到的檔案的集合。後的資料庫被關閉時,該檔案被壓縮回IDB檔案。這使得更快的性能,同時在資料庫打開和較低的磁盤使用時關閉。

< H1 >其他IDB格式: < /H1 >在調試過程中由一個Visual Studio程式中建立的中間檔案,如Visual C, ,節省了編譯器的狀态,并用于最小的重建計劃和增量編譯。

int fseek(FILE *stream, long int offset, int whence) 設定流 stream 的檔案位置為給定的偏移 offset,參數 offset 意味着從給定的 whence 位置查找的位元組數。第三個參數可能取值為:SEEK_CUR、 SEEK_END 或 SEEK_SET

SEEK_SET: 檔案開頭

SEEK_CUR: 目前位置

SEEK_END: 檔案結尾

其中SEEK_SET,SEEK_CUR和SEEK_END和依次為0,1和2.

long int ftell(FILE *stream) 傳回給定流 stream 的目前檔案位置。

v8 = 0;
  v9 = 1;
  v10 = 2;
  v11 = 3;
  v12 = 3;
  v13 = 4;
  File = fopen("data", "rb");
  if ( !File )
    return -1;
  fseek(File, 0, 2);
  v18 = ftell(File);     //v18為檔案大小
  fseek(File, 0, 0);
  v17 = ftell(File);     //v17=0
  if ( v17 )
  {
    puts("something wrong");
    result = 0;
  }
  else
  {
    for ( i = 0; i < v18; ++i )
      {
        v4 = i;
        *((_BYTE *)&v7 + v4) = fgetc(v19);//将data檔案字元指派str
      }
      v5 = strlen((const char *)&v7);
     
    if ( v5 <= v18 ) 
    {
      v18 = v11;              //3
      i = 0;
      v17 = v13;              //4
      while ( i <= 2 )
      {
        v6 = i + 1;
        *(&v8 + v6) = (*(&v14 + i))((int)&v8, v12, v13);
        v12 = ++i;
        v13 = i + 1;
      }
      if ( v11 )
      {
        result = -1;
      }
      else
      {
        get_key(v18, v17);
        system("PAUSE");
        result = 0;
      }
           

其中

v14 = func0;                                  // a1[a2]<=>a1[a3]
  v15 = func1;                                  // |a1[a2]+a1[a3]|-|a1[a2]|-|a1[a3]|+2
  v16 = func2;                                  // |a1[a3]|-|a1[a3]+a1[a2]|+|a1[a2]|+2
           

開始以為

get_key(v18, v17);

通過指派就是3、4,但是通過

*((_BYTE *)&v7 + v4) = fgetc(v19);

棧溢出可以對v7-v13重新指派,使v11最後為0。

原本應是v11通過func2指派永遠大于0,通過棧溢出修改v12、v13為7、8,在執行

*(&v8 + v6) = (*(&v14 + i))((int)&v8, v12, v13);

時就将v15、v16互換,使v11通過func1指派。

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 07 00 00 00 08 00 00 00
           

[SCTF2019]babyre

花指令

jb      short near ptr loc_98F+1
jnb     short near ptr loc_98F+1
.text:0000000000000AD8                 jb      short near ptr loc_ADC+1
.text:0000000000000ADA                 jnb     short near ptr loc_ADC+1

.text:0000000000000B4F                 jb      short near ptr loc_B53+1
.text:0000000000000B51                 jnb     short near ptr loc_B53+1

.text:0000000000000E0F                 jb      short near ptr loc_E13+1
.text:0000000000000E11                 jnb     short near ptr loc_E13+1
           
switch ( v1 )
    {
      case \'w\':
        v4 -= 5;
        break;
      case \'s\':
        v4 += 5;
        break;
      case \'d\':
        ++v4;
        break;
      case \'a\':
        --v4;
        break;
      case \'x\':
        v4 += 25;
        break;
      case \'y\':
        v4 -= 25;
        break;
      default:
        v3 = 0;
        break;
    }
    ++v2;
    if ( *v4 != \'.\' && *v4 != \'#\' )
      v3 = 0;
    if ( *v4 == \'#\' )
    {
      puts("good!you find the right way!\nBut there is another challenge!");
      break;
    }
  }
           

迷宮,但是還有xy,是三維的

* * * * .
* * * * *
* . s * *
. * * * *


* * * . .
* . . * *
* * . * *
* * * * *
* * * * *

* . . * *
* * # . .
* * . . *
. . * * *
. . * * *

* * . * *
* * * * *
* * * . *
* * * * *
* * * * *

. . * * .
* * . . *
* * * . *
. . * . .
. * * . *
           

路徑

ddwwxxssxaxwwaasasyywwdd

loc_C22建立函數不了

摁Y鍵修改類型。将其改為一個獨立的函數。

就是sctf_9102的base64

c2N0Zl85MTAy
           

最後sub_ffa

signed __int64 __fastcall sub_FFA(char *a1)
{
  v48 = __readfsqword(0x28u);
  v8 = 190;
  v9 = 4;
  v10 = 6;
  v11 = 128;
  v12 = 197;
  v13 = 175;
  v14 = 118;
  v15 = 71;
  v16 = 159;
  v17 = 204;
  v18 = 64;
  v19 = 31;
  v20 = 216;
  v21 = 191;
  v22 = 146;
  v23 = 239;
  v1 = (a1[6] << 8) | (a1[5] << 16) | (a1[4] << 24) | a1[7];
  v2 = (a1[10] << 8) | (a1[9] << 16) | (a1[8] << 24) | a1[11];
  v3 = (a1[14] << 8) | (a1[13] << 16) | (a1[12] << 24) | a1[15];
  v7 = 0;
  v5 = 4;
  v40 = sub_78A((a1[2] << 8) | (a1[1] << 16) | (*a1 << 24) | (unsigned int)a1[3]);
  v41 = sub_78A(v1);
  v42 = sub_78A(v2);
  v43 = sub_78A(v3);
  do
  {
    *(&v40 + v5) = sub_143B(
                     (unsigned int)*(&v40 + v7),
                     (unsigned int)*(&v40 + v7 + 1),
                     (unsigned int)*(&v40 + v7 + 2),
                     (unsigned int)*(&v40 + v7 + 3));
    ++v7;
    ++v5;
  }
  while ( v5 <= 29 );
  v24 = v44 >> 24;
  v25 = BYTE2(v44);
  v26 = BYTE1(v44);
  v27 = (unsigned __int8)v44;
  v28 = v45 >> 24;
  v29 = BYTE2(v45);
  v30 = BYTE1(v45);
  v31 = (unsigned __int8)v45;
  v32 = v46 >> 24;
  v33 = BYTE2(v46);
  v34 = BYTE1(v46);
  v35 = (unsigned __int8)v46;
  v36 = v47 >> 24;
  v37 = BYTE2(v47);
  v38 = BYTE1(v47);
  v39 = (unsigned __int8)v47;
  for ( i = 0; i <= 15; ++i )
  {
    if ( *(&v24 + i) != *(&v8 + i) )
      return 0xFFFFFFFFLL;
  }
  return 1LL;
}
           
#include"stdio.h"
#include"string.h"
#define ROL(x, r)  (((x) << (r)) | ((x) >> (32 - (r))))
#define ROR(x, r)  (((x) >> (r)) | ((x) << (32 - (r))))

unsigned int a[288] = {0x0D6, 0x90, 0x0E9, 0x0FE, 0x0CC, 0x0E1, 0x3D, 0x0B7, 0x16, 0x0B6, 0x14, 0x0C2, 0x28, 0x0FB, 0x2C, 0x5, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0x0BE, 0x4, 0x0C3, 0x0AA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x6, 0x99, 0x9C, 0x42, 0x50, 0x0F4, 0x91, 0x0EF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0x0ED, 0x0CF, 0x0AC, 0x62, 0x0E4, 0x0B3, 0x1C, 0x0A9, 0x0C9, 0x8, 0x0E8, 0x95, 0x80, 0x0DF, 0x94, 0x0FA, 0x75, 0x8F, 0x3F, 0x0A6, 0x47, 0x7, 0x0A7, 0x0FC, 0x0F3, 0x73, 0x17, 0x0BA, 0x83, 0x59, 0x3C, 0x19, 0x0E6, 0x85, 0x4F, 0x0A8, 0x68, 0x6B, 0x81, 0x0B2, 0x71, 0x64, 0x0DA, 0x8B, 0x0F8, 0x0EB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0x0D1, 0x0A2, 0x25, 0x22, 0x7C, 0x3B, 0x1, 0x21, 0x78, 0x87, 0x0D4, 0x0, 0x46, 0x57, 0x9F, 0x0D3, 0x27, 0x52, 0x4C, 0x36, 0x2, 0x0E7, 0x0A0, 0x0C4, 0x0C8, 0x9E, 0x0EA, 0x0BF, 0x8A, 0x0D2, 0x40, 0x0C7, 0x38, 0x0B5, 0x0A3, 0x0F7, 0x0F2, 0x0CE, 0x0F9, 0x61, 0x15, 0x0A1, 0x0E0, 0x0AE, 0x5D, 0x0A4, 0x9B, 0x34, 0x1A, 0x55, 0x0AD, 0x93, 0x32, 0x30, 0x0F5, 0x8C, 0x0B1, 0x0E3, 0x1D, 0x0F6, 0x0E2, 0x2E, 0x82, 0x66, 0x0CA, 0x60, 0x0C0, 0x29, 0x23, 0x0AB, 0x0D, 0x53, 0x4E, 0x6F, 0x0D5, 0x0DB, 0x37, 0x45, 0x0DE, 0x0FD, 0x8E, 0x2F, 0x3, 0x0FF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, 0x8D, 0x1B, 0x0AF, 0x92, 0x0BB, 0x0DD, 0x0BC, 0x7F, 0x11, 0x0D9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0x0D8, 0x0A, 0x0C1, 0x31, 0x88, 0x0A5, 0x0CD, 0x7B, 0x0BD, 0x2D, 0x74, 0x0D0, 0x12, 0x0B8, 0x0E5, 0x0B4, 0x0B0, 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0x0B9, 0x0F1, 0x9, 0x0C5, 0x6E, 0x0C6, 0x84, 0x18, 0x0F0, 0x7D, 0x0EC, 0x3A, 0x0DC, 0x4D, 0x20, 0x79, 0x0EE, 0x5F, 0x3E, 0x0D7, 0x0CB, 0x39, 0x48, 0x0C6, 0x0BA, 0x0B1, 0x0A3, 0x50, 0x33, 0x0AA, 0x56, 0x97, 0x91, 0x7D, 0x67, 0x0DC, 0x22, 0x70, 0x0B2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
unsigned int foo2(unsigned int a1)
{
    unsigned v1;
    unsigned char byte[4];
    byte[0] = a1&0xff;
    byte[1] = (a1>>8)&0xff;
    byte[2] = (a1>>16)&0xff;
    byte[3] = (a1>>24)&0xff;
    v1 = (a[byte[0]])|(a[byte[1]]<<8)|(a[byte[2]]<<16)|(a[byte[3]]<<24);
    return ROL(v1,12)^ROL(v1,8)^ROR(v1,2)^ROR(v1,6);
}

unsigned int foo(unsigned int a1, unsigned int a2, unsigned int a3, unsigned int a4)
{
    return a1 ^ foo2(a2^a3^a4);
}

int main()
{
    unsigned int tmp[30] = {0};
    unsigned int cipher[4] = {0xBE040680, 0xC5AF7647, 0x9FCC401F, 0xD8BF92EF};
    memcpy(tmp+26,cipher,16);

    for(int i = 25;i>=0;i--)
        tmp[i] = foo(tmp[i+4],tmp[i+1],tmp[i+2],tmp[i+3]);
    tmp[4] = 0;
    printf("%sn",(char *)tmp);
    return 0;
}
           
fl4g_is_s0_ug1y!
           

day46 8.16

[SUCTF2019]hardcpp

加了控制流平坦化,先看看

v45 = time(0LL);
  puts("func(?)=\"01abfc750a0c942167651c40d088531d\"?");
  s[0] = getchar();
  fgets(&s[1], 21, stdin);
  v39 = time(0LL);
  v38 = v39 - v45;
  v49 = v39 - v45;
           

第一個是哈希值,解密付費。

輸入22位

但是因為v49大于0,無論輸入什麼都會調到

puts("Let the silent second hand take the place of my doubt...");
           

靜态分析

從兩個

you win

逆向推,最後發現其實就是while ( v28 == -2090540314 ) 或 if ( v28 == 1299792285 )對flag除第一位逐位加密(加密效果相同)。

int __cdecl main(int argc, const char **argv, const char **envp)
{

  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            while ( 1 )
            {
              while ( 1 )
              {
                while ( 1 )
                {
                  while ( 1 )
                  {
                    while ( 1 )                 // -1
                    {
                      while ( 1 )
                      {
                        while ( 1 )
                        {
                          while ( 1 )
                          {
                            while ( 1 )
                            {
                              while ( v28 == -2090540314 )
                              {
                                v35 = v38 ^ s[v36];
                                v34 = main::$_0::operator() const(&v44, (unsigned int)v35);
                                v33 = main::$_1::operator() const(&v42, (unsigned int)*(&s[v38 - 1] + v36));
                                v11 = ZZZ4mainENK3__1clEcENKUliE_clEi(&v33, 7LL);
                                v35 = ZZZ4mainENK3__0clEcENKUlcE_clEc(&v34, (unsigned int)v11);
                                v32 = main::$_2::operator() const(&v45, (unsigned int)v35);
                                v31 = main::$_2::operator() const(&v45, (unsigned int)*(&s[v38 - 1] + v36));
                                v12 = ZZZ4mainENK3__2clEcENKUlcE_clEc(&v31, 18LL);
                                v30 = main::$_3::operator() const(&v43, (unsigned int)v12);
                                v13 = ZZZ4mainENK3__3clEcENKUlcE_clEc(&v30, 3LL);
                                v29 = main::$_0::operator() const(&v44, (unsigned int)v13);
                                v14 = ZZZ4mainENK3__0clEcENKUlcE_clEc(&v29, 2LL);
                                v15 = ZZZ4mainENK3__2clEcENKUlcE_clEc(&v32, (unsigned int)v14);
                                v16 = 1299792285;
                                v35 = v15;
                                v52 = (unsigned __int8)enc[(signed __int64)(v36 - 1)] != (unsigned __int8)v15;
                                if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
                                  v16 = -424557443;
                                v28 = v16;
                              }
                              if ( v28 != -1957245689 )
                                break;
                              v28 = 1587023630;
                            }
                            if ( v28 != -1884297895 )
                              break;
                            v28 = -984930794;
                            puts("You win");
                          }
                          if ( v28 != -1852837876 )
                            break;
                          v18 = 1375414539;
                          if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
                            v18 = 1154698238;
                          v28 = v18;
                        }
                        if ( v28 != -1220297252 )
                          break;                // -1
                        v21 = -1884297895;
                        if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
                          v21 = -984930794;
                        v28 = v21;
                      }
                      if ( v28 != -984930794 )
                        break;
                      puts("You win");
                      v22 = -1884297895;
                      if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
                        v22 = 456293525;
                      v28 = v22;
                    }
                    if ( v28 != -883606692 )
                      break;
LABEL_70:
                    v19 = -350248402;
                    if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
                      v19 = -55540564;
                    v28 = v19;
                  }
                  if ( v28 != -740226431 )
                    break;
                  v4 = 2137069843;
                  if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
                    v4 = 739060228;
                  v28 = v4;
                }
                if ( v28 == -459161563 )
                  exit(0);
                if ( v28 != -424557443 )
                  break;
                v17 = 1856799435;
                if ( v52 )
                  v17 = -1852837876;
                v28 = v17;
              }
              if ( v28 != -350248402 )
                break;
              v28 = -55540564;
            }
            if ( v28 != -294402024 )
              break;
            v6 = 1721328217;
            if ( v51 )
              v6 = -459161563;
            v28 = v6;
          }
          if ( v28 != -226137905 )
            break;
          v28 = 24093646;
        }
        if ( v28 != -55540564 )
          break;
        v20 = -350248402;
        if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
          v20 = -226137905;
        v28 = v20;
      }
      if ( v28 != 24093646 )
        break;
      ++v36;
      v28 = 1587023630;
    }
    if ( v28 == 456293525 )
      return 0;
    if ( v28 == 506113758 )
    {
      puts("Let the silent second hand take the place of my doubt...");
      exit(0);
    }
    switch ( v28 )
    {
      case 623475433:
        v36 = 1;
        v28 = 1132336453;
        break;
      case 739060228:
        v37 = strlen(s);
        v51 = v37 != 21;
        v5 = 2137069843;
        if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
          v5 = -294402024;
        v28 = v5;
        break;
      case 1011555671:
        v10 = 1299792285;
        if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
          v10 = -2090540314;
        v28 = v10;
        break;
      case 1132336453:
        v8 = 623475433;
        v36 = 1;
        if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
          v8 = -1957245689;
        v28 = v8;
        break;
      default:
        if ( v28 == 1154698238 )
          exit(0);
        if ( v28 == 1299792285 )                // -3 循環21次,對flag加密 與while ( v28 == -2090540314 )相同
        {
          v35 = v38 ^ s[v36];
          v34 = main::$_0::operator() const(&v44, (unsigned int)v35);
          v33 = main::$_1::operator() const(&v42, (unsigned int)*(&s[v38 - 1] + v36));
          v24 = ZZZ4mainENK3__1clEcENKUliE_clEi(&v33, 7LL);
          v35 = ZZZ4mainENK3__0clEcENKUlcE_clEc(&v34, (unsigned int)v24);
          v32 = main::$_2::operator() const(&v45, (unsigned int)v35);
          v31 = main::$_2::operator() const(&v45, (unsigned int)*(&s[v38 - 1] + v36));
          v25 = ZZZ4mainENK3__2clEcENKUlcE_clEc(&v31, 18LL);
          v30 = main::$_3::operator() const(&v43, (unsigned int)v25);
          v26 = ZZZ4mainENK3__3clEcENKUlcE_clEc(&v30, 3LL);
          v29 = main::$_0::operator() const(&v44, (unsigned int)v26);
          v27 = ZZZ4mainENK3__0clEcENKUlcE_clEc(&v29, 2LL);
          v35 = ZZZ4mainENK3__2clEcENKUlcE_clEc(&v32, (unsigned int)v27);
          v28 = -2090540314;
        }
        else
        {
          if ( v28 == 1375414539 )
            exit(0);
          if ( v28 == 1587023630 )              // -2
          {
            v9 = -1220297252;
            if ( v36 < 21 )
              v9 = 1011555671;
            v28 = v9;
          }
          else if ( v28 == 1721328217 )
          {
            v7 = 623475433;
            if ( y < 10 || (((_BYTE)x - 1) * (_BYTE)x & 1) == 0 )
              v7 = 1132336453;
            v28 = v7;
          }
          else
          {
            if ( v28 == 1856799435 )
              goto LABEL_70;
            if ( v28 == 1883240069 )
            {
              v3 = -740226431;
              if ( v50 > 0 )
                v3 = 506113758;
              v28 = v3;
            }
            else if ( v28 == 2137069843 )
            {
              v37 = strlen(s);
              v28 = 739060228;
            }
          }
        }
        break;
    }
  }
}
           

加密看起來多,但是代碼邏輯很清楚,裡面有很多無用的,抓住傳回值就好。

v35 = v38 ^ s[v36];
v34 = re_a2((__int64)&v43, v35);// v34 = v35 = s[v36]
v33 = re_a2_1((__int64)&v41, *(&s[v38 - 1] + v36));// v33 = s[v36-1]
v11 = re_a1_mod_a2((__int64)&v33, 7);// v11 = v33%7
v35 = re_a1_add_a2((__int64)&v34, v11);// v35 = v34 + v11
v32 = re_a2_2((__int64)&v44, v35);// v32 = v35
v31 = re_a2_2((__int64)&v44, *(&s[v38 - 1] + v36));// v31 = s[v36-1]
v12 = re_a2_xor_a1((__int64)&v31, 18);// v12 = v31 ^ 18
v30 = re_a2_3((__int64)&v42, v12);// v30 = v12
v13 = re_a2xa1((__int64)&v30, 3);// v13 = v30 * 3
v29 = re_a2((__int64)&v43, v13);// v29 = v13
v14 = re_a1_add_a2((__int64)&v29, 2);// v14 = v29 +2
v15 = re_a2_xor_a1((__int64)&v32, v14);// v15 = v14 ^ v32
v51 = (unsigned __int8)enc[(signed __int64)(v36 - 1)] != (unsigned __int8)v15;// enc[v36-1]==v15
           

v15=(((s[v36-1]) ^ 18)*3 +2)^(s[v36] + ((s[v36-1])%7))==enc[v36-1]

v36從1開始,flag第一位爆破,注意&0xff

enc = [0xf3,0x2e,0x18,0x36,0xe1,0x4c,0x22,0xd1,0xf9,0x8c,0x40,0x76,0xf4,0xe,0x0,0x5,0xa3,0x90,0xe,0xa5]

#v15=(((s[v36-1]) ^ 18)*3 +2)^(s[v36] + ((s[v36-1])%7))==enc[v36-1]
flag=\'\'
for i in range(32,127):
	flag = \'\'
	flag += chr(i)
	for j in range(20):
		num = ((enc[j]^((ord(flag[j])^18)*3+2))-(ord(flag[j])%7))&0xff
		flag += chr(num)
	print flag

           

day47 9.2

babymips

mips寄存器

REGISTER NAME USAGE
$0 $zero 常量0(constant value 0)
$1 $at 保留給彙編器(Reserved for assembler)
$2-$3 $v0-$v1 函數調用傳回值(values for results and expression evaluation)
$4-$7 $a0-$a3 函數調用參數(arguments)
$15 $t0-$t7 暫時的(或随便用的)
$16-$23 $s0-$s7 儲存的(或如果用,需要SAVE/RESTORE的)(saved)
$24-$25 $t8-$t9 暫時的(或随便用的)
$28 $gp 全局指針(Global Pointer)
$29 $sp 堆棧指針(Stack Pointer)
$30 $fp 幀指針(Frame Pointer)
$31 $ra 傳回位址(return address)

通過字元串找到輸入位置

sw      $zero, 0x48+var_30($fp)
.text:00400A1C loc_400A1C:                              # CODE XREF: sub_4009A8+DC↓j
.text:00400A1C                 lw      $v0, 0x48+var_30($fp)  # $v0=var_30
.text:00400A20                 addiu   $v1, $fp, 0x48+var_30  # $v1=&v0
.text:00400A24                 addu    $v0, $v1, $v0    # $v0=$v1+$v0
.text:00400A28                 lb      $v1, 4($v0)      # $v1=bt mem[v0+4]
.text:00400A2C                 lw      $v0, 0x48+var_30($fp)  # $v0=var_30
.text:00400A30                 nop
.text:00400A34                 andi    $v0, 0xFF        # $v0&=0xff
.text:00400A38                 li      $a0, 0x20
.text:00400A3C                 subu    $v0, $a0, $v0    # $v0=$a0-$v0
.text:00400A40                 andi    $v0, 0xFF        # $v0&=0xff
.text:00400A44                 sll     $v0, 24          # $v0<<24
.text:00400A48                 sra     $v0, 24          # $v0>>24
.text:00400A4C                 xor     $v0, $v1, $v0    # $v0=$v1^$v0
.text:00400A50                 sll     $v1, $v0, 24
.text:00400A54                 sra     $v1, 24
.text:00400A58                 lw      $v0, 0x48+var_30($fp)
.text:00400A5C                 addiu   $a0, $fp, 0x48+var_30
.text:00400A60                 addu    $v0, $a0, $v0
.text:00400A64                 sb      $v1, 4($v0)      # bt mem[$v0+4]=$v1
.text:00400A68                 lw      $v0, 0x48+var_30($fp)  # $v0=vsr_30
.text:00400A6C                 nop
.text:00400A70                 addiu   $v0, 1           # $v0+=1
.text:00400A74                 sw      $v0, 0x48+var_30($fp)  # $var_30=$v0
.text:00400A78
.text:00400A78 loc_400A78:                              # CODE XREF: sub_4009A8+6C↑j
.text:00400A78                 lw      $v0, 0x48+var_30($fp)  # $v0=var_30
.text:00400A7C                 nop
.text:00400A80                 slti    $v0, 0x20        # 比較0x20,flag長度應為32位
.text:00400A84                 bnez    $v0, loc_400A1C  # while循環
.text:00400A88                 nop
.text:00400A8C                 lui     $v0, 0x41        # $v0=0x41<<16
.text:00400A90                 lw      $v1, _fdata      # $v1=Q|j{g
.text:00400A94                 addiu   $v0, $fp, 0x48+var_2C  # $v0=&var_2c
.text:00400A98                 li      $a2, 5           # ???
.text:00400A9C                 move    $a1, $v1         # $a1=$v1
.text:00400AA0                 move    $a0, $v0         # $a0=$v0
.text:00400AA4                 jal     strncmp          # a0、a1、a2是參數
.text:00400AA8                 nop
.text:00400AAC                 bnez    $v0, loc_400ACC  # #如果前5位不為Q|j{g跳轉wrong
.text:00400AB0                 nop
.text:00400AB4                 addiu   $v0, $fp, 0x48+var_2C  # $v0=var_2c
.text:00400AB8                 move    $a0, $v0
.text:00400ABC                 jal     sub_4007F0
.text:00400AC0                 nop
.text:00400AC4                 b       loc_400ADC
           

假設原位元組為 87654321( 1-8 表示第 1-8 個 bit),在 v0 為奇數的時候加密後為 65432187, 在 v0 為偶數的時候加密後為 21345678。

最後比較的是一段密文,這個過程都是可逆的,我們隻要反推出來輸入就可以了

//qctf{ReA11y_4_B@89_mlp5_4_XmAn_}
#include <stdio.h>
#include <string.h>
char *check1="Q|j{g";
char *check2= "\x52\xfd\x16\xa4\x89\xbd\x92\x80\x13\x41\x54\xa0\x8d\x45\x18\x81\xde\xfc\x95\xf0\x16\x79\x1a\x15\x5b\x75\x1f";
void check(char *s){
	int i;
	for(i=5;i<strlen(s);i++){
		if(i%2)
			s[i]=(s[i]>>2)|((s[i]<<6)&0xff);
		else
			s[i]=((s[i]<<2)&0xff)|(s[i]>>6);	
	}
	if(!strncmp(&s[5],check2,27))
		printf("Right!\n");
	else
		printf("Wrong!\n");
}
void main(){
	char s[33];
	int i;
	printf("Give me your flag:");
	scanf("%32s",s);
	
	for(i=0;i<32;i++)
		s[i]^=(32-i);
	if(!strncmp(s,check1,5))
		check(s);
	else
		printf("Wrong\n");
}
           

day48 9.8

[GKCTF2020]WannaReverse

點進去桌面換了,給了私鑰

-----BEGIN RSA PRIVATE KEY-----

MIIEowIBAAKCAQEAyEc4zIZtCKBiKPOW8Xd5o9Mb5221zgAGvQv6CYNzVQAORKPQ

wjDgh77xVtDFmVF10+QOx5rCz/O3u5Zmpbyj7fNcbZjXcBDarHiD4B2PvxhwEwRF

nFuSXctTqlLJ4bmbW6JVUGLuX2hUvb9eLRb0LLEbbnGgGUk7G4/SZYs75EJIx2Dy

0x2Ir7mpL6I56kon42UFLQQAfTLm6aB1k2NSWTOB/s59vYy11/3FhVr97qaNCg7a

4wLJmO+fBZn8mpB71ZVOvu0cxnOlbyDMJ0nS2B2R+Aep/zeMWQr7JvYQbgd38VuK

N5W3LASF2fWBh6nNExbKlIIxB+qigFL61A5K1wIDAQABAoIBACWc2pnulQONu2Gd

fbeTjJCr0Q3BmOc7MgjG+wpWWY6ZGBTj/wy5STG1NnXrd3C3z70fk3cBJZ0QVG0y

bcyqhM7naXBbx/oP8EF70KiCZMCqwkGQB9K5j991lBzkt21hAkBPWF5kdggM+/02

t2UYbnsGN/Sh+kNFcYhXllfjsjfHtY0dxizQudqybuXToLiJKR4UPypDMO+GsChr

PJbMKc6aL4EsM4tTcbllO5bZ6Tg9ovoWw71n6OsSRY3Moe1UkK4JM8plyFIoeS/y

398k/N7GUqFZF1Bc4H/XM2PCdmmdfLIG8M7cg6TIW/Brru015PH4OIFRq9bgOPqB

JUPaWsECgYEA+sFptO0CdLAi6zWi8zVhNPKdsbNJtUsYSFpf+3mpVMHO7IT+uCxr

tULzBUQX/yDaFComHstzhk8coMjl5Dda5WTmRXDzNuDYAFXVXzemXz3ZIHJ4wAkz

gV9bubLM7hOgeSxy07dFNsDiDYJY91eTW/3LHspSc1N6qZXkLCBafd8CgYEAzHeL

g+XLvCdErP+vb7hILRyYdbNrBdXYZoC0bxN4lZ6hm3q7n3jbLWiNhIRfCBPKvcSq

zCVLaH/A18xXQIgDoIlFa5HVPAILj0rLzbyJflcPasoef+/FoGJFRwy1ByVS+sko

4fnsHOMF1cHc8tUNVAzI/7RX5ssQ4VBjqehf4gkCgYACAEcirX2Ght1QeTYasMNc

087UWzTsYHQKJ8Z6UEc8qOtI0erid2BIqwcbdKaoX4+993QkbMU4PithURkckCCG

kh6QUU1vk63Fmum//8axHeI8sw0poykpECTAP6AJClkOfn9QFzdTL4jeSLsDBkzj

wAu97ClqSDFDZzHR9FQkiwKBgDllcX+UGU33A/tARyIoa/Jl7ZJUzD02G2oixQPN

RnNRtXHs0RBiH7yuddN2SSr+S1JcC8oEyhdKjXrGfNO7mrEM97TLmj0fIdmWmIFn

ZH1XuRc0J72oNCTikSnxsjuQSavmnhhZTOOLAw9PPVPZZMVsVVwaZvZ9mH53T5LZ

jVjpAoGBALlu8lBiGXBV7r4+f4IWO3lSdUPdG2EJNpHR0f/TJOu98M0RB/3MF/5s

7m5VBJQHOC2jGBHPcSVtg1qVpJ2wH0yADnlGLnP4Ml2KcboARDUxEdF32O/yl+/+

1k81HHdL38wJYjE6Z+iszFhfek4uKtIUYf7nrxkvKOvP+FxIavO7

-----END RSA PRIVATE KEY-----

通過字元串encrypto success定位

v7 = 0i64;
  v8 = 0i64;
  WinExec("clickme.exe", 1u);
  v11 = \'98\';
  v10 = qword_44F3DC;                           // //\'76543210\'
  v12 = 0;
  v0 = sub_415930(0);
  sub_40BAB0(v0);
  v1 = 0;
  do
    *((_BYTE *)&v7 + v1++) = *((_BYTE *)&v10 + sub_40BA70() % 10);
  while ( v1 < 32 );
  v6 = v2;
  v9 = 0;
  v3 = sub_402D00(v2, (int)&v7);
  v4 = "encrypto success!";
  if ( !v3 )
    v4 = "encrypto false!";
  sub_402420((int)v4, v6);
           

v7 32位,全為0-9

re的刷題0
re的刷題0

動調發現每次不一樣,應該是随機的。

好多函數。

原型是wannacry,AES加密檔案,并使用非對稱加密算法RSA 2048加密随機密鑰。

#* -*- coding:utf-8 -*-
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import base64

# 私鑰
private_key = \'\'\'-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAyEc4zIZtCKBiKPOW8Xd5o9Mb5221zgAGvQv6CYNzVQAORKPQ
wjDgh77xVtDFmVF10+QOx5rCz/O3u5Zmpbyj7fNcbZjXcBDarHiD4B2PvxhwEwRF
nFuSXctTqlLJ4bmbW6JVUGLuX2hUvb9eLRb0LLEbbnGgGUk7G4/SZYs75EJIx2Dy
0x2Ir7mpL6I56kon42UFLQQAfTLm6aB1k2NSWTOB/s59vYy11/3FhVr97qaNCg7a
4wLJmO+fBZn8mpB71ZVOvu0cxnOlbyDMJ0nS2B2R+Aep/zeMWQr7JvYQbgd38VuK
N5W3LASF2fWBh6nNExbKlIIxB+qigFL61A5K1wIDAQABAoIBACWc2pnulQONu2Gd
fbeTjJCr0Q3BmOc7MgjG+wpWWY6ZGBTj/wy5STG1NnXrd3C3z70fk3cBJZ0QVG0y
bcyqhM7naXBbx/oP8EF70KiCZMCqwkGQB9K5j991lBzkt21hAkBPWF5kdggM+/02
t2UYbnsGN/Sh+kNFcYhXllfjsjfHtY0dxizQudqybuXToLiJKR4UPypDMO+GsChr
PJbMKc6aL4EsM4tTcbllO5bZ6Tg9ovoWw71n6OsSRY3Moe1UkK4JM8plyFIoeS/y
398k/N7GUqFZF1Bc4H/XM2PCdmmdfLIG8M7cg6TIW/Brru015PH4OIFRq9bgOPqB
JUPaWsECgYEA+sFptO0CdLAi6zWi8zVhNPKdsbNJtUsYSFpf+3mpVMHO7IT+uCxr
tULzBUQX/yDaFComHstzhk8coMjl5Dda5WTmRXDzNuDYAFXVXzemXz3ZIHJ4wAkz
gV9bubLM7hOgeSxy07dFNsDiDYJY91eTW/3LHspSc1N6qZXkLCBafd8CgYEAzHeL
g+XLvCdErP+vb7hILRyYdbNrBdXYZoC0bxN4lZ6hm3q7n3jbLWiNhIRfCBPKvcSq
zCVLaH/A18xXQIgDoIlFa5HVPAILj0rLzbyJflcPasoef+/FoGJFRwy1ByVS+sko
4fnsHOMF1cHc8tUNVAzI/7RX5ssQ4VBjqehf4gkCgYACAEcirX2Ght1QeTYasMNc
087UWzTsYHQKJ8Z6UEc8qOtI0erid2BIqwcbdKaoX4+993QkbMU4PithURkckCCG
kh6QUU1vk63Fmum//8axHeI8sw0poykpECTAP6AJClkOfn9QFzdTL4jeSLsDBkzj
wAu97ClqSDFDZzHR9FQkiwKBgDllcX+UGU33A/tARyIoa/Jl7ZJUzD02G2oixQPN
RnNRtXHs0RBiH7yuddN2SSr+S1JcC8oEyhdKjXrGfNO7mrEM97TLmj0fIdmWmIFn
ZH1XuRc0J72oNCTikSnxsjuQSavmnhhZTOOLAw9PPVPZZMVsVVwaZvZ9mH53T5LZ
jVjpAoGBALlu8lBiGXBV7r4+f4IWO3lSdUPdG2EJNpHR0f/TJOu98M0RB/3MF/5s
7m5VBJQHOC2jGBHPcSVtg1qVpJ2wH0yADnlGLnP4Ml2KcboARDUxEdF32O/yl+/+
1k81HHdL38wJYjE6Z+iszFhfek4uKtIUYf7nrxkvKOvP+FxIavO7
-----END RSA PRIVATE KEY-----
\'\'\'
text = \'\'\'R6AlR0HASXaugIAawobUR2CafHOfsCvvbAhPmFSODz/audwDYr/c3lQnzjL8eERYk4Tw4roclSen8Nlg4HoPh6F7FFGg+H8MC8JX+zIXFbStVvvyzgoU3gLZBut3Nz71xEeuuzjPKnz3sf4NfsPW6wB3TXiQXSEaRwp/oIfwp1WFkjYY3Ox9N/25PEPn407RYd/id9BScQ3h9mh4C/WRU3lxlXnHzuPGrVA7Gb7oEvUCduaPP13zKGwB+4RQMsOoHyID2F06dIp2RFrUiS5nf8T7THo+7HJDwWhxDgqAUK5zaMaF4Dv3sl38w7nEk3jGSiFmbx83ROVqULkfs+g4fA==
\'\'\'

# 公鑰
public_key = \'\'\'-----BEGIN PUBLIC KEY-----
hfgghftetet
-----END PUBLIC KEY-----\'\'\'
def rsa_encrypt(message):
    """校驗RSA加密 使用公鑰進行加密"""
    cipher = Cipher_pkcs1_v1_5.new(RSA.importKey(public_key))
    cipher_text = base64.b64encode(cipher.encrypt(message.encode())).decode()
    return cipher_text


def rsa_decrypt(text):
    """校驗RSA加密 使用私鑰進行解密"""
    cipher = Cipher_pkcs1_v1_5.new(RSA.importKey(private_key))
    retval = cipher.decrypt(base64.b64decode(text), \'ERROR\').decode(\'utf-8\')
    return retval


	
print rsa_decrypt(text)
#key:30776159143604297789676442413079

c=\'\'\'5C BC EA 89 BA 2B 18 27 79 3F 13 0A 8A 97 B4 9B CD 78 9B D8 35 92 05 45 4C 22 A5 69 37 EB 6E 2B 0E BD 84 0F 91 61 38 F6 F1 BA 99 19 41 72 07 91 F0 26 68 06 61 26 5C 20 35 DD CF FC 77 57 54 81 F2 F2 E4 AF BF A2 1D 29 AE 6C 08 3B 76 1B 66 B8 FE 72 CB D6 94 C3 D5 6A E7 0C 7A 28 DC BC AC 80\'\'\'.replace(\' \',\'\').lower()
print str

key = "30776159143604297789676442413079"
aes = AES.new(key.encode(\'utf-8\'), AES.MODE_ECB)
c = aes.decrypt(a2b_hex(c))

print c.replace(\' \',\'\')
#\' l a g { 3 8 5 f a 8 6 9 - 3 0 4 6 - 4 4 e e - 9 d 3 0 - c 0 3 5 5 1 2 7 3 8 6 7 }\'

           

day49 9.9

[UTCTF2020]babymips

day50 9.14

[GWCTF 2019]babyvm

*(_DWORD *)a1 = 0;
  *(_DWORD *)(a1 + 4) = 0x12;
  *(_DWORD *)(a1 + 8) = 0;
  *(_DWORD *)(a1 + 12) = 0;
  *(_QWORD *)(a1 + 16) = &unk_202060;           // opcode
  *(_BYTE *)(a1 + 24) = 0xF1u;
  *(_QWORD *)(a1 + 32) = sub_B5F;               // move
  *(_BYTE *)(a1 + 40) = 0xF2u;
  *(_QWORD *)(a1 + 48) = sub_A64;               // a1[0]^=a1[1],++a1[16]
  *(_BYTE *)(a1 + 56) = 0xF5u;
  *(_QWORD *)(a1 + 64) = sub_AC5;               // 輸入qword_2022A8長度==21,++a1[16]
  *(_BYTE *)(a1 + 72) = 0xF4u;
  *(_QWORD *)(a1 + 80) = sub_956;               // ++a1[16]
  *(_BYTE *)(a1 + 88) = 0xF7u;
  *(_QWORD *)(a1 + 96) = sub_A08;               // dw a1[0]=a1[3], qw ++a1[16]
  *(_BYTE *)(a1 + 104) = 0xF8u;
  *(_QWORD *)(a1 + 112) = sub_8F0;              // a[0]<==>a[1], qw ++a1[2]
  *(_BYTE *)(a1 + 120) = 0xF6u;
  *(_QWORD *)(a1 + 128) = sub_99C;              // dw a1[0]=a1[2]+2**a1[1]+3**a1[0], qw ++a1[16] 
           
v3 = (signed int *)(*(_QWORD *)(a1 + 16) + 2LL);
  v1 = *(unsigned __int8 *)(*(_QWORD *)(a1 + 16) + 1LL);
  switch ( (unsigned int)off_1130 )
  {
    case 0xE1u:
      *(_DWORD *)a1 = *((char *)qword_2022A8 + *v3);// a1[0] = A8[v3]
      break;
    case 0xE2u:
      *(_DWORD *)(a1 + 4) = *((char *)qword_2022A8 + *v3);// a1[1] = A8[v3]
      break;
    case 0xE3u:
      *(_DWORD *)(a1 + 8) = *((char *)qword_2022A8 + *v3);// a1[2] = A8[v3]
      break;
    case 0xE4u:
      *((_BYTE *)qword_2022A8 + *v3) = *(_DWORD *)a1;// A8[v3] = a1[0]
      break;
    case 0xE5u:
      *(_DWORD *)(a1 + 12) = *((char *)qword_2022A8 + *v3);// a1[3] = A8[v3]
      break;
    case 0xE7u:
      *((_BYTE *)qword_2022A8 + *v3) = *(_DWORD *)(a1 + 4);// A8[v3] = a1[1]
      break;
    default:
      break;
  }
  *(_QWORD *)(a1 + 16) += 6LL;
           
F1 move
	0xE1u a1[0] = A8[v3]
	0xE2U a1[1] = A8[v3]
	0XE3u a1[2] = A8[v3]
	0xE4u A8[v3] = a1[0]
	0xE5u a1[3] = A8[v3]
	0xE7u A8[v3] = a1[1]

F2 a1[0] ^= a1[1]
F7 a1[0] *= a1[3]
F8 a[0]<==>a[1]
F6 a1[0]=a1[2]+2**a1[1]+3**a1[0]
           

按照opcode還原,卡住了

F5
輸入flag
F1 E1 00 00 00 00
a[0] = flag[0]
F2 F1 E4 20 00 00 00 
a[0] ^= 
           

sub_E0B

for ( i = 0; **(_BYTE **)(a1 + 16) != *(_BYTE *)(16 * (i + 1LL) + a1 + 8); ++i )
    ;
(*(void (__fastcall **)(__int64))(16 * (i + 1LL) + a1 + 16))(a1);
           

opcode

(a1 + 16)不再是

&unk_202060

,那麼去找滿足條件的位置,

&unk_202060

是F5,下一個F5就是真正的

opcode

opcode解析

#* -*- coding:utf-8 -*-
def deOpcode(opcode):
	for i in range(len(opcode)):
		if opcode[i]==\'F5\':
			print \'input\'
		
		if opcode[i]==\'F4\':
			print \'done\'
		
		if opcode[i]==\'F2\':
			print \'a[0] ^= a1[1]\'

		if opcode[i]==\'F7\':
			print \'a[0] *= a1[3]\'

		if opcode[i]==\'F8\':
			print \'a[0]<==>a[1]\'

		if opcode[i]==\'F6\':
			print \'a[0]=a[2]+2*a[1]+3*a[0]\'

		if opcode[i]==\'F1\':
			if opcode[i+1] == \'E1\':
				print \'a[0] = flag[\'+opcode[i+2]+\']\'
			if opcode[i+1] == \'E2\':
				print \'a[1] = flag[\'+opcode[i+2]+\']\'
			if opcode[i+1] == \'E3\':
				print \'a[2] = flag[\'+opcode[i+2]+\']\'
			if opcode[i+1] == \'E4\':
				print \'flag[\'+opcode[i+2]+\'] = a[0]\'
			if opcode[i+1] == \'E5\':
				print \'a[3] = flag[\'+opcode[i+2]+\']\'
			if opcode[i+1] == \'E7\':
				print \'flag[\'+opcode[i+2]+\'] = a[1]\'
			i=i+6

opcode=\'\'\'F5 F1 E1 00 00 00 00 F1  E2 01 00 00 00 F2 F1 E4
00 00 00 00 F1 E1 01 00  00 00 F1 E2 02 00 00 00
F2 F1 E4 01 00 00 00 F1  E1 02 00 00 00 F1 E2 03
00 00 00 F2 F1 E4 02 00  00 00 F1 E1 03 00 00 00
F1 E2 04 00 00 00 F2 F1  E4 03 00 00 00 F1 E1 04
00 00 00 F1 E2 05 00 00  00 F2 F1 E4 04 00 00 00
F1 E1 05 00 00 00 F1 E2  06 00 00 00 F2 F1 E4 05
00 00 00 F1 E1 06 00 00  00 F1 E2 07 00 00 00 F1
E3 08 00 00 00 F1 E5 0C  00 00 00 F6 F7 F1 E4 06
00 00 00 F1 E1 07 00 00  00 F1 E2 08 00 00 00 F1
E3 09 00 00 00 F1 E5 0C  00 00 00 F6 F7 F1 E4 07
00 00 00 F1 E1 08 00 00  00 F1 E2 09 00 00 00 F1
E3 0A 00 00 00 F1 E5 0C  00 00 00 F6 F7 F1 E4 08
00 00 00 F1 E1 0D 00 00  00 F1 E2 13 00 00 00 F8
F1 E4 0D 00 00 00 F1 E7  13 00 00 00 F1 E1 0E 00
00 00 F1 E2 12 00 00 00  F8 F1 E4 0E 00 00 00 F1
E7 12 00 00 00 F1 E1 0F  00 00 00 F1 E2 11 00 00
00 F8 F1 E4 0F 00 00 00  F1 E7 11 00 00 00 F4\'\'\'
opcode = opcode.replace(\'\n\',\' \').split()
#print opcode
           

僞代碼

input
a[0] = flag[00]
a[1] = flag[01]
a1[0] ^= a1[1]
flag[00] = a[0]

a[0] = flag[01]
a[1] = flag[02]
a1[0] ^= a1[1]
flag[01] = a[0]

a[0] = flag[02]
a[1] = flag[03]
a1[0] ^= a1[1]
flag[02] = a[0]

a[0] = flag[03]
a[1] = flag[04]
a1[0] ^= a1[1]
flag[03] = a[0]

a[0] = flag[04]
a[1] = flag[05]
a1[0] ^= a1[1]
flag[04] = a[0]

a[0] = flag[05]
a[1] = flag[06]
a1[0] ^= a1[1]
flag[05] = a[0]
//flag 0-5位 flag[i] = flag[i]^flag[i+1]


a[0] = flag[06]
a[1] = flag[07]
a[2] = flag[08]
a[3] = flag[0C]
a[0]=a[2]+2**a[1]+3**a[0]  
a[0] *= a1[3]
flag[06] = a[0]            //flag[06] = (flag[08]+2*flag[07]+3*[06])*flag[0c]

a[0] = flag[07]
a[1] = flag[08]
a[2] = flag[09]
a[3] = flag[0C]
a[0]=a[2]+2*a[1]+3*a[0]
a[0] *= a1[3]
flag[07] = a[0]

a[0] = flag[08]
a[1] = flag[09]
a[2] = flag[0A]
a[3] = flag[0C]
a[0]=a[2]+2*a[1]+3*a[0]
a[0] *= a1[3]
flag[08] = a[0]
//flag 6-8位 flag[i] = (flag[i+2]+2*flag[i+1]+3*[i])*flag[12]


a[0] = flag[0D]
a[1] = flag[13]
a[0]<==>a[1]
flag[0D] = a[0]
flag[13] = a[1]

a[0] = flag[0E]
a[1] = flag[12]
a[0]<==>a[1]
flag[0E] = a[0]
flag[12] = a[1]

a[0] = flag[0F]
a[1] = flag[11]
a[0]<==>a[1]
flag[0F] = a[0]
flag[11] = a[1]
//flag 13-15 flag[i] <==> flag[32-i]
       19-17
    
done
           

按理說檢查函數就是

sub_F83

unsigned __int64 sub_F83()
{
  int i; // [rsp+Ch] [rbp-14h]
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  for ( i = 0; dword_2022A4 - 1 > i; ++i )
  {
    if ( *((_BYTE *)qword_2022A8 + i + 32) != aFzAmAmFmtSum[i] )
    {
      puts("WRONG!");
      exit(0);
    }
  }
  puts("Congratulation?");
  puts("tips: input is the start");
  return __readfsqword(0x28u) ^ v2;
}
           

但是

Congratulation?

...還有這個tips,在

aFzAmAmFmtSum

上面找到可疑資料

byte_202020

,檢視引用

.data:0000000000202020 byte_202020     db 69h, 45h, 2Ah, 37h, 9, 17h, 0C5h, 0Bh, 5Ch, 72h, 33h
.data:0000000000202020                                         ; DATA XREF: sub_F00+41↑o
.data:0000000000202020                 db 76h, 33h, 21h, 74h, 31h, 5Fh, 33h, 73h, 72h, 0Ch dup(0)
           
unsigned __int64 sub_F00()
{
  int i; // [rsp+Ch] [rbp-14h]
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  for ( i = 0; dword_2022A4 - 1 > i; ++i )
  {
    if ( *((_BYTE *)qword_2022A8 + i) != byte_202020[i] )
      exit(0);
  }
  return __readfsqword(0x28u) ^ v2;
}
           

這應該是真的了。

trueEnFlag = \'69 45 2A 37 09 17 C5 0B 5C 72 33 76 33 21 74 31 5F 33 73 72\'
trueEnFlag = trueEnFlag.split()
flag=[0]*21
for i in range(len(trueEnFlag)):
	flag[i] = int(trueEnFlag[i],16)
	
flag[6] = 118
flag[7] = 51
flag[8] = 95


for i in range(5,-1,-1):
	flag[i]=flag[i]^flag[i+1]

for i in range(13,16):
	flag[i],flag[32-i]=flag[32-i],flag[i]

a=\'\'
for i in flag:
	a+= chr(i)
print len(a)	
           

angr

.text:0000000000001081                 lea     rdi, aAndTheFlagIsGw ; "And the flag is GWHT{true flag}"
           
import angr

p = angr.Project(\'./babyvm\')  
state = p.factory.entry_state()   
simgr = p.factory.simgr(state)  

simgr.explore(find=0x00401081)  
flag = simgr.found[0].posix.dumps(0)
print(flag)

           
re的刷題0

國賽

.text:00401151     loc_401151:                             ; CODE XREF: .text:loc_401151↑j
.text:00401151                     jmp     short near ptr loc_401151+1
           
printf("plz input your flag:");
  scanf("%42s", byte_40336C);
  Handles = CreateThread(0, 0, StartAddress, 0, 0, 0);
  v3 = CreateThread(0, 0, loc_401200, 0, 0, 0);
  CreateThread(0, 0, sub_401240, 0, 0, 0);
  WaitForMultipleObjects(2u, &Handles, 1, 0xFFFFFFFF);
  v0 = 0;
  do
  {
    if ( byte_40336C[v0] != byte_402150[v0] )
           
.text:004011BF                 xor     eax, eax
.text:004011C1                 jnz     short loc_4011C8
.text:004011C3                 call    near ptr loc_4011C8+1
           
.text:0040116B                 jge     loc_4011F1
.text:00401171                 mov     ecx, [ebp-4]
.text:00401174                 movzx   edx, byte ptr [ecx+40336Ch]
.text:0040117B                 sar     edx, 2
.text:0040117E                 mov     eax, [ebp-4]
.text:00401181                 movzx   ecx, byte_40336C[eax]
.text:00401188                 shl     ecx, 6
.text:0040118B                 xor     edx, ecx
.text:0040118D                 mov     eax, [ebp-4]
.text:00401190                 mov     [eax+40336Ch], dl
.text:00401196                 mov     ecx, [ebp-4]
.text:00401199                 movzx   edx, byte_40336C[ecx]
.text:004011A0                 xor     edx, 23h
.text:004011A3                 mov     eax, [ebp-4]
.text:004011A6                 mov     byte_40336C[eax], dl
.text:004011AC                 push    6               ; dwMilliseconds
.text:004011AE                 call    ds:Sleep
.text:004011B4                 mov     ebx, large fs:30h
.text:004011BB                 movzx   ebx, byte ptr [ebx+2]
.text:004011BF                 xor     eax, eax
.text:004011C1                 jnz     short loc_4011C8
.text:004011C3                 call    sub_4011C9
           
re的刷題0

起飛

flag=\'\'
a=\'\'\'62 6C 7F 76  7A 7B 66 73 76 50 52 7D
40 54 55 79 40 49 47 4D  74 19 7B 6A 42 0A 4F 52
7D 69 4F 53 0C 64 10 0F  1E 4A 67 03 7C 67 02 6A
31 67 61 37 7A 62 2C 2C  0F 6E 17 00 16 0F 16 0A
6D 62 73 25 39 76 2E 1C  63 78 2B 74 32 16 20 22
44 19 00 00 00 00 00 4E\'\'\'
b = a.replace(\'\n\',\' \').replace(\'  \',\' \').split(\' \')
for i in range(len(b)):
	flag+=chr(int(b[i],16)^(i+0x17))
print flag

           

utflag{mips_cpp_gang_5VDm:~`N]ze;)5%vZ=C\'C(r#$q=*efD"ZNY_GX>6&sn.wF8\(v*mvA@\'}efghi\)

神奇

等待單個線程傳回 WaitForSingleObject

1. 函數原型

DWORD WINAPI WaitForSingleObject(
    _In_ HANDLE hHandle,
    _In_ DWORD dwMilliseconds
    );
           

2.參數說明

第一個參數

_In_ HANDLE hHandle

是對象的句柄,可以是以下幾種:

  • Change notification
  • Console input
  • Event
  • Memory resource notification
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer

第二個參數

_In_ DWORD dwMilliseconds

為等待時間,以毫秒為機關。參數dwMilliseconds有兩個具有特殊意義的值:0和INFINITE。若為0,則該函數立即傳回;若為INFINITE,則線程一直被挂起,直到hHandle所指向的對象變為有信号狀态時為止。

3.傳回值

  • WAIT_ABANDONED 0x00000080:當hHandle為mutex時,如果擁有mutex的線程在結束時沒有釋放核心對象會引發此傳回值。
  • WAIT_OBJECT_0 0x00000000 :指定的對象出有有信号狀态
  • WAIT_TIMEOUT 0x00000102:等待逾時
  • WAIT_FAILED 0xFFFFFFFF :出現錯誤,可通過GetLastError得到錯誤代碼

等待多個線程傳回 WaitForMulitpleObjects

1. 函數原型

DWORD WINAPI WaitForMultipleObjects(
  _In_       DWORD   nCount,
  _In_ const HANDLE  *lpHandles,
  _In_       BOOL    bWaitAll,
  _In_       DWORD   dwMilliseconds
);
           

2.參數說明

  • 第一個參數

    DWORD dwCount

    為等待的核心對象個數,可以是0到MAXIMUM_WAIT_OBJECTS(64)中的一個值。
  • 第二個參數

    CONST HANDLE* phObjects

    為一個存放被等待的核心對象句柄的數組
  • 第三個參數

    BOOL bWaitAll

    是否等到所有核心對象為已通知狀态後才傳回,如果為TRUE,則隻有當等待的所有核心對象為已通知狀态時函數才傳回,如果為FALSE,則隻要一個核心對象為已通知狀态,則該函數傳回。
  • 第四個參數

    DWORD dwMilliseconds

    為等待時間,和WaitForSingleObject中的dwMilliseconds參數類似。

知識點

NET語言的全稱應該是ASP.NET,是微軟新推出的一種程式設計架構理論或者說是一種程式設計标準,它可以通過微軟出品的Visual Studio 開發工具進行項目開發,應用于網站類的開發一般使用C#語言進行編寫,應用程式類一般使用VB進行編寫。

unity是用C#開發,被編譯到了 Assembly-CSharp.dll

C#是微軟公司釋出的一種由C和C++衍生出來的面向對象的程式設計語言、運作于.NET Framework和.NET Core(完全開源,跨平台)之上的進階程式設計語言。

dnSpy 是一款針對 .NET 程式的逆向工程工具。

lo、hiword

LOWORD()得到一個32bit數的低16bit

HIWORD()得到一個32bit數的高16bit

LOBYTE()得到一個16bit數最低(最右邊)那個位元組

HIBYTE()得到一個16bit數最高(最左邊)那個位元組

IDA逆向常用宏定義

/*

   This file contains definitions used by the Hex-Rays decompiler output.
   It has type definitions and convenience macros to make the
   output more readable.

   Copyright (c) 2007-2011 Hex-Rays

*/

#if defined(__GNUC__)
  typedef          long long ll;
  typedef unsigned long long ull;
  #define __int64 long long
  #define __int32 int
  #define __int16 short
  #define __int8  char
  #define MAKELL(num) num ## LL
  #define FMT_64 "ll"
#elif defined(_MSC_VER)
  typedef          __int64 ll;
  typedef unsigned __int64 ull;
  #define MAKELL(num) num ## i64
  #define FMT_64 "I64"
#elif defined (__BORLANDC__)
  typedef          __int64 ll;
  typedef unsigned __int64 ull;
  #define MAKELL(num) num ## i64
  #define FMT_64 "L"
#else
  #error "unknown compiler"
#endif
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;

typedef          char   int8;
typedef   signed char   sint8;
typedef unsigned char   uint8;
typedef          short  int16;
typedef   signed short  sint16;
typedef unsigned short  uint16;
typedef          int    int32;
typedef   signed int    sint32;
typedef unsigned int    uint32;
typedef ll              int64;
typedef ll              sint64;
typedef ull             uint64;

// Partially defined types:
#define _BYTE  uint8
#define _WORD  uint16
#define _DWORD uint32
#define _QWORD uint64
#if !defined(_MSC_VER)
#define _LONGLONG __int128
#endif

#ifndef _WINDOWS_
typedef int8 BYTE;
typedef int16 WORD;
typedef int32 DWORD;
typedef int32 LONG;
#endif
typedef int64 QWORD;
#ifndef __cplusplus
typedef int bool;       // we want to use bool in our C programs
#endif

// Some convenience macros to make partial accesses nicer
// first unsigned macros:
#define LOBYTE(x)   (*((_BYTE*)&(x)))   // low byte
#define LOWORD(x)   (*((_WORD*)&(x)))   // low word
#define LODWORD(x)  (*((_DWORD*)&(x)))  // low dword
#define HIBYTE(x)   (*((_BYTE*)&(x)+1))
#define HIWORD(x)   (*((_WORD*)&(x)+1))
#define HIDWORD(x)  (*((_DWORD*)&(x)+1))
#define BYTEn(x, n)   (*((_BYTE*)&(x)+n))
#define WORDn(x, n)   (*((_WORD*)&(x)+n))
#define BYTE1(x)   BYTEn(x,  1)         // byte 1 (counting from 0)
#define BYTE2(x)   BYTEn(x,  2)
#define BYTE3(x)   BYTEn(x,  3)
#define BYTE4(x)   BYTEn(x,  4)
#define BYTE5(x)   BYTEn(x,  5)
#define BYTE6(x)   BYTEn(x,  6)
#define BYTE7(x)   BYTEn(x,  7)
#define BYTE8(x)   BYTEn(x,  8)
#define BYTE9(x)   BYTEn(x,  9)
#define BYTE10(x)  BYTEn(x, 10)
#define BYTE11(x)  BYTEn(x, 11)
#define BYTE12(x)  BYTEn(x, 12)
#define BYTE13(x)  BYTEn(x, 13)
#define BYTE14(x)  BYTEn(x, 14)
#define BYTE15(x)  BYTEn(x, 15)
#define WORD1(x)   WORDn(x,  1)
#define WORD2(x)   WORDn(x,  2)         // third word of the object, unsigned
#define WORD3(x)   WORDn(x,  3)
#define WORD4(x)   WORDn(x,  4)
#define WORD5(x)   WORDn(x,  5)
#define WORD6(x)   WORDn(x,  6)
#define WORD7(x)   WORDn(x,  7)

// now signed macros (the same but with sign extension)
#define SLOBYTE(x)   (*((int8*)&(x)))
#define SLOWORD(x)   (*((int16*)&(x)))
#define SLODWORD(x)  (*((int32*)&(x)))
#define SHIBYTE(x)   (*((int8*)&(x)+1))
#define SHIWORD(x)   (*((int16*)&(x)+1))
#define SHIDWORD(x)  (*((int32*)&(x)+1))
#define SBYTEn(x, n)   (*((int8*)&(x)+n))
#define SWORDn(x, n)   (*((int16*)&(x)+n))
#define SBYTE1(x)   SBYTEn(x,  1)
#define SBYTE2(x)   SBYTEn(x,  2)
#define SBYTE3(x)   SBYTEn(x,  3)
#define SBYTE4(x)   SBYTEn(x,  4)
#define SBYTE5(x)   SBYTEn(x,  5)
#define SBYTE6(x)   SBYTEn(x,  6)
#define SBYTE7(x)   SBYTEn(x,  7)
#define SBYTE8(x)   SBYTEn(x,  8)
#define SBYTE9(x)   SBYTEn(x,  9)
#define SBYTE10(x)  SBYTEn(x, 10)
#define SBYTE11(x)  SBYTEn(x, 11)
#define SBYTE12(x)  SBYTEn(x, 12)
#define SBYTE13(x)  SBYTEn(x, 13)
#define SBYTE14(x)  SBYTEn(x, 14)
#define SBYTE15(x)  SBYTEn(x, 15)
#define SWORD1(x)   SWORDn(x,  1)
#define SWORD2(x)   SWORDn(x,  2)
#define SWORD3(x)   SWORDn(x,  3)
#define SWORD4(x)   SWORDn(x,  4)
#define SWORD5(x)   SWORDn(x,  5)
#define SWORD6(x)   SWORDn(x,  6)
#define SWORD7(x)   SWORDn(x,  7)


// Helper functions to represent some assembly instructions.

#ifdef __cplusplus

// Fill memory block with an integer value
inline void memset32(void *ptr, uint32 value, int count)
{
  uint32 *p = (uint32 *)ptr;
  for ( int i=0; i < count; i++ )
    *p++ = value;
}

// Generate a reference to pair of operands
template<class T>  int16 __PAIR__( int8  high, T low) { return ((( int16)high) << sizeof(high)*8) | uint8(low); }
template<class T>  int32 __PAIR__( int16 high, T low) { return ((( int32)high) << sizeof(high)*8) | uint16(low); }
template<class T>  int64 __PAIR__( int32 high, T low) { return ((( int64)high) << sizeof(high)*8) | uint32(low); }
template<class T> uint16 __PAIR__(uint8  high, T low) { return (((uint16)high) << sizeof(high)*8) | uint8(low); }
template<class T> uint32 __PAIR__(uint16 high, T low) { return (((uint32)high) << sizeof(high)*8) | uint16(low); }
template<class T> uint64 __PAIR__(uint32 high, T low) { return (((uint64)high) << sizeof(high)*8) | uint32(low); }

// rotate left
template<class T> T __ROL__(T value, uint count)
{
  const uint nbits = sizeof(T) * 8;
  count %= nbits;

  T high = value >> (nbits - count);
  value <<= count;
  value |= high;
  return value;
}

// rotate right
template<class T> T __ROR__(T value, uint count)
{
  const uint nbits = sizeof(T) * 8;
  count %= nbits;

  T low = value << (nbits - count);
  value >>= count;
  value |= low;
  return value;
}

// carry flag of left shift
template<class T> int8 __MKCSHL__(T value, uint count)
{
  const uint nbits = sizeof(T) * 8;
  count %= nbits;

  return (value >> (nbits-count)) & 1;
}

// carry flag of right shift
template<class T> int8 __MKCSHR__(T value, uint count)
{
  return (value >> (count-1)) & 1;
}

// sign flag
template<class T> int8 __SETS__(T x)
{
  if ( sizeof(T) == 1 )
    return int8(x) < 0;
  if ( sizeof(T) == 2 )
    return int16(x) < 0;
  if ( sizeof(T) == 4 )
    return int32(x) < 0;
  return int64(x) < 0;
}

// overflow flag of subtraction (x-y)
template<class T, class U> int8 __OFSUB__(T x, U y)
{
  if ( sizeof(T) < sizeof(U) )
  {
    U x2 = x;
    int8 sx = __SETS__(x2);
    return (sx ^ __SETS__(y)) & (sx ^ __SETS__(x2-y));
  }
  else
  {
    T y2 = y;
    int8 sx = __SETS__(x);
    return (sx ^ __SETS__(y2)) & (sx ^ __SETS__(x-y2));
  }
}

// overflow flag of addition (x+y)
template<class T, class U> int8 __OFADD__(T x, U y)
{
  if ( sizeof(T) < sizeof(U) )
  {
    U x2 = x;
    int8 sx = __SETS__(x2);
    return ((1 ^ sx) ^ __SETS__(y)) & (sx ^ __SETS__(x2+y));
  }
  else
  {
    T y2 = y;
    int8 sx = __SETS__(x);
    return ((1 ^ sx) ^ __SETS__(y2)) & (sx ^ __SETS__(x+y2));
  }
}

// carry flag of subtraction (x-y)
template<class T, class U> int8 __CFSUB__(T x, U y)
{
  int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);
  if ( size == 1 )
    return uint8(x) < uint8(y);
  if ( size == 2 )
    return uint16(x) < uint16(y);
  if ( size == 4 )
    return uint32(x) < uint32(y);
  return uint64(x) < uint64(y);
}

// carry flag of addition (x+y)
template<class T, class U> int8 __CFADD__(T x, U y)
{
  int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);
  if ( size == 1 )
    return uint8(x) > uint8(x+y);
  if ( size == 2 )
    return uint16(x) > uint16(x+y);
  if ( size == 4 )
    return uint32(x) > uint32(x+y);
  return uint64(x) > uint64(x+y);
}

#else
// The following definition is not quite correct because it always returns
// uint64. The above C++ functions are good, though.
#define __PAIR__(high, low) (((uint64)(high)<<sizeof(high)*8) | low)
// For C, we just provide macros, they are not quite correct.
#define __ROL__(x, y) __rotl__(x, y)      // Rotate left
#define __ROR__(x, y) __rotr__(x, y)      // Rotate right
#define __CFSHL__(x, y) invalid_operation // Generate carry flag for (x<<y)
#define __CFSHR__(x, y) invalid_operation // Generate carry flag for (x>>y)
#define __CFADD__(x, y) invalid_operation // Generate carry flag for (x+y)
#define __CFSUB__(x, y) invalid_operation // Generate carry flag for (x-y)
#define __OFADD__(x, y) invalid_operation // Generate overflow flag for (x+y)
#define __OFSUB__(x, y) invalid_operation // Generate overflow flag for (x-y)
#endif

// No definition for rcl/rcr because the carry flag is unknown
#define __RCL__(x, y)    invalid_operation // Rotate left thru carry
#define __RCR__(x, y)    invalid_operation // Rotate right thru carry
#define __MKCRCL__(x, y) invalid_operation // Generate carry flag for a RCL
#define __MKCRCR__(x, y) invalid_operation // Generate carry flag for a RCR
#define __SETP__(x, y)   invalid_operation // Generate parity flag for (x-y)

// In the decompilation listing there are some objects declarared as _UNKNOWN
// because we could not determine their types. Since the C compiler does not
// accept void item declarations, we replace them by anything of our choice,
// for example a char:

#define _UNKNOWN char

#ifdef _MSC_VER
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif
           

Tea/XTea/XXTea

Tea

在密碼學中,微型加密算法(Tiny Encryption Algorithm,TEA)是一種易于描述和執行的塊密碼,通常隻需要很少的代碼就可實作。其設計者是劍橋大學計算機實驗室的大衛 · 惠勒與羅傑 · 尼達姆。

參考代碼:

#include <stdint.h>

void encrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */
    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i < 32; i++) {                       /* basic cycle start */
        sum += delta;
        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);  
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}

void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */
    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<32; i++) {                         /* basic cycle start */
        v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        sum -= delta;                                   
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}
int main()
{
    uint32_t v[2]={1,2},k[4]={2,2,3,4};
    // v為要加密的資料是兩個32位無符号整數
    // k為加密解密密鑰,為4個32位無符号整數,即密鑰長度為128位
    printf("加密前原始資料:%u %u\n",v[0],v[1]);
    encrypt(v, k);
    printf("加密後的資料:%u %u\n",v[0],v[1]);
    decrypt(v, k);
    printf("解密後的資料:%u %u\n",v[0],v[1]);
    return 0;
}

           

XTea

XTEA是TEA的更新版,增加了更多的密鑰表,移位和異或操作等等,設計者是Roger Needham, David Wheeler

#include <stdio.h>
#include <stdint.h>
 
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
 
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
    for (i=0; i < num_rounds; i++) {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
    }
    v[0]=v0; v[1]=v1;
}
 
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    for (i=0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    }
    v[0]=v0; v[1]=v1;
}
 
int main()
{
    uint32_t v[2]={1,2};
    uint32_t const k[4]={2,2,3,4};
    unsigned int r=32;//num_rounds建議取值為32
    // v為要加密的資料是兩個32位無符号整數
    // k為加密解密密鑰,為4個32位無符号整數,即密鑰長度為128位
    printf("加密前原始資料:%u %u\n",v[0],v[1]);
    encipher(r, v, k);
    printf("加密後的資料:%u %u\n",v[0],v[1]);
    decipher(r, v, k);
    printf("解密後的資料:%u %u\n",v[0],v[1]);
    return 0;
}

           

XXTea

XXTEA,又稱Corrected Block TEA,是XTEA的更新版,設計者是Roger Needham, David Wheeler

#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
 
void btea(uint32_t *v, int n, uint32_t const key[4])
{
    uint32_t y, z, sum;
    unsigned p, rounds, e;
    if (n > 1)            /* Coding Part */
    {
        rounds = 6 + 52/n;
        sum = 0;
        z = v[n-1];
        do
        {
            sum += DELTA;
            e = (sum >> 2) & 3;
            for (p=0; p<n-1; p++)
            {
                y = v[p+1];
                z = v[p] += MX;
            }
            y = v[0];
            z = v[n-1] += MX;
        }
        while (--rounds);
    }
    else if (n < -1)      /* Decoding Part */
    {
        n = -n;
        rounds = 6 + 52/n;
        sum = rounds*DELTA;
        y = v[0];
        do
        {
            e = (sum >> 2) & 3;
            for (p=n-1; p>0; p--)
            {
                z = v[p-1];
                y = v[p] -= MX;
            }
            z = v[n-1];
            y = v[0] -= MX;
            sum -= DELTA;
        }
        while (--rounds);
    }
}
 
 
int main()
{
    uint32_t v[2]= {1,2};
    uint32_t const k[4]= {2,2,3,4};
    int n= 2; //n的絕對值表示v的長度,取正表示加密,取負表示解密
    // v為要加密的資料是兩個32位無符号整數
    // k為加密解密密鑰,為4個32位無符号整數,即密鑰長度為128位
    printf("加密前原始資料:%u %u\n",v[0],v[1]);
    btea(v, n, k);
    printf("加密後的資料:%u %u\n",v[0],v[1]);
    btea(v, -n, k);
    printf("解密後的資料:%u %u\n",v[0],v[1]);
    return 0;
}
           
############################################################  
#                                                          #  
# The implementation of PHPRPC Protocol 3.0                #  
#                                                          #  
# xxtea.py                                                 #  
#                                                          #  
# Release 3.0.0                                            #  
# Copyright (c) 2005-2008 by Team-PHPRPC                   #  
#                                                          #  
# WebSite:  http://www.phprpc.org/                         #  
#           http://www.phprpc.net/                         #  
#           http://www.phprpc.com/                         #  
#           http://sourceforge.net/projects/php-rpc/       #  
#                                                          #  
# Authors:  Ma Bingyao <[email protected]>                  #  
#                                                          #  
# This file may be distributed and/or modified under the   #  
# terms of the GNU Lesser General Public License (LGPL)    #  
# version 3.0 as published by the Free Software Foundation #  
# and appearing in the included file LICENSE.              #  
#                                                          #  
############################################################  
#  
# XXTEA encryption arithmetic library.  
#  
# Copyright (C) 2005-2008 Ma Bingyao <[email protected]>  
# Version: 1.0  
# LastModified: Oct 5, 2008  
# This library is free.  You can redistribute it and/or modify it.  
  
import struct  
  
_DELTA = 0x9E3779B9  
  
def _long2str(v, w):  
    n = (len(v) - 1) << 2  
    if w:  
        m = v[-1]  
        if (m < n - 3) or (m > n): return \'\'  
        n = m  
    s = struct.pack(\'<%iL\' % len(v), *v)  
    return s[0:n] if w else s  
  
def _str2long(s, w):  
    n = len(s)  
    m = (4 - (n & 3) & 3) + n  
    s = s.ljust(m, "\0")  
    v = list(struct.unpack(\'<%iL\' % (m >> 2), s))  
    if w: v.append(n)  
    return v  
  
def encrypt(str, key):  
    if str == \'\': return str  
    v = _str2long(str, True)  
    k = _str2long(key.ljust(16, "\0"), False)  
    n = len(v) - 1  
    z = v[n]  
    y = v[0]  
    sum = 0  
    q = 6 + 52 // (n + 1)  
    while q > 0:  
        sum = (sum + _DELTA) & 0xffffffff  
        e = sum >> 2 & 3  
        for p in xrange(n):  
            y = v[p + 1]  
            v[p] = (v[p] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff  
            z = v[p]  
        y = v[0]  
        v[n] = (v[n] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[n & 3 ^ e] ^ z))) & 0xffffffff  
        z = v[n]  
        q -= 1  
    return _long2str(v, False)  
  
def decrypt(str, key):  
    if str == \'\': return str  
    v = _str2long(str, False)  
    k = _str2long(key.ljust(16, "\0"), False)  
    n = len(v) - 1  
    z = v[n]  
    y = v[0]  
    q = 6 + 52 // (n + 1)  
    sum = (q * _DELTA) & 0xffffffff  
    while (sum != 0):  
        e = sum >> 2 & 3  
        for p in xrange(n, 0, -1):  
            z = v[p - 1]  
            v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff  
            y = v[p]  
        z = v[n]  
        v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffff  
        y = v[0]  
        sum = (sum - _DELTA) & 0xffffffff  
    return _long2str(v, True)  
  
if __name__ == "__main__":  
    print decrypt(encrypt(\'Hello XXTEA!\', \'16bytelongstring\'), \'16bytelongstring\')  
           

原文連結:https://blog.csdn.net/gsls200808/java/article/details/48243019

write/readfile

BOOL WriteFile( 
  HANDLE hFile, 
  LPCVOID lpBuffer, 
  DWORD nNumberOfBytesToWrite, 
  LPDWORD lpNumberOfBytesWritten, 
  LPOVERLAPPED lpOverlapped
); 
/**
參量
hFile
[in]處理要寫入的檔案。必須已使用GENERIC_WRITE通路該檔案的檔案句柄。
lpBuffer
[in]指向包含要寫入檔案的資料的緩沖區的指針。
nNumberOfBytesToWrite
[輸入]要寫入檔案的位元組數。

零值表示空寫入操作。空寫入操作不會寫入任何位元組,但是會導緻時間戳發生變化。此功能不會截斷檔案。要截斷或擴充檔案,請使用SetEndOfFile函數。

lpNumberOfBytesWritten
[out]指向此函數調用寫入的位元組數的指針。在執行操作或檢查錯誤之前,此功能将此值設定為零。
lpOverlapped
[輸入]不支援。設定為NULL。
**/
           
BOOL ReadFile(
  HANDLE hFile,
  LPVOID lpBuffer,
  DWORD nNumberOfBytesToRead,
  LPDWORD lpNumberOfBytesRead,
  LPOVERLAPPED lpOverlapped
);
/**
參量
hFile
[in]處理要讀取的檔案。必須已使用GENERIC_READ通路該檔案的檔案句柄。此參數不能是套接字句柄。
lpBuffer
[out]指向緩沖區的指針,該緩沖區接收從檔案讀取的資料。
nNumberOfBytesToRead
[in]要從檔案讀取的位元組數。
lpNumberOfBytesRead
[out]指向讀取的位元組數的指針。在執行操作或檢查錯誤之前,此功能将此值設定為零。
lpOverlapped
[輸入]不支援。設定為NUL
**/
           

AEH

AddVectoredExceptionHandler function

Registers a vectored exception handler.

  • Syntax
PVOID AddVectoredExceptionHandler(
  ULONG                       First,
  PVECTORED_EXCEPTION_HANDLER Handler
);
           
  • Return value

If the function succeeds, the return value is a handle to the exception handler.

If the function fails, the return value is NULL.

異常處理

pysm4

pysm4是國密SM4算法的Python實作, 提供了

encrypt

decrypt

encrypt_ecb

decrypt_ecb

encrypt_cbc

decrypt_cbc

等函數用于加密解密, 用法如下:

1.

encrypt

decrypt

>>> from pysm4 import encrypt, decrypt
# 明文
>>> clear_num = 0x0123456789abcdeffedcba9876543210
# 密鑰
>>> mk = 0x0123456789abcdeffedcba9876543210
# 加密
>>> cipher_num = encrypt(clear_num, mk)
>>> hex(cipher_num)[2:].replace(\'L\', \'\')
\'681edf34d206965e86b3e94f536e4246\'
# 解密
>>> clear_num == decrypt(cipher_num, mk)
True
           

2.

encrypt_ecb

decrypt_ecb

>>> from pysm4 import encrypt_ecb, decrypt_ecb
# 明文
>>> plain_text = \'pysm4是國密SM4算法的Python實作\'
# 密鑰
>>> key = \'hello, world!\'  # 密鑰長度小于等于16位元組
# 加密
>>> cipher_text = encrypt_ecb(plain_text, key)
>>> cipher_text
\'ng3L4ldgvsZciAgx3LhplDvIzrd0+GXiNqNmd1VW0YOlwo+ojtpownOCbnxbq/3y\'
# 解密
>>> plain_text == decrypt_ecb(cipher_text, key)
True
           

3.

encrypt_cbc

decrypt_cbc

>>> from pysm4 import encrypt_cbc, decrypt_cbc
# 明文
>>> plain_text = \'pysm4是國密SM4算法的Python實作\'
# 密鑰
>>> key = \'hello, world!\'  # 密鑰 長度小于等于16位元組
# 初始化向量
>>> iv = \'11111111\'        # 初始化向量  長度小于等于16位元組
# 加密
>>> cipher_text = encrypt_cbc(plain_text, key, iv)
\'cTsdKRSH2FqIJf22NHMjX5ZFHghR4ZtJ10wbNwj2//bJSElBXVeMtFycjdlVKP15\'
# 解密
>>> plain_text == decrypt_cbc(cipher_text, key, iv)
True
           

idc

idc基礎

llvm

底層虛拟機

Low Level Virtual Machine

LLVM是構架編譯器(compiler)的架構系統,C++編寫,用于優化以任意程式語言編寫的程式的編譯時間(compile-time)、連結時間(link-time)、運作時間(run-time)以及空閑時間(idle-time)。

優勢

傳統編譯器分三個階段:

前端(Frontend)-- 優化器(Optimizer)-- 後端(Backend)

前端負責分析源代碼,可以檢查文法級錯誤,并建構針對語言的抽象文法樹(AST);抽象文法樹可以進一步轉換為優化,最終轉為新的表示方式,然後再交給讓優化器和後端處理;最終由後端生成可執行的機器碼。

llvm:

前端可以使用不同的編譯工具對代碼檔案做詞法分析以形成抽象文法樹AST,然後将分析好的代碼轉換成LLVM的中間表示IR(intermediate representation);中間部分的優化器隻對中間表示IR操作,通過一系列的pass對IR做優化;後端負責将優化好的IR解釋成對應平台的機器碼。LLVM的優點在于,中間表示IR代碼編寫良好,而且不同的前端語言最終都轉換成同一種的IR。

IR

unsigned add1(unsigned a, unsigned b) {
  return a+b;
}

// Perhaps not the most efficient way to add two numbers.
unsigned add2(unsigned a, unsigned b) {
  if (a == 0) return b;
  return add2(a-1, b+1);
}
           
define i32 @add1(i32 %a, i32 %b) {
entry:
  %tmp1 = add i32 %a, %b
  ret i32 %tmp1
}

define i32 @add2(i32 %a, i32 %b) {
entry:
  %tmp1 = icmp eq i32 %a, 0
  br i1 %tmp1, label %done, label %recurse

recurse:
  %tmp2 = sub i32 %a, 1
  %tmp3 = add i32 %b, 1
  %tmp4 = call i32 @add2(i32 %tmp2, i32 %tmp3)
  ret i32 %tmp4

done:
  ret i32 %b
}
           

LLVM編譯工具鍊編譯流程

re的刷題0
clang -c -emit-llvm test1.c -o test1.bc           編譯産生位元組碼

clang -S -emit-llvm test.c -o test.ll             編譯産生可視化位元組碼

llvm-dis test1.bc test1.ll                        bc位元組碼轉為可視化位元組碼ll

llvm-as test1.ll test1.bc                         可視化位元組碼轉為位元組碼b
           

https://blog.csdn.net/Night_ZW/article/details/55100646

sudo apt-get install subversion
sudo apt-get install cmake
           

測試

#hello.c
#include <stdio.h>
int main(){
	//first
	printf("hello world\n");
	return 0;

}
           
clang -emit-llvm -c hello.c -o hello.bc    生成位元組碼檔案
clang hello.c -o hello.out                 生成可執行檔案
           
#運作
./hello.out
lli hello.bc
           
#llvm中間碼IR
./llvm-dis hello.bc –o hello.ll
           
; ModuleID = \'hello.bc\'
source_filename = "hello_world.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1

; Function Attrs: noinline nounwind uwtable
define i32 @main() #0 {
  %1 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0))
  ret i32 0
}

declare i32 @printf(i8*, ...) #1

attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.ident = !{!0}

!0 = !{!"Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)"}

           
llc hello.bc -o hello.s               生成彙編代碼
           
.text
	.file	"hello.bc"
	.globl	main
	.p2align	4, 0x90
	.type	main,@function
main:                                   # @main
	.cfi_startproc
# BB#0:
	pushq	%rbp
.Lcfi0:
	.cfi_def_cfa_offset 16
.Lcfi1:
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
.Lcfi2:
	.cfi_def_cfa_register %rbp
	subq	$16, %rsp
	movl	$0, -4(%rbp)
	movl	$.L.str, %edi
	xorl	%eax, %eax
	callq	printf
	xorl	%eax, %eax
	addq	$16, %rsp
	popq	%rbp
	retq
.Lfunc_end0:
	.size	main, .Lfunc_end0-main
	.cfi_endproc

	.type	.L.str,@object          # @.str
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	"hello world\n"
	.size	.L.str, 13


	.ident	"Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)"
	.section	".note.GNU-stack","",@progbits
           

ollvm

#include <stdio.h>
int main() {
  int t=7;
  if(t<4){
  t++;
  }else{
        switch(t){
                case 1:printf("1\n");break;
                case 2:printf("2\n");break;
                case 3:printf("3\n");break;
                case 4:printf("4\n");break;

        }
  }
  printf("hello world\n");
  return 0;
}

           

運作

re的刷題0
re的刷題0
re的刷題0

堆棧平衡

#include<stdio.h>
int addd(int a,int b)
{
    
    return a + b;
}
void main()
{ 
	printf("aaa");
  	printf("%d",addd(1,2));
}
           

安卓

内容入口 含義解釋
AndroidManifest.xml 二進制xml檔案,提供裝置運作應用程式所需的各種資訊
classes.dex 以dex格式編譯的應用程式代碼
resources.arsc 包含預編譯應用程式資源的二進制XML檔案
res/ 此檔案夾中包含未編譯到resources.arsc檔案中的資源
assets/ 此檔案夾包含應用程式的原始資源,由AssetManager提供對這些資産檔案的通路
META-INF/ 它包含MANIFEST.MF檔案,該檔案存儲有關JAR内容的中繼資料。APK簽名也存儲在此檔案夾中
lib/ 此檔案夾包含已編譯的代碼,例如本地代碼庫

frida-dexdump

#連接配接
adb connect 127.0.0.1:62001
#檢視cpu
adb shell getprop ro.product.cpu.abi
#查找包名
adb shell dumpsys package | grep ***
#設定端口
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
           
re的刷題0
  1. HelloWorld.java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
           
  1. 将 java 源檔案編譯為 class 位元組碼檔案
javac HelloWorld.java
           
  1. dex:Android系統的可執行檔案
dx  --dex --output=HelloWorld.dex HelloWorld.class
           
re的刷題0

dex檔案頭中magic字段開始0x0、長度8 ,魔數字段,值為"dex035"

re的刷題0

DEXdump原理就是暴力搜尋記憶體64 65 78 0A 30 33 35 00,對于抹頭的dex,通過比對一些特征來找到,然後自動修複檔案頭。

FRIDA-DEXDump\agent.js

scandex: function scandex() {
        var result = [];
        Process.enumerateRanges(\'r--\').forEach(function (range) {
            try {
                Memory.scanSync(range.base, range.size, "64 65 78 0a 30 ?? ?? 00").forEach(function (match)
           

FRIDA-DEXDump\main.py

matches = api.scandex()
    for info in matches:
        try:
            bs = api.memorydump(info[\'addr\'], info[\'size\'])
            if bs[:4] != b"dex\n":
                bs = b"dex\n035\x00" + bs[8:]
            click.secho("[DEXDump]: DexSize={}, DexMd5={}, SavePath={}/{}/{}.dex"
                        .format(hex(info[\'size\']), md, os.getcwd(), pkg_name, info[\'addr\']), fg=\'green\')
           

MIPS/X86/ARM

https://blog.csdn.net/BtB5e6Nsu1g511Eg5XEg/article/details/88839679?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param

RISC(精簡指令集計算機)

CISC(複雜指令集計算機)

http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html

https://blog.csdn.net/frozenshore/article/details/44706299

REGISTER NAME USAGE
$0 $zero 常量0(constant value 0)
$1 $at 保留給彙編器(Reserved for assembler)
$2-$3 $v0-$v1 函數調用傳回值(values for results and expression evaluation)
$4-$7 $a0-$a3 函數調用參數(arguments)
$8-$15 $t0-$t7 暫時的(或随便用的)
$16-$23 $s0-$s7 儲存的(或如果用,需要SAVE/RESTORE的)(saved)
$24-$25 $t8-$t9 暫時的(或随便用的)
$28 $gp 全局指針(Global Pointer)
$29 $sp 堆棧指針(Stack Pointer)
$30 $fp 幀指針(Frame Pointer)
$31 $ra 傳回位址(return address)
指令 功能 應用執行個體
LB 從存儲器中讀取一個位元組的資料到寄存器中 LB R1, 0(R2)
LH 從存儲器中讀取半個字的資料到寄存器中 LH R1, 0(R2)
LW 從存儲器中讀取一個字的資料到寄存器中 LW R1, 0(R2)
LD 從存儲器中讀取雙字的資料到寄存器中 LD R1, 0(R2)
L.S 從存儲器中讀取單精度浮點數到寄存器中 L.S R1, 0(R2)
L.D 從存儲器中讀取雙精度浮點數到寄存器中 L.D R1, 0(R2)
LBU 功能與LB指令相同,但讀出的是不帶符号的資料 LBU R1, 0(R2)
LHU 功能與LH指令相同,但讀出的是不帶符号的資料 LHU R1, 0(R2)
LWU 功能與LW指令相同,但讀出的是不帶符号的資料 LWU R1, 0(R2)
SB 把一個位元組的資料從寄存器存儲到存儲器中 SB R1, 0(R2)
SH 把半個位元組的資料從寄存器存儲到存儲器中 SH R1,0(R2)
SW 把一個字的資料從寄存器存儲到存儲器中 SW R1, 0(R2)
SD 把兩個位元組的資料從寄存器存儲到存儲器中 SD R1, 0(R2)
S.S 把單精度浮點數從寄存器存儲到存儲器中 S.S R1, 0(R2)
S.D 把雙精度資料從存儲器存儲到存儲器中 S.D R1, 0(R2)
DADD 把兩個定點寄存器的内容相加,也就是定點加 DADD R1,R2,R3
DADDI 把一個寄存器的内容加上一個立即數 DADDI R1,R2,#3
DADDU 不帶符号的加 DADDU R1,R2,R3
DADDIU 把一個寄存器的内容加上一個無符号的立即數 DADDIU R1,R2,#3
ADD.S 把一個單精度浮點數加上一個雙精度浮點數,結果是單精度浮點數 ADD.S F0,F1,F2
ADD.D 把一個雙精度浮點數加上一個單精度浮點數,結果是雙精度浮點數 ADD.D F0,F1,F2
ADD.PS 兩個單精度浮點數相加,結果是單精度浮點數 ADD.PS F0,F1,F2
DSUB 兩個寄存器的内容相減,也就是定點數的減 DSUB R1,R2,R3
DSUBU 不帶符号的減 DSUBU R1,R2,R3
SUB.S 一個雙精度浮點數減去一個單精度浮點數,結果為單精度 SUB.S F1,F2,F3
SUB.D 一個雙精度浮點數減去一個單精度浮點數,結果為雙精度浮點數 SUB.D F1,F2,F3
SUB.PS 兩個單精度浮點數相減 SUB.SP F1,F2,F3
DDIV 兩個定點寄存器的内容相除,也就是定點除 DDIV R1,R2,R3
DDIVU 不帶符号的除法運算 DDIVU R1,R2,R3
DIV.S 一個雙精度浮點數除以一個單精度浮點數,結果為單精度浮點數 DIV.S F1,F2,F3
DIV.D 一個雙精度浮點數除以一個單精度浮點數,結果為雙精度浮點數 DIV.D F1,F2,F3
DIV.PS 兩個單精度浮點數相除,結果為單精度 DIV.PS F1,F2,F3
DMUL 兩個定點寄存器的内容相乘,也就是定點乘 DMUL R1,R2,R3
DMULU 不帶符号的乘法運算 DMULU R1,R2,R3
MUL.S 一個雙精度浮點數乘以一個單精度浮點數,結果為單精度浮點數 DMUL.S F1,F2,F3
MUL.D 一個雙精度浮點數乘以一個單精度浮點數,結果為雙精度浮點數 DMUL.D F1,F2,F3
MUL.PS 兩個單精度浮點數相乘,結果為單精度浮點數 DMUL.PS F1,F2,F3
AND 與運算,兩個寄存器中的内容相與 ANDR1,R2,R3
ANDI 一個寄存器中的内容與一個立即數相與 ANDIR1,R2,#3
OR 或運算,兩個寄存器中的内容相或 ORR1,R2,R3
ORI 一個寄存器中的内容與一個立即數相或 ORIR1,R2,#3
XOR 異或運算,兩個寄存器中的内容相異或 XORR1,R2,R3
XORI 一個寄存器中的内容與一個立即數異或 XORIR1,R2,#3
BEQZ 條件轉移指令,當寄存器中内容為0時轉移發生 BEQZ R1,0
BNEZ 條件轉移指令,當寄存器中内容不為0時轉移發生 BNEZ R1,0
BEQ 條件轉移指令,當兩個寄存器内容相等時轉移發生 BEQ R1,R2
BNE 條件轉移指令,當兩個寄存器中内容不等時轉移發生 BNE R1,R2
J 直接跳轉指令,跳轉的位址在指令中 J name
JR 使用寄存器的跳轉指令,跳轉位址在寄存器中 JR R1
JAL 直接跳轉指令,并帶有連結功能,指令的跳轉位址在指令中,跳轉發生時要把傳回位址存放到R31這個寄存器中 JAL R1 name
JALR 使用寄存器的跳轉指令,并且帶有連結功能,指令的跳轉位址在寄存器中,跳轉發生時指令的放回位址放在R31這個寄存器中 JALR R1
MOV.S 把一個單精度浮點數從一個浮點寄存器複制到另一個浮點寄存器 MOV.S F0,F1
MOV.D 把一個雙精度浮點數從一個浮點寄存器複制到另一個浮點寄存器 MOV.D F0,F1
MFC0 把一個資料從通用寄存器複制到特殊寄存器 MFC0 R1,R2
MTC0 把一個資料從特殊寄存器複制到通用寄存器 MTC0 R1,R2
MFC1 把一個資料從定點寄存器複制到浮點寄存器 MFC1 R1,F1
MTC1 把一個資料從浮點寄存器複制到定點寄存器 MTC1 R1,F1
LUI 把一個16位的立即數填入到寄存器的高16位,低16位補零 LUI R1,#42
DSLL 雙字邏輯左移 DSLL R1,R2,#2
DSRL 雙字邏輯右移 DSRL R1,R2,#2
DSRA 雙字算術右移 DSRA R1,R2,#2
DSLLV 可變的雙字邏輯左移 DSLLV R1,R2,#2
DSRLV 可變的雙字羅伊右移 DSRLV R1,R2,#2
DSRAV 可變的雙字算術右移 DSRAV R1,R2,#2
SLT 如果R2的值小于R3,那麼設定R1的值為1,否則設定R1的值為0 SLT R1,R2,R3
SLTI 如果寄存器R2的值小于立即數,那麼設定R1的值為1,否則設定寄存器R1的值為0 SLTI R1,R2,#23
SLTU 功能與SLT一緻,但是帶符号的 SLTU R1,R2,R3
SLTUI 功能與SLT一緻,但不帶符号 SLTUI R1,R2,R3
MOVN 如果第三個寄存器的内容為負,那麼複制一個寄存器的内容到另外一個寄存器 MOVN R1,R2,R3
MOVZ 如果第三個寄存器的内容為0,那麼複制一個寄存器的内容到另外一個寄存器 MOVZ R1,R2,R3
TRAP 根據位址向量轉入管态
ERET 從異常中傳回到使用者态
MADD.S 一個雙精度浮點數與單精度浮點數相乘加,結果為單精度
MADD.D 一個雙精度浮點數與單精度浮點數相乘加,結果為雙精度
MADD.PS 兩個單精度浮點數相乘加,結果為單精度

angr

docker安裝angr

https://nocbtm.github.io/2019/10/02/docker安裝angr/#安裝angr

網鼎杯一道簡單的vm逆向,分析好久,後來知道了可以用angr符号執行,最簡單的angr,記錄一下。

import angr
p = angr.Project(\'./signal.exe\')   #指定angr跑的程式
state = p.factory.entry_state()    #建立一個SimState的對象,得到一個初始化到二進制入口函數的SimState對象。
simgr = p.factory.simgr(state)   #建立simulation manager,angr的主要入口
simgr.explore(find=0x004017A5 ,avoid=0x004016E6)  #争取跑到輸出成功的位址,避免跑到輸出wrong的位址
flag = simgr.found[0].posix.dumps(0)[:15]     #得到flag
print(flag)
           
re的刷題0

同時angr架構可以實作去除可以去ollvm的控制流平坦化和虛假控制流。

去除test_fla的控制流平坦化。

re的刷題0
re的刷題0

中間長的是無用函數,全為nop

[

re的刷題0

](

upx

source

#include <stdio.h>
#include <windows.h>
void ad(int a,int b){
	int r = a+b;
	printf("%d",r);
} 
int su(int a,int b){
	int r = a-b;
	printf("%d",r);
} 
int main(){
	int a,b;
	a=3;
	b=4;
	if(a>=b){
		su(a,b);
	}else{
		ad(a,b);
	}
	printf("hello");
	Sleep(123456);
} 
           

ida

re的刷題0
re的刷題0
re的刷題0

附件

CryptCreateHash:ALG_ID

Identifier Value Description
CALG_3DES 0x00006603 Triple DES encryption algorithm.
CALG_3DES_112 0x00006609 Two-key triple DES encryption with effective key length equal to 112 bits.
CALG_AES 0x00006611 Advanced Encryption Standard (AES). This algorithm is supported by the Microsoft AES Cryptographic Provider.
CALG_AES_128 0x0000660e 128 bit AES. This algorithm is supported by the Microsoft AES Cryptographic Provider.
CALG_AES_192 0x0000660f 192 bit AES. This algorithm is supported by the Microsoft AES Cryptographic Provider.
CALG_AES_256 0x00006610 256 bit AES. This algorithm is supported by the Microsoft AES Cryptographic Provider.
CALG_AGREEDKEY_ANY 0x0000aa03 Temporary algorithm identifier for handles of Diffie-Hellman–agreed keys.
CALG_CYLINK_MEK 0x0000660c An algorithm to create a 40-bit DES key that has parity bits and zeroed key bits to make its key length 64 bits. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_DES 0x00006601 DES encryption algorithm.
CALG_DESX 0x00006604 DESX encryption algorithm.
CALG_DH_EPHEM 0x0000aa02 Diffie-Hellman ephemeral key exchange algorithm.
CALG_DH_SF 0x0000aa01 Diffie-Hellman store and forward key exchange algorithm.
CALG_DSS_SIGN 0x00002200 DSA public key signature algorithm.
CALG_ECDH 0x0000aa05 Elliptic curve Diffie-Hellman key exchange algorithm.[!Note] This algorithm is supported only through Cryptography API: Next Generation. Windows Server 2003 and Windows XP: This algorithm is not supported.
CALG_ECDH_EPHEM 0x0000ae06 Ephemeral elliptic curve Diffie-Hellman key exchange algorithm.[!Note] This algorithm is supported only through Cryptography API: Next Generation. Windows Server 2003 and Windows XP: This algorithm is not supported.
CALG_ECDSA 0x00002203 Elliptic curve digital signature algorithm.[!Note] This algorithm is supported only through Cryptography API: Next Generation. Windows Server 2003 and Windows XP: This algorithm is not supported.
CALG_ECMQV 0x0000a001 Elliptic curve Menezes, Qu, and Vanstone (MQV) key exchange algorithm. This algorithm is not supported.
CALG_HASH_REPLACE_OWF 0x0000800b One way function hashing algorithm.
CALG_HUGHES_MD5 0x0000a003 Hughes MD5 hashing algorithm.
CALG_HMAC 0x00008009 HMAC keyed hash algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_KEA_KEYX 0x0000aa04 KEA key exchange algorithm (FORTEZZA). This algorithm is not supported.
CALG_MAC 0x00008005 MAC keyed hash algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_MD2 0x00008001 MD2 hashing algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_MD4 0x00008002 MD4 hashing algorithm.
CALG_MD5 0x00008003 MD5 hashing algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_NO_SIGN 0x00002000 No signature algorithm.
CALG_OID_INFO_CNG_ONLY 0xffffffff The algorithm is only implemented in CNG. The macro, IS_SPECIAL_OID_INFO_ALGID, can be used to determine whether a cryptography algorithm is only supported by using the CNG functions.
CALG_OID_INFO_PARAMETERS 0xfffffffe The algorithm is defined in the encoded parameters. The algorithm is only supported by using CNG. The macro, IS_SPECIAL_OID_INFO_ALGID, can be used to determine whether a cryptography algorithm is only supported by using the CNG functions.
CALG_PCT1_MASTER 0x00004c04 Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_RC2 0x00006602 RC2 block encryption algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_RC4 0x00006801 RC4 stream encryption algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_RC5 0x0000660d RC5 block encryption algorithm.
CALG_RSA_KEYX 0x0000a400 RSA public key exchange algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_RSA_SIGN 0x00002400 RSA public key signature algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_SCHANNEL_ENC_KEY 0x00004c07 Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SCHANNEL_MAC_KEY 0x00004c03 Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SCHANNEL_MASTER_HASH 0x00004c02 Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SEAL 0x00006802 SEAL encryption algorithm. This algorithm is not supported.
CALG_SHA 0x00008004 SHA hashing algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_SHA1 0x00008004 Same as CALG_SHA. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_SHA_256 0x0000800c 256 bit SHA hashing algorithm. This algorithm is supported by Microsoft Enhanced RSA and AES Cryptographic Provider..Windows XP with SP3: This algorithm is supported by the Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype). Windows XP with SP2, Windows XP with SP1 and Windows XP: This algorithm is not supported.
CALG_SHA_384 0x0000800d 384 bit SHA hashing algorithm. This algorithm is supported by Microsoft Enhanced RSA and AES Cryptographic Provider.Windows XP with SP3: This algorithm is supported by the Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype). Windows XP with SP2, Windows XP with SP1 and Windows XP: This algorithm is not supported.
CALG_SHA_512 0x0000800e 512 bit SHA hashing algorithm. This algorithm is supported by Microsoft Enhanced RSA and AES Cryptographic Provider.Windows XP with SP3: This algorithm is supported by the Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype). Windows XP with SP2, Windows XP with SP1 and Windows XP: This algorithm is not supported.
CALG_SKIPJACK 0x0000660a Skipjack block encryption algorithm (FORTEZZA). This algorithm is not supported.
CALG_SSL2_MASTER 0x00004c05 Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SSL3_MASTER 0x00004c01 Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SSL3_SHAMD5 0x00008008 Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_TEK 0x0000660b TEK (FORTEZZA). This algorithm is not supported.
CALG_TLS1_MASTER 0x00004c06 Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_TLS1PRF 0x0000800a Used by the Schannel.dll operations system. This ALG_ID should not be used by applications.