-
-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Silent Hunter 3 fails to unpack #37
Comments
Sorry for not seeing this sooner. This appears to be SteamStub 2.0 but, this does look like it could be the very first version of the stub 2.0 variant. This is not using the same setup as the more commonly seen variants for 2.0. Support for this will hopefully come later, for now it won't be supported yet since it's a fully different version of 2 that is going to require some more work to implement support for. |
…s version. I only have 1 sample with this version of the stub so it is solely based on this one exe. The full stub has been reversed for this file though. You can find more about that in issue #37)
This is now supported via: 769232f For those interested, this stub is pretty old and what I feel is the real 2.0 start. I've renamed the old 2.0's to 2.1 as they are newer and closer to what 3.x implements. So I feel like those are not the real 2.0 variants. Here is my reversed notes for this stub if anyone is interested in checking it out: // bad sp value at call has been detected, the output may be wrong!
int start()
{
int v0; // eax
int v1; // eax
int v2; // eax
int v3; // eax
int v4; // edx
int v5; // ecx
int v6; // eax
int v8; // [esp-4h] [ebp-1004h]
int v9; // [esp-4h] [ebp-1004h]
int v11; // [esp+2E8h] [ebp-D18h]
int v12; // [esp+2F4h] [ebp-D0Ch]
signed int nn; // [esp+2F8h] [ebp-D08h]
int *v14; // [esp+2FCh] [ebp-D04h]
int v15[3]; // [esp+300h] [ebp-D00h] BYREF
int v16; // [esp+30Ch] [ebp-CF4h]
int v17; // [esp+31Ch] [ebp-CE4h] BYREF
int v18; // [esp+320h] [ebp-CE0h] BYREF
unsigned int kk; // [esp+324h] [ebp-CDCh]
WINTRUST_DATA *v20; // [esp+328h] [ebp-CD8h]
unsigned int jj; // [esp+32Ch] [ebp-CD4h]
int *v22; // [esp+330h] [ebp-CD0h]
int (__stdcall *ptr_WinVerifyTrust)(_DWORD, GUID *, WINTRUST_DATA *); // [esp+334h] [ebp-CCCh]
int buff_SystemDirectory[65]; // [esp+338h] [ebp-CC8h] BYREF
int handle_WinTrust; // [esp+43Ch] [ebp-BC4h]
WINTRUST_DATA trustData; // [esp+440h] [ebp-BC0h] BYREF
GUID trustGuidVerifyv2; // [esp+470h] [ebp-B90h] BYREF
int v28[4]; // [esp+480h] [ebp-B80h] BYREF
int v29; // [esp+490h] [ebp-B70h]
char v30[520]; // [esp+494h] [ebp-B6Ch] BYREF
int v31; // [esp+69Ch] [ebp-964h] BYREF
void (__stdcall *ptr_IsWow64Process)(int); // [esp+6A0h] [ebp-960h]
char v33; // [esp+6A7h] [ebp-959h]
int ii; // [esp+6A8h] [ebp-958h]
int v35; // [esp+6ACh] [ebp-954h]
int v36; // [esp+6B0h] [ebp-950h]
int i; // [esp+6B4h] [ebp-94Ch]
int *v38; // [esp+6B8h] [ebp-948h]
unsigned int n; // [esp+6BCh] [ebp-944h]
int *v40; // [esp+6C0h] [ebp-940h]
unsigned int m; // [esp+6C4h] [ebp-93Ch]
stubheader_t *v42; // [esp+6C8h] [ebp-938h]
unsigned int i3; // [esp+6CCh] [ebp-934h]
int *v44; // [esp+6D0h] [ebp-930h]
unsigned int i1; // [esp+6D4h] [ebp-92Ch]
stubheader_t *v46; // [esp+6D8h] [ebp-928h]
unsigned int mm; // [esp+6DCh] [ebp-924h]
int *v48; // [esp+6E0h] [ebp-920h]
unsigned int ll; // [esp+6E4h] [ebp-91Ch]
stubheader_t *v50; // [esp+6E8h] [ebp-918h]
int v51; // [esp+6ECh] [ebp-914h]
int buff_CommandLine_Cleaned[66]; // [esp+6F0h] [ebp-910h] BYREF
_BYTE *buff_CommandLine; // [esp+7F8h] [ebp-808h]
void (__stdcall *ptr_ShellExecuteA)(_DWORD, _DWORD, char *, int *, _DWORD, int); // [esp+7FCh] [ebp-804h]
int handle_Shell32; // [esp+800h] [ebp-800h]
int (*ptr_GetCommandLineA)(void); // [esp+804h] [ebp-7FCh]
int v57; // [esp+808h] [ebp-7F8h] BYREF
int v58; // [esp+80Ch] [ebp-7F4h] BYREF
unsigned int l; // [esp+814h] [ebp-7ECh]
int *v61; // [esp+818h] [ebp-7E8h]
int v62; // [esp+81Ch] [ebp-7E4h]
int v63; // [esp+820h] [ebp-7E0h]
unsigned int k; // [esp+824h] [ebp-7DCh]
char *v65; // [esp+828h] [ebp-7D8h]
char *v66; // [esp+82Ch] [ebp-7D4h]
unsigned int j; // [esp+830h] [ebp-7D0h]
char *v68; // [esp+834h] [ebp-7CCh]
char *v69; // [esp+838h] [ebp-7C8h]
int (__cdecl *ptr_ExitProcess)(_DWORD); // [esp+83Ch] [ebp-7C4h]
int (__fastcall *ptr_OEP)(int, int); // [esp+840h] [ebp-7C0h]
char str_AppLoadError[25]; // [esp+844h] [ebp-7BCh] BYREF
char v73[18]; // [esp+85Dh] [ebp-7A3h] BYREF
char v74; // [esp+86Fh] [ebp-791h]
void (__cdecl *ptr_SteamCleanup)(int *); // [esp+870h] [ebp-790h]
void (__stdcall *ptr_MessageBoxA)(_DWORD, char *, char *, int); // [esp+874h] [ebp-78Ch]
stubheader_t *stub_HeaderStart_Copy; // [esp+878h] [ebp-788h]
int (__cdecl *ptr_SteamStartup)(int, int *); // [esp+87Ch] [ebp-784h]
stubheader_t stub_HeaderStart; // [esp+880h] [ebp-780h] BYREF
int v80[66]; // [esp+C38h] [ebp-3C8h] BYREF
int v81[69]; // [esp+D40h] [ebp-2C0h] BYREF
char v82; // [esp+E57h] [ebp-1A9h]
int handle_Steam; // [esp+E58h] [ebp-1A8h]
int (__cdecl *ptr_SteamIsAppSubscribed)(int, int *, int *, int *); // [esp+E5Ch] [ebp-1A4h]
char v85; // [esp+E63h] [ebp-19Dh]
int v86; // [esp+E64h] [ebp-19Ch]
char buff_ModuleFileName[268]; // [esp+E68h] [ebp-198h] BYREF
int handle_User32; // [esp+F74h] [ebp-8Ch]
unsigned int v89; // [esp+F78h] [ebp-88h]
int i2; // [esp+F7Ch] [ebp-84h]
char str_SteamError[16]; // [esp+F80h] [ebp-80h] BYREF
int handle_Kernel32; // [esp+F90h] [ebp-70h] BYREF
void (__stdcall *ptr_VirtualProtect)(int, int, int, int *); // [esp+F94h] [ebp-6Ch]
void (__stdcall *ptr_VirtualQuery)(int, int *, int); // [esp+F98h] [ebp-68h]
void (__stdcall *ptr_FlushInstructionCache)(int); // [esp+F9Ch] [ebp-64h]
int (__stdcall *ptr_LoadLibraryExA)(char *, _DWORD, _DWORD); // [esp+FA0h] [ebp-60h]
void (__stdcall *ptr_FreeLibrary)(int); // [esp+FA4h] [ebp-5Ch]
void (__stdcall *ptr_GetModuleFileNameA)(_DWORD, char *, int); // [esp+FA8h] [ebp-58h]
void (__stdcall *ptr_lstrcatA)(int *, char *); // [esp+FACh] [ebp-54h]
void (__stdcall *ptr_Sleep)(int); // [esp+FB0h] [ebp-50h]
void (__stdcall *ptr_MultiByteToWideChar)(_DWORD, _DWORD, int *, int, char *, int); // [esp+FB4h] [ebp-4Ch]
int ptr_GetModuleHandleA; // [esp+FB8h] [ebp-48h]
int (__stdcall *ptr_GetSystemDirectoryA)(int *, int); // [esp+FBCh] [ebp-44h]
int ptr_GetStartupInfoA; // [esp+FC0h] [ebp-40h]
int ptr_DuplicateHandle; // [esp+FC4h] [ebp-3Ch]
int ptr_OpenProcess; // [esp+FC8h] [ebp-38h]
int ptr_MapViewOfFile; // [esp+FCCh] [ebp-34h]
int ptr_UnmapViewOfFile; // [esp+FD0h] [ebp-30h]
int ptr_CloseHandle; // [esp+FD4h] [ebp-2Ch]
int ptr_GetCurrentProcessId; // [esp+FD8h] [ebp-28h]
int ptr_OutputDebugStringA; // [esp+FDCh] [ebp-24h]
int ptr_CreateToolhelp32Snapshot; // [esp+FE0h] [ebp-20h]
int ptr_Thread32First; // [esp+FE4h] [ebp-1Ch]
int ptr_Thread32Next; // [esp+FE8h] [ebp-18h]
int (*ptr_GetLastError)(void); // [esp+FECh] [ebp-14h]
int (__stdcall *ptr_GetCurrentProcess)(int *); // [esp+FF0h] [ebp-10h]
qmemcpy(&stub_HeaderStart, dword_6344D8, sizeof(stub_HeaderStart));
stub_HeaderStart_Copy = &stub_HeaderStart;
v35 = stub_HeaderStart.XorKey1;
v38 = &stub_HeaderStart.XorKey2;
for ( i = 0xED; i > 0; --i )
{
v36 = *v38;
*v38 ^= v35;
v35 = v36;
++v38;
}
v82 = 48;
v69 = str_SteamError;
v68 = &stub_HeaderStart.StubData[0x2AC]; // String: Steam Error
for ( j = 0; j < 0x10; ++j )
v69[j] = v68[j];
v66 = str_AppLoadError;
v65 = &stub_HeaderStart.StubData[0x314]; // String: Application load error X:XXXXXXXXXX
for ( k = 0; k < 0x28; ++k )
v66[k] = v65[k];
if ( (stub_HeaderStart.Flags & 1) != 0 )
{
v63 = stub_HeaderStart.ValidationHash;
stub_HeaderStart.ValidationHash = 0;
v0 = sub_633266(stub_HeaderStart.BindSectionVirtualAddress, stub_HeaderStart.BindSectionCodeSize, 0);// Validates the .bind code section..
v62 = sub_633266((int)stub_HeaderStart_Copy, 0x3B8, v0);// Validates the .bind stub header data..
if ( v62 != v63 )
v82 = 49;
}
v61 = &handle_Kernel32;
for ( l = 0; l < 0x6C; ++l )
*((_BYTE *)v61 + l) = 0;
if ( stub_HeaderStart.GetModuleHandleA_idata )
handle_Kernel32 = (*(int (__stdcall **)(char *))stub_HeaderStart.GetModuleHandleA_idata)(stub_HeaderStart.StubData);// GetModuleHandleA(kernel32.dll)
else
handle_Kernel32 = (*(int (__stdcall **)(char *))stub_HeaderStart.GetModuleHandleW_idata)(stub_HeaderStart.StubData);// GetModuleHandleW(kernel32.dll)
if ( !stub_HeaderStart.GetProcAddress_idata )
stub_HeaderStart.GetProcAddress_idata = (int)&stub_HeaderStart.GetProcAddress_bind;
ptr_ExitProcess = (int (__cdecl *)(_DWORD))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[572]);// GetProcAddress(ExitProcess)
if ( v82 != 48 )
goto LABEL_153;
ptr_GetModuleHandleA = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[152]);// GetProcAddress(GetModuleHandleA)
ptr_LoadLibraryExA = (int (__stdcall *)(char *, _DWORD, _DWORD))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[80]);// GetProcAddress(LoadLibraryExA)
ptr_FreeLibrary = (void (__stdcall *)(int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[96]);// GetProcAddress(FreeLibrary)
ptr_GetModuleFileNameA = (void (__stdcall *)(_DWORD, char *, int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[128]);// GetProcAddress(GetModuleFileNameA)
ptr_lstrcatA = (void (__stdcall *)(int *, char *))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[556]);// GetProcAddress(lstrcatA)
ptr_Sleep = (void (__stdcall *)(int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[676]);// GetProcAddress(Sleep)
ptr_MultiByteToWideChar = (void (__stdcall *)(_DWORD, _DWORD, int *, int, char *, int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[412]);// GetProcAddress(MultiByteToWideChar)
ptr_GetSystemDirectoryA = (int (__stdcall *)(int *, int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[284]);// GetProcAddress(GetSystemDirectoryA)
ptr_GetStartupInfoA = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[308]);// GetProcAddress(GetStartupInfoA)
ptr_DuplicateHandle = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[328]);// GetProcAddress(DuplicateHandle)
ptr_OpenProcess = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[348]);// GetProcAddress(OpenProcess)
ptr_CloseHandle = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[364]);// GetProcAddress(CloseHandle)
ptr_GetCurrentProcessId = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[264]);// GetProcAddress(GetCurrentProcessId)
ptr_MapViewOfFile = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[380]);// GetProcAddress(MapViewOfFile)
ptr_UnmapViewOfFile = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[396]);// GetProcAddress(UnmapViewOfFile)
ptr_VirtualProtect = (void (__stdcall *)(int, int, int, int *))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[176]);// GetProcAddress(VirtualProtect)
ptr_VirtualQuery = (void (__stdcall *)(int, int *, int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[192]);// GetProcAddress(VirtualQuery)
ptr_FlushInstructionCache = (void (__stdcall *)(int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[208]);// GetProcAddress(FlushInstructionCache)
ptr_OutputDebugStringA = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[436]);// GetProcAddress(OutputDebugStringA)
ptr_CreateToolhelp32Snapshot = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[460]);// GetProcAddress(CreateToolhelp32Snapshot)
ptr_Thread32First = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[492]);// GetProcAddress(Thread32First)
ptr_Thread32Next = (*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[508]);// GetProcAddress(Thread32Next)
ptr_GetLastError = (int (*)(void))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[524]);// GetProcAddress(GetLastError)
ptr_GetCurrentProcess = (int (__stdcall *)(int *))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[652]);// GetProcAddress(GetCurrentProcess)
if ( !ptr_GetModuleHandleA
|| !ptr_LoadLibraryExA
|| !ptr_FreeLibrary
|| !ptr_GetModuleFileNameA
|| !ptr_lstrcatA
|| !ptr_Sleep
|| !ptr_MultiByteToWideChar
|| !ptr_GetSystemDirectoryA
|| !ptr_GetStartupInfoA
|| !ptr_DuplicateHandle
|| !ptr_OpenProcess
|| !ptr_CloseHandle
|| !ptr_GetCurrentProcessId
|| !ptr_MapViewOfFile
|| !ptr_UnmapViewOfFile
|| !ptr_VirtualProtect
|| !ptr_VirtualQuery
|| !ptr_FlushInstructionCache
|| !ptr_OutputDebugStringA
|| !ptr_CreateToolhelp32Snapshot
|| !ptr_Thread32First
|| !ptr_Thread32Next
|| !ptr_GetLastError )
{
v82 = 69;
LABEL_153:
v89 = *(_DWORD *)&stub_HeaderStart.SteamAppIDString[8];// 0 value..
if ( !*(_DWORD *)&stub_HeaderStart.SteamAppIDString[8] )
v89 = ptr_GetLastError(); // 0 value; check for last error..
v89 += 0xFF98; // Encode the last error by adding junk to it..
handle_User32 = ptr_LoadLibraryExA(&stub_HeaderStart.StubData[16], 0, 0);// LoadLibraryExA(user32.dll, 0, 0)
ptr_MessageBoxA = (void (__stdcall *)(_DWORD, char *, char *, int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_User32, &stub_HeaderStart.StubData[112]);// GetProcAddress(MessageBoxA)
v42 = &stub_HeaderStart; // Null the header..
for ( m = 0; m < 0x3B8; ++m )
*((_BYTE *)&v42->XorKey1 + m) = 0;
v40 = &handle_Kernel32; // Null locals..
for ( n = 0; n < 0x6C; ++n )
*((_BYTE *)v40 + n) = 0;
if ( ptr_MessageBoxA )
{
str_AppLoadError[23] = v82; // Append the error id based on the exit point of the stub..
sub_633203(v89, (int)v73); // Convert the encoded error id into a string..
ptr_MessageBoxA(0, str_AppLoadError, str_SteamError, 16);// Display the application error message..
}
return ptr_ExitProcess(v82); // Exit the process with the exit point of the stub..
}
// Thread Check Validation..
if ( (stub_HeaderStart.Flags & 8) != 0 && sub_6333C0((int)&handle_Kernel32) != 1 )
{
v82 = 57;
goto LABEL_153;
}
// Get the current module file name and build path to Steam.dll..
handle_Steam = 0;
ptr_GetModuleFileNameA(0, buff_ModuleFileName, 260);
do
{
if ( buff_ModuleFileName && buff_ModuleFileName[0] )
{
for ( ii = 0; buff_ModuleFileName[ii]; ++ii )
;
if ( *((_BYTE *)&v86 + ii + 3) == '\\' )
--ii;
while ( ii > 0 )
{
if ( *((_BYTE *)&v86 + ii + 3) == '\\' )
{
buff_ModuleFileName[ii] = 0;
v33 = 1;
goto LABEL_66;
}
--ii;
}
v33 = 0;
}
else
{
v33 = 0;
}
LABEL_66:
if ( !v33 )
break;
LOBYTE(v80[0]) = 0;
ptr_lstrcatA(v80, buff_ModuleFileName);
ptr_lstrcatA(v80, &stub_HeaderStart.StubData[700]);// String: Steam.dll
handle_Steam = ptr_LoadLibraryExA((char *)v80, 0, 0);// LoadLibraryExA(full_path_to_Steam.dll, 0, 0);
}
while ( !handle_Steam );
if ( !handle_Steam )
{
v82 = 50;
goto LABEL_153;
}
// Get the Steam.dll API function pointers..
ptr_SteamIsAppSubscribed = (int (__cdecl *)(int, int *, int *, int *))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Steam, &stub_HeaderStart.StubData[732]);// GetProcAddress(SteamIsAppSubscribed)
ptr_SteamStartup = (int (__cdecl *)(int, int *))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Steam, &stub_HeaderStart.StubData[756]);// GetProcAddress(SteamStartup)
ptr_SteamCleanup = (void (__cdecl *)(int *))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Steam, &stub_HeaderStart.StubData[772]);// GetProcAddress(SteamCleanup)
if ( !ptr_SteamIsAppSubscribed || !ptr_SteamStartup || !ptr_SteamCleanup )
{
v82 = 52;
goto LABEL_153;
}
// Validate the file via WinVerifyTrust..
if ( (stub_HeaderStart.Flags & 2) != 0 )
{
v31 = 0;
ptr_IsWow64Process = (void (__stdcall *)(int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[636]);// GetProcAddress(IsWow64Process)
if ( ptr_IsWow64Process )
{
v1 = ptr_GetCurrentProcess(&v31);
ptr_IsWow64Process(v1);
}
if ( !v31 )
{
if ( ptr_GetSystemDirectoryA(buff_SystemDirectory, 260) )
{
ptr_lstrcatA(buff_SystemDirectory, &stub_HeaderStart.StubData[48]);// String: \wintrust.dll
handle_WinTrust = ptr_LoadLibraryExA((char *)buff_SystemDirectory, 0, 0);// LoadLibraryExA(wintrust.dll, 0, 0);
if ( handle_WinTrust )
{
ptr_WinVerifyTrust = (int (__stdcall *)(_DWORD, GUID *, WINTRUST_DATA *))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_WinTrust, &stub_HeaderStart.StubData[620]);// GetProcAddress(WinVerifyTrust)
trustGuidVerifyv2.Data1 = 0xAAC56B; // WINTRUST_ACTION_GENERIC_VERIFY_V2
trustGuidVerifyv2.Data2 = 0xCD44;
trustGuidVerifyv2.Data3 = 0x11D0;
trustGuidVerifyv2.Data4[0] = 0x8C;
trustGuidVerifyv2.Data4[1] = 0xC2;
trustGuidVerifyv2.Data4[2] = 0;
trustGuidVerifyv2.Data4[3] = 0xC0;
trustGuidVerifyv2.Data4[4] = 0x4F;
trustGuidVerifyv2.Data4[5] = 0xC2;
trustGuidVerifyv2.Data4[6] = 0x95;
trustGuidVerifyv2.Data4[7] = 0xEE;
if ( ptr_WinVerifyTrust )
{
ptr_MultiByteToWideChar(0, 0, v80, -1, v30, 260);
v22 = v28;
for ( jj = 0; jj < 0x10; ++jj )
*((_BYTE *)v22 + jj) = 0;
v28[0] = 16;
v28[1] = (int)v30;
v28[2] = 0;
v28[3] = 0;
v20 = &trustData;
for ( kk = 0; kk < 0x30; ++kk )
*((_BYTE *)&v20->cbStruct + kk) = 0;
trustData.cbStruct = 48; // WINTRUST_DATA
trustData.pPolicyCallbackData = 0;
trustData.pSIPClientData = 0;
trustData.dwUIChoice = 2;
trustData.fdwRevocationChecks = 0;
trustData.dwUnionChoice = 1;
trustData.dwStateAction = 0;
trustData.hWVTStateData = 0;
trustData.pwszURLReference = 0;
trustData.dwProvFlags = 256;
trustData.dwUIContext = 0;
trustData.pFile = (WINTRUST_FILE_INFO_ *)v28;
v29 = ptr_WinVerifyTrust(0, &trustGuidVerifyv2, &trustData);// WinVerifyTrust(0, WINTRUST_ACTION_GENERIC_VERIFY_V2, buffer);
if ( v29 )
*(_DWORD *)&stub_HeaderStart.SteamAppIDString[8] = ptr_GetLastError();
ptr_FreeLibrary(handle_WinTrust);
v82 = v29 != 0 ? 51 : 48;
}
else
{
ptr_FreeLibrary(handle_WinTrust);
v82 = 67;
}
}
else
{
v82 = 66;
}
}
else
{
v82 = 65;
}
if ( v82 != 48 )
goto LABEL_153;
}
}
v74 = 0;
v85 = 0;
// Ensure that steam is loaded and the app is subscribed..
if ( ptr_SteamStartup(14, v81) )
{
v58 = 0;
v57 = 0;
if ( ptr_SteamIsAppSubscribed(stub_HeaderStart.SteamAppID, &v58, &v57, v81) )
{
if ( !v81[0] && v58 )
v74 = 1;
}
else
{
v85 = 1;
}
ptr_SteamCleanup(v81);
}
else
{
v85 = 1;
}
if ( v85 || !v74 )
{
handle_Shell32 = ptr_LoadLibraryExA(&stub_HeaderStart.StubData[32], 0, 0);// LoadLibraryExA(shell32.dll, 0, 0);
ptr_ShellExecuteA = (void (__stdcall *)(_DWORD, _DWORD, char *, int *, _DWORD, int))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Shell32, &stub_HeaderStart.StubData[588]);// GetProcAddress(ShellExecuteA)
ptr_GetCommandLineA = (int (*)(void))(*(int (__stdcall **)(int, char *))stub_HeaderStart.GetProcAddress_idata)(handle_Kernel32, &stub_HeaderStart.StubData[604]);// GetProcAddress(GetCommandLineA)
if ( ptr_ShellExecuteA && ptr_GetCommandLineA )
{
if ( v85 )
{
// Build path to launch Steam with the app due to failing to validate it was launched with Steam..
LOBYTE(buff_CommandLine_Cleaned[0]) = 0;
ptr_lstrcatA((int *)buff_ModuleFileName, &stub_HeaderStart.StubData[716]);// String: Steam.exe
ptr_lstrcatA(buff_CommandLine_Cleaned, &stub_HeaderStart.StubData[860]);// String: -applaunch
ptr_lstrcatA(buff_CommandLine_Cleaned, stub_HeaderStart.SteamAppIDString);
buff_CommandLine = (_BYTE *)ptr_GetCommandLineA();
if ( buff_CommandLine && *buff_CommandLine )
{
v51 = 0;
if ( *buff_CommandLine == '"' )
{
++v51;
while ( buff_CommandLine[v51] && buff_CommandLine[v51] != '"' )
++v51;
if ( buff_CommandLine[v51] )
++v51;
}
while ( buff_CommandLine[v51] && buff_CommandLine[v51] != ' ' )
++v51;
if ( buff_CommandLine[v51] == ' ' )
ptr_lstrcatA(buff_CommandLine_Cleaned, &buff_CommandLine[v51]);
}
ptr_ShellExecuteA(0, 0, buff_ModuleFileName, buff_CommandLine_Cleaned, 0, 1);// ShellExecuteA(0, 0, "Steam.exe -applaunch app_id_here", cmd_line_here, 0, 1);
}
else
{
// Open the store page if we don't own the game..
ptr_lstrcatA((int *)&stub_HeaderStart.StubData[828], stub_HeaderStart.SteamAppIDString);// String: steam://store/
ptr_ShellExecuteA(0, 0, &stub_HeaderStart.StubData[828], 0, 0, 1);// ShellExecuteA(0, 0, "steam://store/app_id_here", 0, 0, 1);
}
}
if ( stub_HeaderStart.SteamAppID )
{
v50 = &stub_HeaderStart;
for ( ll = 0; ll < 0x3B8; ++ll )
*((_BYTE *)&v50->XorKey1 + ll) = 0; // Null the header..
v48 = &handle_Kernel32;
for ( mm = 0; mm < 0x6C; ++mm ) // Null locals..
*((_BYTE *)v48 + mm) = 0;
((void (__stdcall *)(_DWORD))ptr_ExitProcess)((char)(54 - (v85 != 0)));// Kill the process..
}
}
// Validate startup inforamtion via memory mapped view..
if ( (stub_HeaderStart.Flags & 0x10) != 0 && !sub_6332D9(&stub_HeaderStart, (int)&handle_Kernel32) )
{
v82 = 55;
goto LABEL_153;
}
// Decrypt/Decode the .text (code) section..
if ( (stub_HeaderStart.Flags & 4) != 0 )
{
ptr_VirtualQuery(stub_HeaderStart.CodeSectionVirtualAddress, v15, 28);
v18 = 4;
v17 = 0;
ptr_VirtualProtect(v15[0], v16, 4, &v17);
v11 = stub_HeaderStart.CodeSectionXorKey;
v14 = (int *)stub_HeaderStart.CodeSectionVirtualAddress;
for ( nn = (unsigned int)stub_HeaderStart.CodeSectionSize >> 2; nn > 0; --nn )
{
v12 = *v14;
*v14 ^= v11;
v11 = v12;
++v14;
}
ptr_VirtualProtect(v15[0], v16, v17, &v18);
v2 = ((int (__stdcall *)(int, int))ptr_GetCurrentProcess)(v15[0], v16);
ptr_FlushInstructionCache(v2);
}
ptr_OEP = (int (__fastcall *)(int, int))stub_HeaderStart.OEP;
v46 = &stub_HeaderStart;
for ( i1 = 0; i1 < 0x3B8; ++i1 )
*((_BYTE *)&v46->XorKey1 + i1) = 0; // Null the header..
// Look for running threads and let them attempt to complete/finish..
v86 = 0;
v3 = sub_6333C0((int)&handle_Kernel32);
v5 = v8;
for ( i2 = v3; i2 > 1 && v86 < 1000; i2 = v6 )
{
ptr_Sleep(50);
v86 += 50;
v6 = sub_6333C0((int)&handle_Kernel32);
v5 = v9;
}
if ( i2 <= 1 )
ptr_FreeLibrary(handle_Steam);
v44 = &handle_Kernel32;
for ( i3 = 0; i3 < 0x6C; ++i3 )
*((_BYTE *)v44 + i3) = 0; // Null locals..
return ptr_OEP(v5, v4); // Invoke the real OEP..
} |
int __cdecl sub_633266(int a1, int a2, int a3)
{
int j; // [esp+0h] [ebp-Ch]
int i; // [esp+4h] [ebp-8h]
for ( i = 0; i < a2; ++i )
{
a3 ^= *(char *)(i + a1) << 24;
for ( j = 8; j > 0; --j )
{
if ( a3 >= 0 )
a3 *= 2;
else
a3 = (2 * a3) ^ 0x488781ED;
}
}
return a3;
}
The handling for that looks like this: bool __cdecl sub_6332D9(stubheader_t *header, int ptrs)
{
int v2; // eax
int v3; // eax
int v5[4]; // [esp+0h] [ebp-78h] BYREF
int v6; // [esp+10h] [ebp-68h]
int v7; // [esp+14h] [ebp-64h]
STARTUPINFOA startInfo; // [esp+18h] [ebp-60h] BYREF
DWORD v9; // [esp+64h] [ebp-14h]
int v10; // [esp+68h] [ebp-10h]
bool v11; // [esp+6Fh] [ebp-9h]
int v12; // [esp+70h] [ebp-8h] BYREF
DWORD v13; // [esp+74h] [ebp-4h]
startInfo.cb = 68;
(*(void (__stdcall **)(STARTUPINFOA *))(ptrs + 48))(&startInfo);// ptr_GetStartupInfoA
v11 = 0;
v13 = startInfo.dwX;
v12 = 0;
v9 = startInfo.dwY;
v10 = (*(int (__stdcall **)(int, _DWORD, DWORD))(ptrs + 56))(0x40, 0, startInfo.dwY);// ptr_OpenProcess(PROCESS_DUP_HANDLE, 0, procId);
if ( v10 )
{
v2 = (*(int (__stdcall **)(int *, int, _DWORD, _DWORD))(ptrs + 96))(&v12, 4, 0, 0);// ptr_GetCurrentProcess
if ( (*(int (__stdcall **)(int, DWORD, int))(ptrs + 52))(v10, v13, v2) )// ptr_DuplicateHandle
{
v7 = (*(int (__stdcall **)(int, int, _DWORD, _DWORD, _DWORD))(ptrs + 60))(v12, 4, 0, 0, 0);// ptr_MapViewOfFile
if ( v7 )
{
v6 = *(_DWORD *)(v7 + 4 * (startInfo.dwXSize % 0x20) + 16);
v5[1] = (*(int (__cdecl **)(DWORD))(ptrs + 72))(startInfo.dwXSize);// ptr_GetCurrentProcessId
v5[2] = header->SteamAppID;
v5[3] = header->Unknown0000;
v3 = sub_633266((int)v5, 16, 0);
v11 = v6 == v3;
(*(void (__stdcall **)(int))(ptrs + 64))(v7);// ptr_UnmapViewOfFile
}
}
(*(void (__stdcall **)(int))(ptrs + 68))(v10);// ptr_CloseHandle
}
return v11;
} Since I cannot debug this file or have other samples with this stub version, I can't say for 100% certainty what's happening, but it looks like Steam may be overriding some of the startup info data returned from GetStartupInfoA to validate things are not tampered with. My guess is this is used for some means of injection detection. |
This is now fixed/closed with the release of 3.0.0.11: |
Thank you very much, it works! |
Back in my day I created a loader that read any assembly around these variants (too lazy to build an unpacker) that walked through and halted execution and simply updated pointers and bypassed WinVerifyTrust and such. Feel old, eh. Edit I think I recall laughing at the 69 constant too in those old days. Might've been a different project with that constant. Ah who knows. :] |
"Use Experimental Features" doesn't help.
Any advice?
http://s000.tinyupload.com/index.php?file_id=03808280615560158692
The text was updated successfully, but these errors were encountered: