Сейчас на форуме: rmn, Magister Yoda, vasilevradislav, tyns777, zombi-vadim (+4 невидимых)

 eXeL@B —› Программирование —› Пооптимизируем код :-)
Посл.ответ Сообщение

Ранг: 46.9 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 12 мая 2008 09:38 · Поправил: Zloy
· Личное сообщение · #1

Вот ознакомьтесь товарищи,написал на асме процедурку получения адресов апи фунций по их хешам занимает 68 байт и это не может не радовать ,но мои чувства подсказывают мне,что можно сделать еще меньше.

Сам код в виде BIN->DB

;68 bytes long
db 96,139,68,36,36,137,195,3,64,60,139,80,120,1,218,139
db 74,24,139,122,32,1,223,137,222,3,116,143,252,49,192,193
db 192,7,50,6,70,128,62,0,117,245,51,68,36,40,116,6
db 226,229,49,192,235,6,139,68,138,36,1,216,137,68,36,28
db 97,194,8,0


Также тестовая программа на Flat Assembler:
;By ZloY (x) 2008
format PE GUI
include 'include\win32ax.inc'
.data
tmp dd ?
.code
start:
;Step(1) : Get Kernel Base(read it from PEB,NT ONLY).
mov eax,[fs:30h]
mov eax,[eax+0Ch]
mov esi,[eax+1Ch]
lodsd
mov ebx,[eax+08h]
;Step(2) : Find 'GetProcAddress' address.
push 0x1FC0EAEE; hashed 'GetProcAddress'
push ebx ;kernel32 base
call .getproc
mov ecx,eax
;Step(3) : Find 'LoadLibraryA' address.
push 0xC8AC8026 ; hashed 'LoadLibraryA'
push ebx ;kernel32 base
call .getproc
;Step(4) : Load the 'user32.dll'
pushd 'user32'
call eax
;Step(5) Find 'MessageBoxA' address.
push 0xABBC680D ;hashed 'MessageBoxA'
push eax ;user32 base
call .getproc
;Step(6) Testing,now in eax pointer to 'MessageBoxA' func.
;i dont use here(push 0) if it 4 times pasted = 8 bytes,i use:
;(xor ecx,ecx) and 4 times (push ecx) = 6 bytes
xor ecx,ecx
push ecx
push ecx
push ecx
push ecx
call eax
ret

.getproc:
pushad
mov eax,[esp+0x24] ;module handle
mov ebx,eax ;save module handle
add eax,[eax+3Ch];pe header
mov edx,[eax+78h];export table rva
add edx,ebx ;module handle
mov ecx,[edx+0x18];Num of Name Pointers
mov edi,[edx+0x20];Name Pointers RVA
add edi,ebx ;module handle
.getproc_scan:
mov esi,ebx ;module handle
add esi,[edi+(ecx-1)*4] ;poiner to apiname
xor eax,eax
.getproc_hash:
rol eax,7
xor al,[esi]
inc esi
cmp byte[esi],0
jnz .getproc_hash
xor eax,[esp+0x28] ;~cmp ... if eax=[esp+0x28] then eax =0 and jump
jz .getproc_found
loop .getproc_scan
xor eax, eax
jmp .getproc_quit
.getproc_found:
mov eax,[edx+28h+(ecx-1)*4]
add eax,ebx
.getproc_quit:
mov dword[esp+01Ch],eax ; return result on eax
popad
retn 8
.end start


Вот собственно помогите отпимизировать процедуру получения адреса или я залез уже выше крыши?
Хотя мне кажеться вот тут:

mov edi,[edx+0x20];Name Pointers RVA
add edi,ebx ;module handle
.getproc_scan:
mov esi,ebx ;module handle
add esi,[edi+(ecx-1)*4] ;poiner to apiname

Можно отпимизировать на 1-2 байта




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 12 мая 2008 13:08
· Личное сообщение · #2

=) Я так понял ты оптимизируешь по размеру а не по скорости , глянь тут www.wasm.ru/publist.php?list=10 , может и видел но может некоторые команды оптимизируешь заменой схожими , хотя вроде ты rol ы тоже используешь.

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 16 мая 2008 03:27 · Поправил: S_T_A_S_
· Личное сообщение · #3

Имена некоторых команд говорят сами за себя - popa Сразу теряется 4 байта на возврат значения в eax.
Если сохранять только регистры в соответствии с распространёнными соглашениями о вызовах - ebx esi edi (ebp здесь не используется, а esp восстанавливается и так) - в сумме будут теже 6 байт, вроде выгоды нет... пока не начнёшь передавать параметры в регистрах - -4 байта на чтение module handle. Передавать можно сразу в ebx - и не надо будет его сохранять + некоторые add можно убрать.

В общем получается вот такое начало:
.getproc:
; ebx - module handle
mov eax,[ebx+3Ch];pe header
mov edx,[eax+78h + ebx];export table rva
add edx,ebx ;module handle
;...

Да, самое главное забыл В ассемблере для возврата значений используют флаги. Здесь получается, что если импорт найдет, то автоматически установлен ZF (но позже сбрасывается add eax,ebx - можно заменить на lea). Главное здесь не экономия 1 байта в этой функции, а экономия 2х байт на проверку возвращаемого значения после каждого вызова.



Ранг: 46.9 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 16 мая 2008 06:57
· Личное сообщение · #4

Уменьшил на 1 байт
.getproc_found:
xchg eax,ebx
add eax,[edx+28h+(ecx-1)*4]
.getproc_quit:

И вот с этой dll почему то не работает slil.ru/25794741 IsValidUrl пробую найти в этой .dll и выдает неверный адрес,мне кажеться где то я забыл пофиксить кол-во импортов по именам и ординалам


 eXeL@B —› Программирование —› Пооптимизируем код :-)
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати