Сейчас на форуме: vasilevradislav, tyns777, zombi-vadim (+3 невидимых)

 eXeL@B —› Программирование —› Перехват функций Io и Ps в Ring0
Посл.ответ Сообщение


Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 30 января 2008 21:24
· Личное сообщение · #1

Доброе время суток.

Проблема такова. Пишу свой драйвер. Пытался в нём перехватить функцию IoGetCurrentProcess.
В результате драйвер запускается, якобы перехатывает, но ниодного вызова этой функции не фиксирует?
Проверил на функции к прмеру ZwQuerySystemInformation там всё работает, каждый вызов фиксируется, а функции IoGetCurrentProcess, IoGetCurrentProcessId и PsGetCurrentProcessId не вызываются. Почему?
Может они вызываются особым образом или их нельзя перехватывать?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 30 января 2008 21:41
· Личное сообщение · #2

Дык перехватывает или нет? Как хук то ставишь? Хоть что-нить бы в студию предоставил. Сайс возьми, потрассируй дров, разберись.



Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 31 января 2008 03:47
· Личное сообщение · #3

Дык она просто не вызывается

DDK пишет:
Comments
This routine is identical to PsGetCurrentProcess.




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

Создано: 31 января 2008 12:02
· Личное сообщение · #4

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




Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 31 января 2008 12:16
· Личное сообщение · #5

undb пишет:
Во первых в каком контексте ты это перехватил , там и будет у тебя работать

А почему тогда перехват ZwQuerySystemInformation работает для всех контекстов? Не хотел давать исходники, т.к. сейчас начнётся флуд по поводу стиля и выбранного языка программирования. Ну да Бог с ним. Вот основное:

procedure HookFunctions(ADriverObject: PDriverObject);
begin
DbgPrint('HookingEnable()');

asm //disable WP bit
mov eax, cr0 //move CR0 register into EAX
and eax, not 000010000h //disable WP bit
mov cr0, eax //write register back
end;

OldZwQuerySystemInformation := TZwQuerySystemInformation(InterlockedExchange(SystemService(ZwQuerySys temInformationAddr), LONG(@NewZwQuerySystemInformation)));
OldIoGetCurrentProcess := TIoGetCurrentProcess(InterlockedExchange(SystemService(IoGetCurrentPro cessAddr), LONG(@NewIoGetCurrentProcess)));

asm //enable WP bit
mov eax, cr0 //move CR0 register into EAX
or eax, 000010000h //enable WP bit
mov cr0, eax //write register back
end;
end;

function NewIoGetCurrentProcess: PEPROCESS; stdcall;
begin
DbgPrint('IoGetCurrentProcess');
Result := OldIoGetCurrentProcess;
end;

function NewZwQuerySystemInformation(SystemInformationClass: ULONG; SystemInformation: PVOID; SystemInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;
begin
DbgPrint('ZwQuerySystemInformation');
Result := OldZwQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
end;


Когда это всё запускается, то в DbgView.exe видны вызовы ZwQuerySystemInformation, а IoGetCurrentProcess нет.




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 31 января 2008 14:57
· Личное сообщение · #6

Дык ты чо творишь то? SystemService()-это ж из SDT таблицы хук функи, походу. А твоей функи нет в СДТ. Сплайсинг юзать надо =\




Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 31 января 2008 15:26
· Личное сообщение · #7

Ну и на этом уже спасибо =).
Archer пишет:
Дык ты чо творишь то? SystemService()-это ж из SDT таблицы хук функи, походу. А твоей функи нет в СДТ.

А как я могу узнать какие функции представлены в SDT, а какие нет? Можете ссылкой ткнуть.



Ранг: 110.7 (ветеран)
Активность: 0.070
Статус: Участник
~ tPORt ~

Создано: 31 января 2008 18:04
· Личное сообщение · #8

--> шлёп <-- http://www.wasm.ru/pub/21/files/sysservice.rar




Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 31 января 2008 18:21 · Поправил: SLayer
· Личное сообщение · #9

Ура, LazzY спасибо.

Вернёмся к сплайсингу.
Имеем функцию

function PsGetCurrentProcess: PEPROCESS; stdcall; external NTOSKrnl name '_PsGetCurrentProcess@0';

Смотрим в дизассемблере код этой ф-ции:

.text:000110A4 PsGetCurrentProcess proc near
.text:000110A4 jmp ds:__imp_PsGetCurrentProcess
...
...
.idata:000110EC extrn __imp_PsGetCurrentProcess:dword


Т.е. это ничто иное как некий JMP на некую ф-цию, смотрим то куда мы попадаем:

HEX: E8 E2 4E 80 F8 DF 4F 80

что соответсвует:

ASM: call 0F8804FB6

т.е. я так понимаю что тут по этому адресу и нужно сплайсить? Если так, то не могу разобраться с тем где в указанной выше HEX последовательности лежит собственно адрес 0F8804FB6 ? Как из HEX вытащить этот адрес?



Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 31 января 2008 18:28
· Личное сообщение · #10

Гарри Неббета лучше поищи. А поскольку набор функций увеличивается со временем, грузи в ида и смотри _KiServiceTable.

ЗЫ: для полноты картины поправлю себя - PsGetCurrentProcess и IoGetCurrentProcess могут быть физически реализованы как одной, так и 2мя разными (даже в реализации) функциями.




Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 31 января 2008 18:38 · Поправил: SLayer
· Личное сообщение · #11

Вопрос про Hex отпадает.
Вот asm значение одной и той же последовательности в зависимости от того, где она выполняется.
000000ED: E800000000 call 0000000F2 ---↓ (4)
000000F2: E800000000 call 0000000F7 ---↓ (5)
000000F7: E800000000 call 0000000FC ---↓ (6)
000000FC: E800000000 call 000000101 ---↓ (7)


S_T_A_S_, Гарри Неббета уже ищу.




Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 31 января 2008 18:55 · Поправил: SLayer
· Личное сообщение · #12

Как-то туго ищется, только купить нахоится Гэри Неббета.
Я конечно и купить не против, но нужно сейчас, а книга прийдёт потом...

Помогите плиз, мож у кого есть.




Ранг: 527.7 (!), 381thx
Активность: 0.160.09
Статус: Участник
Победитель турнира 2010

Создано: 31 января 2008 20:08
· Личное сообщение · #13

SLayer
--> Gary Nebbett Windows NT, 2000 Native API Reference <-- http://dump.ru/files/o/o9303217327/

-----
127.0.0.1, sweet 127.0.0.1




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

Создано: 31 января 2008 20:39 · Поправил: Great
· Личное сообщение · #14

Эх вы.

SLayer
1) я перехватывал IoGetCurProc и могу дать сорс. все работает чудесно

2) undb
>> Во первых в каком контексте ты это перехватил , там и будет у тебя работать.
что за бред, мистер) системное АП одно, за вычетом пространства сессии, где лежит win32k.
читайте руссиновича, или, на крайняк, мою статью про менеджмент памяти.

3) SLayer
>> А как я могу узнать какие функции представлены в SDT, а какие нет? Можете ссылкой ткнуть.
Все Nt* функции. Io*, Ke*, Ps*, Ob*, Rtl* и прочее не представлено в SSDT.
Они экспортируются ядром, следовательно, нужно сплайсить ее в ядре.

4) S_T_A_S_
Садись, два. Обе функции указывают на одну точку входа:

.text:004174D2 ; Exported entry 383. IoGetCurrentProcess
.text:004174D2 ; Exported entry 854. PsGetCurrentProcess
.text:004174D2
.text:004174D2 ; =============== S U B R O U T I N E =======================================
.text:004174D2
.text:004174D2
.text:004174D2 ; int __stdcall PsGetCurrentProcess()
.text:004174D2 public _PsGetCurrentProcess@0
.text:004174D2 _PsGetCurrentProcess@0 proc near




Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 31 января 2008 23:46
· Личное сообщение · #15

Great, с удовольствием поразбираюсь в сорсах. Если можно, плиз...
Отдельный сенкс to OKOB.



Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 01 февраля 2008 05:20
· Личное сообщение · #16

Great
Учитель, взгляните же на старые ядра ;) Там даже по разному имполементировано: через fs и захардкоженный адрес.



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

Создано: 01 февраля 2008 09:08
· Личное сообщение · #17

Я не думаю что его интересуют щас старые ядра =)
Ты бы еще 9х вспомнил



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

Создано: 01 февраля 2008 10:00 · Поправил: Great
· Личное сообщение · #18


#include <ntifs.h>

void probe_read(void* f)
{
ULONG a = *(ULONG*)f;
}

bool splicefunc(void* func, void* hook, void* buffer, int nbytestocopy)
{
if( KeGetCurrentIrql() >= DISPATCH_LEVEL )
return false;

// Load from swap
probe_read(func);
probe_read(hook);
probe_read(buffer);

// IF=0
__asm pushfd;
__asm cli;

memcpy(buffer, func, nbytestocopy);

((BYTE*)func)[0] = 0xE9;
*(ULONG*)((ULONG)func+1) = (ULONG)hook - (ULONG)func - 5;

__asm popfd;

return true;
}

BYTE iogetcpbuf[10];

PVOID modbuff = NULL;


BOOLEAN
NewIoGetCurrentProcess(
ULONG ReturnAddress,
PEPROCESS* Process
)
{
//
// функционал нового обработичика. возвращает TRUE если надо вернуть оригинальный процесс
// или FALSE если нужно подменить результат.
//

return true;
}

//
// новый обработчик IoGetCurProc, вызывает NewIoGetCurrentProcess( см выше)
// и возвращает оригинальный блок EPROCESS если та вернула TRUE или
// значение, возвращенное NewIoGetCurProcess во втором аргументе, если та вернула FALSE
//

__declspec(naked)
PEPROCESS
__NewIoGetCurrentProcess(
VOID
)
{
__asm
{
mov eax, [esp] ; return address

push esi

; reserve dword
push 0
mov esi, esp

push esi ; reserved dword
push eax ; return address
call NewIoGetCurrentProcess

test al,al ; returns 1 if call should be passed to old handler.
jz _ret

add esp, 4
pop esi

lea edx, iogetcpbuf
jmp edx

_ret: mov eax, [esi]
add esp, 4
pop esi
retn
}
}


// Driver entry point
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
KdPrint(("[~] DriverEntry()\n"));

// Splice IoGetCurProc
UNICODE_STRING uiogetcp;
void* iogetcp;
RtlInitUnicodeString( &uiogetcp, L"IoGetCurrentProcess" );
iogetcp = MmGetSystemRoutineAddress( &uiogetcp );

if( splicefunc(iogetcp, __NewIoGetCurrentProcess, iogetcpbuf, sizeof(iogetcpbuf)) )
{
KdPrint(("Spliced\r\n"));
}
else
{
KdPrint(("Not spliced\r\n"));
}

return STATUS_SUCCESS;
}





Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 01 февраля 2008 12:36
· Личное сообщение · #19

Ознакомился, вроде всё понятно кроме одного:

// Load from swap
probe_read(func);
probe_read(hook);
probe_read(buffer);


Зачем это делается, разве при memcpy эти данные не загрузятся из SWAP? Или загрузка обрабатывается через прерывание которое мы запрещаем?



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

Создано: 01 февраля 2008 16:31
· Личное сообщение · #20

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




Ранг: 90.3 (постоянный), 1thx
Активность: 0.030
Статус: Участник

Создано: 01 февраля 2008 17:51
· Личное сообщение · #21

Ясно, огромное спасибо всем откликнувшимся. Отдельное ПАСИБА to Great.
Тема закрыта.


 eXeL@B —› Программирование —› Перехват функций Io и Ps в Ring0
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати