Запуск своего потока в чужом процессе
От: pukapin  
Дата: 20.08.03 20:40
Оценка:
Помогите понять что не правильно. Возникает ошибка при попытке получении адреса потока внедренной dll!

GetProcAddress выдает что указанный модуль не найден!
В чем причина?

Код программы:


int main ( )
{
    DWORD dwProcessId = GetProcessId ( "calc.exe" );
    if ( dwProcessId == 0 )
    {
        MessageBox ( NULL, _T("Can't get process id"), _T("ERROR"), MB_OK );
        return 0;
    }

    if ( InjectLib (dwProcessId, 
        _T("C:\\Program Files\\Microsoft Visual Studio\\"
        "MyProjects\\Injection\\MyDll\\Debug\\MyDll.dll")) == FALSE)
    {
        MessageBox ( NULL, 
            _T("Can't inject dll into the process"), _T("ERROR"), MB_OK );
        return 0;
    }

    HANDLE hProcess = OpenProcess ( PROCESS_CREATE_THREAD | 
                                        PROCESS_VM_OPERATION | 
                                        PROCESS_VM_WRITE, FALSE, dwProcessId );
    if ( hProcess == NULL )
    {
        MessageBox ( NULL, _T("Can't get process handle"), _T("ERROR"), MB_OK );
        if ( EjectLib (dwProcessId, _T("MyDll.dll")) == FALSE )
            printf ( "\r\nCan't eject library...\r\n" );
        return 0;
    }

    HMODULE hDll = GetModuleInstance ( _T("MyDll.dll"), dwProcessId );
    if ( hDll == NULL )
    {
        ShowLastError ( );
        MessageBox ( NULL, _T("Can't get module instance"), _T("ERROR"), MB_OK );
        if ( EjectLib (dwProcessId, _T("MyDll.dll")) == FALSE )
            printf ( "\r\nCan't eject library...\r\n" );
        return 0;
    }
    
    PFNSHOWMESSAGE ThreadProc = (PFNSHOWMESSAGE)GetProcAddress 
        ( hDll, _T("ShowMessage") );
    if ( ThreadProc == NULL )
    {
        ShowLastError ( );
        MessageBox ( NULL, "Can't get thread address!", "ERROR", MB_OK );
        if ( EjectLib (dwProcessId, _T("MyDll.dll")) == FALSE )
            printf ( "\r\nCan't eject library...\r\n" );
        return 0;
    }

    if ( CreateRemoteThread (hProcess, NULL, 0, ThreadProc, 
        _T("This is my message"), NULL, NULL) != NULL )
    {
        MessageBox ( NULL, "Can't execute remote thread!", "ERROR", MB_OK );
        if ( EjectLib (dwProcessId, _T("MyDll.dll")) == FALSE )
            printf ( "\r\nCan't eject library...\r\n" );
        return 0;
    }


    return 0;
}


DWORD GetProcessId ( LPTSTR lpszProcess )
{
    TCHAR lpszProcessName [100];
    PROCESSENTRY32 ProcessEntry32;
    HANDLE hSnapshot;
    
    hSnapshot = CreateToolhelp32Snapshot ( 
        TH32CS_SNAPPROCESS, 0 );
    ZeroMemory ( lpszProcessName, 100 );
    lstrcpy ( lpszProcessName, lpszProcess );

    if ( !Process32First (hSnapshot, &ProcessEntry32) )
    {
        ShowLastError ();
        CloseHandle ( hSnapshot );
        return 0;
    }    
    do 
    {
        //printf ( "\r\n%s - %ul\r\n", ProcessEntry32.szExeFile, ProcessEntry32.th32ProcessID );
        if ( _tcsstr (_tcsupr ( ProcessEntry32.szExeFile ),
            _tcsupr ( lpszProcessName )) != NULL )
        {
            printf ( "\r\nGetProcessId: %s - %ul\r\n", ProcessEntry32.szExeFile, 
                ProcessEntry32.th32ProcessID );
            CloseHandle ( hSnapshot );
            return ProcessEntry32.th32ProcessID;
        }
    }
    while ( Process32Next (hSnapshot, &ProcessEntry32) );

    return 0;
}

HMODULE GetModuleInstance ( LPTSTR lpszLibrary, DWORD dwProcessId )
{
    TCHAR lpszLibraryName [100];
    HANDLE hSnapshot;
    MODULEENTRY32 ModuleEntry32;

    ZeroMemory ( lpszLibraryName, 100 );
    lstrcpy ( lpszLibraryName, lpszLibrary );
    hSnapshot = CreateToolhelp32Snapshot ( TH32CS_SNAPMODULE, dwProcessId );

    if ( !Module32First (hSnapshot, &ModuleEntry32) )
    {
        CloseHandle ( hSnapshot );
        return NULL;
    }
    do
    {
        if ( _tcsstr (_tcsupr ( ModuleEntry32.szModule ),
            _tcsupr ( lpszLibraryName )) != NULL )
        {
            printf ( "\r\nGetModuleInstance: %s - %ul\r\n", ModuleEntry32.szModule, 
                ModuleEntry32.hModule );

            CloseHandle ( hSnapshot );
            return ModuleEntry32.hModule;
        }
    }
    while ( Module32Next (hSnapshot, &ModuleEntry32) );

    return NULL;
}

BOOL WINAPI InjectLib(
   DWORD dwProcessId,    LPCTSTR pszLibFile )
{
     if ( !dwProcessId ) 
     {
          return FALSE;
     }
     BOOL fOk = FALSE; // Assume that the function fails
     HANDLE hProcess = NULL, hThread = NULL;
     PTSTR pszLibFileRemote = NULL;
     
     __try {
          // Get a handle for the target process.
          hProcess = OpenProcess(
               PROCESS_QUERY_INFORMATION |   // Required by Alpha
               PROCESS_CREATE_THREAD     |   // For CreateRemoteThread
               PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx
               PROCESS_VM_WRITE,             // For WriteProcessMemory
               FALSE, dwProcessId);
          if (hProcess == NULL) __leave;
          
          // Calculate the number of bytes needed for the DLL's pathname
          int cch = 1 + _tcslen(pszLibFile);
          int cb  = cch * sizeof(TCHAR);
          
          // Allocate space in the remote process for the pathname
          pszLibFileRemote = (PTSTR) 
               VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
          if (pszLibFileRemote == NULL) __leave;
          
          // Copy the DLL's pathname to the remote process's address space
          if (!WriteProcessMemory(hProcess, pszLibFileRemote, 
               (PVOID) pszLibFile, cb, NULL)) __leave;
          
          // Get the real address of LoadLibraryW in Kernel32.dll
#ifdef UNICODE
          PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
               GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
#else
          PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
               GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");
#endif //UNICODE
          if (pfnThreadRtn == NULL) __leave;
          
          // Create a remote thread that calls LoadLibraryW(DLLPathname)
          hThread = CreateRemoteThread(hProcess, NULL, 0, 
               pfnThreadRtn, pszLibFileRemote, 0, NULL);
          if (hThread == NULL) __leave;
          
          // Wait for the remote thread to terminate
          WaitForSingleObject(hThread, INFINITE);
          
          fOk = TRUE; // Everything executed successfully
     }
     __finally { // Now, we can clean everthing up
          
          // Free the remote memory that contained the DLL's pathname
          if (pszLibFileRemote != NULL) 
               VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
          
          if (hThread  != NULL) 
               CloseHandle(hThread);
          
          if (hProcess != NULL) 
               CloseHandle(hProcess);
     }
     
     return(fOk);
}

BOOL WINAPI EjectLib(DWORD dwProcessId, LPCTSTR pszLibFile) 
{
     if ( !dwProcessId ) 
     {
          return FALSE;
     }     
     BOOL fOk = FALSE; // Assume that the function fails
     HANDLE hthSnapshot = NULL;
     HANDLE hProcess = NULL, hThread = NULL;
     
     __try {
          // Grab a new snapshot of the process
          hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
          if (hthSnapshot == NULL) __leave;
          
          // Get the HMODULE of the desired library
          MODULEENTRY32 me = { sizeof(me) };
          BOOL fFound = FALSE;
          BOOL fMoreMods = Module32First(hthSnapshot, &me);
          for (; fMoreMods; fMoreMods = Module32Next(hthSnapshot, &me)) {
               fFound = (_tcsicmp(me.szModule,  pszLibFile) == 0) || 
                    (_tcsicmp(me.szExePath, pszLibFile) == 0);
               if (fFound) break;
          }
          if (!fFound) __leave;
          
          // Get a handle for the target process.
          hProcess = OpenProcess(
               PROCESS_QUERY_INFORMATION |   // Required by Alpha
               PROCESS_CREATE_THREAD     | 
               PROCESS_VM_OPERATION,  // For CreateRemoteThread
               FALSE, dwProcessId);
          if (hProcess == NULL) __leave;
          
          // Get the real address of LoadLibraryW in Kernel32.dll
          PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
               GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "FreeLibrary");
          if (pfnThreadRtn == NULL) __leave;
          
          // Create a remote thread that calls LoadLibraryW(DLLPathname)
          hThread = CreateRemoteThread(hProcess, NULL, 0, 
               pfnThreadRtn, me.modBaseAddr, 0, NULL);
          if (hThread == NULL) __leave;
          
          // Wait for the remote thread to terminate
          WaitForSingleObject(hThread, INFINITE);
          
          fOk = TRUE; // Everything executed successfully
     }
     __finally { // Now we can clean everything up
          
          if (hthSnapshot != NULL) 
               CloseHandle(hthSnapshot);
          
          if (hThread     != NULL) 
               CloseHandle(hThread);
          
          if (hProcess    != NULL) 
               CloseHandle(hProcess);
     }
     
     return(fOk);
}

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.