Сейчас на форуме: YDS, _MBK_, user99 (+8 невидимых)

 eXeL@B —› Основной форум —› Виртуальные адреса WinAPI
Посл.ответ Сообщение

Ранг: 4.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 22 ноября 2005 17:39
· Личное сообщение · #1

Можно ли при написании программы на ассемблере вызывать WinAPI функции на прямую, а не через таблицу импорта. Если можно, то где взять в Интернете информацию об адресах.



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

Создано: 22 ноября 2005 17:45
· Личное сообщение · #2

Перехват API функций в Windows NT от MS-Rem на WASMe можно найти.



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 22 ноября 2005 17:59
· Личное сообщение · #3

b0lt пишет:
где взять в Интернете информацию об адресах.


Прикольно.

А информацию о PE-формате ты читал? А статьи на васме?
Как минимум надо почитать Рихтера.

Суть в том, что dll (а API - это не что иное как экспорт dll) не имеют абсолютно постоянного адреса. И даже не смотря на то, что база у них постоянная, адреса будут разные для других версий, компов, систем, дров и т.п.

-----
Всем привет, я вернулся





Ранг: 199.6 (ветеран), 12thx
Активность: 0.10
Статус: Участник
www.uinc.ru

Создано: 24 ноября 2005 15:45
· Личное сообщение · #4

Видимо он спрашивал как использовать функции LoadLibrary()/GetProcAddress()




Ранг: 1288.1 (!!!!), 273thx
Активность: 1.290
Статус: Участник

Создано: 24 ноября 2005 15:56
· Личное сообщение · #5

DrGolova пишет:
Видимо он спрашивал как использовать функции LoadLibrary()/GetProcAddress()

А как вызвать их, не используя таблицу импорта?



Ранг: 500.5 (!), 8thx
Активность: 0.230
Статус: Участник

Создано: 24 ноября 2005 16:19
· Личное сообщение · #6

Ara пишет:
А как вызвать их, не используя таблицу импорта?

Есть два варианта:
1) разобрать заголовок системной библиотеки и найти их там
2) использовать конст. адрес - естесно работать будет только на той же версии ОС

-----
"Пусть видят, что мы не шутим. Стволы для понта, ножи для дела" Lock, Stock & Two Smoking Barrels





Ранг: 1288.1 (!!!!), 273thx
Активность: 1.290
Статус: Участник

Создано: 24 ноября 2005 16:22
· Личное сообщение · #7

Smon пишет:
1) разобрать заголовок системной библиотеки и найти их там

Не совсем понятно, что имелось ввиду... Что мы найдем в этом заголовке, "разобрав" его?

п.2 отпадает по указанным причинам %)



Ранг: 500.5 (!), 8thx
Активность: 0.230
Статус: Участник

Создано: 24 ноября 2005 16:30
· Личное сообщение · #8

Процедура GetAPI_ET_CRC32
; -------------------------
;
; Хех, сложное имя? Эта процедура ищет имя API-функции в таблице экспортов
; KERNEL32 (после небольших изменений она будет работать для любой DLL), но
; теперь требуется только CRC32 API-функции, а не вся строка . Также
; потребуется процедура для получения CRC32 вроде той, которую я привел выше.
;
; на входе:
; EAX = CRC32 имени функции в формате ASCIIz
; на выходе:
; EAX = адрес API-функции
;

GetAPI_ET_CRC32 proc
xor edx,edx
xchg eax,edx ; Помещаем CRC32 функции в EDX
mov word ptr [ebp+Counter],ax ; Сбрасываем счетчик
mov esi,3Ch
add esi,[ebp+kernel] ; Получае PE-заголовок KERNEL32
lodsw
add eax,[ebp+kernel] ; Нормализуем

mov esi,[eax+78h] ; Получаем указатель на
add esi,1Ch ; таблицу экспортов
add esi,[ebp+kernel]

lea edi,[ebp+AddressTableVA] ; Указатель на таблицу адресов
lodsd ; Получаем значение AddressTable
add eax,[ebp+kernel] ; Нормализуем
stosd ; И сохраняем в ее переменной

lodsd ; Получаем значение NameTable
add eax,[ebp+kernel] ; Нормализуем
push eax ; Помещаем ее на стек
stosd ; Сохраняем в ее переменной

lodsd ; Получаем значение OrdinalTable
add eax,[ebp+kernel] ; Нормализуем
stosd ; Сохраняем

pop esi ; ESI = NameTable VA

@?_3: push esi ; Снова сохраняем
lodsd ; Получ. указ. на имя API-ф-ции
add eax,[ebp+kernel] ; Нормализуем
xchg edi,eax ; Сохраняем указатель в EDI
mov ebx,edi ; И в EBX

push edi ; Сохраняем EDI
xor al,al ; Доходим до NULL'а
scasb ; Это конец имени API-функции
jnz $-1
pop esi ; ESI = Указ. на имя API-ф-ции

sub edi,ebx ; EDI = Размер имени API-ф-ции

push edx ; Сохраняем CRC32 функции
call CRC32 ; Получаем текущий CRC функции
pop edx ; Восстанавливаем CRC32 функции
cmp edx,eax ; Они совпадают?
jz @?_4 ; Если да, это то, что нам надо

pop esi ; Восст. указ. на имя функции
add esi,4 ; Переходим к следующему
inc word ptr [ebp+Counter] ; И увеличиваем знач. счетчика
jmp @?_3 ; Получаем следующую API-ф-цию!
@?_4:
pop esi ; Убираем мусор из стека
movzx eax,word ptr [ebp+Counter] ; AX = счетчик
shl eax,1 ; *2 (это массив слов)
add eax,dword ptr [ebp+OrdinalTableVA] ; Нормализуем
xor esi,esi ; Очищаем ESI
xchg eax,esi ; ESI = Указ. на ординал; EAX=0
lodsw ; В AX получаем ординал
shl eax,2 ; И с его помощью переходим к
add eax,dword ptr [ebp+AddressTableVA] ; AddressTable (массив
xchg esi,eax ; двойных слов)
lodsd ; Получаем адресс API RVA
add eax,[ebp+kernel] ; и нормализуем!! Все!
ret
GetAPI_ET_CRC32 endp

AddressTableVA dd 00000000h ;\
NameTableVA dd 00000000h ; &rt; В ЭТОМ ПОРЯДКЕ!!
OrdinalTableVA dd 00000000h ;/

kernel dd 0BFF70000h ; Подгоните под свои нужды ;)
Counter dw 0000h
;---[ CUT HERE ]-------------------------------------------------------------

Далее следует эквивалентный код, но работающий с таблицей импортов. Таким образом вы сможете написать перпроцессный резидент с помощью одних только CRC32 имен API-функций ;).


;---[ CUT HERE ]-------------------------------------------------------------
;
; Процедура GetAPI_IT_CRC32
; -------------------------
;
; Эта процедура ищет в таблице импортов API-функция, CRC32 которой совпадает
; с переданным процедуре. Это полезно для создания перпроцессных резидентов
; (смотри главу "Перпроцессная резидентность" в данном туториале).
;
; на входе:
; EAX = CRC32 имени API-функции в формате ASCIIz
; на выходе:
; EAX = адрес API-функции
; EBX = указатель на адрес API-функции в таблице импортов
; CF = устанавливаем, если вызов функции не удался
;

GetAPI_IT_CRC32 proc
mov dword ptr [ebp+TempGA_IT1],eax ; Сохранить CRC32 API-функции
; на будущее

mov esi,dword ptr [ebp+imagebase] ; ESI = база образа
add esi,3Ch ; Получ. указ. на PE-заголовок
lodsw ; AX = тот указатель
cwde ; Очищаем MSW EAX'а
add eax,dword ptr [ebp+imagebase] ; Нормализуем указатель
xchg esi,eax ; ESI = такой указатель
lodsd ; Получаем DWORD

cmp eax,"EP" ; Это метка PE?
jnz nopes ; Нет... duh!

add esi,7Ch ; ESI = PE-заголовок+80h
lodsd ; Ищем .idata
push eax
lodsd ; Получаем размер
mov ecx,eax
pop esi
add esi,dword ptr [ebp+imagebase] ; Нормализуем

SearchK32:
push esi ; Сохраняем ESI в стек
mov esi,[esi+0Ch] ; ESI = указатель на имя
add esi,dword ptr [ebp+imagebase] ; Нормализуем
lea edi,[ebp+K32_DLL] ; Указатель на 'KERNEL32.dll'
mov ecx,K32_Size ; Размер строки
cld ; Очищаем флаг направления
push ecx ; Сохраняем ECX
rep cmpsb ; Сохраняем байты
pop ecx ; Восстанавливаем ECX
pop esi ; Восстанавливаем ESI
jz gotcha ; Были ли они равны? Черт...
add esi,14h ; Получаем другое поле
jmp SearchK32 ; И ищем снова
gotcha:
cmp byte ptr [esi],00h ; Это OriginalFirstThunk 0?
jz nopes ; Проклятье, если так...
mov edx,[esi+10h] ; Получаем FirstThunk
add edx,dword ptr [ebp+imagebase] ; Нормализуем
lodsd ; Получаем его
or eax,eax ; Это 0?
jz nopes ; Проклятье...

xchg edx,eax ; Получаем указатель на него
add edx,[ebp+imagebase]
xor ebx,ebx
loopy:
cmp dword ptr [edx+00h],00h ; Последний RVA?
jz nopes ; Проклятье...
cmp byte ptr [edx+03h],80h ; Ординал?
jz reloop ; Проклятье...

mov edi,[edx] ; Получаем указатель на
add edi,dword ptr [ebp+imagebase] ; импортированную API-функцию
inc edi
inc edi
mov esi,edi ; ESI = EDI

pushad ; Сохраняем все регистры
eosz_edi ; В EDI получаем конец строки
sub edi,esi ; EDI = размер имени функции

call CRC32
mov [esp+18h],eax ; В ECX - результат после POPAD
popad

cmp dword ptr [ebp+TempGA_IT1],ecx ; CRC32 данной API-функции
jz wegotit ; совпадает с той, которая
; нам нужна?
reloop:
inc ebx ; Если, совершаем следующий
add edx,4 ; проход и ищем нужную функцию
; в таблице импортов
loop loopy
wegotit:
shl ebx,2 ; Умножаем на 4
add ebx,eax ; Добавляем FirstThunk
mov eax,[ebx] ; EAX = адрес API-функции
test al,00h ; Пересечение: избегаем STC
org $-1
nopes:
stc
ret
GetAPI_IT_CRC32 endp

TempGA_IT1 dd 00000000h
imagebase dd 00400000h
K32_DLL db "KERNEL32.dll",0
K32_Size equ $-offset K32_DLL

;---[ CUT HERE ]------------------------------------

-----
"Пусть видят, что мы не шутим. Стволы для понта, ножи для дела" Lock, Stock & Two Smoking Barrels




Ранг: 500.5 (!), 8thx
Активность: 0.230
Статус: Участник

Создано: 24 ноября 2005 16:31
· Личное сообщение · #9

CRC32 некоторых API-функций:


Имя API-функции CRC32 Имя API-функции CRC32
--------------- ----- --------------- -----
CreateFileA 08C892DDFh CloseHandle 068624A9Dh
FindFirstFileA 0AE17EBEFh FindNextFileA 0AA700106h
FindClose 0C200BE21h CreateFileMappingA 096B2D96Ch
GetModuleHandleA 082B618D4h GetProcAddress 0FFC97C1Fh
MapViewOfFile 0797B49ECh UnmapViewOfFile 094524B42h
GetFileAttributesA 0C633D3DEh SetFileAttributesA 03C19E536h
ExitProcess 040F57181h SetFilePointer 085859D42h
SetEndOfFile 059994ED6h DeleteFileA 0DE256FDEh
GetCurrentDirectoryA 0EBC6C18Bh SetCurrentDirectoryA 0B2DBD7DCh
GetWindowsDirectoryA 0FE248274h GetSystemDirectoryA 0593AE7CEh
LoadLibraryA 04134D1ADh GetSystemTime 075B7EBE8h
CreateThread 019F33607h WaitForSingleObject 0D4540229h
ExitThread 0058F9201h GetTickCount 0613FD7BAh
FreeLibrary 0AFDF191Fh WriteFile 021777793h
GlobalAlloc 083A353C3h GlobalFree 05CDF6B6Ah
GetFileSize 0EF7D811Bh ReadFile 054D8615Ah
GetCurrentProcess 003690E66h GetPriorityClass 0A7D0D775h
SetPriorityClass 0C38969C7h FindWindowA 085AB3323h
PostMessageA 086678A04h MessageBoxA 0D8556CF7h
RegCreateKeyExA 02C822198h RegSetValueExA 05B9EC9C6h
MoveFileA 02308923Fh CopyFileA 05BD05DB1h
GetFullPathNameA 08F48B20Dh WinExec 028452C4Fh
CreateProcessA 0267E0B05h _lopen 0F2F886E3h
MoveFileExA 03BE43958h CopyFileExA 0953F2B64h
OpenFile 068D8FC46h

Эт Бельцебу накатал, который Билли =)

-----
"Пусть видят, что мы не шутим. Стволы для понта, ножи для дела" Lock, Stock & Two Smoking Barrels




Ранг: 500.5 (!), 8thx
Активность: 0.230
Статус: Участник

Создано: 24 ноября 2005 16:34
· Личное сообщение · #10

Ara пишет:
Не совсем понятно, что имелось ввиду... Что мы найдем в этом заголовке, "разобрав" его?

Адрес таблицы экспортов

-----
"Пусть видят, что мы не шутим. Стволы для понта, ножи для дела" Lock, Stock & Two Smoking Barrels




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

Создано: 24 ноября 2005 17:58
· Личное сообщение · #11

Если есть возможность, найди выпуск "Хакер" за август 2005го. Там есть неплохая статейка на эту тему, правда не на асме, а на С++, но идею имхо можно заюзать...



Ранг: 4.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 25 ноября 2005 15:45
· Личное сообщение · #12

Спасибо всем за ответы. Тему можно закрыть.


 eXeL@B —› Основной форум —› Виртуальные адреса WinAPI
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати