Особенности функции CreateRemoteThread

Тема в разделе "WASM.WIN32", создана пользователем Aivengo, 6 фев 2007.

  1. Aivengo

    Aivengo New Member

    Публикаций:
    0
    Регистрация:
    6 фев 2007
    Сообщения:
    29
    Заметил любопытную вещь - при создании потока в удалённом процессе и внедрении в него кода сам процес приостанавливается и ждёт завершения работы вновь созданного потока. Почему так происходит ведь это должен быть отдельный поток? Как это можно обойти?
     
  2. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    C чего это ты взял, что он останавливается? Если ты сам не остановишь все треды, то они будут работать, но при создании нового в планирование будет включен ещё один поток.
     
  3. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Это может произойти тока если ты открываешь процесс отладчиком... А простой VirtualAllocEx, WriteProcessMemory, CreateRemoteThread такого эффекта не дают.
     
  4. Aivengo

    Aivengo New Member

    Публикаций:
    0
    Регистрация:
    6 фев 2007
    Сообщения:
    29
    Угу... я тоже так думаю (код чуть ли не по Рихтеру весь)... но получилось всё несколько иначе :dntknw:
    Во внедряемой dll в функции DllMain стоит просто запуск ShowMessage c одной кнопкой OK. При внедрении в процес Explorer'а несмотря на установленный низкий приоритет вновь создаваемого потока, пока не нажмёшь на кнопку ОК Explorer просто подвисает.
     
  5. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    странно, у меня подобного не наблюдается
     
  6. Aivengo

    Aivengo New Member

    Публикаций:
    0
    Регистрация:
    6 фев 2007
    Сообщения:
    29
    Вот код DLL:

    Код (Text):
    1. #include <vcl.h>
    2. #include <windows.h>
    3. #include "psapi.h"
    4. #pragma hdrstop
    5. #pragma argsused
    6.  
    7. int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    8. {char s[40];
    9.  char szProcessName[MAX_PATH] = "unknown";
    10.  int res = 0;
    11.  
    12.  if(reason == DLL_THREAD_ATTACH)
    13.  {// Get a handle to the process.
    14.   HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId());
    15.  
    16.   // Get the process name.
    17.   if (NULL != hProcess )
    18.   {
    19.    HMODULE hMod;
    20.    DWORD cbNeeded;
    21.  
    22.    if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
    23.    {
    24.     GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) );
    25.    }
    26.    else return 0;
    27.   }
    28.   else return 0;
    29.  
    30.   CloseHandle( hProcess );
    31.  
    32.  
    33.   strcpy(s, "Ïðîèçâåäåíà èíêàïñóëÿöèÿ â ïðîöåññ ");
    34.   strcat(s, szProcessName);
    35.   MessageBox(NULL, s, "Èíêàïñóëÿöèÿ", MB_OK);
    36.  }
    37.  
    38.  return 1;
    39. }
    Инжекция по Рихтеру. Сам никак понять не могу в чём дело.
     
  7. Aivengo

    Aivengo New Member

    Публикаций:
    0
    Регистрация:
    6 фев 2007
    Сообщения:
    29
    Неужели без вариантов?
     
  8. amitophia

    amitophia New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2004
    Сообщения:
    44
    Дело не в CreateRemoteThread, а в LoadLibrary. Например, пока она работает, GetModuleHandle, вызванная в другом потоке, будет висеть и ждать её завершения.
     
  9. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Ты прав, конечно, но при чем тут весь процесс процесс??? Просто LoadLibrary не вернется, пока DllMain не вернет что-нибудь. А т.к. она вызывается в отдельном треде, то зависнуть должен только тред, а не весь процесс.

    Кроме того даже в этом случае зависание имхо должно произойти только при первом вызове DllMain, т.е. когда reason = DLL_PROCESS_ATTACH, а код обрабатывает DLL_THREAD_ATTACH.

    Осталось посмотреть, не подвели ли звезды :)

    А если серъезно, отладчик в зубы и веперед - больше ниче не могу посоветовать. Посмотри, может где-то рекурсия вызывается, может ты какие-то не те параметры где-то передаешь. Попробуй внедрить код в другой процес...
     
  10. amitophia

    amitophia New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2004
    Сообщения:
    44
    А весь процесс и не виснет. Виснут только те потоки, которые ждут окончания LoadLibrary, ну и те, которые ждут тех, которые повисли :)). А THREAD_ или PROSESS_ATTACH влияет только на то, когда зависнет: сразу при подгрузке длл или при создании очередного потока.
     
  11. Aivengo

    Aivengo New Member

    Публикаций:
    0
    Регистрация:
    6 фев 2007
    Сообщения:
    29
    2MSoft
    Пробовал внедрять в другие процессы - результат тот же.

    Попробовал переиграть ситуацию следующим образом:

    Код (Text):
    1. #include <vcl.h>
    2. #include <windows.h>
    3. #include "psapi.h"
    4. #pragma hdrstop
    5. #pragma argsused
    6.  
    7. VOID CALLBACK _export TimerProc(
    8.   HWND hwnd,    // handle of window for timer messages
    9.   UINT uMsg,    // WM_TIMER message
    10.   UINT idEvent, // timer identifier
    11.   DWORD dwTime  // current system time
    12. )
    13. {
    14.  char s[40];
    15.  char szProcessName[MAX_PATH] = "unknown";
    16.  int res = 0;
    17.  
    18.  KillTimer(NULL, idEvent);
    19.  
    20.  HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId());
    21.  
    22.   // Get the process name.
    23.   if (NULL != hProcess )
    24.   {
    25.    HMODULE hMod;
    26.    DWORD cbNeeded;
    27.  
    28.    if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
    29.    {
    30.     GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) );
    31.    }
    32.    else return;
    33.   }
    34.   else return;
    35.  
    36.   CloseHandle( hProcess );
    37.  
    38.  
    39.   strcpy(s, "Ïðîèçâåäåíà èíêàïñóëÿöèÿ â ïðîöåññ ");
    40.   strcat(s, szProcessName);
    41.   MessageBox(NULL, s, "Èíêàïñóëÿöèÿ", MB_OK);
    42. }
    43.  
    44. int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    45. {
    46.  if(reason == DLL_PROCESS_ATTACH)//(reason == DLL_THREAD_ATTACH)
    47.  {
    48.   if(!SetTimer(NULL, 0, 10000, (TIMERPROC)TimerProc))
    49.    MessageBox(NULL, "Íå ìîãó ñîçäàòü òàéìåð.", "Èíêàïñóëÿöèÿ", MB_OK);
    50.  
    51.   MessageBox(NULL, "DLL_PROCESS_ATTACH", "Èíêàïñóëÿöèÿ", MB_OK);
    52.  }
    53.  
    54.  return 1;
    55. }
    результат тотже, правда не понятно почему функция таймера вызывается только в том случае, если DllMain ещё не завершилась (специально туда MessageBox сунул)... иначе ничего не происходит. Каким образом можно ещё переиграть? Может имеет смысл попытаться после загрузки Dll через CreateRemoteThread вызвать через него же нужную функцию в этой dll? Правда тогда надо будет каким-то образом вычислить её адрес в новом процессе. Если да, то как?
     
  12. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    запиши в память машинные коды вызова LoadLibrary, и создавай поток на них
    а после вызова поставь джамп на нужную функцию, ее адрес заполнишь прямо их DllMain
    единственный вопрос - как в DllMain узнать, где находится твой код
     
  13. amitophia

    amitophia New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2004
    Сообщения:
    44
    Aivengo
    Создай в DllMain свои потоки, которые будут делать, что нужно. Они выполнятся после выхода из DllMain. типа такого:
    Код (Text):
    1. #include "stdafx.h"
    2.  
    3. #include <windows.h>
    4. #include "psapi.h"
    5.  
    6. DWORD WINAPI thread_proc(LPVOID x)
    7. {
    8.  
    9.    
    10.     char s[40];
    11.     char szProcessName[MAX_PATH] = "unknown";
    12.     int res = 0;
    13.     HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId());
    14.  
    15.     // Get the process name.
    16.     if (NULL != hProcess )
    17.     {
    18.         HMODULE hMod;
    19.         DWORD cbNeeded;
    20.  
    21.         if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
    22.         {
    23.             GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) );
    24.         } else
    25.             return 1;
    26.     } else
    27.         return 1;
    28.     CloseHandle( hProcess );
    29.  
    30.     strcpy(s, "opened process ");
    31.     strcat(s, szProcessName);
    32.     MessageBox(NULL, s, "Messagebox", MB_OK);
    33.  
    34.  
    35.     return 0;
    36. }
    37.  
    38. int WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    39. {
    40.  
    41.     if(reason == DLL_PROCESS_ATTACH)
    42.     {
    43.         // Get a handle to the process.
    44.         DWORD tid;
    45.         HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_proc, NULL,0,&tid);
    46.         if (hThread == NULL)
    47.             return 0;
    48.         CloseHandle (hThread);
    49.     }
    50.  
    51.     return 1;
    52. }
     
  14. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Почитай самое первое сообщение:
    Если я правильно понял проблему, то именно сам процесс и виснет :)
     
  15. amitophia

    amitophia New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2004
    Сообщения:
    44
    MSoft
    А что значит "процесс приостанавливается"? Это значит, приостанавливаются его потоки. Либо все, либо те, которые создают видимость его работы. Если все потоки друг с другом как-то синхронизируются, то при зависании одного потока запросто может повиснуть и другой, и т.д.

    Вот пример процесса с 2-мя потоками. Внедрите в него длл с масаджбоксом в DllMain на PROCESS_ATTACH, и посмотрите, что будет
    Код (Text):
    1. #include <windows.h>
    2. #include <stdio.h>
    3.  
    4. DWORD WINAPI thr1(LPVOID x)
    5. {
    6.     int i=0;
    7.     while (i<100) {
    8.         Sleep(2000);
    9.         GetModuleHandle("kernel32.dll");
    10.         printf("Thread1: Got module handle %X\n",i);
    11.         i++;
    12.     }
    13.     return 0;
    14. }
    15.  
    16. DWORD WINAPI thr2(LPVOID x)
    17. {
    18.     int i=0;
    19.     while (i<100) {
    20.         Sleep(2000);
    21.         printf("Thread2: Got module handle %X\n",i);
    22.         i++;
    23.     }
    24.     return 0;
    25. }
    26.  
    27. int main(int argc, char* argv[])
    28. {
    29.     DWORD tid1,tid2;
    30.     HANDLE hThr1, hThr2;
    31.     hThr1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thr1, 0, 0, &tid1);
    32.     hThr2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thr2, 0, 0, &tid2);
    33.     WaitForSingleObject(hThr1,500000);
    34.     WaitForSingleObject(hThr2,500000);
    35.     return 0;
    36. }
    Можно и не внедрять, а просто дописать создание третьего потока, в котором сделать LoadLibrary дллки с месаджбоксом. CreateRemoteThread тут ни при чём.
     
  16. Aivengo

    Aivengo New Member

    Публикаций:
    0
    Регистрация:
    6 фев 2007
    Сообщения:
    29
    Спасибо за вариант... попробую...
    Т .е. получается это так LoadLibrary криво отрабатывает?
     
  17. amitophia

    amitophia New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2004
    Сообщения:
    44
    Думаю, было бы криво, если бы она работала не так ;) Просто нечего в DllMain 2 часа просто так висеть при загрузке либы :))