Экспорт функций в FASM

Тема в разделе "WASM.BEGINNERS", создана пользователем Praetor11, 4 ноя 2009.

  1. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Начал программировать на FASM, скачал его последнюю версию + документацию (хоть и на англицком но понять можно). И вот почти сразу возник вопрос: как экпортировать из exe/dll функцию или переменную. На сайте www.flatassembler.net такой инфы не обнаружилось ни в FAQ, ни в документации (там про PE формат вообще не много: только stack,heap и возможность включения любого stub) В COFF там есть какое-то описание но я никогда не сталкивался с этим форматом и не понимаю, почему нельзя экспортировать из PE.

    Если кто знает как это сделать, отпишите плиз.
     
  2. Asterix

    Asterix New Member

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

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    fasm.pdf
    3.1.4. Exports... у меня это стр.95
     
  4. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    А можете на конкретном примере продемонстрировать то что там написано, а то я не понял, (кстати страница 107 - объем справки вырос однако).
     
  5. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Урра! Разобрался..Спс Фриману. А не поможете с вопросом: почему нельзя установить другое выравнивание секий окромя 512, align 32 вроде как компилирует но выравнивание не меняется. Неплохо бы также разобратца с импортом из произвольной длл.
     
  6. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    Код (Text):
    1. ...
    2. proc dummy
    3. ...
    4. endp
    5. ...
    6. data export
    7.   export 'xxxx.dll',\
    8.      dummy,'dummy'
    9. end data
     
  7. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Спс вам Фриман, с экспортом разобрался (правда к сожалению заметил что макрос export не поддерживает экспорта функций по оридналу (и уж тем более по произвольному ординалу), зато импорт из библиотек меня порадовал основательно, хоть по ординалу, хоть по имени, и без всяких lib-файлов! Красотень...
     
  8. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    пощите по форуму, тут свои макросы люди песали вроде под это дело более удобные. и даж с нуля ехе мутили
     
  9. Asterix

    Asterix New Member

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

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    вернее это импорт по ординалу поддерживает %)
     
  11. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Заюзал поиск по форуму. Нашелся один результат на точно такой же вопрос: http://www.wasm.ru/forum/viewtopic.php?id=34584

    Однако приведенный там макрос для экспорта по ординалу не работает. Так что считаю вопрос открытым. Я слабо разбираюсь в том макросе, но мне необходимо экспортировать функцию безымянной под неким ординалом с малопредсказуемым числом (например 256). Вообще возможно ли это реализовать на фасм, и если да то как? Мб кто-то сумеет подправить макрос экспорт из той ветки формуа:

    Код (Text):
    1. macro export dllname,[label,string,ordinal]
    2.  { common
    3.     local module,addresses,names,count
    4.     count = 0
    5.    forward
    6.     count = count+1
    7.    common
    8.     dd 0,0,0,RVA module,1
    9.     dd count,count,RVA addresses,RVA names,RVA ordinal
    10.     addresses:
    11.    forward
    12.     dd RVA label
    13.    common
    14.     names:
    15.    forward
    16.     local name
    17.     dd RVA name
    18.    common
    19.     ordinal:
    20.    forward
    21.     dw ordinal
    22.    common
    23.     module db dllname,0
    24.    forward
    25.     name db string,0
    26.    common
    27. }
     
  12. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Если нужно экспортировать одну функцию exported под ординалом ord, то следующий код поможет:
    Код (Text):
    1. align 4
    2. data export
    3.     dd  0, 0, 0, rva dllname, ord, 1, 0, rva @f, 0, 0
    4. @@  dd  rva exported
    5. dllname db  '1.dll',0
    6. end data
    (вместо 1.dll нужно подставить имя своей dll или exe). Если интересно узнать, что здесь происходит, почему надо так писать и что делать, если нужно добавить другие экспорты - следует изучать формат PE, директорию экспорта (data export ровно её и задаёт, без всяких преобразований со стороны компилятора).
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Praetor11
    А не подскажете, зачем это нужно? Если Вы хотите таким образом "спрятать" экспортируемую функцию, то это неудачный вариант, т.к. в любом PE-редакторе достаточно открыть будет Ваш PE и весь экспорт будет, как на ладони.
    Если нужно экспортировать только одну функцию с неизвестно каким ординалом, то достаточно указать Ordinal Base понравившимся значением (в оригинальном макросе заменить единицу в строке dd 0,0,0,RVA module,1). Соответственно ординалы экспорта будут начинаться именно с этого числа.
    Если нужно экспортировать несколько функций с нехорошими ординалами (например, 317, 539, 1195), то придётся оставлять кучу пустых мест в массиве RVA функций. Т.о. Ваша таблица экспорта разрастётся до размеров более
    (1195-317+1)*4 = почти 3,5 КБ. И чего Вы этим добьётесь кроме увеличения размеров файла?
     
  14. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Чисто для проверки возможностей фасма. По-моему невозможность такого экспорта - большой недостаток. А не у кого не возникало желания дописать такие макросы для фасма/масма? Я в принципе понимаю создателя фасма в том, что он не вписал ординал в свой макрос экпорта - дабы избежать ошибок типа нескольких функций с одинаковыми ординалами, либо вот 317,539,1195 - вроде логично. Хотя я вроде уже нашел что мне нужно: export '1.dll',export_func,'' создает экспорт по ординалу, но только по порядку (((
     
  15. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    это легко проверяется на фасме, просто этим методом в основном ни кто не пользуется. да и пусть энтузиасты тренируются.
     
  16. SiruS

    SiruS Алекс

    Публикаций:
    0
    Регистрация:
    19 фев 2005
    Сообщения:
    145
    Адрес:
    Львов
    макрос для экспорта по ординалам (любезно предоставленный товарищем, который пожелал остаться неизвестным =) ):
    Код (Text):
    1. macro exportByOrdinals dllname,[label,string,fordinal]
    2.  { common
    3.     local module,addresses,names,minOrdinal,maxOrdinal,ordinal,count,funcRVASize
    4.     count = 0
    5.     minOrdinal = 0FFFFh
    6.     maxOrdinal = 0
    7.    forward
    8.     count = count+1
    9.     if fordinal<minOrdinal
    10.        minOrdinal = fordinal
    11.     end if
    12.     if fordinal>maxOrdinal
    13.        maxOrdinal = fordinal
    14.     end if
    15.    common
    16.     dd 0,0,0,RVA module,minOrdinal
    17.     dd maxOrdinal-minOrdinal+1,count,RVA addresses,RVA names,RVA ordinal
    18.     addresses:
    19.     funcRVASize = 0
    20.     while funcRVASize < maxOrdinal-minOrdinal+1
    21.      funcRVASize = funcRVASize+1
    22.      dd 0
    23.     end while
    24.    forward
    25.     store dword RVA label at addresses+(fordinal-minOrdinal)*4
    26.    common
    27.     names:
    28.    forward
    29.     local name
    30.     dd RVA name
    31.    common
    32.     ordinal:
    33.    forward
    34.     dw fordinal-minOrdinal
    35.    common
    36.     module db dllname,0
    37.    forward
    38.     name db string,0
    39.    common
    40.     local x,y,z,str1,str2,v1,v2
    41.     x = count shr 1
    42.     while x > 0
    43.      y = x
    44.      while y < count
    45.       z = y
    46.       while z-x >= 0
    47.        load v1 dword from names+z*4
    48.        str1=($-RVA $)+v1
    49.        load v2 dword from names+(z-x)*4
    50.        str2=($-RVA $)+v2
    51.        while v1 > 0
    52.         load v1 from str1+%-1
    53.         load v2 from str2+%-1
    54.         if v1 <> v2
    55.          break
    56.         end if
    57.        end while
    58.        if v1<v2
    59.         load v1 dword from names+z*4
    60.         load v2 dword from names+(z-x)*4
    61.         store dword v1 at names+(z-x)*4
    62.         store dword v2 at names+z*4
    63.         load v1 word from ordinal+z*2
    64.         load v2 word from ordinal+(z-x)*2
    65.         store word v1 at ordinal+(z-x)*2
    66.         store word v2 at ordinal+z*2
    67.        else
    68.         break
    69.        end if
    70.        z = z-x
    71.       end while
    72.       y = y+1
    73.      end while
    74.      x = x shr 1
    75.     end while }
    внутри секции експорта применять так:

    Код (Text):
    1. exportByOrdinals 'wrapper.dll',\
    2.         wrapped_AcceptEx,'AcceptEx',475h,\
     
  17. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Раз уж мне сегодня пришлось вспомнить структуру экспорта, довёл макрос из предыдущего поста до более пристойного вида:

    Код (Text):
    1. macro exportByOrdinals dllname*,[label,string,ordinal]
    2. {
    3.     common
    4.         local dllnameptr,functions,names,ordinals,NumberOfFunctions,NumberOfNames,\
    5.                 minOrdinal,maxOrdinal,buf
    6.         NumberOfFunctions = 0
    7.         NumberOfNames = 0
    8.     forward
    9.         NumberOfFunctions = NumberOfFunctions + 1
    10.         if ~ string eq
    11.             NumberOfNames = NumberOfNames+1
    12.         end if
    13.         if ~ ordinal eq
    14.             if ~ defined maxOrdinal | defined @F
    15.                 @@:
    16.                 minOrdinal = ordinal
    17.                 maxOrdinal = ordinal
    18.             else
    19.                 if ordinal<minOrdinal
    20.                     minOrdinal = ordinal
    21.                 end if
    22.                 if ordinal>maxOrdinal
    23.                     maxOrdinal = ordinal
    24.                 end if
    25.             end if
    26.         end if
    27.     common
    28.         if ~ defined maxOrdinal
    29.             minOrdinal = 1
    30.         else
    31.             if maxOrdinal-minOrdinal+1 > NumberOfFunctions
    32.                 NumberOfFunctions = maxOrdinal-minOrdinal+1
    33.             end if
    34.         end if
    35.        
    36.         dd 0,0,0,RVA dllnameptr,minOrdinal
    37.         dd NumberOfFunctions,NumberOfNames,RVA functions,RVA names,RVA ordinals
    38.        
    39.         functions: times NumberOfFunctions dd 0
    40.     forward
    41.         ;only functions with an explicitly specified ordinal are saved here
    42.         if ~ ordinal eq
    43.             load buf dword from functions+(ordinal-minOrdinal)*4
    44.             if buf
    45.                 display 'Error: ordinal ' # `ordinal # ' redefinition',13,10
    46.                 err
    47.             end if
    48.             store dword RVA label at functions+(ordinal-minOrdinal)*4
    49.         end if
    50.     common
    51.         names:
    52.     forward
    53.         local name
    54.         if ~ string eq
    55.             dd RVA name
    56.         end if
    57.     common
    58.         ordinals:
    59.     forward
    60.         ;only functions without an explicitly specified ordinal are saved here
    61.         if ordinal eq
    62.             repeat NumberOfFunctions
    63.                 load buf dword from functions+(%-1)*4
    64.                 if ~ buf
    65.                     store dword RVA label at functions+(%-1)*4
    66.                     if ~ string eq
    67.                         dw %-1
    68.                     end if
    69.                     break
    70.                 end if
    71.             end repeat
    72.         else
    73.             if ~ string eq
    74.                 dw ordinal-minOrdinal
    75.             end if
    76.         end if
    77.     common
    78.         dllnameptr db dllname,0
    79.     forward
    80.         if ~ string eq
    81.             name db string,0
    82.         end if
    83.     common
    84.         local x,y,z,str1,str2,v1,v2
    85.  
    86.         x = NumberOfNames shr 1
    87.         while x > 0
    88.             y = x
    89.             while y < NumberOfNames
    90.                 z = y
    91.                 while z-x >= 0
    92.                     load v1 dword from names+z*4
    93.                     str1=($-RVA $)+v1
    94.                     load v2 dword from names+(z-x)*4
    95.                     str2=($-RVA $)+v2
    96.                     while v1 > 0
    97.                         load v1 from str1+%-1
    98.                         load v2 from str2+%-1
    99.                         if v1 <> v2
    100.                             break
    101.                         end if
    102.                     end while
    103.                     if v1<v2
    104.                         load v1 dword from names+z*4
    105.                         load v2 dword from names+(z-x)*4
    106.                         store dword v1 at names+(z-x)*4
    107.                         store dword v2 at names+z*4
    108.                         load v1 word from ordinals+z*2
    109.                         load v2 word from ordinals+(z-x)*2
    110.                         store word v1 at ordinals+(z-x)*2
    111.                         store word v2 at ordinals+z*2
    112.                     else
    113.                         break
    114.                     end if
    115.                     z = z-x
    116.                 end while
    117.                 y = y+1
    118.             end while
    119.             x = x shr 1
    120.         end while
    121. }
    В отличие от предыдущего добавлена возможность экспорта только по ординалу. Кроме того, можно указывать только имя (тогда будет выбран первый свободный ординал). Можно также вообще не указывать ни имя, ни ординал (экспорт только по ординалу, выбран будет первый свободный), но полезность этой возможности сомнительна. В общем, следующего вида экспорт вполне валиден:
    Код (Text):
    1. data export
    2.     exportByOrdinals 'ORDINALS.DLL',\
    3.         Fun1,'Fun1',475,\
    4.         Fun2,'Fun2',,\
    5.         Fun3,,,\
    6.         Fun4,'Fun4',350,\
    7.         Fun5,,300,\
    8.         Fun6
    9. end data
    Ах да... Добавлен контроль повторов явно указанных ординалов.