![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Кратчайший путь нахождения адреса 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 ![]()
|