Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.22.119.251] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Помогите, перечитал документаций о том, как делать резиденты
невидимыми (в хороших целях), но у меня нифига не получается. В чём тут ошибка ? (см.ниже) Эта прога - эксперемент, она ничего не делает, только возвращает управление стандартному обработчику и .... зависает. Assume CS:MySegment MySegment Segment ORG(100h) Begin: ORIG DD 0 MOV AX,CS:[02] SUB AX,5h ; 5h - от фонаря MOV SI,OFFSET MYINT MOV ES,AX XOR DI,DI MOV CX,OFFSET THE_END - OFFSET MYINT ; CLD REPE MOVSB MOV BX,DS DEC BX MOV DS,BX SUB word ptr DS:[03h],5h SUB word ptr DS:[12h],5h CLI PUSH AX XOR BX,BX MOV DS,BX MOV AX, DS:[9*4] MOV WORD PTR ES : [ORIG], AX MOV AX, DS:[9*4+2] MOV WORD PTR ES : [ORIG+2], AX POP AX MOV DS,BX MOV word ptr DS:[9*4],0 MOV word ptr DS:[9*4+2],AX STI RET MYINT: JMP DWORD PTR ES:[ORIG] THE_END: MySegment Ends End Begin |
Сообщ.
#2
,
|
|
|
А нахрена делать такой экзотический способ установки JMP на свой обработчик ???
И что значит невидимой ??? К тому же ваша программа является крайне недружелюбной по отношению к другим резидентам, т.е. если у вас на прерывании, которое вы хотите занять, уже стоит какая-либо программа, то она будет забыта в памяти навечно :o |
Сообщ.
#3
,
|
|
|
Просмотрел вашу программу. Хочу вас разочаровать. Скорее всего, программа виснет на выполнении команды ORIG DD 0, по крайней мере, мне неизвестна реакция процессора на машинный код 00000000, а именно это и выполняется в данной программе первой командой. :P
Если вы думаете, что ваша программа выполняется, начиная с команды CLI, то вы неправы. ;D (Это только мое предположение, потому как, начиная с команды CLI идет код, отдаленно напоминающий код резидента, ели вы так не думали, то простите ;D) По крайней мере виден код установки чего-то на клавиатурное прерывание (int 9h) Немного советов по написанию резидентов: Резидент должен состоять из двух частей: резидентной и установочной. Установочная программа выполняет установку резидентной части и перехват прерываний. Соответственно, она выполняется первой. Значит в начале программы должен стоять Jmp на установочную часть. Для .COM резидентов, установочная часть заканчивается командой lea dx, TSRend Int 27h ;Выйти без освобожления памати |
Сообщ.
#4
,
|
|
|
2 Андруишка:
Подозреваю, что 95\% твоих программ не обладают дружелюбностью, в частности к пользователю, однако ты их все-таки пишешь, несмотря ни на что... Так что твое замечание, а по сути флейм, про экзотику и дружелюбность в недружелюбной ОС весьма не уместно! 2 Ilyia При беглом просмотре в глаза бросаются следующие очевидные ошибки (по мере прочтения кода): 1) ... Begin: ORIG DD 0 ... Так как ты через данные не перескакиваешь, вместо "DD 0" выполнится следующий код: mov [bx+si],al mov [bx+si],al Куда шарахнул AL в памяти, одному Богу известно! Это как ты понимаешь, не есть хорошо! 2) ... STI RET ... Командой ret не стоит завершать программу, повиснет однозначно (как понимаю, это плоды плагиата). Можно, конечно, завершить командой retf, но для этого надо сделать некоторые предварительные действия. Посему пользуйся старыми проверенными способами! 3) ... MOV WORD PTR ES : [ORIG], AX MOV AX, DS:[9*4+2] MOV WORD PTR ES : [ORIG+2], AX ... Опять пишешь туда, не знаю куда, а именно по адресам es:100h и es:102h соответственно, а так как пропустил всего 5 параграфов, значит в занятую область памяти 4) ... MYINT: JMP DWORD PTR ES:[ORIG] ... Не будет работать стопроцентно! Представь, вот обработчик установлен, происходит прерывание, где эта переменная "ORIG" и что за значение в ES. Предложения: 1) Меня убивает упорство в использовании конструкции: ORIG DD 0 ... JMP DWORD PTR CS:[ORIG] Ну куда проще, эффективней и экономичнее: DB 0EAh ;jmp xxxx:xxxx ORIG DD ? Ну дело Ваше, это так лирика и особой роли не играет 2) Используй относительные смещения и помести адрес старого обработчика в конец нового в таком варианте: ... MYINT: JMP DWORD PTR СS:[ORIG] ORIG = $ - MYINT DD 0 ... Метку у DD не ставь, она не нужна! Может, чего и просмотрел, чересчур много ошибок, а проверять лень Пиши внимательней и пытайся представлять, как будет работать конечный код |
Сообщ.
#5
,
|
|
|
2 Андруишка:
Ознакомился с твоей второй мессагой. Для меня удивительно как такие широкие познания сочетаются с таким пренебрежительным тоном, обычно они взаимоисключаемы |
Сообщ.
#6
,
|
|
|
Надо было подумать хорошо самому, прежде чем спрашивать в форуме , виноват.
Я уже разобрался !!! Ошибка (причём весьма грубая) в том, что забыл перепрыгнуть через данные. Стормозил. Сильно стормозил. А так работает и незаметно ;) Всем спасибо ! |
Сообщ.
#7
,
|
|
|
2Rivitna
Знаешь, в свое время (когда я писал для DOS) я повидал столько всяческих резидентов, которые в самый неподходящий момент подвешивали компьютер... А под дружелюбностью я понимаю то, что резидент не должен влиять на существующую среду, т.е. пользователь должен иметь возможность пользоваться кроме твоего резидента еще и другими... А, вообще, я когда-то разрабатывал программу-резидент для защиты каталогов (исключительно для себя ;D) Потом, я стал оптимизировать ее код с целью уменьшения размеров (я все-таки считаю, что на Ассемблере надо писать исключительно компактный код). Тогда, я и начал использовать конструкцию типа DB 0EAh... как показано у тебя... Далее, я посмотрел список загруженных программ в память (если не знаешь, то есть такая функция в VC) И ужаснулся... Резидент размером (на диске) 300 байт оставляет в памяти кусок размером в 500 байт... И стал разбираться... Оказывается, что в DOS перед каждой программой существует структура (так называемый PSP - program segment prefix) размером в 256 байт... И этот ненужный кусок памяти тоже остается вместе с резидентной частью... <--- Лирическое отступление ---> Если помнишь, была такая программа PU_1700 (Расширитель дисковых форматов), так вот, автор этой вещи разработал систему оставления резидентов в памяти без PSP. Далее я воссоздал эту технологию, и мой резидент стал занимать ровно столько, сколько занимает резидентная часть. Т.е. полноценные 200 байтов... Если кто хочет, то могу поделиться алгоритмом оставления программы в памяти без PSP. (К сожалению, только по памяти, так как программа умерла вместе со старым винчестером пару лет назад) |
Сообщ.
#8
,
|
|
|
2Ilyia
А в этом куске кода я вообще практически ничего не понял :o, единственное что я понял, так это то, что программа делает попытку занять прерывание от клавиатуры. Я все-таки не очень понял, что значил сделать резидент невидимым Если ты хочешь написать программу, которая маскируется под область данных DOS, то на это также существуют методы. (Я точно не помню, где я это видел, но видел точно 8)) 2rivitna Замечание о том, что нельзя выходить из программы с помощью ret, не совсем корректно. С помошью ret выходить можно, если к моменту выхода из программы стек оставлен в том же виде, в каком он был при ее старте. DOS при старте помещает в стек адрес начала PSP, где прописана команда int 20h (0CDh 20h), соответственно по ret программа завершится. (Естественно, все вышесказанное, относится только к программам в формате .com, где существует только один сегмент и на старте CS=DS ;D) |
Сообщ.
#9
,
|
|
|
Кстати вышеописанную прогу не выдно в упомянутом тобой VC если нажать ALT-F5
(просмотр памяти). И PSP она не оставляет. Вот она - экономия памяти ! |
Сообщ.
#10
,
|
|
|
Я извиняюсь, что привёл программу без комментариев. :-[ :-[ :-[ Посмотри внимательней: она "крадёт" кусок памяти. Уменьшаю то слово в PSP и описателе MCB-блока, которое указывает на размер выделяемой программе памяти. |
Сообщ.
#11
,
|
|
|
Вполне понятно! Ведь она не остается резидентной! В привычном смысле слова.
Ведь она использует довольно известную технологию вирусов семейства small, а именно забивание резидентной части в произвольный кусок памяти (Правда вирусы small использовали для этого фиксированный кусок памяти в области таблицы векторов прерываний). Здесь же вообще непонятно где окажется резидентная часть этой программы. То есть результат исполнения команд: MOV AX,CS:[02] SUB AX,5h ; 5h - от фонаря MOV SI,OFFSET MYINT MOV ES,AX XOR DI,DI MOV CX,OFFSET THE_END - OFFSET MYINT ; CLD REPE MOVSB Мне лично не известен. И далеко не однозначен при различных запусках программы. Дело в том, что CS:[02] указывает на область PSP и соответственно, эти поля заполняет операционная система. (DOS) Если вы хотели обратиться к полю данных ORIG, то обращение должно быть оформлено как CS:[102h] А на какой кусок наложится ваш резидентный код становится известно только процессору и то, только в момент выполнения программы... А если она затрет важный кусок BIOS в памяти (например обработчик прерывания 13h) ??? Ну, в этом случае, вы получите мелко нарезанный винчестер. Сразу же по окончании программы... А разговоры об экономии памяти здесь неуместны 8) |
Сообщ.
#12
,
|
|
|
Прости, когда писал ответ, не видел сообщения #9
Увидел операции с MCB. Однако то, что ты уменьшаешь размер блока, выделяемого программе не мешает DOS освободить этот самый кусок памяти... Сразу по окончании программы... |
Сообщ.
#13
,
|
|
|
Мне хотелось бы также выяснить, у кого она крадет кусок памяти... :-/
|
Сообщ.
#14
,
|
|
|
Цитата То есть результат исполнения команд: MOV AX,CS:[02] SUB AX,5h ; 5h - от фонаря MOV SI,OFFSET MYINT MOV ES,AX XOR DI,DI MOV CX,OFFSET THE_END - OFFSET MYINT ; CLD REPE MOVSB Мне лично не известен. И далеко не однозначен при различных запусках программы. Дело в том, что CS:[02] указывает на область PSP и соответственно, эти поля заполняет операционная система. (DOS) Результат-то известен и практика показывает, что особых ошибок это не вызовет. При запуске com-программы ОС выделяет всю доступную основную память. Код обработчика будет находится в конце свободной основной памяти, забивание которой очень маловероятно. С тем, что это экстремально и ненадежно я согласен. Цитата Если вы хотели обратиться к полю данных ORIG, то обращение должно быть оформлено как CS:[102h] В том виде, в котором изложена программа, это не верно и вызовет ошибки. Цитата А на какой кусок наложится ваш резидентный код становится известно только процессору и то, только в момент выполнения программы... А если она затрет важный кусок BIOS в памяти (например обработчик прерывания 13h) ??? Ну, в этом случае, вы получите мелко нарезанный винчестер. Сразу же по окончании программы... А разговоры об экономии памяти здесь неуместны 8) По поводу места попадания смотри выше. Повторюсь, что обработчик запишется в свободную на момент запуска программы память По поводу int 13h полный бред! Про экономию речь действительно не идет, речь идет о отображении занятых и свободных блоков. Такой обработчик сидит в блоке без MCB, в любой момент может быть затерт, но опять же это весьма маловероятно. По поводу ret согласен, стереотип exe сыграл роль. А по поводу данной TSR: Это экстремальный стиль, я так не пишу, но на жизнь имеет право существования... |
Сообщ.
#15
,
|
|
|
Я поправлюсь, тем не менее экономия есть, так как обработчик с точки зрения ОС (хотя она и подозревать об этом блоке не будет) будет занимать полное число параграфов без дополнительной информации. Почему "с точки зрения ОС", потому что ОС выделяет память параграфами. Чем ближе код обработчика к краю, тем меньше вероятность его затирания.
Экономия ценою экстремальной работы! Но тем не менее... |