![]() |
![]() |
![]() |
![]() |
![]() |
|
|
Кратчайший путь нахождения адреса KERNEL32
Оригинальный текст: Billy Belcebu/DDT
.586p ; Ну... просто ради прикола.
.model flat ; Hehehe я люблю 32 bit фишки ;)
.data ; Некоторые данные
; (для нужд TASM32/TLINK32)
db 00h
.code
start:
mov eax,[esp] ; Теперь в EAX должно быть BFF8XXXXh
; (если система w9X)
ret ; Способ завершить процесс ;)
end start
Вроде просто. Мы имеем в EAX число приблизительноравное BFF8XXXX (XXXX это ненужные циферки, потому что нет нужды знать их точно, не надоедайте мне с такими простыми вещами, как эта ;). Win32 платформы обычно все вырывнивают на границу страницы, мы можем искать заголовок KERNEL'а на любой странице, он просто находится в начале страницы, и мы с легкостью можем это проверить. И когда мы найдем заголовок PE мы будем знать адрес KERNEL32. Хрмм, предел для поиска мы могли бы установить в 50h страниц. Хехе, не беспокойтесь. Пример последует ;)
.586p
.model flat
.data
extrn ExitProcess:PROC
db 0
kernel equ 0BFF70000h
imagebase equ 000400000h
limit equ (50000h/1000h)
;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·;
; Бесполезные и несущественные данные :) ;
;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·;
.code
test:
call delta
delta:
pop ebp
sub ebp,offset delta
mov esi,[esp]
and esi,0FFFFF000h ; AND ESI,-1000
call GetK32
push 00000000h
call ExitProcess
;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·;
; Блин, я предполагаю что ты немного умеешь кодить на ASMе, еще я предпола-;
; гаю что ты знаешь, что первый блок инструкций - для получения смещения, ;
; (не нужно в этом примере, но всеравно мне нравиться делать это похожим на;
; вирусный код). Второй блок - это как раз то, что нас интересует. Мы имеем;
; в ESI адрес, откуда "вызвано" наше приложение, этот адрес указывает нам ;
; ESP (если мы конечно не трогали стек после загрузки программы). Вторая ;
; команда, AND, для выравния адреса, с которого нас вызвали, на границу ;
; страницы. Мы вызовем нашу процедурку, и после этого завершим процесс ;) ;
;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·;
GetK32:
__1: cmp byte ptr [ebp+K32_Limit],00h
jz WeFailed
cmp word ptr [esi],"ZM"
jz CheckPE
__2: sub esi,1000h
dec byte ptr [ebp+K32_Limit]
jmp __1
;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·;
; Первым делом мы проверим не превысили ли мы предел наших 50 страниц.После;
; После этого мы проверим начало страницы на предмет сигнатуры MZ (как это ;
; должно быть), если она там - проверим на предмет PE заголовка. Если ниче-;
; го не совпало - вычитаем из адреса 1 страницу (1000h байт, 4096d байт), ;
; уменьшим значение предела для поиска страниц и поищем снова... ;
;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·;
CheckPE:
mov edi,[esi+3Ch]
add edi,esi
cmp dword ptr [edi],"EP"
jz WeGotK32
jmp __2
WeFailed:
stc
WeGotK32:
xchg eax,esi
ret
K32_Limit dw limit
;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·;
; Мы взяли число по смещению 3Ch из MZ заголовка (указывающий RVA адрес где;
; начинается PE заголовок), мы устаканили его с адресом страницы, и если по;
; этому смещению стоят буковки PE, я думаю мы его нашли... неужели мы его ;
; нашли! ;) ;
;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·;
end test
|