fasm dll & отсутствие релоков

Тема в разделе "WASM.WIN32", создана пользователем QuAzI, 13 дек 2005.

  1. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    имхо, МАСМ поступает исключительно верно



    хоть его так ругали на протяжении нескольких страниц

    одного из топиков на этом форуме
     
  2. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    А х.з., я ж и говорю надо в спецификации прочитать, факт что масм в релоках ставит dd 0,8 и больше ничего, это работает, значит такая запись чем-то определена?
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    O, пока я собирался поделиться соображениями, bogrus уже раскрыл миру "секрет" dd 0,8 ;)



    Я методом квазинаучного тыка тоже до этого допер - чтобы вылечить фасм можно после объявы section '.reloc' добавить следующее
    Код (Text):
    1. if rva $ and 0FFFh = 0 ;если начало страницы, то с вероятность 99.9(9) релоков нет
    2.   dd 0,8 ;page RVA = 0 (не важно), block size = 8, т.е. число релоков = 0
    3. end if
    Суть в том, что если релоков нет, то fasm создает в PE-заголовке запись секции, нормально указывает ее адрес и адрес таблицы релоков, но вот размеры устанавливает в 0 и саму секцию в файл не пишет, что видимо винде и не нравится. Действительно, вроде как инициализированные данные, а в файле их нет - подозрение на "коррупцию". А винде видимо нужно явное подтверждение отсутствия релоков, т.е. таблица должна быть обязательно, но если релоков нет, то должна быть запись одного пустого блока: размер таблицы = 8, page RVA = 0 (или любое значение, т.к. до него дело не доходит), block size = 8 (т.е. дальше ничего нет)

    Причем интересно, что XP SP2 сама глюкавая, т.к. если задать block size = 0, то при загрузке хрюша выдает Access Violation на начале страницы, следующей за секцией .reloc - возможно тупо сканирует всю секцию в поисках неведомо чего ;)
     
  4. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine




    В w2k точно также! (если ставить dd 0,0), мне кажется в MSPECOFF об этом одном блоке ничего не сказано(потому в фасме этого и нет), хотя кто знает инглиш лучше посмотрит спецификацию, и на форуме фасма надо сообщить если там явно указано
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    В спецификации вроде как ничего такого нет

    Поэтому это больше похоже на глюк MS, т.к. с точки зрения здравой логики достаточно указать размеры секции и таблицы релоков = 0, а не выделять 512 байт в файле и 4К драгоценной физпамяти ради магических 8 байт dd 0,8 ;)
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Кажется я поторопился с выводами

    По всей видимости причина ошибки в том, что секция инициализированных данных не может иметь размер = 0.

    По крайней мере в XP, именно это приводит к отказу загрузки. При отсутствии релоков в XP достаточно указать размер таблицы = 0, при этом никакой секции reloc не требуется вообще, а если она есть, то ее размер должен быть > 0, но заполнена она м.б. нулями или вообще любым мусором. Если же размер таблицы > 0, то в ней по кр.мере должен быть один (пустой) валидный блок с blocksize > 0, иначе винда может заглючить



    Вывод: все таки это ошибка фасма, т.к. если релоков нет, то нужно либо

    1) вообще не создавать секцию reloc (если это катит в других win), либо

    2) создавать секцию и соответственно отводить под нее место в файле и либо

    2.1) указывать размер таблицы = 0 и забивать секцию нулями, либо

    2.2) указывать размер таблицы = 8 и писать в секцию пустой блок dd 0,8
     
  7. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Число релокейшенов определяется по след. формуле:

    (Размер chunk'a - 8(<-- размер заголовка chunk'a) )/2



    В случае масма, если релоков нет, то имеем:

    (8 - 8)/2 = 0 (т.е всё правильно)



    Для фасма соответственно 0, т.е. получаем

    (0 - 8)/2 = ...???

    Скорее всего, дело именно в этом.



    P.S. и в этом фасм обоср.лся.
     
  8. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    ааа... там даже до этого дело не доходит:


    Код (Text):
    1. ДДДДДKERNEL32!VirtualQueryEx+27A9ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД ДДДДPROT32Д
    2. 016F:BFF87A4C  JNZ       BFF87A75                          
    3. 016F:BFF87A4E  PUSH      10                                
    4. 016F:BFF87A50  MOV       EAX,[EBP-00F0]   ; ImageSize      
    5. 016F:BFF87A56  ADD       EAX,00000FFF                      
    6. 016F:BFF87A5B  SHR       EAX,0C                            
    7. 016F:BFF87A5E  PUSH      EAX                              
    8. 016F:BFF87A5F  MOV       EAX,[EBP-010C]   ; ImageBase      
    9. 016F:BFF87A65  SHR       EAX,0C                            
    10. 016F:BFF87A68  PUSH      EAX                              
    11. 016F:BFF87A69  PUSH      00010000     ; _PageReserve      
    12. 016F:BFF87A6E  CALL      KERNEL32!ORD_0001                
    13. 016F:BFF87A73  MOV       EDI,EAX                          
    14. 016F:BFF87A75  CMP       EDI,-01      ; is addr already in use?
    15. 016F:BFF87A78  JNZ       BFF87AD3
    16. 016F:BFF87A7A  CMP       DWORD PTR [ESI+000000A4],04  ; <-- !!! SizeOfDir for Fixup Directory
    17. 016F:BFF87A81  JA        BFF87A8F
    18. 016F:BFF87A83  PUSH      0B                                
    19. 016F:BFF87A85  PUSH      DWORD PTR [EBP+08]                
    20. 016F:BFF87A88  PUSH      0C                                
    21. 016F:BFF87A8A  JMP       BFF87B26                          
    22. 016F:BFF87A8F  PUSH      10                                
    23. 016F:BFF87A91  MOV       EAX,[EBP-00F0]                    
    24. 016F:BFF87A97  ADD       EAX,00000FFF                      
    25. 016F:BFF87A9C  SHR       EAX,0C                            
    26. 016F:BFF87A9F  CMP       EBX,01                            
    27. 016F:BFF87AA2  PUSH      EAX                              
    28. 016F:BFF87AA3  SBB       EAX,EAX                          
    29. 016F:BFF87AA5  AND       EAX,FFFA0400                      
    30. 016F:BFF87AAA  SUB       EAX,7FFA0000                      
    31. 016F:BFF87AAF  PUSH      EAX                              
    32. 016F:BFF87AB0  PUSH      00010000                          
    33. 016F:BFF87AB5  CALL      KERNEL32!ORD_0001                
    34. 016F:BFF87ABA  MOV       EDI,EAX                          
    35. 016F:BFF87ABC  MOV       ECX,[EBP-08]                      
    36. 016F:BFF87ABF  OR        BYTE PTR [ECX],02                
    37. 016F:BFF87AC2  CMP       EDI,-01                          
    38. 016F:BFF87AC5  MOV       [ESI+34],EDI                      
    39. 016F:BFF87AC8  JNZ       BFF87AD3                          
    40. ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДKERNEL32!.text+EA4CДДДДДДДДДДДДДДДДДДДДДДДДД
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    _BC_

    > "Скорее всего, дело именно в этом"

    Наверное ты прав, и именно так винда без всяких проверок определяет число релоков и соответсвенно глупо нарывается на Access Viоlation при TableSize > 0 и BlockSize = 0. И обоср-ся тут не фасм, а гениальные ламеры от микрософта ;)



    А фасм, как я уже сказал, не прав в том что указывает размер секции инициализированных данных SizeOfRawData = 0, что ес-но недопустимо. Если заменить флаг секции с INITIALIZED на UNINITIALIZED или вообще не создавать секцию reloc, то при TableSize=0 все грузится без проблем.

    А логика загрузки видимо такая. Сначала просто анализируется PE-хидер и создается сырой образ. Если встречается инициализированная секция с SizeOfRawData = 0, то на выход с песнями и сообщением о неверном формате. Если же сырой образ создается нормально, то на стадии релока первым делом проверяется размер таблицы релоков. Если он = 0, то винда считает, что релоков нет и идет дальше. Если размер таблицы > 0, то тупая винда забывает про этот размер и начинает без всяких проверок обрабатывать блоки таблицы, наивно предполагая что тут ошибок быть не может и все BlockSize >= 8. Скорее всего по жизни так оно и есть, но все таки такой подход выглядит чистейшой шарой и ламерством ;)
     
  10. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Имхо товарищи, это наш глюк :) Такая dll нормально грузится по любому адресу и работает
    Код (Text):
    1. ;=================================
    2. format      pe gui dll
    3. include     '%fasminc%\win32a.inc'
    4. ;=================================
    5. entry $
    6.             xor     eax,eax
    7.             inc     eax
    8.             ret     0x0c
    9. ;=================================
    Т.ч. нам релоки тут не нужны и нефиг их сюда добавлять, Привалов абсолютно прав, все в наших руках, а масму если хочется создавать отдельную секцию, тем более когда это не надо - то его проблемы (попробуйте заставить его это не делать :)



    IceStudent собсно сразу это и сказал, нам надо было протестировать без релоков, загрузчик тогда сообщает Message=Debug string: LDR: Fixups won't be re-applied to non-Dll @ 140000, где 140000 - новый imagebase
     
  11. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    фасм должен сам знать создавать ему релоки или нет
     
  12. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    масм тоже должен! короче раз так:



    масм

    - сам создает релоки (даже когда они не нужны)

    - всегда в отдельной секции (merge не работает)



    фасм

    - возможно указать создавать или нет

    - возможность определить в отдельной секции или нет



    Масм это HL ассемблер, не дающий право выбора программисту(переход в LL решается патчингом), Фасм это LL ассемблер, требующий явных указаний прораммистом (переход в HL решается макросами)
     
  13. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    масму однако тоже можно указать чтоб релоков не создавал :derisive:

    используем ключ /fixed
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    bogrus, ты не прав ;)

    Если уж фасм взялся создавать секцию, то должен это делать правильно или по кр.мере выдавать соответсвующий лог или предупреждение, что фиксапов 0, секция пуста, создавать ее в любом сл. или нет и т.п. А то, что "нам тут релоки не нужны" легко сообразить в твоем простейшем примере и не так просто в общем случае и тем более начинающему программеру, который возможно о релоках то ничего не слышал ;)
     
  15. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    А точно, я забыл ключик /FIXED кажется



    ну ладно, мир дружба жвачка :)
     
  16. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    leo





    Не смотрел на ХР, но W9x останавливает загрузку на проверке размера директории релоков (должна быть более 4, строка с '!!!' в вышеприведенном фрагменте), section header для секции .reloc вообще не трогается на данном этапе. Если ImageBase dll'ки не занят, то никакие проверки вообще не выполняются.
     
  17. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    _BC_

    Да ты прав - 98SE отказывается грузить dll при Relocation Table Size = 0

    Значит для совместимости с 9x таблица релоков все таки должна быть в любом случае и надо бы ткнуть упрямого Томаша носом в этот фак(т) ;)))

    Поэтому добавочка dd 0,8 при отсутсвии релоков все таки нужна. Что-то вроде этого:
    Код (Text):
    1. fixupstart:
    2. data fixups
    3.   if rva $ = rva fixapstart
    4.      dd 0,8
    5.   end if
    6. end data
    Кстати в 98 есть еще одна хитрая фишка, если фиксапы расположить в секции кода. Если релоков нет (т.е. рулит dd 0,8) то dll грузится нормально. При наличии релоков dll грузится без проблем только в случае, если секция кода writeable, иначе происходит капитальный висяк. Если же совать фиксапы в другие секции без атрибута writeble (.data,.export,.import), то все грузится нормально. Вот такие хитрости :dntknw:
     
  18. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    leo

    сходи по линку и ткни, я уже устал доказывать, может ты будешь убедительнее
     
  19. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    leo




    Так значит мой мини-пример dll без релоков не будет загружен LoadLibrary на 9x? Хм, это же все меняет (очередной раз :), значит где-то должно быть четко сказано: любая dll обязана иметь директорию релоков с размером не меньше 8 байт!!!



    Т.ч. если хотите тыкать кого-то носом, найдите сперва куда тыкать (у меня не получается, bad english)



    Peering Inside the PE: A Tour of the Win32 Portable Executable File Format



    PE File Base Relocations

    When the linker creates an EXE file, it makes an assumption about where the file will be mapped into memory. Based on this, the linker puts the real addresses of code and data items into the executable file. If for whatever reason the executable ends up being loaded somewhere else in the virtual address space, the addresses the linker plugged into the image are wrong. The information stored in the .reloc section allows the PE loader to fix these addresses in the loaded image so that they're correct again. On the other hand, <font color="red]if the loader was able to load the file at the base address assumed by the linker, the .reloc section data isn't needed and is ignored</font><!--color-->. The entries in the .reloc section are called base relocations since their use depends on the base address of the loaded image.



    Может это был баг 9x, который потом исправили? Такое не редко бывает, мы же все не можем знать
     
  20. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    bogrus

    ИМХО если бы это было где-то четко сказано, то наверное Томаш бы в эту фигню не "вляпался" ;) Скорее всего это просто недокументированная особенность 9х, проверить которую никому не пришло в голову



    PS: Не понятно, что и зачем ты выделил красным, т.к. если базовый адрес не изменяется, то все нормально работает без всяких релоков и в NT и в 9х. А секция .reloc вообще не обязательна, т.к. таблица (директория) релоков может располагаться в любой другой секции