Remote functions
So you want to remotely control an application, get some information about it?
Maybe your GetRemoteProcAddress implementation sucks alot?
Check this thing out, it's just some code i wrote while working on my manual mapping issues, this isn't *the* code i used but rather its own standalone version, the version i use is a little more sophisticated but basically does the same things.
Remote.h
Remote.cpp
Usage
Benefits using this implementation for a loader for example, would be that you don't need to actually load modules into your loader to get the foreign address of them (Except Kernel32.dll, but, COME ON, lol) and that modules impossible to load from your loader (like CSS's tier0.dll or vstdlib.dll) will not be a problem anymore.
Maybe your GetRemoteProcAddress implementation sucks alot?
Check this thing out, it's just some code i wrote while working on my manual mapping issues, this isn't *the* code i used but rather its own standalone version, the version i use is a little more sophisticated but basically does the same things.
Remote.h
PHP Code:
#ifndef __REMOTE_HEADER__
#define __REMOTE_HEADER__
namespace Remote {
namespace Allocate
{
void* Alloc( HANDLE hProcess, size_t Size );
void* Commit( HANDLE hProcess, void* Data, size_t Size );
void Free( HANDLE hProcess, void* Data, size_t Size );
};
HANDLE GetRemoteProcessHandleA( char *pszProcessName );
HMODULE GetRemoteModuleHandleA( HANDLE hProcess, const char *szModule );
HMODULE RemoteLoadLibraryA( HANDLE hProcess, char *pszLibraryPath );
FARPROC GetRemoteProcAddress( HANDLE hProcess, char *pszModuleName, char *pszProcName );
};
#endif //__REMOTE_HEADER__
PHP Code:
#include "stdafx.h"
#include "Remote.h"
namespace Remote {
namespace Allocate
{
void* Alloc( HANDLE hProcess, size_t Size )
{
return VirtualAllocEx( hProcess, NULL, Size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
}
void* Commit( HANDLE hProcess, void* Data, size_t Size )
{
void* AllocatedPointer = Alloc( hProcess, Size );
if( AllocatedPointer )
{
if( WriteProcessMemory( hProcess, AllocatedPointer, Data, Size, NULL ) == TRUE )
{
return AllocatedPointer;
}
Free( hProcess, AllocatedPointer, Size );
}
return NULL;
}
void Free( HANDLE hProcess, void* Data, size_t Size )
{
VirtualFreeEx( hProcess, Data, Size, MEM_RELEASE );
}
};
HANDLE GetRemoteProcessHandleA( char *pszProcessName )
{
HANDLE tlh = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, NULL );
PROCESSENTRY32 proEntry;
proEntry.dwSize = sizeof( PROCESSENTRY32 );
Process32First( tlh, &proEntry );
do
{
if( _stricmp( pszProcessName, proEntry.szExeFile ) == 0 )
{
CloseHandle( tlh );
return OpenProcess( PROCESS_ALL_ACCESS, FALSE, proEntry.th32ProcessID );
}
}
while( Process32Next( tlh, &proEntry ) );
CloseHandle( tlh );
return INVALID_HANDLE_VALUE;
}
HMODULE GetRemoteModuleHandleA( HANDLE hProcess, const char *szModule )
{
HANDLE tlh = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, GetProcessId( hProcess ) );
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof( MODULEENTRY32 );
Module32First( tlh, &modEntry );
do
{
if( _stricmp( szModule, modEntry.szModule ) == 0 )
{
CloseHandle( tlh );
return modEntry.hModule;
}
}
while( Module32Next( tlh, &modEntry ) );
CloseHandle( tlh );
return NULL;
}
HMODULE RemoteLoadLibraryA( HANDLE hProcess, char *pszLibraryPath )
{
unsigned long ulReturnValue = NULL;
if( pszLibraryPath )
{
FARPROC fpLoadLibraryARemote = GetRemoteProcAddress( hProcess, "Kernel32.dll", "LoadLibraryA" );
if( fpLoadLibraryARemote )
{
void* AllocatedResult = Allocate::Alloc( hProcess, sizeof( unsigned long ) );
void* CommitedLibName = Allocate::Commit( hProcess, pszLibraryPath, strlen( pszLibraryPath ) + 1 );
if( CommitedLibName )
{
unsigned char LoadLibraryAThreadBuffer[ 22 ] =
{
0x68, 0x00, 0x00, 0x00, 0x00, //push lib name
0xB8, 0x00, 0x00, 0x00, 0x00, //mov eax, LoadLibraryA
0xFF, 0xD0, //call eax
0xA3, 0x00, 0x00, 0x00, 0x00, //mov result, eax
0x33, 0xC0, //xor eax, eax (eax = 0)
0xC2, 0x04, 0x00 //retn 4
};
*( unsigned long* )( LoadLibraryAThreadBuffer + 0x01 ) = ( unsigned long ) CommitedLibName;
*( unsigned long* )( LoadLibraryAThreadBuffer + 0x06 ) = ( unsigned long ) fpLoadLibraryARemote;
*( unsigned long* )( LoadLibraryAThreadBuffer + 0x0D ) = ( unsigned long ) AllocatedResult;
void* RemoteBufferToWrite = Allocate::Commit( hProcess, LoadLibraryAThreadBuffer, sizeof( LoadLibraryAThreadBuffer ) );
if( RemoteBufferToWrite )
{
HANDLE hSpawnedThread = CreateRemoteThread( hProcess, 0, 0, ( LPTHREAD_START_ROUTINE ) RemoteBufferToWrite, 0, 0, 0 );
WaitForSingleObject( hSpawnedThread, INFINITE ); // Async..
ReadProcessMemory( hProcess, AllocatedResult, &ulReturnValue, sizeof( unsigned long ), NULL );
Allocate::Free( hProcess, RemoteBufferToWrite, sizeof( LoadLibraryAThreadBuffer ) );
}
Allocate::Free( hProcess, CommitedLibName, strlen( pszLibraryPath ) + 1 );
}
}
}
return reinterpret_cast< HMODULE >( ulReturnValue );
}
FARPROC GetRemoteProcAddress( HANDLE hProcess, char *pszModuleName, char *pszProcName )
{
FARPROC fpReturnValue = NULL;
HMODULE hLocalKernel = GetModuleHandleA( "Kernel32.dll" );
if( hLocalKernel )
{
HMODULE hRemoteKernel = GetRemoteModuleHandleA( hProcess, "Kernel32.dll" );
if( hRemoteKernel )
{
unsigned long RemoteGetProcAddress =
( unsigned long ) hRemoteKernel + ( unsigned long )( ( unsigned long ) GetProcAddress - ( unsigned long ) hLocalKernel );
void* ResultOfGetProcAddress = Allocate::Alloc( hProcess, sizeof( unsigned long ) );
void* CommitedProcName = Allocate::Commit( hProcess, pszProcName, strlen( pszProcName ) + 1 );
if( ResultOfGetProcAddress && CommitedProcName )
{
unsigned char GetProcAddressThreadBuffer[ 27 ] =
{
0x68, 0x00, 0x00, 0x00, 0x00, //push proc name
0x68, 0x00, 0x00, 0x00, 0x00, //push module address
0xB8, 0x00, 0x00, 0x00, 0x00, //mov eax, GetProcAddress
0xFF, 0xD0, //call eax
0xA3, 0x00, 0x00, 0x00, 0x00, //mov result, eax
0x33, 0xC0, //xor eax, eax (eax = 0)
0xC2, 0x04, 0x00 //retn 4
};
*( unsigned long* )( GetProcAddressThreadBuffer + 0x01 ) = ( unsigned long ) CommitedProcName;
*( unsigned long* )( GetProcAddressThreadBuffer + 0x06 ) = ( unsigned long ) hRemoteKernel;
*( unsigned long* )( GetProcAddressThreadBuffer + 0x0B ) = ( unsigned long ) RemoteGetProcAddress;
*( unsigned long* )( GetProcAddressThreadBuffer + 0x12 ) = ( unsigned long ) ResultOfGetProcAddress;
void* RemoteBufferToWrite = Allocate::Commit( hProcess, GetProcAddressThreadBuffer, sizeof( GetProcAddressThreadBuffer ) );
if( RemoteBufferToWrite )
{
HANDLE hSpawnedThread = CreateRemoteThread( hProcess, 0, 0, ( LPTHREAD_START_ROUTINE ) RemoteBufferToWrite, 0, 0, 0 );
WaitForSingleObject( hSpawnedThread, INFINITE ); // Async..
ReadProcessMemory( hProcess, ResultOfGetProcAddress, &fpReturnValue, sizeof( unsigned long ), NULL );
Allocate::Free( hProcess, RemoteBufferToWrite, sizeof( GetProcAddressThreadBuffer ) );
}
}
if( ResultOfGetProcAddress )
{
Allocate::Free( hProcess, ResultOfGetProcAddress, sizeof( unsigned long ) );
}
if( CommitedProcName )
{
Allocate::Free( hProcess, CommitedProcName, strlen( pszProcName ) + 1 );
}
}
}
return fpReturnValue;
}
};
PHP Code:
#include "stdafx.h"
#include "Remote.h"
DWORD WINAPI lpThreadForSpaceBar( LPVOID lpParam )
{
while( ( GetAsyncKeyState( VK_SPACE ) & 1 ) == 0 )
{
Sleep( 100 );
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hCalculator = Remote::GetRemoteProcessHandleA( "calc.exe" );
if( hCalculator != INVALID_HANDLE_VALUE )
{
FARPROC RemoteLoadLibraryA = Remote::GetRemoteProcAddress( hCalculator, "Kernel32.dll", "LoadLibraryA" );
if( RemoteLoadLibraryA )
{
printf( "LoadLibraryA Address is [0x%X]\n", RemoteLoadLibraryA );
}
else
{
printf( "LoadLibraryA Address was not found..\n" );
}
HMODULE hRemoteUser32 = Remote::RemoteLoadLibraryA( hCalculator, "User32.dll" );
if( hRemoteUser32 )
{
printf( "USER32.DLL Address is [0x%X][0x%X]\n", hRemoteUser32, GetModuleHandleA( "User32.dll" ) );
}
else
{
printf( "USER32.DLL was not found..\n" );
}
CloseHandle( hCalculator ); // Remember to close the handle from OpenProcess
}
else
{
printf( "Error opening process: INVALID_HANDLE_VALUE\n" );
}
printf( "Press the space bar to continue...\n" );
WaitForSingleObject( CreateThread( 0, 0, lpThreadForSpaceBar, 0, 0, 0 ), INFINITE );
return 0;
}
0 comentarios:
Publicar un comentario