PDA

Просмотр полной версии : EncodePointer


0x0c0de
19.11.2008, 21:39
[EncodePointer].

*my system: Windows XP SP3 [тестила и на win xp2 то же]

Пишу сию небольшую заметочку про EncodePointer. Статьей это => не является.

Некогда довелось мне заниматься VEH и писать плаг под Olly, перебирающий все обработчики в дебажимом процессе. И функция EncodePointer создала мне на системах с SP (в виндах без СП, как выяснилось этой функции нет вовсе) некоторые проблемы и при получении адреса вех-обработчика я извращалась с трейсом.
Как вы можете прочесть в msdn


The EncodePointer function encodes the specified pointer. Encoded pointers can be used to provide another layer of protection for pointer values.
PVOID EncodePointer(
PVOID Ptr
);


Здесь все предельно понятно. И вех-обработчики в системах с SP как раз-таки подвергаются такой обработке.
Функция шифрует адрес Ptr неким значением, уникальным для каждого процесса. Теперь попробуем разобраться в общих чертах как оно работает и откуда это значение берется.

Код функции RtlEncodePointer


7C9133DF ntdll.RtlEncodePointer /$ 8BFF MOV EDI,EDI ; ntdll.7C910208
7C9133E1 |. 55 PUSH EBP
7C9133E2 |. 8BEC MOV EBP,ESP
7C9133E4 |. 51 PUSH ECX ; ntdll.7C9164EE
7C9133E5 |. 6A 00 PUSH 0 ; /pReqsize = NULL
7C9133E7 |. 6A 04 PUSH 4 ; |Bufsize = 4
7C9133E9 |. 8D45 FC LEA EAX,[LOCAL.1] ; |
7C9133EC |. 50 PUSH EAX ; |Buffer = NULL
7C9133ED |. 6A 24 PUSH 24 ; |InfoClass = 24 (36.)
7C9133EF |. 6A FF PUSH -1 ; |hProcess = FFFFFFFF
7C9133F1 |. E8 EAA3FFFF CALL ZwQueryInformationProcess ; \ZwQueryInformationProcess
7C9133F6 |. 8B45 FC MOV EAX,[LOCAL.1]
7C9133F9 |. 3345 08 XOR EAX,[ARG.1]
7C9133FC |. C9 LEAVE
7C9133FD \. C2 0400 RET 4


То есть мы вызываем ZwQueryInformationProcess с InfoClass = SystemContextSwitchInformation (36) и ксорим с адресом, переданным функции в качестве аргумента. Ясное дело, что в ntdll более нам делать нечего, надо спускаться в ядро и смотреть откуда берется этот уникальный дворд.
Загружаем ntoskrnl.exe в IDA и смотрим функцию NtQueryInformationProcess. Весь код функции, приводить, конечно, не буду, ибо нет смысла. Выделю только основные моменты. Найдем то место в функции, которое обрабатывает InfoClass = SystemContextSwitchInformation = 36 = 0x24



PAGE:0049CEFA mov eax, [ebp+ProcessInformationClass]
PAGE:0049CEFD push 16h
PAGE:0049CEFF pop ecx
PAGE:0049CF00 cmp eax, ecx
PAGE:0049CF02 jg loc_4A0E7F
PAGE:0049CF08 jz loc_4A1379


Ну тут ясно, что в eax в нашем случае (0049CF00) будет 24h, а в ecx 16h. Значит нам по адресу loc_4A0E7F.


loc_4A0E7F: ; CODE XREF: NtQueryInformationProcess(x,x,x,x,x)+53
PAGE:004A0E7F add eax, -17h ; switch 15 cases
PAGE:004A0E82 cmp eax, 0Eh
PAGE:004A0E85 ja Invalid_InfoClass ; default
PAGE:004A0E8B jmp ds:off_4A18CA[eax*4] ; switch jump


Мысленно(или на калькуляторе %) ) eax(==24h) +(-17h). Получаем 0D. Далее
Выполняем джамп (при eax = 0d)


PAGE:004A0E8B jmp ds:off_4A18CA[eax*4]


Попадаем сюда


PAGE:004A0E92 SystemContextSwitchInformation_0: ; DATA XREF: PAGE:off_4A18CA o
PAGE:004A0E92 cmp edi, edx ; case 0x24
PAGE:004A0E94 jnz InfoLengthMismatch
PAGE:004A0E9A cmp [ebp+Handle], 0FFFFFFFFh
PAGE:004A0E9E jnz not_current_process



Обратите внимание на сделанное мной обозначение. То есть, если передан хендл не текущего процесса, то


PAGE:004A1578 not_current_process: ; CODE XREF: NtQueryInformationProcess(x,x,x,x,x)+3FEF j
PAGE:004A1578 ; NtQueryInformationProcess(x,x,x,x,x)+46BA j ...
PAGE:004A1578 mov eax, STATUS_INVALID_PARAMETER


Ну оно и верно. Если бы этот дворд можно было получить из другого процесса, было бы странно. Теперь продолжим. Если мы интересуемся своим процессом


PAGE:004A0EA4 mov eax, large fs:124h
PAGE:004A0EAA mov eax, [eax+44h]
PAGE:004A0EAD mov [ebp+var_34], eax
PAGE:004A0EB0 get_dw: ; CODE XREF: NtQueryInformationProcess(x,x,x,x,x)+18E71 j
PAGE:004A0EB0 mov edi, [ebp+PEPROCESS]
PAGE:004A0EB3 add edi, 258h
PAGE:004A0EB9 mov eax, [edi]
PAGE:004A0EBB test eax, eax
PAGE:004A0EBD jz get_time



Некоторым первые строки покажутся очень знакомыми. В eax после их исполнения окажется указатель на структуру EPROCESS текущего процесса. Далее мы добавляем к началу EPROCESS 258h. И берем по этому адресу dword.

Если значение нулевое, то


PAGE:004A0EBB test eax, eax
PAGE:004A0EBD jz get_time


Получаем системное время


PAGE:004B5CF6 get_time: ; CODE XREF: NtQueryInformationProcess(x,x,x,x,x)+400E j
PAGE:004B5CF6 lea eax, [ebp+CurrentTime]
PAGE:004B5CF9 push eax ; CurrentTime
PAGE:004B5CFA call _KeQuerySystemTime@4 ; KeQuerySystemTime(x)
PAGE:004B5CFF mov eax, large fs:_KPRCB
PAGE:004B5D05 mov ecx, [eax+_KPRCB.KeSystemCalls]
PAGE:004B5D0B xor ecx, [eax+_KPRCB.InterruptTime]
PAGE:004B5D11 xor ecx, [ebp+CurrentTime.HighPart]
PAGE:004B5D14 xor ecx, [ebp+CurrentTime.LowPart]
PAGE:004B5D17 xor eax, eax
PAGE:004B5D19 lock cmpxchg [edi], ecx
PAGE:004B5D1D push 4
PAGE:004B5D1F pop edx
PAGE:004B5D20 jmp get_dw

И дубль 2 =) Пробуем снова получить дворд…
Смотрим описание функции KeQuerySystemTime


The KeQuerySystemTime routine obtains the current system time.
VOID
KeQuerySystemTime(
OUT PLARGE_INTEGER CurrentTime
);




Теперь мы знаем откуда берется это значение и можно написать драйвер, который по id процесса будет возвращать уникальный дворд. Использовать NtQueryInformationProcess мы не можем напрямую, поэтому просто осуществим аналогичные действия (начиная с метки get_timе я опустила, ибо лень, могу сказать, что все корректно определяется). И соответственно программа, которая этот драйвер использует. В самом драйвере пишем


ULONG ProcessDwordByProcessId(ULONG piD)
{
ULONG dwDbg;
PEPROCESS cproc;
if(NT_SUCCESS(PsLookupProcessByProcessId(piD,&cproc)))
{
_asm{
mov edi,cproc
add edi,0x258
mov edi,dword ptr[edi]
mov dwDbg,edi
}
return dwDbg;
}
return 0;

}


В вызывающей программе


DWORD GetPrDword(DWORD pID){
//Аргумент - id процесса
DWORD mag=0,BytesReturned=0;
if( !DeviceIoControl(hHandle,IOCTL_GET_PROCESS_DWORD,&pID, 4,&mag,4,&BytesReturned, NULL ))
{
printf("Error in DeviceIoControl\n");
return 0;
}
// возвращаемое значение - process dword
return mag;
}


Скрин

http://img56.imageshack.us/my.php?image=23297865ee9.jpg

Program

http://rapidshare.com/files/165383629/tst.rar.html