![]() |
eXeL@B —› Основной форум —› Виртуальные адреса WinAPI |
Посл.ответ | Сообщение |
|
Создано: 22 ноября 2005 17:39 · Личное сообщение · #1 |
|
Создано: 22 ноября 2005 17:45 · Личное сообщение · #2 |
|
Создано: 22 ноября 2005 17:59 · Личное сообщение · #3 b0lt пишет: где взять в Интернете информацию об адресах. ![]() Прикольно. А информацию о PE-формате ты читал? А статьи на васме? Как минимум надо почитать Рихтера. Суть в том, что dll (а API - это не что иное как экспорт dll) не имеют абсолютно постоянного адреса. И даже не смотря на то, что база у них постоянная, адреса будут разные для других версий, компов, систем, дров и т.п. ----- Всем привет, я вернулся ![]() |
|
Создано: 24 ноября 2005 15:45 · Личное сообщение · #4 |
|
Создано: 24 ноября 2005 15:56 · Личное сообщение · #5 |
|
Создано: 24 ноября 2005 16:19 · Личное сообщение · #6 Ara пишет: А как вызвать их, не используя таблицу импорта? Есть два варианта: 1) разобрать заголовок системной библиотеки и найти их там ![]() 2) использовать конст. адрес - естесно работать будет только на той же версии ОС ![]() ----- "Пусть видят, что мы не шутим. Стволы для понта, ножи для дела" Lock, Stock & Two Smoking Barrels ![]() |
|
Создано: 24 ноября 2005 16:22 · Личное сообщение · #7 |
|
Создано: 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 ![]() |
|
Создано: 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 ![]() |
|
Создано: 24 ноября 2005 16:34 · Личное сообщение · #10 |
|
Создано: 24 ноября 2005 17:58 · Личное сообщение · #11 |
|
Создано: 25 ноября 2005 15:45 · Личное сообщение · #12 |
![]() |
eXeL@B —› Основной форум —› Виртуальные адреса WinAPI |
Эта тема закрыта. Ответы больше не принимаются. |