FARPROC CRemoteLoader::GetRemoteProcAddress( PCHAR Module, SHORT Function )
{
	HMODULE hKernel32 = LoadLibraryA( "Kernel32.dll" );

	if( hKernel32 == NULL ) return NULL;

	DWORD GetProcAddressOffset = ( DWORD ) GetProcAddress - ( DWORD ) hKernel32;

	HMODULE hRemoteKernel32 = GetRemoteModuleHandleA( "Kernel32.dll" );

	if( hRemoteKernel32 == NULL ) return NULL;
	
	HMODULE hRemoteModule = GetRemoteModuleHandleA( Module );

	if( hRemoteModule == NULL ) return NULL;
	
	PVOID ReturnPointerValue = RemoteAllocateMemory( sizeof( DWORD ) );

	PushInt( ( INT ) hRemoteModule ); // HACKHACK: Why is this an int?
	PushInt( ( INT ) Function );
	PushCall( CCONV_STDCALL, ( FARPROC )( ( DWORD_PTR ) hRemoteKernel32 + ( DWORD_PTR ) GetProcAddressOffset ) );

	//mov ptr, eax
	AddByteToBuffer( 0xA3 );
	AddLongToBuffer( ( DWORD ) ReturnPointerValue );

	//xor eax, eax
	AddByteToBuffer( 0x33 );
	AddByteToBuffer( 0xC0 );

	//retn 4
	AddByteToBuffer( 0xC2 );
	AddByteToBuffer( 0x04 );
	AddByteToBuffer( 0x00 );

	if( ExecuteRemoteThreadBuffer( m_CurrentRemoteThreadBuffer, true ) == false )
	{
		RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );

		return NULL;
	}

	DWORD ProcAddressRemote = 0;

	if( ReadProcessMemory( GetProcess(), ReturnPointerValue, &ProcAddressRemote, sizeof( DWORD ), NULL ) == TRUE )
	{
		RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );

		return ( FARPROC ) ProcAddressRemote;
	}
	
	RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );

	return NULL;
}
HMODULE CRemoteLoader::GetRemoteModuleHandleW( PWCHAR Module )
{
	CHAR ModuleAnsi[ MAX_PATH ] = { 0 };

	wcstombs( ModuleAnsi, Module, MAX_PATH );

	return GetRemoteModuleHandleA( ModuleAnsi );
}
Example #3
0
int main(int argc, char* argv[])
{
    DWORD dwProcessId = GetCurrentProcessId();
    char szProcessName[256] = {0};
    char szModuleName[MAX_PATH] = {0};

    for (int i = 1; i < argc; i++) {
        if (_stricmp(argv[i], "-pid") == 0 && i < (argc - 1)) {
            dwProcessId = atoi(argv[i + 1]);
        }

        if (_stricmp(argv[i], "-name") == 0 && i < (argc - 1)) {
            strcpy_s(szProcessName, argv[i + 1]);
        }

        if (_stricmp(argv[i], "-dll") == 0 && i < (argc - 1)) {
            strcpy_s(szModuleName, argv[i + 1]);
        }
    }

    if (strlen(szModuleName) == 0) {
        printf("Module name is required...\n");
        return 0;
    }

    if (strlen(szProcessName) == 0 && dwProcessId == GetCurrentProcessId()) {
        printf("Invalid parameters!\n");
        return 0;
    }

    if (strlen(szProcessName) > 0) {
        if (dwProcessId == GetCurrentProcessId()) { // Only change the processid if it's not already set
            dwProcessId = GetProcessIdFromProcessName(szProcessName);

            if (dwProcessId == GetCurrentProcessId()) {
                printf("Failed to obtain process \"%s\"...\n", szProcessName);
                return 0;
            }
        }
    }

    HMODULE hKernel = LoadLibraryA("kernel32.dll");
    DWORD64 dwLoadLibraryA = (DWORD64) GetProcAddress(hKernel, "LoadLibraryA") - (DWORD64) hKernel;
    printf("kernel32.dll: %016llX\n", hKernel);
    printf("LoadLibraryA: %016llX\n", dwLoadLibraryA);
    printf("Module Name: %s\n", szModuleName);
    char szCurrentModulePath[MAX_PATH] = {0};
    GetModuleFileNameA(GetModuleHandle(NULL), szCurrentModulePath, MAX_PATH);

    for (size_t i = strlen(szCurrentModulePath); i > 0; i--) {
        if (szCurrentModulePath[ i ] == '\\') {
            szCurrentModulePath[ i + 1 ] = 0;
            break;
        }
    }

    strcat_s(szCurrentModulePath, szModuleName);
    printf("Full Path: %s\n", szCurrentModulePath);
    DWORD dwFileAttributes = GetFileAttributesA(szCurrentModulePath);

    if (dwFileAttributes == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND) {
        printf("File not found...\n");
        return 0;
    }

    printf("Injecting: %s\n", szCurrentModulePath);
    HMODULE hRemoteKernel = GetRemoteModuleHandleA(dwProcessId, "kernel32.dll");

    if (hRemoteKernel == NULL) {
        printf("Failed to locate kernel32 in remote process...\n");
        return 0;
    }

    printf("kernel32 (remote): 0x%016llX\n", hRemoteKernel);
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);

    if (hProcess == INVALID_HANDLE_VALUE) {
        printf("Failed to locate remote process...\n");
        return 0;
    }

    LPVOID lpModuleName = VirtualAllocEx(hProcess, NULL, strlen(szCurrentModulePath) + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if (lpModuleName == NULL) {
        printf("Failed to allocate module name in remote process...\n");
        return 0;
    }

    if (WriteProcessMemory(hProcess, lpModuleName, szCurrentModulePath, strlen(szCurrentModulePath), NULL) == FALSE) {
        printf("Failed to write module name in remote process...\n");
        return 0;
    }

    DWORD64 dwRemoteLoadLibraryAddress = ((DWORD64)hRemoteKernel + dwLoadLibraryA);
    printf("LoadLibraryA (remote): %016llX\n", dwRemoteLoadLibraryAddress);
    HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE) dwRemoteLoadLibraryAddress, lpModuleName, 0, 0);
    printf("Injecting... ");
    WaitForSingleObject(hThread, INFINITE);
    printf("Injected!\n");
    return 0;
}
Example #4
0
    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; 
    } 
BOOL CRemoteLoader::ProcessImportTable( PVOID BaseAddress, PVOID RemoteAddress, PCHAR OptionalPath )
{
	IMAGE_NT_HEADERS* ImageNtHeaders = ToNts( BaseAddress );

	if( ImageNtHeaders == NULL )
		return FALSE;

	if( ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].Size )
	{
		IMAGE_IMPORT_DESCRIPTOR* ImageImportDescriptor = ( IMAGE_IMPORT_DESCRIPTOR* )
			RvaToPointer( ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress, BaseAddress );

		if( ImageImportDescriptor )
		{
			for( ; ImageImportDescriptor->Name; ImageImportDescriptor++ )
			{
				PCHAR ModuleName = ( PCHAR ) RvaToPointer( ImageImportDescriptor->Name, BaseAddress );

				if( ModuleName == NULL )
				{
					DebugShout( "[ProcessImportTable] Module name for entry NULL" );

					continue;
				}

				DebugShout( "[ProcessImportTable] Module Name [%s]", ModuleName );

				HMODULE ModuleBase = GetRemoteModuleHandleA( ModuleName );

				if( ModuleBase == NULL )
				{
					ModuleBase = LoadLibraryByPathA( ModuleName );
				}

				if( ModuleBase == NULL )
				{
					DebugShout( "[ProcessImportTable] Failed to obtain module handle [%s]", ModuleName );

					continue;
				}

				IMAGE_THUNK_DATA *ImageThunkData	= NULL;
				IMAGE_THUNK_DATA *ImageFuncData		= NULL;

				if( ImageImportDescriptor->OriginalFirstThunk )
				{
					ImageThunkData	= ( IMAGE_THUNK_DATA* ) RvaToPointer( ImageImportDescriptor->OriginalFirstThunk, BaseAddress );
					ImageFuncData	= ( IMAGE_THUNK_DATA* ) RvaToPointer( ImageImportDescriptor->FirstThunk, BaseAddress );
				}
				else
				{
					ImageThunkData	= ( IMAGE_THUNK_DATA* ) RvaToPointer( ImageImportDescriptor->FirstThunk, BaseAddress );
					ImageFuncData	= ( IMAGE_THUNK_DATA* ) RvaToPointer( ImageImportDescriptor->FirstThunk, BaseAddress );
				}

				
				if( ImageThunkData == NULL )
				{
					DebugShout( "[ProcessImportTable] Image Thunk Data is NULL" );
				}

				if( ImageFuncData == NULL )
				{
					DebugShout( "[ProcessImportTable] Image Func Data is NULL" );
				}

				for( ; ImageThunkData->u1.AddressOfData; ImageThunkData++, ImageFuncData++ )
				{
					FARPROC FunctionAddress = NULL;

					if( IMAGE_SNAP_BY_ORDINAL( ImageThunkData->u1.Ordinal ) )
					{
						SHORT Ordinal = ( SHORT ) IMAGE_ORDINAL( ImageThunkData->u1.Ordinal );

						FunctionAddress = ( FARPROC ) GetRemoteProcAddress( ModuleName, Ordinal );

						DebugShout( "[ProcessImportTable] Processed (%s -> %i) -> (0x%X)", 
							ModuleName, Ordinal, FunctionAddress );

						if( this->GetProcess() == INVALID_HANDLE_VALUE )
						{
							DebugShout( "[ProcessImportTable] Normal Value (0x%X)",
								GetProcAddress( GetModuleHandleA( ModuleName ), ( LPCSTR ) Ordinal ) );
						}
					}
					else
					{
						IMAGE_IMPORT_BY_NAME* ImageImportByName = ( IMAGE_IMPORT_BY_NAME* )
							RvaToPointer( *( DWORD* ) ImageThunkData, BaseAddress );

						PCHAR NameOfImport = ( PCHAR ) ImageImportByName->Name;

						FunctionAddress = ( FARPROC ) GetRemoteProcAddress( ModuleName, NameOfImport );

						DebugShout( "[ProcessImportTable] Processed (%s -> %s) -> (0x%X)", 
							ModuleName, NameOfImport, FunctionAddress );

						if( this->GetProcess() == INVALID_HANDLE_VALUE )
						{
							DebugShout( "[ProcessImportTable] Normal Value (0x%X)",
								GetProcAddress( GetModuleHandleA( ModuleName ), NameOfImport ) );
						}
					}

					ImageFuncData->u1.Function = ( DWORD ) FunctionAddress;
				}
			}

			return TRUE;
		}
		else
		{
			DebugShout( "[ProcessImportTable] Size of table confirmed but pointer to data invalid!" );

			return FALSE;
		}
	}
	else
	{
		DebugShout( "[ProcessImportTable] No Imports" );

		return TRUE;
	}

	return FALSE;
}