Начал программировать на FASM, скачал его последнюю версию + документацию (хоть и на англицком но понять можно). И вот почти сразу возник вопрос: как экпортировать из exe/dll функцию или переменную. На сайте www.flatassembler.net такой инфы не обнаружилось ни в FAQ, ни в документации (там про PE формат вообще не много: только stack,heap и возможность включения любого stub) В COFF там есть какое-то описание но я никогда не сталкивался с этим форматом и не понимаю, почему нельзя экспортировать из PE. Если кто знает как это сделать, отпишите плиз.
А можете на конкретном примере продемонстрировать то что там написано, а то я не понял, (кстати страница 107 - объем справки вырос однако).
Урра! Разобрался..Спс Фриману. А не поможете с вопросом: почему нельзя установить другое выравнивание секий окромя 512, align 32 вроде как компилирует но выравнивание не меняется. Неплохо бы также разобратца с импортом из произвольной длл.
Спс вам Фриман, с экспортом разобрался (правда к сожалению заметил что макрос export не поддерживает экспорта функций по оридналу (и уж тем более по произвольному ординалу), зато импорт из библиотек меня порадовал основательно, хоть по ординалу, хоть по имени, и без всяких lib-файлов! Красотень...
пощите по форуму, тут свои макросы люди песали вроде под это дело более удобные. и даж с нуля ехе мутили
Заюзал поиск по форуму. Нашелся один результат на точно такой же вопрос: http://www.wasm.ru/forum/viewtopic.php?id=34584 Однако приведенный там макрос для экспорта по ординалу не работает. Так что считаю вопрос открытым. Я слабо разбираюсь в том макросе, но мне необходимо экспортировать функцию безымянной под неким ординалом с малопредсказуемым числом (например 256). Вообще возможно ли это реализовать на фасм, и если да то как? Мб кто-то сумеет подправить макрос экспорт из той ветки формуа: Код (Text): macro export dllname,[label,string,ordinal] { common local module,addresses,names,count count = 0 forward count = count+1 common dd 0,0,0,RVA module,1 dd count,count,RVA addresses,RVA names,RVA ordinal addresses: forward dd RVA label common names: forward local name dd RVA name common ordinal: forward dw ordinal common module db dllname,0 forward name db string,0 common }
Если нужно экспортировать одну функцию exported под ординалом ord, то следующий код поможет: Код (Text): align 4 data export dd 0, 0, 0, rva dllname, ord, 1, 0, rva @f, 0, 0 @@ dd rva exported dllname db '1.dll',0 end data (вместо 1.dll нужно подставить имя своей dll или exe). Если интересно узнать, что здесь происходит, почему надо так писать и что делать, если нужно добавить другие экспорты - следует изучать формат PE, директорию экспорта (data export ровно её и задаёт, без всяких преобразований со стороны компилятора).
Praetor11 А не подскажете, зачем это нужно? Если Вы хотите таким образом "спрятать" экспортируемую функцию, то это неудачный вариант, т.к. в любом PE-редакторе достаточно открыть будет Ваш PE и весь экспорт будет, как на ладони. Если нужно экспортировать только одну функцию с неизвестно каким ординалом, то достаточно указать Ordinal Base понравившимся значением (в оригинальном макросе заменить единицу в строке dd 0,0,0,RVA module,1). Соответственно ординалы экспорта будут начинаться именно с этого числа. Если нужно экспортировать несколько функций с нехорошими ординалами (например, 317, 539, 1195), то придётся оставлять кучу пустых мест в массиве RVA функций. Т.о. Ваша таблица экспорта разрастётся до размеров более (1195-317+1)*4 = почти 3,5 КБ. И чего Вы этим добьётесь кроме увеличения размеров файла?
Чисто для проверки возможностей фасма. По-моему невозможность такого экспорта - большой недостаток. А не у кого не возникало желания дописать такие макросы для фасма/масма? Я в принципе понимаю создателя фасма в том, что он не вписал ординал в свой макрос экпорта - дабы избежать ошибок типа нескольких функций с одинаковыми ординалами, либо вот 317,539,1195 - вроде логично. Хотя я вроде уже нашел что мне нужно: export '1.dll',export_func,'' создает экспорт по ординалу, но только по порядку (((
это легко проверяется на фасме, просто этим методом в основном ни кто не пользуется. да и пусть энтузиасты тренируются.
макрос для экспорта по ординалам (любезно предоставленный товарищем, который пожелал остаться неизвестным =) ): Код (Text): macro exportByOrdinals dllname,[label,string,fordinal] { common local module,addresses,names,minOrdinal,maxOrdinal,ordinal,count,funcRVASize count = 0 minOrdinal = 0FFFFh maxOrdinal = 0 forward count = count+1 if fordinal<minOrdinal minOrdinal = fordinal end if if fordinal>maxOrdinal maxOrdinal = fordinal end if common dd 0,0,0,RVA module,minOrdinal dd maxOrdinal-minOrdinal+1,count,RVA addresses,RVA names,RVA ordinal addresses: funcRVASize = 0 while funcRVASize < maxOrdinal-minOrdinal+1 funcRVASize = funcRVASize+1 dd 0 end while forward store dword RVA label at addresses+(fordinal-minOrdinal)*4 common names: forward local name dd RVA name common ordinal: forward dw fordinal-minOrdinal common module db dllname,0 forward name db string,0 common local x,y,z,str1,str2,v1,v2 x = count shr 1 while x > 0 y = x while y < count z = y while z-x >= 0 load v1 dword from names+z*4 str1=($-RVA $)+v1 load v2 dword from names+(z-x)*4 str2=($-RVA $)+v2 while v1 > 0 load v1 from str1+%-1 load v2 from str2+%-1 if v1 <> v2 break end if end while if v1<v2 load v1 dword from names+z*4 load v2 dword from names+(z-x)*4 store dword v1 at names+(z-x)*4 store dword v2 at names+z*4 load v1 word from ordinal+z*2 load v2 word from ordinal+(z-x)*2 store word v1 at ordinal+(z-x)*2 store word v2 at ordinal+z*2 else break end if z = z-x end while y = y+1 end while x = x shr 1 end while } внутри секции експорта применять так: Код (Text): exportByOrdinals 'wrapper.dll',\ wrapped_AcceptEx,'AcceptEx',475h,\
Раз уж мне сегодня пришлось вспомнить структуру экспорта, довёл макрос из предыдущего поста до более пристойного вида: Код (Text): macro exportByOrdinals dllname*,[label,string,ordinal] { common local dllnameptr,functions,names,ordinals,NumberOfFunctions,NumberOfNames,\ minOrdinal,maxOrdinal,buf NumberOfFunctions = 0 NumberOfNames = 0 forward NumberOfFunctions = NumberOfFunctions + 1 if ~ string eq NumberOfNames = NumberOfNames+1 end if if ~ ordinal eq if ~ defined maxOrdinal | defined @F @@: minOrdinal = ordinal maxOrdinal = ordinal else if ordinal<minOrdinal minOrdinal = ordinal end if if ordinal>maxOrdinal maxOrdinal = ordinal end if end if end if common if ~ defined maxOrdinal minOrdinal = 1 else if maxOrdinal-minOrdinal+1 > NumberOfFunctions NumberOfFunctions = maxOrdinal-minOrdinal+1 end if end if dd 0,0,0,RVA dllnameptr,minOrdinal dd NumberOfFunctions,NumberOfNames,RVA functions,RVA names,RVA ordinals functions: times NumberOfFunctions dd 0 forward ;only functions with an explicitly specified ordinal are saved here if ~ ordinal eq load buf dword from functions+(ordinal-minOrdinal)*4 if buf display 'Error: ordinal ' # `ordinal # ' redefinition',13,10 err end if store dword RVA label at functions+(ordinal-minOrdinal)*4 end if common names: forward local name if ~ string eq dd RVA name end if common ordinals: forward ;only functions without an explicitly specified ordinal are saved here if ordinal eq repeat NumberOfFunctions load buf dword from functions+(%-1)*4 if ~ buf store dword RVA label at functions+(%-1)*4 if ~ string eq dw %-1 end if break end if end repeat else if ~ string eq dw ordinal-minOrdinal end if end if common dllnameptr db dllname,0 forward if ~ string eq name db string,0 end if common local x,y,z,str1,str2,v1,v2 x = NumberOfNames shr 1 while x > 0 y = x while y < NumberOfNames z = y while z-x >= 0 load v1 dword from names+z*4 str1=($-RVA $)+v1 load v2 dword from names+(z-x)*4 str2=($-RVA $)+v2 while v1 > 0 load v1 from str1+%-1 load v2 from str2+%-1 if v1 <> v2 break end if end while if v1<v2 load v1 dword from names+z*4 load v2 dword from names+(z-x)*4 store dword v1 at names+(z-x)*4 store dword v2 at names+z*4 load v1 word from ordinals+z*2 load v2 word from ordinals+(z-x)*2 store word v1 at ordinals+(z-x)*2 store word v2 at ordinals+z*2 else break end if z = z-x end while y = y+1 end while x = x shr 1 end while } В отличие от предыдущего добавлена возможность экспорта только по ординалу. Кроме того, можно указывать только имя (тогда будет выбран первый свободный ординал). Можно также вообще не указывать ни имя, ни ординал (экспорт только по ординалу, выбран будет первый свободный), но полезность этой возможности сомнительна. В общем, следующего вида экспорт вполне валиден: Код (Text): data export exportByOrdinals 'ORDINALS.DLL',\ Fun1,'Fun1',475,\ Fun2,'Fun2',,\ Fun3,,,\ Fun4,'Fun4',350,\ Fun5,,300,\ Fun6 end data Ах да... Добавлен контроль повторов явно указанных ординалов.