Обработка TLS

Тема в разделе "WASM.BEGINNERS", создана пользователем Aoizora, 1 авг 2017.

  1. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Возникли проблемы с обработкой TLS загружаемого образа. Перед обработкой TLS я проделал такие шаги:

    1) Загрузил дисковый PE-образ в память
    2) Выделил память в куче и спроецировал туда секции и заголовки
    3) Обработал релоки и импорт

    Теперь надо обработать TLS, если он имеется. Я написал такой код:

    Код (C++):
    1. bool LoadPE_HasTLS(LoadPE_CONTEXT* ctx)
    2. {
    3.     return LoadPE_DirectoryExists(ctx, IMAGE_DIRECTORY_ENTRY_TLS);
    4. }
    5.  
    6. DWORD LoadPE_GetTLS(LoadPE_CONTEXT* ctx)
    7. {
    8.     return ctx->pPeHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
    9. }
    10.  
    11. void LoadPE_ProcessTLS(LoadPE_CONTEXT* ctx)
    12. {
    13.     if (LoadPE_HasTLS(ctx))
    14.     {
    15.         PIMAGE_TLS_DIRECTORY32 tls = PIMAGE_TLS_DIRECTORY32(ctx->pbRealImageBase + LoadPE_GetTLS(ctx));
    16.         std::cout << "StartAddress: " << std::hex << tls->StartAddressOfRawData << std::endl;
    17.         std::cout << "EndAddress: " << std::hex << tls->EndAddressOfRawData << std::endl;
    18.         std::cout << "CallbackAddress: " << std::hex << tls->AddressOfCallBacks << std::endl;
    19.         std::cout << "Callbacks: " << std::endl;
    20.         PIMAGE_TLS_CALLBACK* cb_addr = (PIMAGE_TLS_CALLBACK *)(ctx->pbRealImageBase + tls->AddressOfCallBacks);
    21.         while (*cb_addr++)
    22.         {
    23.             std::cout << cb_addr << std::endl;
    24.         }
    25.     }
    26. }
    Но при вычислении условия цикла программа крашится. Что у меня не так?

    Кроме того, я не до конца понимаю механизм работы TLS, хотя сегодня и прочитал несколько статей. В директории TLS имеется структура с указателями на данные и на массив адресов коллбэков. Коллбэки вызываются загрузчиком, а что делать с адресами данных? Где и для чего выделять память под индекс? Блок данных можно получить при помощи _readfswdord(0x2C). Что с ним делать дальше?

    PS. Загрузчик работает, осталось только вот это.
     
  2. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Aoizora,

    В сурках нт смотрели, первый вопрос ?
     
  3. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Нет, не смотрел. Пытаюсь разобраться по статьям, но не получается. Все, что у меня пока получилось - это вызвать коллбэки до старта программы, но это никак не связано с написанием PE-лоадера.

    Может проблема быть связана с тем, что адреса в структуре TLS абсолютные, а мой загрузчик загружает образ по рандомному адресу и делает релокацию?
     
  4. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.330
    Не может быть, а так и есть. TLS - это, вроде бы, единственное место в заголовках, где хранятся VA, а не RVA.
     
  5. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    И эти адреса не патчатся при обработке релоков?
     
  6. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.330
    Должны патчиться.
     
  7. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Может, в моей функции обработки релоков чего-то не хватает?

    Код (C++):
    1. void LoadPE_PerformRelocation(const LoadPE_CONTEXT* ctx)
    2. {
    3.     DWORD Delta = (DWORD)ctx->pbRealImageBase - ctx->dwPreferImageBase;
    4.  
    5.     PIMAGE_BASE_RELOCATION Reloc = ctx->pRelocs;
    6.     const DWORD RelocDirSize = ctx->dwRelocDirSize;
    7.     DWORD Offset = 0;
    8.  
    9.     while (Offset != RelocDirSize)
    10.     {
    11.         const DWORD FixupCount = (Reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
    12.         const PIMAGE_FIXUP_ENTRY Fixup = PIMAGE_FIXUP_ENTRY((DWORD(Reloc) + sizeof(IMAGE_BASE_RELOCATION)));
    13.         for (int i = 0; i < FixupCount; ++i)
    14.         {
    15.             if (Fixup[i].Type == IMAGE_REL_BASED_HIGHLOW)
    16.             {
    17.                 LoadPE_PatchAddress(ctx, Reloc, &Fixup[i], Delta);
    18.             }
    19.         }
    20.         Offset += Reloc->SizeOfBlock;
    21.         Reloc = PIMAGE_BASE_RELOCATION(DWORD(Reloc) + Reloc->SizeOfBlock);
    22.     }
    23. }
     
  8. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Что копировать, откуда и куда? Непонятно.

    >Третье поле AddressOfIndex - это адрес, куда загрузчик запишет индекс блока данных потока
    Какого блока данных? Как получить его адрес?

    >создаваемого при запуске программы, этот индекс, соответсвенно будет равен нулю
    А потом как будет меняться этот индекс?

    >В это поле необходимо поместить адрес из секции данных
    Секция данных большая, какой именно адрес?

    >Первым делом нужно найти указатель на блок данных, чтобы скопировать реальные данные
    Копировать откуда и куда?

    >Указатель на массив адресов (адресов блоков данных) можно получить из структуры TIB
    Ок, получил. Что с ним делать?

    >но помня, что индекс первого потока равен нулю, получаем
    А если потоков много, кто будет именять индекс?
     
    Последнее редактирование: 1 авг 2017
  9. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Откуда качать сорусы?
     
  10. Aiks

    Aiks Member

    Публикаций:
    0
    Регистрация:
    16 апр 2017
    Сообщения:
    109
    Адрес:
    Украина
    В гугле "windows 2000 sources", второй результат поиска.
     
  11. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    352
    Хорошие исходники. Нашел все, что мне нужно.
     
  12. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Конечно, там ведь сурки загрузчика. Я знал что у вас получится.