这应该是第八周第三道题,我记录一下我的做题过程,虽然有很多疑问
首先查壳
![Image description](https://bbs.xdsec.org/assets/files/2023-04-10/1681115143-134913-image.png)
Unknown EXE,不知道是个啥写的,010看一下吧,没发现有python这样的字符存在,那就ida打开
然后shift+f12先找字符串
有一个个`i_will_not_be_found`,一看就是出题人放的,果断双击后x交叉引用
```
int sub_599C80()
{
int v0; // eax
int v1; // eax
int v2; // eax
int v3; // eax
unsigned int i; // [esp+118h] [ebp-54h]
size_t v6; // [esp+124h] [ebp-48h]
char *Str; // [esp+130h] [ebp-3Ch]
char v8[32]; // [esp+13Ch] [ebp-30h] BYREF
int v9; // [esp+168h] [ebp-4h]
v0 = sub_579EA4("i_will_not_be_found");
v1 = sub_5736A8(v0);
sub_5761A0(v1);
v9 = 0;
if ( !NtCurrentPeb()->BeingDebugged )
{
v2 = sub_579EA4("you_can_not_find_me");
v3 = sub_5736A8(v2);
sub_56DE0B(v3);
}
Str = (char *)sub_577203(v8);
v6 = j__strlen(Str);
for ( i = 0; i < 0x292; ++i )
byte_875188[i] ^= Str[i % v6];//SMC
v9 = -1;
sub_571628(v8);
return 0;
}
```
好像是个SMC?先不管,交叉引用byte_875188看看谁调用了它![Image description](https://bbs.xdsec.org/assets/files/2023-04-10/1681115868-707561-image.png)
果然有,第二个双击跟进
```
bool __cdecl sub_599540(char *a1, unsigned int a2)
{
size_t v2; // eax
char v4; // [esp+Fh] [ebp-141h]
char Buf1[68]; // [esp+D4h] [ebp-7Ch] BYREF
unsigned int i; // [esp+118h] [ebp-38h]
int v7[8]; // [esp+124h] [ebp-2Ch] BYREF
__int16 v8; // [esp+144h] [ebp-Ch]
char v9; // [esp+146h] [ebp-Ah]
memset(v7, 0, sizeof(v7));
v8 = 0;
v9 = 0;
for ( i = 0; i < a2; ++i )
{
v4 = *a1++;
*((_BYTE *)v7 + i) = v4;
}
sub_57971F(v7, a2);
((void (__fastcall *)(char *, int *, unsigned int))byte_875188)(Buf1, v7, a2);
v2 = j__strlen(Str);
return j__memcmp(Buf1, Str, v2) == 0;
}
```
emmmm,return了一个比较函数的返回值,看样子是Buf1只要和Str相等返回值就为1了,emm,看看返回值有啥用,sub_599540交叉引用一下,来到这里
```
void __thiscall sub_5A1080(CWnd *this)
{
void *v1; // esp
int v2; // eax
int v3; // eax
const WCHAR *v4; // eax
LPCWSTR lpText; // [esp+18h] [ebp-18Ch]
char *lpCaption; // [esp+1Ch] [ebp-188h]
const WCHAR *lpCaptiona; // [esp+1Ch] [ebp-188h]
CHAR v8[4]; // [esp+20h] [ebp-184h] BYREF
_RTC_ALLOCA_NODE *PAllocaInfoList; // [esp+12Ch] [ebp-78h]
unsigned int v10; // [esp+138h] [ebp-6Ch]
char *Str; // [esp+144h] [ebp-60h]
int v12; // [esp+150h] [ebp-54h]
wchar_t *String; // [esp+15Ch] [ebp-48h]
UINT CodePage; // [esp+168h] [ebp-3Ch]
int v15; // [esp+174h] [ebp-30h]
char v16[12]; // [esp+180h] [ebp-24h] BYREF
CWnd *v17; // [esp+18Ch] [ebp-18h]
int v18; // [esp+1A0h] [ebp-4h]
v17 = this;
PAllocaInfoList = 0;
if ( NtCurrentPeb()->BeingDebugged )
sub_56F206();
sub_57BDA8(4u);
sub_573856(v16);
v18 = 0;
CWnd::GetDlgItem(v17, 1000);
CWnd::GetWindowTextW(v16);
v15 = 0;
CodePage = sub_573608();
v12 = 0;
String = (wchar_t *)sub_5773F2(v16);
if ( String )
{
v15 = j__wcslen(String) + 1;
if ( v15 <= 0x3FFFFFFF )
{
v1 = alloca(2 * v15 + 36);
lpText = (LPCWSTR)sub_5717A9(v8, String, 2 * v15, CodePage);
}
else
{
lpText = 0;
}
lpCaption = (char *)lpText;
}
else
{
lpCaption = 0;
}
Str = lpCaption;
v10 = j__strlen(lpCaption) >> 1;
if ( sub_57378E(lpCaption, v10) && (unsigned __int8)sub_56D4B0(&Str[v10], v10) )
{
v2 = sub_5768A8(&unk_87989C);
lpCaptiona = (const WCHAR *)sub_57007A(v2);
v3 = sub_57086D(aFlag);
v4 = (const WCHAR *)sub_5782F2(v3);
sub_579328(v4, lpCaptiona, 0);
}
v18 = -1;
sub_57A8E5(v16);
}
```
我们刚刚的返回值就在最后那个if里,返回值为1才会执行里面的操作,if里的第三行好像就显示falg正确(aflag里存的是flag正确),那现在我们要做的就是,分析sub_57378E()和sub_56D4B0()这两个函数就行
(看样子是把字符串分成两部分了,v10>>1
先分析第一部分:
```
bool __cdecl sub_599540(char *a1, unsigned int a2)
{
size_t v2; // eax
char v4; // [esp+Fh] [ebp-141h]
char Buf1[68]; // [esp+D4h] [ebp-7Ch] BYREF
unsigned int i; // [esp+118h] [ebp-38h]
int v7[8]; // [esp+124h] [ebp-2Ch] BYREF
__int16 v8; // [esp+144h] [ebp-Ch]
char v9; // [esp+146h] [ebp-Ah]
memset(v7, 0, sizeof(v7));
v8 = 0;
v9 = 0;
for ( i = 0; i < a2; ++i )
{
v4 = *a1++;
*((_BYTE *)v7 + i) = v4;
}
RC4((int)v7, a2);
((void (__fastcall *)(char *, int *, unsigned int))byte_875188)(Buf1, v7, a2);
v2 = j__strlen(Str);
return j__memcmp(Buf1, Str, v2) == 0;
}
```
经分析对密钥是有一个类似RC4操作的,密钥是`sorry_you_are_wrong`,然后先把这个SMC解了吧(
```
int sub_599C80()
{
int v0; // eax
int v1; // eax
int v2; // eax
int v3; // eax
unsigned int i; // [esp+118h] [ebp-54h]
size_t v6; // [esp+124h] [ebp-48h]
char *Str; // [esp+130h] [ebp-3Ch]
char v8[32]; // [esp+13Ch] [ebp-30h] BYREF
int v9; // [esp+168h] [ebp-4h]
v0 = sub_579EA4("i_will_not_be_found");
v1 = sub_5736A8(v0);
sub_5761A0(v1);
v9 = 0;
if ( !NtCurrentPeb()->BeingDebugged )
{
v2 = sub_579EA4("you_can_not_find_me");
v3 = sub_5736A8(v2);
sub_56DE0B(v3);
}
Str = (char *)sub_577203(v8);
v6 = j__strlen(Str);
for ( i = 0; i < 0x292; ++i )
byte_875188[i] ^= Str[i % v6];
v9 = -1;
sub_571628(v8);
return 0;
}
```
```
from ida_bytes import *
addr =0x875188
key="you_can_not_find_me"
for i in range(0x292):
patch_byte(addr+i,get_byte(addr+i)^ord(key[i%len(key)]))
```
奇怪,解出来是这样的
```
void __usercall sub_875231(int a1@<edx>, _BYTE *a2@<ecx>, int a3@<ebp>)
{
unsigned int v3; // edi
char v4; // bl
char v5; // dl
int v6; // ecx
_BYTE *v7; // eax
unsigned int v8; // ebx
char v9; // cl
unsigned int v10; // esi
char v11; // dl
char v12; // dl
char v13; // cl
char v14; // dl
char v15; // cl
v8 = *(_DWORD *)(a3 + 8);
v7 = a2;
v10 = 0;
*(_DWORD *)(a3 - 4) = a1;
v3 = v8 - 2;
*(_DWORD *)(a3 - 8) = a2;
if ( v8 != 2 )
{
do
{
v13 = *(_BYTE *)(a1 + v10);
v12 = v13 & 3;
v9 = (v13 >> 2) & 0x3F;
v11 = 16 * v12;
*v7 = v9 + 35;
v15 = *(_BYTE *)(*(_DWORD *)(a3 - 4) + v10 + 1);
v4 = v15 & 0xF;
v5 = (v15 >> 4) & 0xF | v11;
v6 = *(_DWORD *)(a3 - 4);
v7[1] = v5 + 35;
v14 = *(_BYTE *)(v6 + v10 + 2);
v10 += 3;
v7[2] = ((v14 >> 6) & 3 | (4 * v4)) + 35;
v7[3] = (v14 & 0x3F) + 35;
v7 += 4;
a1 = *(_DWORD *)(a3 - 4);
}
while ( v10 < v3 );
v8 = *(_DWORD *)(a3 + 8);
}
if ( v10 < v8 )
JUMPOUT(0x87540C);
JUMPOUT(0x875222);
}
```
怎么只对了前一部分,啊,抓狂,不会了(
分析第二个函数:
```
bool __cdecl sub_5996C0(char *a1, int a2)
{
__int64 v3; // rax
int v4; // [esp+10h] [ebp-144h]
char v5; // [esp+13h] [ebp-141h]
unsigned int j; // [esp+D8h] [ebp-7Ch]
unsigned __int64 v7; // [esp+E4h] [ebp-70h]
int v8; // [esp+ECh] [ebp-68h]
int v9; // [esp+F0h] [ebp-64h]
unsigned __int64 v10; // [esp+F4h] [ebp-60h]
unsigned __int64 v11; // [esp+FCh] [ebp-58h]
int v12[4]; // [esp+10Ch] [ebp-48h] BYREF
unsigned int i; // [esp+11Ch] [ebp-38h]
int v14[8]; // [esp+128h] [ebp-2Ch] BYREF
__int16 v15; // [esp+148h] [ebp-Ch]
char v16; // [esp+14Ah] [ebp-Ah]
char *v17; // [esp+15Ch] [ebp+8h]
v4 = *a1;
v17 = a1 + 1;
if ( v4 != 102 )
return 0;
memset(v14, 0, sizeof(v14));
v15 = 0;
v16 = 0;
for ( i = 0; i < a2 - 1; ++i )
{
v5 = *v17++;
*((_BYTE *)v14 + i) = v5;
}
for ( j = 0; j < 4; ++j )
{
sub_5751B5((int)&v14[2 * j], (int)v12);
TEA((int)v12, (int)&dword_875048[4 * j]);
*((_DWORD *)&v7 + 2 * j) = v12[0];
*((_DWORD *)&v7 + 2 * j + 1) = 0;
LODWORD(v3) = *((_DWORD *)&v7 + 2 * j);
HIDWORD(v3) = *((_DWORD *)&v7 + 2 * j + 1);
v3 <<= 32;
*((_DWORD *)&v7 + 2 * j) = v3;
*((_DWORD *)&v7 + 2 * j + 1) = HIDWORD(v3);
HIDWORD(v3) = *((_DWORD *)&v7 + 2 * j + 1);
*((_DWORD *)&v7 + 2 * j) |= v12[1];
*((_DWORD *)&v7 + 2 * j + 1) = HIDWORD(v3);
}
return v8 == 798585087
&& v9 == -550095698
&& v7 < v10
&& v10 < v11
&& v10 - v7 == 4568540450738734457i64
&& v7 + v11 == 0x162F924623D2CAE0i64
&& v11 - v10 == 0x7C3C71F1B295D77Fi64;
}
```
这好像是个tea加密
```
unsigned int __fastcall sub_8754EF(unsigned int *a1, int *a2)
{
unsigned int v2; // esi
int v3; // ebx
unsigned int v4; // eax
int v5; // edi
int v6; // edx
unsigned int result; // eax
int v8; // ecx
unsigned int v9; // [esp-28h] [ebp-28h]
int v11; // [esp-14h] [ebp-14h]
int v12; // [esp-10h] [ebp-10h]
int v13; // [esp-Ch] [ebp-Ch]
int v14; // [esp-8h] [ebp-8h]
v2 = *a1;
v4 = a1[1];
v14 = *a2;
v8 = a2[1];
v12 = a2[2];
v3 = 32;
v11 = v8;
v13 = a2[3];
v5 = 0;
do
{
v5 += 607369562;
v2 += (v5 + v4) ^ (v14 + 16 * v4) ^ (v8 + (v4 >> 5));
v6 = (v5 + v2) ^ (v12 + 16 * v2) ^ (v13 + (v2 >> 5));
v8 = v11;
v9 = v6 + v4;
--v3;
v4 += v6;
}
while ( v3 );
result = v9;
*a1 = v2;
a1[1] = v9;
return result;
}
```
可以试着解出后半段的flag
```
#include<stdio.h>
#include<stdint.h>
int decrypto_Tea(uint32_t *a,uint32_t *key)
{
uint32_t v2 =*a;
uint32_t v4 =a[1],v14=*key,v8=key[1],v12=key[2],v13=key[3];
int v3 =32;
uint32_t v5 =0x86772b40;
do{
v3--;
v4-=(v5 + v2) ^ (v12 + 16 * v2) ^ (v13 + (v2 >> 5));
v2 -= (v5 + v4) ^ (v14 + 16 * v4) ^ (v8 + (v4 >> 5));
v5 -= 0x2433B95A;
}while(v3);
*a=v2;
a[1]=v4;
}
int main()
{
uint32_t a[8]={0x2d46347f,0x5e79f6f4,0xDF3634AE,0x2F9970FF,0x6cacebd5,0x12c2fc6d,0xe8e95dc6,0xc558d3ec};
uint32_t key[16] ={
0xD9610D02, 0x2AADA57D, 0xA37537F1, 0xC29E3913, 0xD5942CE8, 0x608CCE66, 0x6D593422, 0x21E5D6F2,
0xED3A9235, 0x9DAD62C4, 0x3856641B, 0x71F75B9D, 0xDCDEDAE8, 0xEAD2D1A0, 0xBAC4F564, 0xDA4772AC};
for(int i=0,j=0;i<8;i+=2,j+=4)
{
decrypto_Tea(&a[i],&key[j]);
printf("0x%x,",a[i]);
printf("0x%x,",a[i+1]);
}
printf("\n");
puts(a);
return 0;
}
//f1cUlt_foR_THe_r0Ok1E_t0_REver5e
```