Форум: "Компоненты";
Текущий архив: 2006.05.28;
Скачать: [xml.tar.bz2];
ВнизРазработка свобственного класса. Найти похожие ветки
← →
The One © (2005-11-16 22:40) [0]Здравствуйте.
Сталкнулся со следующей проблеммой. Существует написая мною dll. Когда она атачится к процессу, устанавливаются хуки на ряд API функций, вместо них выполняются определенные мною процедуры. Декан требует оформить сие безобразие в класс. Я признаться решил, что раз отлаженный, работоспособный код уже существует то сделать сие будет просто, ан нет... Вот шапка, так сказать:
TRegApiHook = class
private
FAdrRegCreateKeyEx,FAdrRegDelKey,FAdrRegDelVal,FAdrRegOpenKey,FAdrZwCreateThread,FAdrZwResumeThread,
FAdrRegSetValEx: pointer;
FOldRegCrK,FOldRegDelK,FOldRegDelVal,FOldRegOpenKey,FOldZwCreateThread,FOldZwResumeThread,
FOldRegSetVE: OldCode;
FJmpRegCrK,FJmpRegDelK,FJmpRegDelVal,FJmpRegOpenKey,FJmpZwCreateThread,FJmpZwResumeThread,
FJmpRegSetVE: far_jmp;
FCurrProc,FCurrProcID,FWriten,Fbw:cardinal;
FOpenRootKey,FOpenSubKey:string;
FNewProcess:boolean;
protected
procedure StopThreads;
procedure SetHook;
procedure RunThreads;
Function InjectDll(Process: dword; ModulePath: PChar): boolean;
Function NewZwCreateThread(ThreadHandle: PDWord;DesiredAccess: ACCESS_MASK;
ObjectAttributes: pointer;ProcessHandle: THandle;ClientId: PClientID;
ThreadContext: pointer;UserStack: pointer;CreateSuspended: boolean):NTStatus; stdcall;
function NewZwResumeThread(ThreadHandle: THandle;PreviousSuspendCount: pdword): NTStatus; stdcall;
function NewRegOpenKeyEx(hKey: HKEY;lpSubKey: LPCTSTR;ulOptions: DWORD;
samDesired:REGSAM;var phkResult: HKEY):integer; stdcall;
function NewRegDeleteKey(hKey: HKEY;lpSubKey: LPCTSTR):dword;stdcall;
function NewRegDeleteValue(hKey: HKEY;lpValueName: LPCTSTR):dword;stdcall;
function NewRegSetValueEx(hKey: HKEY;lpValueName: PAnsiChar;Reserved: Cardinal;
dwType: Cardinal;lpData: Pointer;cbData:Cardinal):integer;stdcall;
function NewRegCreateKeyEx(hKey: HKEY;lpSubKey: PAnsiChar;Reserved: Cardinal;
lpClass: PAnsiChar;dwOptions: Cardinal;samDesired: Cardinal;lpSecurityAttributes: PSECURITYATTRIBUTES;
var phkResult: HKEY;lpdwDisposition: PDWORD):integer;stdcall;
public
property OpenRootKey:string read FOpenRootKey write FOpenRootKey;
property OpenSubKey:string read FOpenSubKey write FOpenSubKey;
constructor Create;
end;
.....
Все это в dll. В блоке begin... end библиотеки выполняю создание объекта класса (именно в конструкторе и происходит установка хуков). Компилируется на ура. При попытке присоеденить библиотеку к процессу, т.е. видимо как раз в момент создание объекта, вылетает ошибка "Память не может быть "read"".
Понимаю что вопрос слишком обобщенный, но хотелось бы узнать ваше мнение. В каком направлении следует копать? Если необходимо выложу полный листинг библиотеки.
ЗЫ: Заранее спасибо.
ЗЫЫ: Сорри за кривой код, только учимся )
← →
Юрий Зотов © (2005-11-17 00:37) [1]Дык... видимо для начала надо запустить под отладчиком и найти точное место возникновения ошибки.
← →
Digitman © (2005-11-17 08:51) [2]это что же получается - точку входа в регулярную WinAPI-функцию ты в пытаешься подменить на точку входа в функциональный метод класса ?!
так дело не пойдет
← →
The One © (2005-11-17 16:55) [3]
> Дык... видимо для начала надо запустить под отладчиком и
> найти точное место возникновения ошибки.
Ошибка возникает в методе NewRegCreateKey, при попытки снять ловушку ( WriteProcessMemory, в качестве входных/выходных параметров сво-ва класса TRegApiHook), дабы была возможность выполнить оригинальную API-функцию.
> это что же получается - точку входа в регулярную WinAPI-
> функцию ты в пытаешься подменить на точку входа в функциональный
> метод класса ?!
Да именно это я и пытаюсь сделать. Заменяю адрес оригинальной функции на адресс метода класса. И при отладке вижу, что api-функция ловится таки, вместо неё выполняется определенный мною метод, НО заметил что часть параметров чудесным образом не передается в "метод-заменитель" + та самая ошибка работы с паматью.
> так дело не пойдет
Я вас правильно понимаю - реализовать фильтрацию вызовов апи-функций процесса с помошью собственного класса - не возможно? Если же я что-то не правильно делаю, укажите плиз на ошибку.
← →
Digitman © (2005-11-17 17:14) [4]для начала объясни, как сочетается то что ты задумал с тем что требует декан ...
как вообще выглядело сие "безобразие" ДО попытки угодить декану ?
← →
Digitman © (2005-11-17 17:15) [5]и вообще - КАК в оригинале выглядело ТЗ на проектирование ?
← →
The One © (2005-11-17 17:53) [6]
> как вообще выглядело сие "безобразие" ДО попытки угодить
> декану ?
Объясню. Существует dll, в ней, так скажем "на процедурном" языке описанны функции, призванные заменить оригинальные api (соответсвенно они имеют тот же набор параметров, тех же типов, что и соответствующей api-функции). В этих функциях, упрощенно, выполняется снятие ловушки, вызов оригинальной api-функции, установка ловушки. Собственно первоначальная установка хуков происходит в момент присоединения dll процессу. Т.е. мы получаем адрес функции-жертвы и заменяем его на адрес функции-двойника.
Также существует простенькая программа загружающая указанный exe и присоединяющий к процессу вышеописанную библиотеку. Плюс к этому программка для создания, модификации и удаления ключей в реестре (исключительно в качестве подопытного кролика).
И эта троица прекрасно работала, до тех пор пока я не решил переделать библиотеку в соответсвии с пожеланием руководителя в лице декана.
> и вообще - КАК в оригинале выглядело ТЗ на проектирование
> ?
Вообще заданием было написать ПО ведущее лог работы с реестром. Там вообще-то не указанно, как именно все должно быть реализованно.
← →
The One © (2005-11-17 17:56) [7]Просто предмет называется Объектно Ориентированное Программирование, отсюда и желание оформить все ввиде класса.
← →
Юрий Зотов © (2005-11-17 18:00) [8]> Заменяю адрес оригинальной функции на адресс метода класса.
В машинном коде вызова метода класса первым параметром в него неявно передается указатель на экземпляр класса (тот самый Self), а в регулярных процедурах такого нет. Поэтому, когда ничего не подозревающая программа вызывает API-функцию, а вместо нее на самом деле вызывается метод класса, то внутри этого метода получаем несовпадение как количества параметров, так и смысла каждого параметра. Естественно, в итоге имеем любые чудеса.
← →
The One © (2005-11-17 20:05) [9]Т.е. возможно выходом будет являтся добавление еще одного параметра, типа TObject? Поставить его первым...
Вообще вылетает на вот этой строчке:WriteProcessMemory(FCurrProc, FAdrRegCreateKeyEx, @FOldRegCrK, SizeOf(OldCode), FWriten);
где FXXX - поля класса. Выделил сомнительное на мой взгляд место.
← →
GuAV © (2005-11-18 01:43) [10]
> Т.е. возможно выходом будет являтся добавление еще
> одного параметра, типа TObject?
Добавить ? И как ?
API уже придуман, все параметры известны.
Вот это может помочь
http://www.kladovka.net.ru/index.cgi?pid=list&rid=49
← →
Digitman © (2005-11-18 09:07) [11]
> The One © (17.11.05 20:05) [9]
мне вот что не понятно - твоя dll осуществляет перехват нужных API-вызовов именно в том процессе, в АП которого dll загружена ИЛИ в любом ином (указанном) процессе ?
← →
The One © (2005-11-18 16:58) [12]
> мне вот что не понятно - твоя dll осуществляет перехват
> нужных API-вызовов именно в том процессе, в АП которого
> dll загружена ИЛИ в любом ином (указанном) процессе ?
В том процессе, в АП которого она загружена.
← →
Separator © (2005-11-19 13:23) [13]А не проще написать просто клас обертку для процедур? Т.е. в процедурах вызываешь нужную функцию класса с передачей параметров
← →
The One © (2005-11-19 14:57) [14]Конечно так проще, но тогда ИМХО теряется смысл. Можно оставить всё как есть в регулярных процедурах.
← →
Separator © (2005-11-19 19:36) [15]Вообще-то иная технология не поддерживается архитектурой
← →
Digitman © (2005-11-21 09:39) [16]
> В том процессе, в АП которого она загружена
а зачем тогда WriteProcessMemory() ?
это же СВОЙ процесс !
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2006.05.28;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.01 c