|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Фев 9, 2004 08:18:47 · Поправил: S_T_A_S_ Привет всем! (не хотелось бы обсуждать приимущества/недостатки различных извратов с таблицей импорта) В общем, делаю я таблицу импорта - там только одна функция - GetProcAddress. Имена остальных - массив ascii строк, заканчивающихся нулями в таком формате: IMPORTED_NAMES: db "имя proc из kernell.dll",0 ..... db "имя proc из kernell.dll",0 db 0 - конец списка функций для dll db "имя *.dll",0 db "имя proc из *.dll",0 ..... db "имя proc из *.dll",0 db 0FFh - конец таблици Далее написал такой код, который этот список обрабатывает при запуске программы. Сейчас он весит 65 байт (если метка ..ENTRY_POINT не далеко). Но в таких случаях хочется меньшего. Какие-нибудь идеи? Может саму таблицу по другому организовать? (CRC32 для имен я использовать не хочу, по той же причине, как и поиск kernel32 через стек) Это FASM, но думаю все понятно: __RTImportLibraries: mov EBX, [GetProcAddress$$] ;; this function IS inside the kernel32.dll mov EBP, EBX @@: xor BX, BX ;; dlls are loaded at addresses XXXX0000h, so align cmp word [EBX], 'MZ' ;; check first 2 bytes of PE jz @f ;; Kernel32.dll found dec EBX ;; search backward. Now -1, ^^ align by 10000h jmp @b ;; here we have got handle to module kernel32.dll in EBX. Really, I like word "address" @@: cld mov EDI, IMPORTED_NAMES mov ESI, LOCKUP_TABLE @@: stdcall EBP, EBX, EDI ;; invoke GetProcAddress mov [ESI], EAX ;; store it in Locup Table add ESI, 4 ;; search next imported name .s: xor Al, AL mov ECX, EDI ;; well, I'm sure strings won't be so big repnz scasb ;; find next string cmp [EDI], AL js ..ENTRY_POINT ;; end of table found, start the programm jnz @b ;; proc name found ;; if we are here, new dll name is found inc EDI invoke LoadLibrary, EDI mov EBX, EAX ;; new dll base address jmp .s ЗЫ Это работает в 98, XP и некоторых 2к. В других не тестировал. Вот пример exe (оптимизирован похуже) |
|
|
Дата: Фев 9, 2004 08:52:59 Вот пример (оптимизирован похуже) на моей 98 выполняет недопустимую операцию... А основной вопрос непонятен. Что мешает таблицу пожать? |
|
|
Дата: Фев 9, 2004 09:14:57 Да, можно и CRC вычислять, но тогда сама процедура увеличится. Так что тут вопрос, когда будет выигрыш. Еще, таблица имен строится простым макросом в FASM. А как я буду ее "пожать" на этапе компиляции? К тому же я пытаюсь использовать ТОЛЬКО документированные приемы (ну, или те которые могут быть к ним приравнены). Маловероятно, что MS будет запускать процесс jmp, но мне в данном случае - все равно, в отличае от поиска кернела через стек. Так что основной вопрос - уменьшение самой процедуры импорта (ну может еще 0-ли уберу в концах строк) Поэтому у меня "оптимизация" в кавычках :) (хотя вообще-то, что-то плохо стало с русским) на моей 98 выполняет недопустимую операцию... Возможно, по команде movntq? У меня вот работает на SE.. |
|
|
Дата: Фев 10, 2004 21:12:55 S_T_A_S_ Это тот случай, когда надо заниматься низкоуровневой оптимизацией. Пожать таблицу можно - для этого достаточно в исходники поместить ее уже пожатой в hex-формате - это можно сделать с помощью либо своей программы, либо сторонней утилиты. Можно и имена хеш-функцией пожать, но и в первом, и во втором случае придется писать код. Я бы использовал ординалы и не парил себе мозги. |
|
|
Дата: Фев 10, 2004 22:22:15 Самый главный вопрос здесь: каков смысл всего этого? Если только "оптимизировать" таблицу импорта, то все равно больше 65 байт не сэкономить :) ст0ит ли свеч? А если уменьшить обьем целевого бинарника, то заниматься надо сжатием всей программы... |
|
|
Дата: Фев 11, 2004 03:28:04 Я согласен, что надо заниматься сжатием всего PE, что бы получить экономию. В таком случае можно рассматривать мои 65 байто в как код, который будет обрабатывать распакованные секции.. и т.д и т.п. - но это другой вопрос Я вот получил 65 байтов, оригинал был несколько больше и юзал ESP. И мне интересно: можно ли сделать еще меньше? И как?? Если меньше нельзя, то положу макросы, которые автоматизирует создание этой лабуды в FASM. Используются вместо "стандартных" library / import. Кому-то может и пригодится, что-бы руками не липить volodya Ординалы, возможно, не всегда хорошо. ( Потом, как мне их FASM выдаст? Ручками считать? ) Хотя с другой стороны модификация будет не большая, если их использовать :) |
|
|
Дата: Май 22, 2004 05:44:20 круче Харона импорт никому не оптимизировать! расковыряйте ulink - найдете много интересного (ftp://ftp.styx.cabel.net/pub/UniLink/) а еще есть BOUND IMPORT - он быстрее всех, т.к. при нем библиотека просто проецируется и усе. а эффективные адреса прописываются еще на стадии компиляции, однако, версия DLL должна быть известна наперед. как вариант можно заюзать DELAY IMPORT, правда, зачастую он дает тормоза, а не ускорение, так что юзать его надо с умом... плюс еще можно загнать в IAT копию INT - на XP это ускоряет загрузку файла, остальные об этой фиче не знают... да много разных вариантов, словом... |
|
|
Дата: Май 22, 2004 22:19:19 Да, вариантов разных много. Навязчивая идея была ипользовать только документированные возможности ОСи, чтобы не появились обломы, если моя прога будет запускаться не CALL, а JMP. Или МС вдруг не поменяет ординалы. |
|
|
Дата: Май 22, 2004 22:48:35 но мне в данном случае - все равно, в отличае от поиска кернела через стек. А нахрена? Ты уже линкуешься с кернелом (GetProcAddress) Кто мешает тебе плясать от GetProcAddress, а не через стек? Ординалы - нахерн.. нахрен.. Не гарантировано это. p.s. для сишных, которые не надо upx-ить добавляю ещё так : #pragma comment(linker, "/FILEALIGN:2 /SECTION:.text,EWRX /IGNORE:4078") В результате порядка 10-20К экономии. |
|
|
Дата: Май 22, 2004 22:59:44 > Ты уже линкуешься с кернелом (GetProcAddress) Кто мешает тебе плясать от GetProcAddress, а не через стек Дык.. я так и делаю :-) |
|
|
Дата: Май 23, 2004 01:46:34 Интересно, вот тут зашел вопрос об aline'е секций, мне стало интересно, я копнул fasm, но не нашел там опций для выравнивания секций, в fasm'е можно это сделать?, не используя линкер? |
|
|
Дата: Май 23, 2004 05:35:45 копайте ulink ;) 1) для своих библиотек _всегда_ используйте bound import, быстрее его ничего не бывает; 2) для библиотек ядра пишите свой GetProcAddress (если надо, я подкину сырец движка, сырой, правда, но работающий). смотрите - имена фунций всегда отсортированы по алфавиту, поэтому поиск нужной функции резко ускоряется (метод вилки), к тому же можно зарелизить функцию, импортирующую за раз много-много экспортов. ну зачем каждый раз делать разбор INT с начала? сортируем свои функции по алфавиту - и проходим экпорт всего однин раз (да и того с учетом вилки не будет). короче говоря, вполне реально получить стократное ускорение, не рискуя при этом разорвать себе задницу. |
|
|
Дата: Май 23, 2004 14:01:25 2rst Ага тока ДЛЛ при такой компиляции запускаться не будет +) минимум это FILEALIGN:512 ... Хотя может кто то знает какой то волебный способ заставить работать и так,? |
|
|
Дата: Май 23, 2004 21:41:29 [ jekyll : AFAIK - копнул fasm, но не нашел там опций для выравнивания секций, в fasm'е можно это сделать? ] AFAIK, используя стандартный форматер (директива format) - нет. Но можно написать весь заголовок через DB/DD (без format) и получить любое выравнивание. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.355 |