CreateRemoteThread и загруженные DLL

Тема в разделе "WASM.WIN32", создана пользователем Deader, 24 дек 2011.

  1. Deader

    Deader New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    96
    Делаю CreateRemoteThread для чужого ехе-шника(естествеено перед этим делаю virtualalloc+writeprocessmemory). Почему адрес, с которого начинается выполнение созданного удаленного потока, лежит внутри страничного имиджа одной из dll, загруженных чужим процессом? Как вообще такое может быть?
     
  2. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Когда PE-модуль загружается, в нём могут присутствовать discardable-секции, память под такие секции сразу же освобождается после использования секции загрузчиком, что приводит к образованию, скажем так, дырки в образе загруженного модуля. Проверь, в какое именно место .dll-модуля ты записал свой код. Ну и вообще, с чего ты взял-то, что в образ записал свой код, как смотрел?
     
  3. Deader

    Deader New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    96
    Запустил ехе-шник через createprocess с параметром DEBUG_ONLY_THIS_PROCESS. Мне пришел отладочный евент LOAD_DLL_DEBUG_EVENT - там передается база dll(lpBaseOfDll). Делаю ReadProcessMemory(....., lpBaseOfDll, DllDosHeader, .....) получаю _lfanew, делаю ReadProcessMemory(..., lpBaseOfDll+DllDosHeader._lfanew, DllImageNTHeaders, ...) получаю DllImageNTHeaders.OptionalHeader.SizeOfImage.
    И потом почему-то при создании удаленного потока, его стартовый адрес находится между lpBaseOfDll и lpBaseOfDll+DllImageNTHeaders.OptionalHeader.SizeOfImage, при этом dll ессно не выгружалась. Как такое бываeт - не понимаю?????
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Deader
    Название dll со стартовым адресом предлагаете угадать? Если в системе нет проактивок, то я ставлю на ntdll :). Поток в режиме пользователя должен именно с неё стартовать. Если же под стартовым адресом понимается то, что возвращается ThreadQuerySetWin32StartAddress (то, что указывается в eax пользовательского контекста при создании потока), то есть проактивки, которые его подменяют (хотя eip стратового контекста они могут точно так же подменять).
     
  5. Deader

    Deader New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    96
    Сорри, но я чет не понял ничего. Проактивок нету. Ну да, в каждый юзермодный процесс всегда сразу грузятся kernel и ntdll. Но почему поток, внедренный с помощью createremotethread, должен стартовать с ntdll? Как вообще когда перед createremotethread я выделяю память(virtualallocex) - как она выделяется в том месте, куда загружен ntdll?
     
  6. Deader

    Deader New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    96
    причем вот еще какая странность - когда я делаю CreateRemoteThread, то указываю там один стартовый адрес, а в отладочном событии CREATE_THREAD_DEBUG_EVENT мне приходит уже совсем другой стартовый адрес CreateThread.lpStartAddress. Почему так?
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Deader
    Так. Ещё раз с нуля. Когда Вы вызываете CreateRemoteThread, инициализируется стартовый контекст нового потока. В стартовом контексте eip указывается равным адресу RtlUserThreadStart в ntdll, а не тому, который указан в параметре CreateRemoteThread. Т.е. пользовательский поток обязан стартовать из ntdll, которая проводит начальную инициализацию потока (вызовы DllMain загруженных dll, инициализация TLS, SEH и т.п.). Тот же адрес, который передаётся параметром CreateRemoteThread, записывается в регистр eax стартового контекста потока. После выполнения начальной инициализации ntdll вызывает процедуру, указанную при вызове CreateRemoteThread, используя это значение eax.
     
  8. Deader

    Deader New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    96
    Все так и есть как сказал l_inc - оказывается в событии CREATE_THREAD_DEBUG_EVENT всегда указывается адрес RtlUserThreadStart из ntdll, а не тот, который в параметре CreateRemoteThread.

    l_inc спасибо ОГРОМНОЕ !!! Прояснили очень важный ньюанс, о котором я понятия не имел.