INT_PTR __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
const char *v4; // esi
const char *v5; // edi
int v7[2]; // [esp+8h] [ebp-20030h] BYREF 虽然看名称不连续,但是通过看偏移地址,可知,这些变量在内存中是连续的,以v7为首
int v8; // [esp+10h] [ebp-20028h]
int v9; // [esp+14h] [ebp-20024h]
int v10; // [esp+18h] [ebp-20020h]
int v11; // [esp+1Ch] [ebp-2001Ch]
int v12; // [esp+20h] [ebp-20018h]
int v13; // [esp+24h] [ebp-20014h]
int v14; // [esp+28h] [ebp-20010h]
int v15; // [esp+2Ch] [ebp-2000Ch]
int v16; // [esp+30h] [ebp-20008h]
CHAR String[65536]; // [esp+34h] [ebp-20004h] BYREF
char v18[65536]; // [esp+10034h] [ebp-10004h] BYREF
if ( a2 == 272 )
return 1;
if ( a2 != 273 )
return 0;
if ( (_WORD)a3 == 1001 )
{
memset(String, 0, 0xFFFFu);
GetDlgItemTextA(hDlg, 1000, String, 0xFFFF);
if ( strlen(String) == 8 ) // 输入的flag,可知为8位
{
v7[0] = 90;
v7[1] = 74;
v8 = 83;
v9 = 69;
v10 = 67;
v11 = 97;
v12 = 78;
v13 = 72;
v14 = 51;
v15 = 110;
v16 = 103;
sub_8210F0((int)v7, 0, 10); // 在v7原来内存中进行修改,修改为3CEHJNSZagn
memset(v18, 0, 0xFFFFu);
v18[0] = String[5];
v18[2] = String[7];
v18[1] = String[6];
v4 = sub_821000((int)v18, strlen(v18)); // 字符串678位
memset(v18, 0, 0xFFFFu);
v18[1] = String[3];
v18[0] = String[2];
v18[2] = String[4];
v5 = sub_821000((int)v18, strlen(v18)); // 字符串的345位
if ( String[0] == v7[0] + 34 // string[0]=chr(ord('3')+34)='U'
&& String[1] == v10 // string[1]='J'
&& 4 * String[2] - 141 == 3 * v8 // string[2]=chr((3*ord('E')+141)//4)='W',注意这里直接除除不尽,需要向下取整
&& String[3] / 4 == 2 * (v13 / 9) // string[3]=chr((2*(ord('Z')//9))*4)=‘P’,同样用到了向下取整
&& !strcmp(v4, "ak1w") // base64解密后678位:jMp
&& !strcmp(
v5,
"V1Ax") )
{ // base64解密后345位:WP1
MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);// 显示对话框,即成功
}
} // 最后string为:UJWP1jMp
return 0;
}
if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 )
return 0;
EndDialog(hDlg, (unsigned __int16)a3);
return 1;
}
上图是主要分析的代码(思路:获取中间变量+倒推)
下图代码用于获得中间变量:(逆向功能:算法分析)
需要修改的地方:
1.在伪代码中,有a1+ 4 * i,a1+4 *result,这样的字符。int占四个字节,所以需要*4.如果是char类型,就不需要.
2.我们知道a1+4*i,也就是a1【i】,a1+4 * result,也就是a1【result】。
将伪代码的寻址方式改为数组寻址,然后将*(_DWORD*) 删掉,因为这是汇编的表示。
所以伪代码变成了C语言代码。
上代码:
#include <stdio.h>
int sub_8210F0(char* a1, int a2, int a3)//这算不算逆向的一个功能: 内部算法的了解分析
{
int result; // eax
int i; // esi
int v5; // ecx
int v6; // edx
result = a3;
for ( i = a2; i <= a3; a2 = i )
{
v5 = i;
v6 = i[a1];
if ( a2 < result && i < result )
{
do
{
if ( v6 > a1[result])
{
if ( i >= result )
break;
++i;
a1[v5] = a1[result];
if ( i >= result )
break;
while ( a1[i]<= v6 )
{
if ( ++i >= result )
goto LABEL_13;
}
if ( i >= result )
break;
v5 =i;
a1[result] = a1[i];
}
--result;
}
while ( i < result );
}
LABEL_13:
a1[result] = v6;
sub_8210F0(a1, a2, i - 1);
result = a3;
++i;
}
return result;
}
int main()
{
char str[]="ZJSECaNH3ng";
sub_8210F0(str,0,10);
printf("%s",str);
return 0;
}
flag{UJWP1jMp}