00401337 |. 8B4424 08 mov eax,dword ptr ss:[esp+0x8] ; kernel32.BaseThreadInitThunk
0040133B |. 83C4 08 add esp,0x8
0040133E |. 83F8 01 cmp eax,0x1
00401341 |. 75 07 jnz short 1c40a4a4.0040134A
00401343 |. 68 90A04000 push 1c40a4a4.0040A090 ; Right!flag is your input\n
00401348 |. EB 05 jmp short 1c40a4a4.0040134F
0040134A |> 68 C0A04000 push 1c40a4a4.0040A0C0 ; Wrong!\n
0040134F |> E8 1C000000 call 1c40a4a4.00401370
004012A4 |. 68 D0A04000 push 1c40a4a4.0040A0D0 ; Please input flag:
004012A9 |. E8 C2000000 call 1c40a4a4.00401370
004012AE |. 8D4424 0C lea eax,dword ptr ss:[esp+0xC]
004012B2 |. 50 push eax
004012B3 |. 68 C8A04000 push 1c40a4a4.0040A0C8 ; %31s
004012B8 |. E8 7A010000 call 1c40a4a4.00401437
004012BD |. 8D7C24 14 lea edi,dword ptr ss:[esp+0x14]
004012C1 |. 83C9 FF or ecx,0xFFFFFFFF
004012C4 |. 33C0 xor eax,eax
004012C6 |. 83C4 0C add esp,0xC
004012C9 |. F2:AE repne scas byte ptr es:[edi]
004012CB |. F7D1 not ecx
004012CD |. 49 dec ecx
004012CE |. 5F pop edi
004012CF |. 83F9 13 cmp ecx,0x13
004012D2 |. 74 1D je short 1c40a4a4.004012F1
004012D4 |. 68 C0A04000 push 1c40a4a4.0040A0C0 ; Wrong!\n
004012D9 |. E8 92000000 call 1c40a4a4.00401370
004012DE |. 68 B8A04000 push 1c40a4a4.0040A0B8 ; pause
004012E3 |. E8 B9000000 call 1c40a4a4.004013A1
打开Your_input文件以后发现里面的内容根本就不是我们写入的1234567890123456789啊,而是一些其他字符但是WriteFile写入的字符串就是1234567890123456789,所以WriteFile指定出现了问题,我们跟进WriteFile看下函数(如下图)
跟进WriteFile内发现居然是个jmp!!!,那说明这个函数被做过手脚啊,通常这种写jmp的都是对这个函数进行了HOOK,所以,我们跳到00401080去看看到底发生了啥?(如下图)
int __cdecl sub_401000(int a1, int a2)
{
char i; // al
char v3; // bl
char v4; // cl
int v5; // eax
for ( i = 0; i < a2; ++i )
{
if ( i == 18 )
{
*(_BYTE *)(a1 + 18) ^= 0x13u;
}
else
{
if ( i % 2 )
v3 = *(_BYTE *)(i + a1) - i;
else
v3 = *(_BYTE *)(i + a1 + 2);
*(_BYTE *)(i + a1) = i ^ v3;
}
}
v4 = 0;
if ( a2 <= 0 )
return 1;
v5 = 0;
while ( byte_40A030[v5] == *(_BYTE *)(v5 + a1) )
{
v5 = ++v4;
if ( v4 >= a2 )
return 1;
}
return 0;
}
0040108C . 56 push esi
0040108D . 57 push edi
0040108E . E8 6DFFFFFF call 1c40a4a4.00401000
//c调用约定
void add(a,b){}
//对应汇编
push b
push a
call add
strlen(byte_40A030)就是等于我们输入字符串的正确长度(0x13),其实这里可以有很大程度可以确定byte_40A030就是flag最后的加密结果,但是为了严谨我们还是通过函数调用来具体分析
if ( v5 )
*lpNumberOfBytesWritten = 1;
if ( NumberOfBytesWritten == 1 )
sub_401370(aRightFlagIsYou);
else
sub_401370(aWrong);
if ( ++result >= (int)(v3 - 1) )
{
if ( result == 21 )
{
result = (int)a2;
*a2 = 1;
}
return result;
}
#include
#include
int main()
{
int v3 = 0;
unsigned char a1[] =
{
0x61, 0x6A, 0x79, 0x67, 0x6B, 0x46, 0x6D, 0x2E, 0x7F, 0x5F,
0x7E, 0x2D, 0x53, 0x56, 0x7B, 0x38, 0x6D, 0x4C, 0x6E, 0x00
};
for (size_t i = 19; i >0; i--)
{
if (i == 18)
{
*(BYTE *)(a1 + 18) ^= 0x13;
}
else
{
v3 = *(BYTE *)(i + a1) ^ i;
if (i%2)
{
*(BYTE *)(i + a1) = v3 + i;
}
else
{
*(BYTE *)(i + a1 + 2) = v3;
}
}
}
printf("%s",a1);
system("pause");
return 0;
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。