0x01 題目來源
感謝cgg投餵喵
0x02 思路
先查殼
無殼,64位程式,丟進ida分析一下,找到main函式,給幾個關鍵函式改個名
獲取輸入flag,然後執行check_constprop_0()
追蹤一下check_constprop_0();
切換到彙編
發現ret指令,中斷了虛擬碼分析,除錯看看這個迴圈幹了什麼
隨便輸個flag
F7一下,發現迴圈就是把step1和step2輪流壓棧
(部分棧的內容)
分別追蹤step1和step2
step1
step2
step1中先將rax壓棧,然後呼叫rand,之後使用rax和flag中的字元作異或運算,這裡要注意,進行異或運算的是eax即32位暫存器,之後pop rcx,使得rcx等於之前的rax的值,比較cl與al的值,如果相同則進行key+=1(此處使用的是rax與rcx低八位,即char型別的變數)
step2即對rax進行異或運算,作為step1的前置步驟
0x03 解密
使用兩個變數以及一個陣列(陣列為long long型別)
先將int型別變數v1進行異或運算,然後將其低八位賦值給char型別v2,之後使用rand函式給v1賦值,之後進行v1與v2的異或運算,即為flag的字元
(rand函式實際上是偽隨機數,被rand卡了一下O.o)
0x04 EXP
#include <iostream>
long v1;
char v2;
int key;
char flag[27];
int main() {
using namespace std;
long long num[26]={0x40CF,
0x8012,
0x809C,
0x4000B9,
0x830,
0x451,
0x20009A,
0x10069,
0x848,
0x8005E,
0x80055,
0x404E,
0x80001A,
0x8B3,
0x40066,
0x200003,
0x2002B,
0x10095,
0x20C5,
0x800029,
0x2000FB,
0x1045,
0x800AC,
0x100090,
0x404F,
0x204F};
for (int i = 25; i >=0; --i)
{
for (int j = i; j <=25 ; ++j)
{
v1^=num[j];
}
v2=(char)v1;
v1=rand();
flag[key++]=v2^v1;
v1=v2;
}
printf(flag);
return 0;
}