![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| TAPAKAH |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.3.2002 Репутация: нет Всего: нет |
Прежде всего .. чего я нашёл, а затем что же мне делать :)
У Мэта Питрэка (это который работал (а возможно и работает) в фирме NuMega и участвовал в разработке SoftIce и BoundsChecker) есть такая замечательная книжка Windows 95 System Programming SECRETS Вот лежит она у меня значит (на русском) и нахожу я там такую забавную вещь 1. Как написать ApiSpy 2. Собственно какие механизмы перехвата вызовов существуют. Ну чаще всего используют такую вещь как DEBUG PROCESS (этого в интернете навалом). Там более менее механизм ясен. можно посмотреть вот здесь http://delphi.mastak.ru/articles/Dapi/index.html Это делается для перехвата вызовов в других процессах ... а вот для своего процесса Питрек предложил следующее (это перевод на Дельфи с C++) PIMAGE_IMPORT_BY_NAME = ^TIMAGE_IMPORT_BY_NAME; TIMAGE_IMPORT_BY_NAME = packed record Hint : WORD; Name : BYTE; end; PIMAGE_THUNK_DATA = ^TIMAGE_THUNK_DATA; TU1_IMAGE_THUNK_DATA = packed record case Integer of 0: (ForwarderString : PBYTE); 1: (Func : PDWORD); 2: (Ordinal : DWORD); 3: (AddressOfData : PIMAGE_IMPORT_BY_NAME); end; TIMAGE_THUNK_DATA = packed record u1 : TU1_IMAGE_THUNK_DATA; end; PIMAGE_IMPORT_DESCRIPTOR = ^TIMAGE_IMPORT_DESCRIPTOR; TIMAGE_IMPORT_DESCRIPTOR= packed record OriginalFirstThunk : DWORD; TimeDateStamp : DWORD; // 0 if not bound, // -1 if bound, and real date\time stamp // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) // O.W. date/time stamp of DLL bound to (Old BIND) ForwarderChain : DWORD; // -1 if no forwarders Name : DWORD; FirstThunk : DWORD; // RVA to IAT (if bound this IAT has actual addresses) end; implementation function HookImportedFunction(FromModule : HMODULE; FuncModule : String; FuncName : String; NewProc : PDWORD) : PDWORD; var OriginalProc : PDWORD; pDOS_HEADER : PImageDosHeader; pNT_HEADER : PImageNtHeaders; pImportDesc : PIMAGE_IMPORT_DESCRIPTOR; pThunk : PIMAGE_THUNK_DATA; ModuleName : String; begin Result:=nil; if IsBadCodePtr(NewProc) then Exit; // Получаем оригинальный адрес функции которую хотим перехватить OriginalProc:=GetProcAddress(GetModuleHandle(PChar(FuncModule)),PChar(FuncName)); if not Assigned(OriginalProc) then Exit; // Всевозможные проверки pDOS_HEADER:=PImageDosHeader(FromModule); if IsBadReadPtr(pDOS_HEADER,SizeOf(TImageDosHeader)) then Exit; if pDOS_HEADER^.e_magic<>IMAGE_DOS_SIGNATURE then Exit; pNT_HEADER:=PImageNtHeaders(DWORD(pDOS_HEADER)+DWORD(pDOS_HEADER^._lfanew)); if IsBadReadPtr(pNT_HEADER,SizeOf(TImageNtHeaders)) then Exit; if pNT_HEADER^.Signature<>IMAGE_NT_SIGNATURE then Exit; // Получаем указатель на секцию импорта модуля. pImportDesc:=PIMAGE_IMPORT_DESCRIPTOR(DWORD(pDOS_HEADER)+ DWORD(pNT_HEADER^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddres s)); if pImportdesc=PIMAGE_IMPORT_DESCRIPTOR(pNT_HEADER) then Exit; // Перебираем дескрипторы с целью поиска дескриптера с именем, соответствующим параметру FuncModule while (pImportdesc^.Name<>0) do begin ModuleName:=StrPas(PChar(DWORD(pDOS_HEADER)+DWORD(pImportdesc^.Name))); if UpperCase(ModuleName)=UpperCase(FuncModule) then Break; Inc(pImportdesc,1); end; if pImportdesc^.Name=0 then Exit; // Получить указатель на таблицу адресов импорта в найденном модуле pThunk:=PIMAGE_THUNK_DATA(DWORD(pDOS_HEADER)+DWORD(pImportdesc^.FirstThunk)); // Просмотр таблицы адресов импорта в поисках адреса // соответсвующего полученному выше с помощью GetProcAddress while (pThunk^.u1.Func<>nil) do begin if DWORD(pThunk^.u1.Func)=DWORD(OriginalProc) then begin // Ура нашли :) Заменим адрес функции, адресом перехвата. И вернем настоящий адрес. pThunk^.u1.Func:=NewProc; Result:=OriginalProc; break; end; Inc(pThunk); end; end; Хочу сразу заметить перевод не совсем точен .. так как добивался чтоб заработало :) (там были ещё вставки чтоб работало и под Win32s) Если кому стало интересно .. то исходные коды (и из Windows 95 System Programming SECRETS в том числе) лежат по адресу http://www.wheaty.net/ Это непосредственно функция .. а вот пример вызова : В своём dpr напишите следующее var OriginalShowWindow : function (hWnd: HWND; nCmdShow: Integer): BOOL; stdcall; function MyShowWindow(hWnd: HWND; nCmdShow: Integer): BOOL; stdcall; begin Windows.Beep(1000,1000); Result:=OriginalShowWindow(hWnd,SW_MAXIMIZE); end; begin @OriginalShowWindow:=HookImportedFunction(GetModuleHandle(nil),'USER32.DLL','ShowWindow',@MyShowWindow); if @OriginalShowWindow=nil then Raise Exception.Create('Hook на ShowWindow не был установлен'); // Application... //... end; А потом запихните сюда ещё и шутку :) http://www.forum.vingrad.ru/cgi-bin....2;t=182 Заранее предупреждаю с MessageBox такая штука например не пройдёт .. у меня почему то её истинный указатель хранится дальше в памяти .. бред какой-то (причём только её) Ну да ладно .. это была вводная часть, а теперь собственно проблема : Мне хотелось бы перехватывать все обращения к строковым ресурсам реализуемые с помощью LoadStringA и надстройкой над ней в Дельфи LoadStr Когда я пытаюсь сделать финт ушами и написать var OriginalLoadString : function (hInstance: HINST; uID: UINT; lpBuffer: PChar; nBufferMax: Integer): Integer; stdcall; function MyLoadString(hInstance: HINST; uID: UINT; lpBuffer: PChar; nBufferMax: Integer): Integer; stdcall; begin Result:=OriginalLoadString(hInstance,uID,lpBuffer,nBufferMax); MessageBox(0,lpBuffer,lpBuffer,MB_OK); end; @OriginalLoadString:=HookImportedFunction(GetModuleHandle('VCL50.BPL'),'USER32.DLL','LoadStringA',@MyLoadString); if @OriginalLoadString=nil then Raise Exception.Create('Hook на LoadStringA не был установлен'); ShowMessage(LoadStr(38807)); То отображаеться два раза окно в котором написано OK OK и третий раз собственно выполняется ShowMessage где и выводится нормальная фраза. Совершенно не догоняю где он берёт этот ОК .. потому что строка там Drag Column .... и так далее. Может кто чего посоветует, или может кто нибудь знает ещё какие-нибудь методы перехвата ... В общем жду помощи .. и обсуждение написанного здесь :) |
|||
|
||||
| Chingachguk |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: нет Всего: 18 |
Может быть, ShowMessage неявно использует эту LoadString, которую ты перехватил ?
Попробуй просто вызвать без ShowMessage ее ?... -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
| TAPAKAH |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.3.2002 Репутация: нет Всего: нет |
Ну по поводу ОК это я конечно ступил ... Понятно что эта строчка запрашивается функцией ShowMessage :)
Вот здесь : function CreateMessageDialog(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons): TForm; .... PChar(LoadResString(ButtonCaptions[B])), -1, ..... Но всё равно непонятно .. куда девается подлинная строчка... Сегодня я буду проверять другой вариант ... с изменением кода в рантайме (вставляется jmp) посмотрим как он сработает .. Если кому интересно здесь (с исходниками на С++) http://www.uinc.ru/articles/26/index.shtml |
|||
|
||||
| Chingachguk |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: нет Всего: 18 |
Насчет сообщения - может, вывести значения указателей на то, что ты хочешь вывести и то, что передается в сам MessageBox ?
-------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
| TAPAKAH |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.3.2002 Репутация: нет Всего: нет |
Chingachguk! Спасибо за поддержку :)
В общем сегодня я разродился . Итак ... Посмотрев на все исходники на си и на паскале .. появилась вот такая вещь : Допустим мы хотим перехватить вызов какой-нибудь функции ... ну просто очень хотим .. например :) LoadStringA Я попробовал вот такой вариант : 1. Ищем адрес этой функции в нашем адресном пространстве.. (попросту вызываем GetProcAddress) 2. Разрешаем изменение памяти с помощью VirtualProtectEx 3. Выделяем память под новую заглушку OrigFunc (новую оригинальную функцию) - нам надо 10 байт .. позже станет ясно почему. 4. Копируем первые пять байт из нашей (OurFunc) функции в OrigFunc (это тот код который мы будем менять) (речь конечно об адресах) 5. Заменяем первые 5 байт по адресу OurFunc на jmp (адрес функции перехвата) 6. Заменяем оставшиеся 5 байт по адресу OrigFunc на jmp OurFunc+5 Усё! Теперь при вызове OurFunc будет произведен переход на функцию ловушку. А если нам необходимо вызвать оригинальную функцию то мы вызываем OrigFunc А я то потел .. :( здесь всё то же самое что и на http://www.uinc.ru/articles/26/index.shtml за одним исключением .. там используется хитрая (одна для всех функций) функция для перехвата ... + чтобы вызвать оригинальный код нужно востановить эти 5 байт .. Вот она моя фукция: (есть конечно вероятность что я где то в теории ложанулся ... но вроде работает) // Рабочий вариант.. использует jmp, возвращает указатель на оригинальную функцию function HookFunction(FuncModule : String; FuncName : String; NewProc : PDWORD) : PDWORD; function HookFunction(FuncModule : String; FuncName : String; NewProc : PDWORD) : PDWORD; var ptr : pointer; ptr_proc : PDWORD; OldProtectAPI : Cardinal; begin Result:=nil; ptr_proc:=GetProcAddress(GetModuleHandle(PChar(FuncModule)),PChar(FuncName)); if not Assigned(ptr_proc) then Exit; if(not VirtualProtectEx(GetCurrentProcess(),ptr_proc, 6, PAGE_EXECUTE_READWRITE, OldProtectAPI)) then begin RaiseLastWin32Error; end; // Создаём новую функцию в которую запоминаем первые пять байт + jmp на остальной код измененной функции ptr:=AllocMem(10); CopyMemory(ptr,ptr_proc,5); PBYTE(DWORD(ptr)+5)^:=$e9; PDWORD(DWORD(ptr)+6)^:=DWORD(ptr_proc)-DWORD(ptr)-5; // Меняем оригинальную функцию : вставляем jmp на хук PBYTE(ptr_proc)^:=$e9; PDWORD(DWORD(ptr_proc)+1)^:=DWORD(NewProc)-DWORD(ptr_proc)-5; Result:=ptr; end; А вот мой многострадальный пример :) var OriginalLoadString : function (hInstance: HINST; uID: UINT; lpBuffer: PChar; nBufferMax: Integer): Integer; stdcall; function MyLoadString(hInstance: HINST; uID: UINT; lpBuffer: PChar; nBufferMax: Integer): Integer; stdcall; begin Result:=OriginalLoadString(hInstance,uID,lpBuffer,nBufferMax); StrCopy(lpBuffer,'Опа'); Result:=3; end; begin @OriginalLoadString:=HookFunction('user32.dll','LoadStringA',@MyLoadString); end; |
|||
|
||||
| Chingachguk |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: нет Всего: 18 |
Слушай ! А я правильно понял, что ты врубил этот jmp ПРЯМО В ТЕЛО user32
Оба-на ! А я как-то пытался только прочитать(! jmp @@Go CallCreate: call CreateFile @@Go: ; Получим адрес jmp-а из команды call CreateFile mov eax,offset CallCreate+5 add eax,cs:[eax+1-5] ; Получим реальный адрес входа в CreateFile ; Получим offset адреса CreateFile из команды jmp ds:[CreateFileA] mov eax,cs:[eax+2] ; jmp ds:[addr] => 25FF(2 байта), addr(4 байта) ; Извлечем сам адрес по смещению в jmp-е mov ebx,ds:[eax] mov eax,ebx call PrintEAX ; Вывести реальный оффсет CreateFileA (сегмент наш) ; Перехватим точку входа в CreateFile mov eax,cs:[ebx] call PrintEAX ; Вывести 4 байта начала CreateFileA ... - И тут-то у меня был JPF Или надо было не через CS читать ?! А самое главное - теперь ЛЮБОЕ приложение, вызвавшее эту ф-цию, передасться тебе сперва ?! Али только если из твоего вызов будет, если для каждой задачи винда делает копию этих dll ? -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
| TAPAKAH |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.3.2002 Репутация: нет Всего: нет |
Я почти понял что ты делаешь .. но это слишком всё таки сложно для меня ... ассемблер я знаю плохо :) (но всё же вместо обьявления вызова функции и дальнейших преобразований легче получить её адрес по имени ... GetProcAddress )
А вот про схему работы рассказать могу :) То что там меняеться копируеться и так далее .. то как ты правильно заметил .. это только для моего адресного пространства Так как винда действительно при создании процесса подгружает все длл в его адресное пространство (во все его 4 гига или 2 :) не помню). => перехват произойдёт только при вызове этой функции из моего процесса. НО :) Всё просто супер .. так как существует такая вещь как SetWindowsHookEx с помощью которой можно внедриться во все процессы системы .. => можно написать некую длл в которой сделать свою функцию которую ты хотел бы использовать вместо стандартной и написать код внедрения её во все процессы .. и тогда бум :) и например вместо стандартного MessageBox будет показываться какой нить супер навороченный диалог :) MessageBox |
|||
|
||||
| TAPAKAH |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.3.2002 Репутация: нет Всего: нет |
Кстати .. знаешь я посмотрел .. повнимательнее вроде стало ясно ...
не знаю по теории всё верно .. да и по практике тоже. А попробуй разлочить на чтение (навряд ли конечно такой бред но кто знает) перед чтением первых четырёх байт самой функции CreateFile VirtualProtectEx(GetCurrentProcess(),ptr_proc, 4, PAGE_EXECUTE_READWRITE, OldProtectAPI)) Скорее всего из-за этого сыпется .. А читать сто пудов надо через cs .. :) |
|||
|
||||
| Fantasist |
|
|||
|
Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: нет Всего: 41 |
Cлушай, ТАРАКАН, можешь в двух словах описать идею о внедрении в процессы с помощью SetWindowsHookEx?
-------------------- Волны гасят ветер... |
|||
|
||||
| TAPAKAH |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.3.2002 Репутация: нет Всего: нет |
если тебе нужен рабочий пример на дельфи .. то пиши, солью
Ну если не углублятся то вот вырезка из МСДН а The global hooks are a shared resource, and installing one affects all applications in the same desktop as the calling thread. All global hook functions must be in libraries. Global hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove its hook procedure. Ну в общем чего здесь написано .. а написано следующее если вы устанавливаете ловушку для всей системы .. то 1. ваша функция-ловушка должна лежать в длл 2. все процессы подгрузят эту длл в своё адресное пространство. Усё .. а дальше на инициализацию своей длл ки вешаешь перехват вызовов функции и получаешь то что я писал в предыдущем постинге. пример вызова SetWindowsHookEx(WH_GETMESSAGE,@CallBackHook,inst,0); и усё инст - HMODULE длл откуда была загружена CallBackHook Кстати .. см шутку .. это продолжение из MSDN Installing and Releasing Hook Procedures You can install a hook procedure by calling the SetWindowsHookEx function and specifying the type of hook calling the procedure, whether the procedure should be associated with all threads in the same desktop as the calling thread or with a particular thread, and a pointer to the procedure entry point. You must place a global hook procedure in a DLL separate from the application installing the hook procedure. The installing application must have the handle to the DLL module before it can install the hook procedure. To retrieve a handle to the DLL module, call the LoadLibrary function with the name of the DLL. After you have obtained the handle, you can call the GetProcAddress function to retrieve a pointer to the hook procedure. Finally, use SetWindowsHookEx to install the hook procedure address in the appropriate hook chain. SetWindowsHookEx passes the module handle, a pointer to the hook-procedure entry point, and 0 for the thread identifier, indicating that the hook procedure should be associated with all threads in the same desktop as the calling thread. This sequence is shown in the following example. HOOKPROC hkprcSysMsg; static HINSTANCE hinstDLL; static HHOOK hhookSysMsg; hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll"); hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,hkprcSysMsg,hinstDLL,0); You can release a thread-specific hook procedure (remove its address from the hook chain) by calling the UnhookWindowsHookEx function, specifying the handle to the hook procedure to release. Release a hook procedure as soon as your application no longer needs it. You can release a global hook procedure by using UnhookWindowsHookEx, but this function does not free the DLL containing the hook procedure. This is because global hook procedures are called in the process context of every application in the desktop, causing an implicit call to the LoadLibrary function for all of those processes. Because a call to the FreeLibrary function cannot be made for another process, there is then no way to free the DLL. The system eventually frees the DLL after all processes explicitly linked to the DLL have either terminated or called FreeLibrary and all processes that called the hook procedure have resumed processing outside the DLL. An alternative method for installing a global hook procedure is to provide an installation function in the DLL, along with the hook procedure. With this method, the installing application does not need the handle to the DLL module. By linking with the DLL, the application gains access to the installation function. The installation function can supply the DLL module handle and other details in the call to SetWindowsHookEx. The DLL can also contain a function that releases the global hook procedure; the application can call this hook-releasing function when terminating. А шутка в том что они насильно подгружают длл .. а вот выгружать бояться .. :) и правильно делают : You can release a global hook procedure by using UnhookWindowsHookEx, but this function does not free the DLL containing the hook procedure. This is because global hook procedures are called in the process context of every application in the desktop, causing an implicit call to the LoadLibrary function for all of those processes. Because a call to the FreeLibrary function cannot be made for another process, there is then no way to free the DLL. То бишь пока ты сам себя не выгрузишь .. либо процесс тебя случайно не найдёт и выгрузит .. либо он завершится .. твоя длл будет болтатся в адресном пространстве этого (любого - всех) процесса |
|||
|
||||
| Chingachguk |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: нет Всего: 18 |
А, все равно это будет типа твоего варианта, только кривенько Если как ты гришь, ты ставишь бряк ТОЛЬКО в свою dll-ку, то и у меня то же самое ... А насчет cs&VirtualProtectEx я попробую ! -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
| TAPAKAH |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.3.2002 Репутация: нет Всего: нет |
Да блин .. всё таки я лажанулся в теории .. хук будет работать прекрассно .. но вот если вызвать оригинальную функцию то (иногда) будет шняга ..
Предположим по аддресу в который мы впаяли jmp инструкцию из 5 байт, было 3 инструкции по 2 байта ... то мы получим просто офигительную ошибку потому что скопируем 2 инструкции и ещё половинку :) вот блин ... самое изящное решение которое я вижу .. копировать не 5 байт а то количество которое необходимо чтобы все инструкции остались "законченными" :) Так вот теперь трабл ... как определить длину инструкции в байтах ??? Chingachguk :) Спасай :) |
|||
|
||||
| Chingachguk |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: нет Всего: 18 |
Ааа ! ж))))
А я-то думаю - что это ты так уверенно заменил пять байтов ... Я винду тока начал рубить, думал - может, так и надо Точно сказать не могу, но вот как это делали вири в досе, когда не хотели менять в таблице прерываний адрес int 21h(ну это чтоб антивири не кричали "int 21 перехвачен !") Называется, кажется, сплайсинг. - Заготавливаем наш обработчик для Trace_Into(режим пошагового выполнения программы - это вроде int 3). Если включен режим трассировки(флаг TF), то после КАЖДОЙ асм-команды к нему переходит управление; - Переводим проц в трайсе-режим и выполняем команду int 21h. Следим за сегментом и смещением команды, с которой нам пришло прерывание - в нашем обработчике; - Как только пошли команды настоящего обработчика, то мониторя их, отмеряем нужное себе количество байт, которые надо поменять. Например, хотим воткнуть команду int 0FAh - переход на вирь. Те нужно 2 байта. Пусть оригинальный обработчик дос-а имеет такой вход: nop ; 1 байт есть, но нам надо два mov ax,bx ; опа, уже 2 байта - нам хватит. mov cx,bx ; - Это следующая команда Запоминаем эти три байта и втыкаем команду int 0EAh, теперь обработчик дос-а имеет вид: int 0FAh мусор в 1 байт, оставщийся от mov ax,bx mov cx,bx ; - Это следующая команда Теперь в обработчике int 0FAh сразу выполняем сохраненные две команды: nop , mov ax,bx И переходим на третью команду - на mov cx,bx. А что, никак в винде нельзя хук поставить на вызов апи-шек ? Стандартно ? Я вот только что прочел, что можно (вызывая стандартный сервис VMM VxD) поставить хуки на другие сервисы VxD -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
| Chingachguk |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: нет Всего: 18 |
to ТАРАКАН:
если интересно, мне в голову пришла идея, как сделать под вин эту проблему - ну, когда у тебя неизвестное число байт занимает первая команда в dll. Безо всяких трейсеров ... -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
| TAPAKAH |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.3.2002 Репутация: нет Всего: нет |
Конечно интересно!
Я её уже сделал, но по железному :) надыбал исходник disasm на си сделал длл и подключил к своему проектику а в длл парочка полезных функций .. например прочитать по такому то адресу в памяти .. инструкцию .. функция читает и возвращает длину прочитанной инструкции. если интересно .. то могу выложить переделанный дельфийный код .. ну а длл .. вышлю мылом :) |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |