информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Spanning Tree Protocol: недокументированное применениеСтрашный баг в WindowsГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Microsoft Authenticator прекращает... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
[Win32] знакомая картина... 06.11.01 09:27  Число просмотров: 1012
Автор: z0 <z0> Статус: Member
<"чистая" ссылка>
посмотрел на структуру описания процесса и вспомнил, как сам такое рисовал

тут фишка в чем - эти штучки очень охотно меняются даже не в версиях а в билдах
так что эти знания скорее академические, толку с них мало
да что говорить - был такой интерфейс ядра int2e, статьи про него писали, исследования и где он сейчас - вызов доступен только с PL0 (начиная с какого-то SP NT4)
так что программерам я сочуствую - все-таки НАДО делать так как микрософт разрешил, шаг влево - шаг вправо - все потом переделывать
<programming>
[Win32] Может кому понадобится :) Про объекты handles. 06.11.01 08:59  
Автор: AAT Статус: Незарегистрированный пользователь
<"чистая" ссылка>
"The term 'handle' in this text refers to handles to the internel kernel32 objects, which are usually cast as type HANDLE. These objects are process related objects like processes, threads, mutexes, semaphores, sockets, files etc. Basically any handle you can close with CloseHandle(). This does NOT include GDI objects, things like HPEN, HDC, HBITMAP etc, they have almost nothing to do with kernel32 objects.

A handle, within the context of a process, is supposedly (not documented by Microsoft) the index into the processes' handle table of the entry which contains the info about the object the handle references. The handle table is a DWORD representing the number of entries in the array followed by an array of handle entries. A handle entry is a DWORD representing the access flags for the entry followed by a pointer to the actual object in memory.

typedef struct _HANDLE_TABLE
{
DWORD cEntries; // Max number of handles in table
HANDLE_TABLE_ENTRY array[1]; // An array (number is given by cEntries)
} HANDLE_TABLE, *PHANDLE_TABLE;

typedef struct _HANDLE_TABLE_ENTRY
{
DWORD flags; // Valid flags depend on what type of object this is
PVOID pObject; // Pointer to the object that the handle refers to
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;

A process ID is actually a pointer to the process structure containing the process information, xor'd with an 'obsfucator'. There are several algorythms I've seen to get this value. I'm using my own which doesn't use any undocumented calls, by calling GetCurrentProcessId() in ring 3, passing that value to a VxD which calls VWIN32_GetCurrentProcessHandle (which returns the unobfuscated pointer to the current PDB) and xor'ing the two to get the 'obsfucator' which is returned to ring 3.

A reasonable method for obtaining this value that does not use a VxD (thanks dd!) is:


DWORD _dw = 0, _dwCurProcId = GetCurrentProcessId();
__asm {
mov eax,dword ptr fs:[18h]
mov eax,dword ptr [eax+30h]
mov ebx,eax
xor ebx,dword ptr [_dwCurProcId]
mov dword ptr [_dw],ebx
};
Unobsfucator = _dw;


A process database structure (PDB) contains all the info about an active process, and is in fact one of the standard 17 types of kernel32 objects.


typedef struct _PROCESS_DATABASE
{
DWORD Type; // 00h KERNEL32 object type (5)
DWORD cReference; // 04h Number of references to process
DWORD un1; // 08h
DWORD someEvent; // 0Ch An event object
DWORD TerminationStatus; // 10h Returned by GetExitCodeProcess
DWORD un2; // 14h
DWORD DefaultHeap; // 18h Address of the process heap
DWORD MemoryContext; // 1Ch pointer to the process's context
DWORD flags; // 20h
DWORD pPSP; // 24h Linear address of PSP?
WORD PSPSelector; // 28h
WORD MTEIndex; // 2Ah
WORD cThreads; // 2Ch
WORD cNotTermThreads; // 2Eh
WORD un3; // 30h
WORD cRing0Threads; // 32h number of ring 0 threads
HANDLE HeapHandle; // 34h Heap to allocate handle tables out of
// This seems to always be the KERNEL32 heap
DWORD W16TDB; // 38h Win16 Task Database selector
DWORD MemMapFiles; // 3Ch memory mapped file list (?)
PENVIRONMENT_DATABASE pEDB; // 40h Pointer to Environment Database
PHANDLE_TABLE pHandleTable; // 44h Pointer to process handle table
struct _PROCESS_DATABASE * ParentPDB; // 48h Parent process database
PMODREF MODREFlist; // 4Ch Module reference list
DWORD ThreadList; // 50h Threads in this process
DWORD DebuggeeCB; // 54h Debuggee Context block?
DWORD LocalHeapFreeHead; // 58h Head of free list in process heap
DWORD InitialRing0ID; // 5Ch
CRITICAL_SECTION crst; // 60h
DWORD un4[2]; // 78h
DWORD pConsole; // 84h Pointer to console for process
DWORD tlsInUseBits1; // 88h // Represents TLS indices 0 - 31
DWORD tlsInUseBits2; // 8Ch // Represents TLS indices 32 - 63
DWORD ProcessDWORD; // 90h
struct _PROCESS_DATABASE * ProcessGroup; // 94h
PMODREF pExeMODREF; // 98h pointer to EXE's MODREF
DWORD TopExcFilter; // 9Ch Top Exception Filter?
DWORD BasePriority; // A0h Base scheduling priority for process
DWORD HeapOwnList; // A4h Head of the list of process heaps
DWORD HeapHandleBlockList;// A8h Pointer to head of heap handle block list
DWORD pSomeHeapPtr; // ACh normally zero, but can a pointer to a
// moveable handle block in the heap
DWORD pConsoleProvider; // B0h Process that owns the console we're using?
WORD EnvironSelector; // B4h Selector containing process environment
WORD ErrorMode; // B6H SetErrorMode value (also thunks to Win16)
DWORD pevtLoadFinished; // B8h Pointer to event LoadFinished?
WORD UTState; // BCh
} PDB, *PPDB;


All kernel32 objects (basically, anything you can get a handle for) share a common header: The first DWORD represents the object type, and the second DWORD represents the usage count (the number of handles referencing the object). The types for the object types are defined as:


K32OBJ_SEMAPHORE 0x1
K32OBJ_EVENT 0x2
K32OBJ_MUTEX 0x3
K32OBJ_CRITICAL_SECTION 0x4
K32OBJ_PROCESS 0x5
K32OBJ_THREAD 0x6
K32OBJ_FILE 0x7
K32OBJ_CHANGE 0x8
K32OBJ_CONSOLE 0x9
K32OBJ_SCREEN_BUFFER 0xA
K32OBJ_MEM_MAPPED_FILE 0xB
K32OBJ_SERIAL 0xC
K32OBJ_DEVICE_IOCTL 0xD
K32OBJ_PIPE 0xE
K32OBJ_MAILSLOT 0xF
K32OBJ_TOOLHELP_SNAPSHOT 0x10
K32OBJ_SOCKET 0x11


To get the process ID of a process referenced by a process handle, I use GetCurrentProcessId() ^ Obsfucator to get a pointer to the current processes database structure. This structure contains a pointer at offset 44h which points to the handle table. All the objects begin with a DWORD indicating the type of the object, followed by a DWORD representing the usage count (the number of handles refering to this object). The handle should be an index into this array, and the process ID for the process refered to by the handle should be the pointer to the object xor'ed with Obsfucator. I'm fairly certain that these pointers (to the objects) are in shared memory, and handles in different processes can point to the same object in shared memory, and that there is one PDB object for each process, and that handles in different processes which refer to the same process will point to the same process structure.

On Win98, and on Win95 with some kernel upgrade, the format of the internal objects seems to have changed. Instead of the process object beginning with the DWORD 5 followed by the usage count, it seems to begin with a WORD (0x0006) followed by a WORD for the usage count, followed by a pointer to something I haven't identified.


typedef struct _newPDB
{
WORD Type;
WORD Usage;
PVOID SomePointer;
...


Most of the rest of the structure seems to be the same, but I think something may have changed with the handle table as well. It seems that a handle is no longer a straight index into the array, it is four times the array index. To tell which form of the kernel object I am looking at, I check the HIWORD of the Type DWORD for being 0. Since all the K32OBJ Type constants are well below 0xffff, the the HIWORD will always be 0 if it is set to one of these values, but in the new format the HIWORD represents the usage count, which will always be greater than 0. So, to get to a process ID for a handle in any given process, I use the following:


DWORD GetProcessID(HANDLE hProcess, DWORD pid)
{
PPDB ppdb = NULL, ppdb2 = NULL;
DWORD index;

// check for special 'current process' value
if ((DWORD)hProcess == 0x7fffffff) return pid;
// initialize 'Obsfucator' by whatever method
if (Unobsfucator == 0) InitUnobsfucator();
if (Unobsfucator == 0) return 0;

ppdb = (PPDB)(pid ^ Unobsfucator); // get pointer to PDB
if (ppdb == NULL) return 0; // make sure not null pointer

// check if new format or old format
if (HIWORD(ppdb->Type) == 0) // old format
index = (DWORD)hProcess; // handle is straight index
else // new format
index = (DWORD)hProcess/4; // handle is index * 4

// make sure index is valid
if (index > ppdb->pHandleTable->cEntries) return 0;
// make sure not empty entry
if (ppdb->pHandleTable->array[index].pObject == NULL) return 0;
// point ppdb2 to object
ppdb2 = (PPDB)ppdb->pHandleTable->array[index].pObject;
// check for process object
if (LOWORD(ppdb2->Type) != LOWORD(ppdb->Type)) return 0;

return (DWORD)ppdb2 ^ Unobsfucator;
}

The new kernel32 object types that I've identified are:
Semaphore: 0x01
Event: 0x02
Mutex: 0x03
Critical section?
Fiber?
Process: 0x06
Thread: 0x07
File: 0x08
Change notify: 0x09
Console in: 0x0a
New console related type?
Screen buffer: 0x0c
File mapping: 0x0d
Serial: 0x0e
VxD handle: 0x0f
Unnamed Pipe: 0x10
Mailslot: 0x11
Toolhelp Snapshot: 0x12
Socket: 0x13
Waitable Timer?
Job? (Win2k)
Tape drive? (Win2k)


If you know anything about this change in the internal structure format such as what upgrade actually caused this change in the kernel, or any of the new formats, or anything else that may have changed also, please share the knowledge! "
[Win32] знакомая картина... 06.11.01 09:27  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка>
посмотрел на структуру описания процесса и вспомнил, как сам такое рисовал

тут фишка в чем - эти штучки очень охотно меняются даже не в версиях а в билдах
так что эти знания скорее академические, толку с них мало
да что говорить - был такой интерфейс ядра int2e, статьи про него писали, исследования и где он сейчас - вызов доступен только с PL0 (начиная с какого-то SP NT4)
так что программерам я сочуствую - все-таки НАДО делать так как микрософт разрешил, шаг влево - шаг вправо - все потом переделывать
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach