Помогите разобратся в структурах PE файла

Тема в разделе "WASM.BEGINNERS", создана пользователем _nic, 31 май 2010.

  1. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Для DLL - читать DllMain, для всего остального - ничего не надо "пихать".
     
  2. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    >>Речь идет о том как понять,какие переменные "ожидает" точка входа.

    Ну если напримр это драйвер, то будут переданы указатель на DRIVER_OBJECT и путь к драйверу в реестре. Если dll, то там передаются тоже параметры в DllMain. Вы про это? У обычных исполняемых файлов таких передаваемых параметров нет.
    Если это драйвер, то у него в подсистеме стоит NATIVE, о нем есть запись в реестре в HKLM\SYSTEM\CurrentControlSet\Services вызов его точки входа будет происходить в ntoskrnl!IopLoadDriver. Если это dll, то вызов точки входа произойдет в ntdll!LdrpRunInitializeRoutines. В случае dll в FileHeader.Characteristics должен присутствовать флаг IMAGE_FILE_DLL.
     
  3. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    И еще по по поводу консольных. Консольные приложения свои параметры берут вообще из переменых BaseUnicode(Ansi)CommandLine (а изначально эти переменные заполняются из PEB.ProcessParameters->CommandLine). Делается это с помощью функций GetCommandLineW(A). Так что точка входа тут вообще ни при чем.
     
  4. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    >>И еще по по поводу консольных

    И gui тоже, которым при старте были какие-то параметры переданы.
     
  5. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Как так?Почему тогда тут http://msdn.microsoft.com/en-us/library/ms633559(VS.85).aspx переменные в функции помечены как " __in "??
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    crt (с-шная "прослойка") получает управление в точке входа, находит нужные параметры и передаёт управление main().
    main() не является точкой входа PE-файла.
     
  7. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    >>http://www.rsdn.ru/article/baseserv/pe_coff.xml

    Чего-то незнал, что перевели Мэта Питрека, всегда листал в оригинале, спасиб c4m310t
     
  8. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Допустим приложение А используя нестандартный загрузчик PE файлов в память загружает приложение Б в свою память,определяет точку входа приложения Б,добавляет адрес точки входа приложения Б к адресу памяти в которое оно загружено,делается приведение аля:
    Код (Text):
    1. typedef int(*_EntryPoint)();
    2. EntryPointC EntryPoint;
    3. ..................................................
    4. EntryPoint=(int(*)())адрес точки входа+адрес памяти с загруженым приложением;
    Выполняется эта функция
    1й случай: все выше описанное применяется к cmd.exe,приложения А консольное.В итоге все ОК,кроме одного матюка:"Не удается найти текст сообщения с номером 0x2350 в файле сообщений Application."
    2й случай:приложение А оконное,запуск notepad.exe.В итоге ни чего неполучается,при входе в точку входа приложения Б компилятор бодро рапортует:"Программа "[3948] Exps.exe: Машинный код" завершилась с кодом 0 (0x0)."
    Собственно вопрос в чем заключается такая великая разница между точкой входа блокнота и виндового командного интерпретатора?
     
  9. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    _nic
    1. Обычно в экзешниках релоков нет. Загрузка по иной базе не возможна, фиксапы не изветсны. В этом случае выполняется автоматический реверсинг, это делают все пермутаторы.
    2. Системный загрузчик не возвращает валидные значения, либо не выполняет необходимые действия, так как нет совместимости с ним. Например его база данных не настроена должным образом. Это проблема всех загрузчиков(ну кроме моего :P).
    3. Если вызывается LdrpWalkImportDescriptor() для подгрузки и настройки импорта необходим флажёк в хидере модуля IMAGE_FILE_DLL.
     
  11. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Вот пока в целях улутчшения своих знаний продолжил дальше копатся в PE файлах.И столкнулся ещё с одной проблемой,неполучается считать таблицу секций,пытаюсь делать во так:
    Код (Text):
    1. HANDLE f=CreateFileA(exe,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    2.     LARGE_INTEGER SZ;
    3.     ZeroMemory(&SZ,sizeof(SZ));
    4.     GetFileSizeEx(f,&SZ);
    5.     char *buf=new char[SZ.QuadPart];
    6.     DWORD rb;
    7.     ReadFile(f,buf,SZ.QuadPart,&rb,0);
    8.     CloseHandle(f);
    9.     _IMAGE_DOS_HEADER stub;
    10.     memcpy(&stub,buf,sizeof(_IMAGE_DOS_HEADER));
    11.     buf+=stub.e_lfanew;
    12.     _IMAGE_NT_HEADERS image;
    13.     memcpy(&image,buf,sizeof(_IMAGE_NT_HEADERS ));
    14.     buf-=stub.e_lfanew;
    15.     _IMAGE_OPTIONAL_HEADER options=image.OptionalHeader;
    16.     printf("Sections:%d\n",image.FileHeader.NumberOfSections);
    17.     printf("Image syze bytes:%d\n",options.SizeOfImage);
    18.     printf("Headers size:%d\n",options.SizeOfHeaders);
    19.     _IMAGE_SECTION_HEADER *sections=new _IMAGE_SECTION_HEADER[image.FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER)];
    20.     buf+=sizeof(_IMAGE_NT_HEADERS);
    21.     memcpy(sections,buf,image.FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER));
    22.     buf-=sizeof(_IMAGE_NT_HEADERS);
    23.     printf("%.8s\n",sections[0].Name);
    24.     delete []buf;
    Имя секции неотображается.Ничего непонимаю :dntknw: Я ведь правильно задал смещение для выхода на таблицу секций.
     
  12. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    Код (Text):
    1. buf-=stub.e_lfanew;
    2. ...
    3. buf+=sizeof(_IMAGE_NT_HEADERS);
    у вас buf указывает на IMAGE_DOS_HEADER. Следовательно, не вычитайте e_lfanew чтобы было верно.
     
  13. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    И вообще лучше писать не

    Код (Text):
    1. buf+=sizeof(_IMAGE_NT_HEADERS);
    а

    Код (Text):
    1. buf+=sizeof(IMAGE_FILE_HEADER)+4+image.FileHeader.SizeOfOptionalHeader;
    ; редактирование =\\
     
  14. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    _nic
    Код (Text):
    1. #define PE_IMAGE_FIRST_SECTION( ntheader ) ((PPE_IMAGE_SECTION_HEADER)        \
    2.     ((ULONG_PTR)ntheader +                                              \
    3.     FIELD_OFFSET( PE_IMAGE_NT_HEADERS, OptionalHeader ) +                 \
    4.     ((PPE_IMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader   \
    5.     ))
     
  15. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Что нужно отнять от RVA смещения что бы получить смещение в PE файле?
     
  16. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    RVA уже relative, чего тут отнимать?
     
  17. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    _nic,

    Когда файл уже отображён, естественно, все RVA должны (но не обязаны) превратиться в VA. Минус база.
     
  18. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Файл неотображен,файл на диске,есть значения смещений RVA(примерно 1.2 гигабайта допустим) указывающие на текст,какой арифметикой эти RVA преобразуются в смещения по файлу?Отнять одну базу ведь недостаточно,надо ещё что то.Только вот что?
     
  19. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Заговорился. Естественно, надо по заголовкам секций найти отображение виртуальных адресов в/на байты файла.
     
  20. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    PE-заголовок вполне конкретно говорит что и куда будет отображено (фиксапы вредят, но не сильно).