就是mark一下里面smc
解法
做的時候可以直接鎖定加密部分sub_4014FA函數(shù)
size_t __cdecl sub_4014FA(char *a1, char *a2)
{
int v2; // eax@3
int v3; // ebx@5
int v4; // eax@5
int v5; // ebx@7
int v6; // eax@7
size_t result; // eax@17
signed int v8; // [sp+10h] [bp-18h]@1
size_t v9; // [sp+10h] [bp-18h]@15
int j; // [sp+14h] [bp-14h]@15
signed int i; // [sp+18h] [bp-10h]@1
int v12; // [sp+1Ch] [bp-Ch]@1
v12 = 0;
v8 = 4 * strlen(a1) / 3;
for ( i = 0; i < v8; ++i )
{
if ( i & 3 )
{
if ( ((((i >> 32) >> 30) + i) & 3) - ((i >> 32) >> 30) == 1 )
{
v3 = 16 * a1[v12 - 1] & 0x30;
v4 = v12++;
a2[i] = byte_405020[v3 | (a1[v4] >> 4)];
}
else if ( ((((i >> 32) >> 30) + i) & 3) - ((i >> 32) >> 30) == 2 )
{
v5 = 4 * a1[v12 - 1] & 0x3C;
v6 = v12++;
a2[i] = byte_405020[v5 | (a1[v6] >> 6)];
}
else
{
a2[i] = byte_405020[a1[v12 - 1] & 0x3F];
}
}
else
{
v2 = v12++;
a2[i] = byte_405020[(a1[v2] >> 2)];
}
}
if ( strlen(a1) % 3 == 1 )
{
a2[v8] = byte_405020[16 * a1[v12 - 1] & 0x30];
a2[v8 + 1] = 61;
a2[v8 + 2] = 61;
}
else if ( strlen(a1) % 3 == 2 )
{
a2[v8] = byte_405020[4 * a1[v12 - 1] & 0x3C];
a2[v8 + 1] = 61;
}
a2[strlen(a2)] = 0;
v9 = strlen(a2);
for ( j = 0; ; ++j )
{
result = v9 - 1;
if ( (v9 - 1) <= j )
break;
a2[j + 1] ^= a2[j]; //每個字符異或和前一位異或
}
return result;
}
改表的base64
文件32位跟加密后數(shù)據(jù)對比
字符異或得到
DnY0m19iAgArMKjSP2Uvme8wOzb0iD==
從網(wǎng)上找個base64解碼拐叉,套腳本就好
題目的解法很簡單
關于smc可以看到
int __cdecl sub_4017AA(char a1)
{
char *Str; // ST00_4@4
char *MaxCount; // [sp+4h] [bp-200h]@3
int DstBuf; // [sp+Eh] [bp-1F6h]@1
__int16 v5; // [sp+12h] [bp-1F2h]@1
int v6; // [sp+3Ch] [bp-1C8h]@1
CHAR Filename; // [sp+40h] [bp-1C4h]@1
char Str1; // [sp+144h] [bp-C0h]@1
char Buf[60]; // [sp+1A8h] [bp-5Ch]@1
unsigned int mum; // [sp+1E4h] [bp-20h]@1
FILE *v11; // [sp+1E8h] [bp-1Ch]@4
char *v12; // [sp+1FCh] [bp-8h]@1
v12 = &a1;
sub_401EE0();
puts("Sorroundings...Weird..");
mum = 0;
memset(Buf, 0, sizeof(Buf));
memset(&Str1, 0, 0x64u);
memset(&Filename, 0, 0x104u);
DstBuf = 0;
v6 = 0;
memset((&v5 & 0xFFFFFFFC), 0, 4 * (((&DstBuf + -(&v5 & 0xFFFFFFFC) + 50) & 0xFFFFFFFC) >> 2));
puts("I see!It's not my fault!Wrong is the world!");
puts("So..Now I should give a shot to fix it!");
************************************************************************
scanf("%u", &mum); //輸入一個數(shù)字
if ( mum > 0x20000 ) //判斷輸入數(shù)字大小
sub_40178C();
getchar(); //吃掉回車
sub_401460(mum); //關鍵
puts("And then,a shiny explosion!");
fgets(Buf, 59, iob);
Buf[strlen(Buf) - 1] = 0;
if ( strlen(Buf) != 22 )
sub_40178C();
**************************************************************************
puts("Seems I have passed a test.");
sub_4014FA(Str, MaxCount);
GetModuleFileNameA(0, &Filename, 0x104u);
v11 = fopen(&Filename, "rb");
fseek(v11, -32, 2);
fread(&DstBuf, 0x20u, 1u, v11);
fclose(v11);
if ( !strcmp(&Str1, &DstBuf) )
{
puts("Congratulations!");
puts("The flag is hgame{your input string + your input num}");
puts("e.g:hgame{aaaaaaaaaa111}");
}
else
{
printf("But Failed..Finally");
}
return 0;
}
進入sub_401460函數(shù)
BOOL __cdecl sub_401460(unsigned int a1)
{
DWORD flOldProtect; // [sp+14h] [bp-14h]@1
unsigned int v3; // [sp+18h] [bp-10h]@1
unsigned int v4; // [sp+1Ch] [bp-Ch]@1
flOldProtect = 0;
VirtualProtect(TopLevelExceptionFilter, 0x4000u, 0x40u, &flOldProtect);//更改頁屬性
v4 = a1 >> 3;
v3 = a1 & 7;
*(TopLevelExceptionFilter + (a1 >> 3)) ^= 1 << (a1 & 7);
return VirtualProtect(TopLevelExceptionFilter, 0x4000u, flOldProtect, &flOldProtect); //基址是TopLevelExceptionFilter 蛇损,0x401000
}
做的時候并沒有太注意,沒有詳細分析懈玻。當喵說了安卓的smc的時候才知道這個也是更改了某個地址蛤吓。
*(TopLevelExceptionFilter + (a1 >> 3)) ^= 1 << (a1 & 7);
[地址基址 + (輸入的數(shù)字右移三位)] 和輸入數(shù)字的后三位異或]
7 bin 0111
后邊3位可以與某個地址異或,剩下的幾位作為地址偏移來改變某一地方揖闸。
查看反匯編發(fā)現(xiàn)了此處跳傳導致sub_4014FA函數(shù)沒有參數(shù)進棧霎挟。
這兩個參數(shù)的作用是顯示出
怎么能保證正常跳轉呢喉恋?這就需要使用上面分析的悄但,將jmp short loc_4018F5改為jmp short loc_4018E5
jmp short loc_4018F5的機器碼為 EB 15棠隐;JMP的機器碼為EB,15為偏移檐嚣。
0x15 = 0x4018F5 - 0x4018DE - jmp長度(2byte)
那么跳到 loc_4018E5就是
x4018E5-0x4018DE-0x2=0x5
所以輸入數(shù)字最低三位應為100
要修改的字節(jié)的地址是0x4018DF 助泽,所以輸入的數(shù)字:
mum=(0x8df<<3) + 0x4 = 0x46FC=18172
(當然可以直接在文件中更改
這樣這個題目也算是完整了:
Byt3_H4cker_sho0O0o0t!
總結:和安卓的那個smc很像,基本可以歸為一類但實現(xiàn)smc的方法明顯安卓的要復雜不少嚎京。