Показать сообщение отдельно

  #7  
Старый 12.11.2007, 00:20
Flame of Soul
Участник форума
Регистрация: 25.05.2007
Сообщений: 290
Провел на форуме:
1740746

Репутация: 435
Отправить сообщение для Flame of Soul с помощью MSN
Lightbulb

Простите если примете за флуд, то что я сейчас напишу ниже взято с нескольких книжек, так что то что тут написано неотноситься к моим заслугам ни как.
Привожу это для тех кто возможно когда-то столкнеться с такой же проблемой как и я.
Спасиба GlOFF за прекрасную подсказку: вот держи поцелуй и +сиков поставлю когда снова разрешат...

Цитата:
2) Зная адресс загрузки, анализируем ядро, как обычный PE-файл, т.е. ддос заголовок, потом PE заголовок, потом переходим в директорию экспорта и получаем адресса необходимых нам процедур, расположенных в ядре.
Detour patching - внедрение обходного пути, позволяя передать управление за пределы функции.

1) Изменение пути прохождения выполнения программы.
Производиться захват 2-х функций ядра - SeAccessCheck и NtDeviceIoControlFile ? самое главное нам необходимо найти эту функцию в дебрях памяти. Но с этими функциями проще так как они экспортируються ядром, следовательно можно найти их адресаотсканировав заголовок PE-файла(что и предложил мне мой любимчик GlOFF), но оказываеться есть более пикантный способ))). Но есть и пара проблем:
a) Выравнивание инструкций (не все инструкции одинаковы в длинне) например JUMP бывает длинной до 7 байт, а PUSH может и 1 байт

байты оригинальной функции


| 55 | 8B | EC | 53 | 33 | DB | 38 | 5D | 24
PUSH MOV...................PUSH XOR CMP


А этот код надо вставить


| EA | AA | AA | AA | AA | 08 | 00 | |
FAR JMP


Как видим последние ячейки не забиты, но ктото очень давно, явно симпатичный русский парень придумал NOP коорая нам позволяет их просто побайтно забить



| EA | AA | AA | AA | AA | 08 | 00 | 90 | 90
FAR JMP............................NOP NOP


Если не сделать этого то система падет)))) (инфо для самых вредных)

2) Проверка версии функции (заранее)
Делаеться для того чтобы убедиться того ли мы парня (простите) ту ли мы функцию пытаемся заарканить под венец.
В данном примере находиться сначала указатель на функцию, а потом побайтовое сравнение значений.(находим это с помощью SoftICE)
И незабываем про длинну последовательности по сравниваниу функций, одна имеет длинну 8 а другая 9 байт.
NTSTATUS CheckFunctionBytesDeviceIOControlFile()
{
int i=0;
char *p=(char *)NTDeviceIOControlFile;
//начало функции DeviceIOControlFile
//должно быть
//55 PUSH EBP
//88EC MOV EBP. ESP
//6A01 PUSH 01

char c[] - {0x55. 0x8B. 0xEC. 0x6A. 0x01. 0xFF. 0x75. 0x2C};
while(i<8)
{
DBGPrint(" - 0x202X". (unsignet char)p[i]);
if(p[i] != c[i])
{
return STATUS_UNSUCCESSFUL;
}
i++;
}
return STATUS_SUCCESS;
}

NTSTATUS CheckFunctionBytesSeAccessCheck()
{
int i=0;
char *p = (char *)SeAccessCheck;

// Начало функции SeAccessCheck
// должно быть:
//55 PUSH EBP
//88EC MOV EBP. ESP
//53 PUSH EBX
//33DB CMP [EBP+24]. BL

char c[] - {0x55. 0x8B. 0xEC. 0x53. 0x33. 0xDB. 0x5D. 0x24};
while(i<9)
{
DBGPrint(" - 0x202X". (unsignet char)p[i]);
if(p[i] != c[i])
{
return STATUS_UNSUCCESSFUL;
}
i++;
}
return STATUS_SUCCESS;
}



3) Исполнение удаленных инструкций

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

//голые функции не имеют порога и эпилога
//здесь они применяються как цепь для интсрукций гото (goto)

_declspec(naked) my_function_detour_seaccesscheck()
{
_asm
{
// выполняем потерянные инструкции
push ebp
mov ebp. esp
push ebx
xor ebx. ebx
cmp [ebp+24. b]

// возврат в захваченную инструкцию
// на следующую инструкцию за инструкцией перехода

_emit 0xEA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0x08
_emit 0x00
}
}

// прежде чем внедрить обход функцию поместим в область неменяемой памяти

_declspec(naked) my_function_detour_ntdeviceiocontrolfile()
{
_asm
{
// выполняем потерянные инструкции
push ebp
mov ebp. esp
push 0x01
push [ebp+0x2C]

// возврат в захваченную инструкцию
// на следующую инструкцию за инструкцией перехода
// нам нужен дальний переход

_emit 0xEA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0x08
_emit 0x00
}
}


4) Неперемещаемый пул памяти

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

5) изменение адресов во время выполнения программы

Если кто обратил внимание 0xAAAAAAAA И 0x11223344 это нерабочие адреса, сделано это для того чтобы когда код обхода будет внедрен мы могли их с радостью изменить, это незя было сделать раньше так значения этих адресов можно получить только во время исполнения программы.
Остаеться добаить только то, что дальше следует изменение этих адресов путем вписывания кода поверх оригинальных иструкций, выравнивания функции и использования этих адресов.

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

Тему думаю можно закрывать, а на счет удаления вам решать господа модераторы, всем спасибо!!!
 
Ответить с цитированием