babyCrack
利用PEID发现是.NET程序,没有加壳,直接用IDA查看
得到key
hctf{bABy_CtsvlmE_!}
阿拉丁神灯
利用PEID发现是.NET程序,没有加壳,直接用IDA查看
将这串字符输入到页面中,得到key
UnPack&Crack2011!!
证明自己吧
利用PEID发现是C程序,没有加壳,直接用IDA查看
先F5 main函数
显然判断密码是否正确的函数为sub_401060
signed int __cdecl sub_401060(const char *a1)
{
unsigned int v1; // edx@2
unsigned int v2; // edx@4
int v3; // edx@6
int v5; // [sp+Ch] [bp-10h]@1
int v6; // [sp+10h] [bp-Ch]@1
int v7; // [sp+14h] [bp-8h]@1
__int16 v8; // [sp+18h] [bp-4h]@1
char v9; // [sp+1Ah] [bp-2h]@1
v5 = dword_40708C;
v6 = dword_407090;
v8 = word_407098;
v9 = byte_40709A;
v7 = dword_407094;
if ( strlen(a1) == strlen((const char *)&v5) )
{
v1 = 0;
if ( strlen(a1) != 0 )
{
do
a1[v1++] ^= 0x20u;
while ( v1 < strlen(a1) );
}
v2 = 0;
if ( strlen((const char *)&v5) != 0 )
{
do
*((_BYTE *)&v5 + v2++) -= 5;
while ( v2 < strlen((const char *)&v5) );
}
v3 = 0;
if ( strlen((const char *)&v5) == 0 )
return 1;
while ( *((_BYTE *)&v5 + v3 + a1 - (const char *)&v5) == *((_BYTE *)&v5 + v3) )
{
if ( ++v3 >= strlen((const char *)&v5) )
return 1;
}
}
return 0;
}
其中a1为我们读进来的字符串,要跟v5比较,我们先查看v5的值,即40708C的内容
因此v5的值为68571948506E5878546A19585E06
通过阅读源代码可以得到求出密码的算法
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
string s="\x68\x57\x19\x48\x50\x6e\x58\x78\x54\x6a\x19\x58\x5e\x06";
int main()
{
for (int i=0;i<s.size();i++)
s[i]=(s[i]-5)^0x20;
cout<<s<<endl;
return 0;
}
得到key
Cr4ckIsSoE4sy!
bin100(ebCTF 2013)
利用OD来调试。每次输出提示信息时更改跳转指令,即可得到答案
得到key
ebCTF{64ec47ece868ba34a425d90044cd2dec}
10000000
没有加壳,我们用IDA查看
main函数代码:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+14h] [bp-34h]@1
char v5; // [sp+18h] [bp-30h]@1
char v6; // [sp+19h] [bp-2Fh]@1
char v7; // [sp+1Ah] [bp-2Eh]@1
char v8; // [sp+1Bh] [bp-2Dh]@1
char v9; // [sp+1Ch] [bp-2Ch]@1
char v10; // [sp+1Dh] [bp-2Bh]@1
char v11; // [sp+1Eh] [bp-2Ah]@1
char v12; // [sp+1Fh] [bp-29h]@1
char v13; // [sp+20h] [bp-28h]@1
int v14; // [sp+28h] [bp-20h]@1
int v15; // [sp+2Ch] [bp-1Ch]@1
int v16; // [sp+3Ch] [bp-Ch]@1
__main();
v14 = 0;
memset(&v15, 0, 0x10u);
memset(&v4, 0, 0x14u);
v4 = -404624154;
v5 = -70;
v6 = -12;
v7 = -27;
v8 = -13;
v9 = -12;
v10 = -12;
v11 = -27;
v12 = -13;
v13 = -12;
v16 = 0;
puts("喵?");
scanf("%s", &v14);
LOBYTE(v16) = 0;
while ( *((_BYTE *)&v14 + v16) )
*((_BYTE *)&v14 + v16++) |= 0x80u;
if ( !strcmp((const char *)&v14, (const char *)&v4) )
printf("good");
else
printf("wrong");
return 0;
}
发现我们的输入|0x80u以后,要和&v4做比,那么这个&v4是多少呢,我们看汇编代码
这些数的首位都是1,所以我们的原输入应该为所有数^0x80u
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
string s="\xe6\xec\xe1\xe7\xba\xf4\xe5\xf3\xf4\xf4\xe5\xf3\xf4";
int main()
{
for (int i = 0; i < 13; i++)
s[i] ^= 0x80;
cout<<s<<endl;
return 0;
}
运行截图
得到key
testtest