作者:无声无息无心跳 | 来源:互联网 | 2024-11-13 12:49
WinMain 函数参数详解
WinMain 函数是 Windows 应用程序的入口点,其定义如下:
int WINAPI WinMain(
HINSTANCE hInstance, // 当前实例的句柄
HINSTANCE hPrevInstance, // 前一个实例的句柄
LPSTR lpCmdLine, // 命令行参数
int nCmdShow // 窗口显示状态
);
WinMain 函数接收4个参数,这些参数由操作系统在调用 WinMain 函数时传递给应用程序。
第一个参数 hInstance 表示当前程序实例的句柄。在 Windows 中,每个运行中的程序实例都有一个唯一的句柄。每当程序的一个实例启动时,系统会为其分配一个句柄并通过 hInstance 参数传递给 WinMain 函数。
第二个参数 hPrevInstance 表示前一个实例的句柄。在 Win32 环境下,此参数始终为 NULL,因为 Win32 不支持多个实例的概念。
第三个参数 lpCmdLine 是一个以空字符终止的字符串,包含传递给应用程序的命令行参数。例如,如果用户双击 D 盘下的 sunxin.txt 文件,系统会启动记事本程序并将其路径 D:\sunxin.txt 作为命令行参数传递给记事本的 WinMain 函数。在 VC++ 开发环境中,可以通过菜单【Project】→【Settings】,选择“Debug”选项卡,在“Program arguments”编辑框中输入想要传递的参数。
第四个参数 nCmdShow 指定程序窗口的初始显示状态,如最大化、最小化或隐藏。此参数的值由调用者指定,应用程序通常不需要关心这个参数的具体值。
示例解析
接下来,我们通过一个示例来解析 WinMain 函数的实现。
首先,我们分析 WinMain 函数的调用过程:
查看 DialogFunc 参数:
BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
const char *v4; // esi
const char *v5; // edi
int v7[11]; // [esp+8h] [ebp-20030h]
CHAR String[9]; // [esp+34h] [ebp-20004h]
CHAR v9[3]; // [esp+10034h] [ebp-10004h]
if ( a2 == 272 )
return 1;
if ( a2 != 273 )
return 0;
if ( a3 == 1001 )
{
memset(String, 0, 0xFFFFu);
GetDlgItemTextA(hDlg, 1000, String, 0xFFFF);
if ( strlen(String) == 8 )
{
v7[0] = 90;
v7[1] = 74;
v7[2] = 83;
v7[3] = 69;
v7[4] = 67;
v7[5] = 97;
v7[6] = 78;
v7[7] = 72;
v7[8] = 51;
v7[9] = 110;
v7[10] = 103;
sub_4010F0(v7, 0, 10);
memset(v9, 0, 0xFFFFu);
v9[0] = String[5];
v9[2] = String[7];
v9[1] = String[6];
v4 = sub_401000(v9, strlen(v9));
memset(v9, 0, 0xFFFFu);
v9[1] = String[3];
v9[0] = String[2];
v9[2] = String[4];
v5 = sub_401000(v9, strlen(v9));
if ( String[0] == v7[0] + 34
&& String[1] == v7[4]
&& 4 * String[2] - 141 == 3 * v7[2]
&& String[3] / 4 == 2 * (v7[7] / 9)
&& !strcmp(v4, "ak1w")
&& !strcmp(v5, "V1Ax") )
{
MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
}
}
return 0;
}
if ( a3 != 1 && a3 != 2 )
return 0;
EndDialog(hDlg, a3);
return 1;
}
其中,sub_4010F0 函数的参数已知,可以直接求出其处理结果。我们将其实现转换为 C 语言脚本:
#include
using namespace std;
int __cdecl sub_4010F0(int *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 = a1[i];
if ( a2 {
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 }
LABEL_13:
a1[result] = v6;
sub_4010F0(a1, a2, i - 1);
result = a3;
++i;
}
return result;
}
int main()
{
int v7[11] = {90, 74, 83, 69, 67, 97, 78, 72, 51, 110, 103};
sub_4010F0(v7, 0, 10);
for (int i = 0; i <11; i++)
{
printf("%c ", v7[i]);
}
return 0;
}
运行上述代码,得到的结果为:
3 C E H J N S Z a g n
接着,我们对两个比较的字符串分别进行 base64 解密。根据代码中的提示,这两个字符串分别是 'ak1w' 和 'V1Ax'。解密后得到:
UJWP1jMp