перехват апи вызова
От: lc  
Дата: 25.09.06 09:16
Оценка:
мне нужно перехватить вызовы GetClipboardData и SetClipboardData
хочу делать перехват изменением таблицы системных сервисов
посмотрел функции в ida, они вызывают NtUserGetClipboardData и NtUserSetClipboardData, которые и являются заглушками для перехода в режим ядра. для перехвата мне надо получить данные по адресам
NtUserGetClipboardData + 1 байт
NtUserSetClipboardData + 1 байт
там номер сервиса в таблице, но код обоих функций находится в user32.dll и наружу не импортируется.
насколько понимаю надо либо получать эти адреса в юзер моде (GetProcAddress) и слать в драйвер либо реализовать тоже в ядре. отсюда два вопроса:
1. какой аналог у GetProcAddress в ядре ?
2. может есть еще какой способ перехватить эти функции ?
изначально задача состоит в том чтобы отслеживать момент копирования данных из/в буфер обмена
Re: перехват апи вызова
От: wellwell Австралия https://www.softperfect.com
Дата: 25.09.06 09:43
Оценка:
"lc" <38370@users.rsdn.ru> wrote in message news:2127720@news.rsdn.ru...
> изначально задача состоит в том чтобы отслеживать момент копирования данных из/в буфер обмена

А не проще будет через SetClipboardViewer (это правда в user mode).
Posted via RSDN NNTP Server 2.0
Re: перехват апи вызова
От: Аноним  
Дата: 25.09.06 10:07
Оценка:
Здравствуйте, lc, Вы писали:

lc>мне нужно перехватить вызовы GetClipboardData и SetClipboardData

lc>хочу делать перехват изменением таблицы системных сервисов
lc>посмотрел функции в ida, они вызывают NtUserGetClipboardData и NtUserSetClipboardData, которые и являются заглушками для перехода в режим ядра. для перехвата мне надо получить данные по адресам
lc>NtUserGetClipboardData + 1 байт
lc>NtUserSetClipboardData + 1 байт
lc>там номер сервиса в таблице, но код обоих функций находится в user32.dll и наружу не импортируется.
lc>насколько понимаю надо либо получать эти адреса в юзер моде (GetProcAddress) и слать в драйвер либо реализовать тоже в ядре. отсюда два вопроса:
lc>1. какой аналог у GetProcAddress в ядре ?
lc>2. может есть еще какой способ перехватить эти функции ?
lc>изначально задача состоит в том чтобы отслеживать момент копирования данных из/в буфер обмена

В общем так:

1. LdrGetProcedureAddress (оно тебе не поможет, да и не нужно)
2. способов перехвата вызовов ядра только 2а: заменой адресов в SDT и заменой первых 5и байт тела вызова.
в данном случае тебе поможет только первый способ, т.е. тот которым, ты и собирался делать.
второй способ не покатит, потому что адрес вызова ядра всё равно придётся получать через SDT (эти функции из ядра не импортируются)

В общем заменяешь адреса этих вызовов в SDT (смещения для всех виндовсов, если надо, — пиши, вышлю) и готово.
Re[2]: перехват апи вызова
От: lc  
Дата: 25.09.06 10:14
Оценка:
Здравствуйте, wellwell, Вы писали:

W>"lc" <38370@users.rsdn.ru> wrote in message news:2127720@news.rsdn.ru...

>> изначально задача состоит в том чтобы отслеживать момент копирования данных из/в буфер обмена

W>А не проще будет через SetClipboardViewer (это правда в user mode).


мне нужно знать какой процесс вызывает и иметь возможность разрешать запрещать
Re[2]: перехват апи вызова
От: lc  
Дата: 25.09.06 10:17
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, lc, Вы писали:


А>1. LdrGetProcedureAddress (оно тебе не поможет, да и не нужно)

почему не поможет и не нужно ?
разве не удобнее находить адрес вместо того чтобы хардкодить ?
Re[3]: перехват апи вызова
От: Аноним  
Дата: 25.09.06 10:34
Оценка:
Здравствуйте, lc, Вы писали:

lc>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, lc, Вы писали:


А>>1. LdrGetProcedureAddress (оно тебе не поможет, да и не нужно)

lc>почему не поможет и не нужно ?
lc>разве не удобнее находить адрес вместо того чтобы хардкодить ?
Удобнее, но если функция не импортируется, то таким способом ее адрес получть не получится.
Re: перехват апи вызова, что не так ?
От: lc  
Дата: 27.09.06 14:30
Оценка:
проблема с перехватом. делаю так

#pragma pack(1)
typedef struct ServiceDescriptorEntry
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]

_asm cli
OldZwCreateKey = (ZWCREATEKEY)(SYSTEMSERVICE(ZwCreateKey));
OldNtUserSetClipboardData = (NTUSERSETCLIPBOARDDATA)(SYSTEMSERVICE(0x77D50F0D));

SYSTEMSERVICE(ZwCreateKey) = (DWORD) NewZwCreateKey;
SYSTEMSERVICE(0x77D50F0D) = (DWORD) NewNtUserSetClipboardData;
_asm sti


0x77D50F0D адрес NtUserSetClipboardData в user32.dll
для ZwCreateKey и еще нескольких функций из ntdll.dll все работает, для NtUserSetClipboardData — синий экран.
по адресу (PUCHAR)NtUserSetClipboardData + 1 лежит значение 0x11FC, а значение количества сервисов 0x11c.
т.е. явно выход за границу, но код NtUserSetClipboardData полностью аналогичен коду ZwCreateKey, разница только в номере сервиса. как же он тогда работает и где я не прав ?
Re[2]: перехват апи вызова, что не так ?
От: Aleksey Pashko Украина about:blank
Дата: 27.09.06 17:10
Оценка: 2 (1)
NtUserSetClipboardData находится в Win32k.sys (syscall(11e9) NtUserSetClipboardData)

попробуй чё-то вроде:


// импортируем версию ядра NT
extern PUSHORT NtBuildNumber;

#define NTCALL(_function) KeServiceDescriptorTable(Shadow)->win32k.ServiceTable[_function]

// определяем версию ядра системы
switch(*NtBuildNumber) 
{
case 2195:  // Windows 2000
    FileID = 0x11e9;
    break; 
default:
    return STATUS_NOT_IMPLEMENTED;
}

// устанавливаем перехват    
TrueNtUserSetClipboardData = NTCALL(FileID);
    
__asm 
{
    cli                     // запрещаем прерывания
    mov eax, cr0
    mov uCR0, eax
    and eax, 0xFFFEFFFF    // сбросить WP bit
    mov cr0, eax
}

NTCALL(FileID) = NewNtUserSetClipboardData;
    
__asm 
{
    mov eax, uCR0    
    mov cr0, eax            // востановить содержимое CR0
    sti                     // разрешаем прерывания
}


я не проверял, но вроде должно работать...
Re[3]: перехват апи вызова, что не так ?
От: lc  
Дата: 28.09.06 07:12
Оценка:
Здравствуйте, Aleksey Pashko, Вы писали:

у меня

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

где

typedef struct ServiceDescriptorEntry
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;


AP>#define NTCALL(_function) KeServiceDescriptorTable(Shadow)->win32k.ServiceTable[_function]


тогда что значит KeServiceDescriptorTable(Shadow) ?
или как у вас определено KeServiceDescriptorTable ?
Re[4]: перехват апи вызова, что не так ?
От: Злость Россия  
Дата: 28.09.06 07:50
Оценка:
Здравствуйте, lc, Вы писали:

[skip]

lc>тогда что значит KeServiceDescriptorTable(Shadow) ?

lc>или как у вас определено KeServiceDescriptorTable ?

Вам стоит почитать книгу здесь
Пусто
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Re[4]: перехват апи вызова, что не так ?
От: Aleksey Pashko Украина about:blank
Дата: 28.09.06 13:52
Оценка:
Здравствуйте, lc, Вы писали:

lc>тогда что значит KeServiceDescriptorTable(Shadow) ?

lc>или как у вас определено KeServiceDescriptorTable ?

typedef struct _SYSTEM_SERVICE_TABLE {
    PNTPROC ServiceTable; 
    PDWORD  CounterTable; 
    ULONG   ServiceLimit; 
    PBYTE   ArgumentTable; 
} SYSTEM_SERVICE_TABLE,
*PSYSTEM_SERVICE_TABLE,
**PPSYSTEM_SERVICE_TABLE;

typedef struct _SERVICE_DESCRIPTOR_TABLE {
    SYSTEM_SERVICE_TABLE ntoskrnl;  // SST для ntoskrnl.exe
    SYSTEM_SERVICE_TABLE win32k;    // SST для win32k.sys
    SYSTEM_SERVICE_TABLE table3;    // не используется
    SYSTEM_SERVICE_TABLE table4;    // не используется
} SERVICE_DESCRIPTOR_TABLE,
*PSERVICE_DESCRIPTOR_TABLE,
**PPSERVICE_DESCRIPTOR_TABLE;

// импортируем указатель на SDT
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;



в Windows2000 KeServiceDescriptorTableShadow располагается непосредственно за KeServiceDescriptorTable, тогда как в WindowsXP — перед KeServiceDescriptorTable. Есть много методов поиска адреса KeServiceDescriptorTableShadow для более общего случая, и тут я не могу не согласиться со Злость, тебе стоит прочитать книгу Свена Шрайбера. Также отлична книга здесь, но там нету практических примеров...
Re[5]: перехват апи вызова, что не так ?
От: Аноним  
Дата: 29.09.06 12:27
Оценка:
Здравствуйте, Aleksey Pashko, Вы писали:

получить книгу пока возможности нет.
но нашел некоторые материалы в поиске.
сейчас уперся в следующее:
shadow table я нашел, мне нужно перехватить NtUserSetClipboardData

user32!NtUserSetClipboardData имеет вид

77d6fea6 b8fc110000 mov eax,11FCh
77d6feab ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
77d6feb0 ff12 call dword ptr [edx]
77d6feb2 c20c00 ret 0Ch

т.е. номер сервиса 11fc, но размер таблицы 0x29b а нужный указатель находится по индексу 1fc
для NtUserGetClipboardData аналогичные значения 0x0x1185 и 0x0x185.
правильно ли будет для получения индекса обнулять соответствующие полбайта или это просто совпадение ?
Re[6]: перехват апи вызова, что не так ?
От: Aleksey Pashko Украина about:blank
Дата: 29.09.06 13:33
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>правильно ли будет для получения индекса обнулять соответствующие полбайта или это просто совпадение ?


В общем случае скорее всего нет, но для конкретного релиза некоторых модулей ОС вполне возможно. Используй этот метод на свой страх и риск...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: перехват апи вызова, что не так ?
От: gear nuke  
Дата: 30.09.06 07:03
Оценка:
Здравствуйте, <Аноним>, Вы писали:

[]

А>номер сервиса 11fc, но размер таблицы 0x29b а нужный указатель находится по индексу 1fc

А>для NtUserGetClipboardData аналогичные значения 0x0x1185 и 0x0x185.
А>правильно ли будет для получения индекса обнулять соответствующие полбайта или это просто совпадение ?

Это не совпадение. Полбайта — номер таблицы (если считать от 0).
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.