先看文件信息:32位程序,没有加壳
打开看看,标题为find flag,也没啥有用的信息
IDA32位打开,找到start函数,看到有个main,跟随跳转
看到几个函数,都跟进查看一下
并没有什么有用的信息
ATOM __cdecl sub_4011D0(HINSTANCE hInstance)
{
WNDCLASSEXA v2; // [esp+4Ch] [ebp-30h] BYREF
v2.cbSize = 48;
v2.style = 3;
v2.lpfnWndProc = (WNDPROC)&sub_401014;
v2.cbClsExtra = 0;
v2.cbWndExtra = 0;
v2.hInstance = hInstance;
v2.hIcon = LoadIconA(hInstance, (LPCSTR)0x6B);
v2.hCursor = LoadCursorA(0, (LPCSTR)0x7F00);
v2.hbrBackground = (HBRUSH)6;
v2.lpszMenuName = (LPCSTR)109;
v2.lpszClassName = ClassName;
v2.hIconSm = LoadIconA(hInstance, (LPCSTR)0x6C);
return RegisterClassExA(&v2);
}
打开string窗口,看到flag的字样,以及一串字符串,跟随跳转
按x交查看叉引用
继续跟随跳转,发现这里被没有别识别为函数,无法查看伪码
将红色部分的代码全部选中,然后按p转为函数,然后就能转换为伪码了
下面就是一点一点分析代码了
先从输出这里入手,有一个strcmp函数,strcmp函数比较是相等的话返回0,看这里应该是要让里面的两个字符串相等。
这里一共调用了两个messageboxA,从意思来看,第二个messageboxA输出的就是flag了
看一下v12的值
这里对flag进行了一个异或变换
v20是未经变换过的string1
下面就是找string1的值是多少了j
这里对string1进行hash加密,但是不知道是哪种类型的hash
int __cdecl sub_4013A0(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)
{
int result; // eax
DWORD i; // [esp+4Ch] [ebp-24h]
CHAR String2[4]; // [esp+50h] [ebp-20h] BYREF
BYTE v6[16]; // [esp+54h] [ebp-1Ch] BYREF
DWORD pdwDataLen; // [esp+64h] [ebp-Ch] BYREF
HCRYPTHASH phHash; // [esp+68h] [ebp-8h] BYREF
HCRYPTPROV phProv; // [esp+6Ch] [ebp-4h] BYREF
if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
return 0;
if ( CryptCreateHash(phProv, 0x8003u, 0, 0, &phHash) )
{
if ( CryptHashData(phHash, pbData, dwDataLen, 0) )
{
CryptGetHashParam(phHash, 2u, v6, &pdwDataLen, 0);
*lpString1 = 0;
for ( i = 0; i < pdwDataLen; ++i )
{
wsprintfA(String2, "%02X", v6[i]);
lstrcatA(lpString1, String2);
}
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
result = 1;
}
else
{
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
result = 0;
}
}
else
{
CryptReleaseContext(phProv, 0);
result = 0;
}
return result;
}
这里是对str进行一个异或操作
然后异或后的结果与string1 hash加密后的结果相比较,如果相等则输出flag
写个脚本来看下异或后的结果
#include
#include
#include
int main()
{
int i;
int a[] = {0x57,0x5E,0x52,0x54,0x49,
0x5F,0x1,0x6D,0x69,0x46,0x2,
0x6E,0x5F,0x2,0x6C,0x57,0x5B,0x54,0x4C};
char str[] = "0kk`d1a`55k222k2a776jbfgd`06cjjb";
char v13[] = "SS";
for(i = 0 ; i < strlen(str); i++)
{
str[i] ^= v13[i % 2];
}
printf("str = %s\n",str);
return 0;
}
运行结果
识别一下这是什么类型的hash
MD5在线解密一下,得到string1的值为12331
完善一下脚本
#include
#include
#include
int main()
{
int i;
int a[] = {0x57,0x5E,0x52,0x54,0x49,
0x5F,0x1,0x6D,0x69,0x46,0x2,
0x6E,0x5F,0x2,0x6C,0x57,0x5B,0x54,0x4C};
char str[] = "0kk`d1a`55k222k2a776jbfgd`06cjjb";
char str1[] = "123321";
char v13[] = "SS";
for(i = 0 ; i < strlen(str); i++)
{
str[i] ^= v13[i % 2];
}
printf("str = %s\n",str);
for(i = 0 ; i < 19; i++)
{
a[i] ^= str1[i % 6];
}
for(i = 0 ; i < 19 ; i++)
{
printf("%c",a[i]);
}
return 0;
}
运行结果
flag: flag{n0_Zu0_n0_die}