::Главная страница :: Assembler :: Статьи ::

 

RTFM_Helpers@yahoogroups.com - избранное.

4 октября 2001г. - 20 ноября 2001


1) Кто нибудь писал плугины для ФАРа, если да, то не могли бы вы выслать исходники очень надо! Необходимо просто получить самы простой шаблон, плугина! И еще ни кто не видел терминала(плугина такого) для фара?
С уважением Михаил C. Мерзляков

Посмотри тут: http://www.programme.ru/index.phtml?arch/102001/102001_52.htm Исходники тоже есть.
Андрей.

SDK с примерами всегда идет вместе с Far`ом в файле Far\PlugDoc.Rar

Плугины я писал. Парочку написал. В принципе, все необходимое есть в инсталляции самого фара в архиве plugins.rar (хелпы, заголовки). Выслаю сырец недоделанного плугина для сравнения папок (там только шаблон, как и просили). Могу еще выслать работающий плугин для редактора CppHelper, который расширяет возможности редактора FAR по редактированию Сишных сырцов. Терминала не видел. Вообще в инете валяется огромная куча разных плугинов - может и найдешь


2) Помогите плиз ! Я знаю, что программа запакована программой PEcompressor, где можно взять декомпресор, чтобы ЕХЕшник стал некомпресированым . И еще на СПЕКТРУМЕ была кнопочка MAGIC - сброс памяти на диск (дамп), слышал я, что такая прога есть и на РС, ссылочки дайте пжлста !

Если прога под ДОС - юзай cup386. Если мод винду - лучше связки SoftICE + IceDump тебе не найти, если конешна руки не кривые.
Dr.Golova

Посмотри в каталоге Windows\command программу debug.exe. Она может и в дамп скинуть память. А отличная инструкция к ней была в рассылке"Низкоуровневое программирование для DZенствующих"
Андрей.


3) Мой вопрос таков: иногда в листингах мне встречаются непонятные условные переходы.
К примеру:
==========
mov edx, ...
inc edx
jle адрес
Что именно должно здесь сравниваться и почему (иногда) происходит переход. Какие флаги проверяются?

Какие именно флаги проверяются какой инструкцией перехода можно посмотреть в любом справочнике. Конкретно для JLE переход выполняется если выполняется условие (SF != OF or ZF = 1). Но это формальный подход. Содержательный подход состоит в том, что jle после inc проверяет, стал ли результат меньше (знаково!) или равен нулю. Например, INC 1 не даст этого условия, а INC -1 или INC -100 дадут.Напомню: большинство инструкций устанавливают флаги в соответствии с результатом. INC, SUB, CMP и подобные инструкции устанавливают флаги в соответствии с результатом арифметических операций.
Best regards! Sincerely yours, Хемуль Советикус.
Утомлённый чаем любитель сладкого, в девичестве Бильбо Ленивчатый.


4) Надо создать свой формат БД, с обычными полями я разобрался (делаю File of Record), но как быть, если надо иметь поле переменного размера, а именно Memo

Организовывать страничную систему. Например, выделять в файле по 4K на каждый кусок текста (по аналогии с кластерами на диске). Как их связать - вопрос второй. Можно держать для инофрмации о связях отдельную страницу (a'la FAT), либо сслыку на следующую страницу держать в первых байтах каждой страницы.
Best regards! Sincerely yours, Хемуль Советикус.
Утомлённый чаем любитель сладкого, в девичестве Бильбо Ленивчатый.

Делай под мему отдельный файл. Потом просто индексируешь с записями основной базы.


5) Я вот тут открыл один файл(конкретно - appath.asm в дире masm32\m32lib)и увидел странный фрагмент кода:
; ...
@@:
lodsb
inc ecx ; count bytes
cmp al, 0
je @F
cmp al, "\"
jne @B
mov edx, ecx ; put count of each "\" in edx
jmp @B
@@:

invoke lstr,ADDR buffer,lpPathBuffer,edx
; ...
В принципе, как это работает - ясно. Только почему здесь стоит две _одинаковые_ метки? И переходы какие-то странные: jmp @B, jmp @F Таких и меток-то нету! Почему jmp @B должен прыгать на верхнюю метку "@@", а jmp @F - на нижнюю? Да и в некоторых других файлах я встречал метки, начинающиеся на @@. Что это вообще за символ такой - @? Разъясните, плз.!

@@ - это анонимные метки. В отличие от всех остальных, их разрешается использовать повторно.
jmp @F будет прыгать на ближайшую метку @@ вперед (F - означает Forward), а
jmp @B - на ближайшую метку @@ назад (B - Backward).


6) Народ, как в САйсе установить бреакпоинт на вызов API из MSVCRT.dll, конкретнее на printf, на стандартные, типа Loadlibrary, ставиться, а на printf - нет.
Igor

Это правильно что не ставятся - сначала надо подгрузить в сайс экспорт этой длл, короче RTFM до полного просветления.

Либо эту длл-ку надо прописать в winice.dat:
EXP=c:\windows\system\msvcrt.dll, а потом перезагрузиться. Либо можно загрузить таблицу экспорта с помощью Symbol Loader: File-Load Exports.
vkim


7) Крайне нужна инфа по байткоду VB. Я понимаю что M$ жмется на эту бадягу, но мне нужно хоть как-то ометить кусок кода в проге чтоб потом в уже скомпиленной найти этот кусок и узнать его размер. Был бы асм -мождно было бы вставить сигнетурку, а без асма как???
Dr.Golova

Смутная тема. Я VB стараюсь обходить стороной - жизнь короткая, жалко ...В MSDN ничего нет. Вот, кажется все, что можно посоветовать:
Url: http://www.digitalrice.com/kaparo/files/compilers/jumpgen.zip
size: 9118
Url: ftp://exetools:member@ftp.exetools.com/Upload/vbdebug13e.exe
size: 432595
Вот еще было (но сайт в дауне)

Visual Basic Virtual machine files (latest version we have):
MSVBVM60.DLL v.6.0.89.64
MSVBVM50.DLL v.5.0.82.44

Symbolic debug files (DBG) files for use with the debugger:
MSVBVM60.DBG v.6.0
MSVBVM50.DBG v.5.0

Symbolic debug files (NMS) for use with SoftIce Symbol Loader.
MSVBVM60.NMS
MSVBVM50.NMS

Url: http://www.suddendischarge.com/files/Debugging/vbdebugsup1.zip
size: 3786475
А чисто отметить, IMHO, вставить в исходник _подряд_ 3-5, например, сравнения строк, а потом эти вызовы подряд уже можно будет найти. Если же где-то есть больше - был бы рад узнать где :-)


8) Кто подскажет, как правильно читать из ком-порта функцией ReadFileEx ? Особенно интересует как ПРАВИЛЬНО заполнить структуру OVERLAPPED. По хелпу (Win32.hlp) получается, что:
1. Поля структуры OVERLAPPED, кроме hEvent можно не устанавливать при асинхронном чтении.

Типа не совсем - для регулярных (дисковых) файлов надо заполнить Offset. Для COM-портов не надо.

2. Поле hEvent ДОЛЖНО быть установлено ДО вызова ReadFileEx.

Должно быть установлено до вызова ReadFile. В ReadFileEx Event не используется, а используется функция завершения

3. hEvent это указатель на событие (event), происходящее при завершении чтения. Вопрос: откуда его взять ?

hEvent это не указатель (не совсем указатель), а Handle заранее созданного тобой (с помощью вызова CreateEvent) объекта Event, который является одним из объектов синхронизации, реализованных в ядре Win32. Event - это такой (возможно именованный) объект, который один поток какого либо процесса может в нужный момент взвести в сработавшее состояние (signaled state), а другой (другие) потоки возможно даже другого приложения могут ожидать этого состояния с помощью функций WaitForSingleObject или WaitForMultipleObjects или еще каких-нибудь.
Т.е. ты должен:
1. Создать Event с помошью вызова CreateEvent
2. Заполнить структуру OVERLAPPED
3. Вызвать ReadFile
4. Выполнять любые действия (среди которых может быть и проверка состояния операции с помощью GetOverlappedResult)
5. ПРИ ЖЕЛАНИИ подождать момента завершения операции с помощью WaitForSingleObject(hEvent) или еще чего Но все это относится к ReadFile и не относится к ReadFileEx

4. lpCompletionRoutine это указатель на процедуру завершения операции чтения, когда вызывающий поток (tread) находится в "опасном состоянии ожидания" (calling thread is in an alertable wait state). Вопрос: откуда взять этот указатель ?
Sergey

Это указатель на ТВОЮ функцию, которую ты должен написать, если хочешь, чтобы она вызывалась при завершении фоновой операции. Ведь ты хочешь проанализировать, как она завершилась ? :)
Метод функции завершения операции можно считать альтернативным методом (по отношению к Event) для определения завершения операции.
Кстати, IMHO "alertable wait state" переводится иначе и означает другое (типа состояния, в котором допустимо прерывать поток для сообщения ему Alert-ов). Можешь прочитать подробнее в том же help-е в разделе Alert Functions. Аналогичная IMHO ситуация присутствует в классических UNIX-системах - сигнал, отправленный процессу, который в данный момент находится в режиме ядра, откладывается до момента выхода процесса из "ядреной" функции. Перед возвратом из ядра в точку вызова проверяется, нет ли"подвешенных" сигналов, и если есть, то выполняется их обработка. Таким механизмом ядро защищает себя от повторных вхождений в критические секции кода.
Oleg Hohloff aka LonelyWolf


9) Киньте кто-нибудь в меня исходником, как на билдере, используя функцию RegCreateKeyEx/RegSetValueEx записать по адресу HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\
подключ, в котором была-бы как значение прописана ком. строка (откуда запустили экзешник). Кроме параметра по умолчанию ничего больше не смог установить. ??? В хелпе вроде все понятно, но не понятно, что подставлять в энту функцу. (Адрес, строку или еще чаво...).
Zubkov Evgeny

 На билдере не могу, нет билдера, но что есть то получи ...

.data
RegistryExe     db      MAX_PATH        dup(?)
szKeyNameis     db      "Software\Microsoft\Windows\CurrentVersion\FoxyApp\",0
szStringValue   db      "Foxy Service",0

.code
[...........]
invoke  SetRegKeysz , ADDR RegistryExe, ADDR szKeyNameis, ADDR szStringValue,SIZEOF
szStringValue
[...........]

;------------------------------------------------------------------------------
; lets open and write a string key (creating it if necessary)
;------------------------------------------------------------------------------
SetRegKeysz  PROC lpszString:DWORD, lpszKeyName:DWORD, lpszValueName:DWORD, dwStringLength
    LOCAL Disp  :DWORD
    LOCAL pKey  :DWORD
    invoke RegCreateKeyEx, HKEY_LOCAL_MACHINE,
                             lpszKeyName, NULL, NULL,
                             REG_OPTION_NON_VOLATILE,
                             KEY_ALL_ACCESS, NULL,
                             addr pKey, addr lpdwDisposition
    .IF eax == ERROR_SUCCESS
        invoke RegSetValueEx, pKey, lpszValueName,
                              NULL, REG_SZ,
                              lpszString, dwStringLength
        invoke RegCloseKey, pKey
    .ENDIF
    ret
SetRegKeysz ENDP


Sergey


 

10)  Прога вылетает при обращении к Int 21h - па-ма-ги-теее
прога - резидент - после запуска запоминает 80 нажатий клавиш(не
учитывая расширенный сканкод) и при нажатии Alt+F4 должна выдавать
коды всех нажатых клавиш... но вылетает... при прямом отображении в
видеобуфер всё Ок... а так нет :(

И для самых-самых вопрос... хочу из резидента обратиться к HDD...
как сделать, чтобы никого не обидеть... в смысле писать на диск,
только если на него никто не пишет

PROG segment
org 100h
assume cs:PROG
Start:
        jmp Init

        len equ 80
        int_16_vect     dd ?
        count           dw 0
        keys            db '$', len dup(0)

        Int_16 proc

        pushf
        cmp     ah,10h
        je      GetIt
Exit:
        popf
        jmp     dword ptr cs:[int_16_vect]

GetIt:
        cmp     count, len
        je      Exit

        call    dword ptr cs:[int_16_vect]

        pushf
        push    bp


        cmp     al,0
        je      Print

        mov     bp, count
        mov     [keys + bp], al
        mov     [keys + bp + 1], '$'

        inc     count
Return:
        pop     bp
        popf
        iret

Print:
        cmp     ah, 6bh
        jne     Return

        push    ax
        push    dx
        push    ds

        mov     ah, 9
        push    cs
        pop     ds
        mov     dx, offset keys
        int     21h

        pop     ds
        pop     dx
        pop     ax

        jmp     Return
        
        Int_16 endp

Init:

        mov ax, 3516h
        int 21h

        mov word ptr int_16_vect, bx
        mov word ptr int_16_vect+2, es

        mov ah, 25h
        mov dx, offset Int_16
        int 21h

        mov dx, offset init
        int 27h

PROG ends
end Start

Я раньше множество таких резидентов писал, и проблему эту исследовал досконально. Самая сильная из таких моих поделок - многозадачный супервизор (ядро) реального времени, исполняющее в DOS-е несколько (много) задач одновременно,и каждая может вызывать DOS. Супервизор был вылизан до промышленного состояния и уже много лет система управления на его базе управляет газопромыслом под Харьковом.
Сейчас попробую изложить все, что еще не забыл :)
Как уже говорилось, DOS нереентерабельный и вызов Int21 (почти любой функции, но есть и исключения) из обработчика аппаратного прерывания чревато либо быстрой либо медленной мучительной смертью :)
Техник обхождения нереетерабельности несколько. В каждой, кстати, есть множество своих подводных камней.
1. контролировать, не занят ли DOS (чужим вызовом). Делать это можно 1а) проверкой текущего состояния InDOS Flag, который находится в области данных DOS и адрес которого можно получить (предварительно) специальной функцией DOS (AH=34h, int 21). Если значение флага ненулевое, вызывать DOS нельзя - его уже заняли. 1б) Повесить в своем же резиденте обработчик-фильтр на INT21, который перед входом в INT21 увеличивает свой флаг-семафор, а после выхода - уменьшает назад. Кстати, вызывать DOS из своей программы в этом случае необходимо не с помощью int 21, а с помощью pushf; call far [cs:Old_ISR_21]. Можно комбинировать оба этих метода (1а и 1б) Техника 1 позволяет, несколько помучавшись, добиться стабильной работы резидента, но обладает некоторыми недостатками, главная из которых - DOS бывает занят надолго. Пример не заставит себя ждать. Как только ты запустишь своего резидента и вернешься в командную строку command.com. Ведь он использует DOS-овую функцию чтения строки с клавиатуры, а она занимает DOS, пока Enter не нажмешь.
2. использовать "недокументированную" (на самом деле описанную в ральфе брауне) DOS Swapable Data Area (SDA). Дело в том, что даже когда кто-то вызвал функцию DOS, он далеко не всегда на самом деле занят. Основная проблема DOS приводящая к нереентерабельности - область статических данных DOS, где он сохраняет временную информацию (например при каждом вызове сохраняет в одном и том же месте
значения регистров. Почему же не в стеке пользователя это делать, черт возьми ?:) и куда назначает свой стек - в одно и то же место при каждом вызове, не проверяя кстати, занят ли уже этот стек (Да - на самом деле стеков два - один для консольных функций 0...0Ch, другой - для всех остальных. И еще есть несколько реентерабельных функций, не переключающих стек). В основном в этих стеках и "зарыт" крах системы при повторном вызове DOS. К счастью, сами мелкомягкие тоже иногда пишут (писали :) резиденты - сетевые серверы, например. Поэтому они предусмотрели обходной маневр, от изящества которого начинает тошнить. Все такие критические глобальные данные они объединили в одно место :) называемое гордо DOS Swappable Data Area. Адрес и размер этого блока памяти можно получить заранее с помощью "потайной" функции AX=5D06. Суть метода такова - перед своей действительно критической секцией кода DOS вызывает AH=80h, int 2Ah, а после завершения критической секции - AH=81h или AH=82h, int 2Ah (подробнее смотреть ральфа брауна. А тем кто проектировал DOS - смотреть рис. 1 :)) Ты должен "повеситься" на int 2A и отслеживать, находится ли DOS в критической секции (установкой флага). Когда тебе нужен DOS, проверяешь этот флаг. Если DOS в критической секции, то вызов DOS запрещен. Если не в критической, то следует скопировать Swappable Data Area в свой буфер, сделать свое дело, а затем восстановить SDA из буфера. Если все сделать аккуратно, то возможно, все будет работать :) У меня, во всяком случае, получилось.
Такую технику используют многие коммерческие программы, в частности Novell NWLite Server.
Кстати, размер SDA составляет порядка нескольких килобайт и меняется от версии к версии и возможно даже от конфигурации.
Весь SDA сохранять/восстанавливать нужно только если DOS вызван (InDOS Flag > 0), а если не вызван, достаточно сохранять/восстанавливать только небольшую начальную область SDA, размером порядка 32..64 байт, не помню точно.
В дополнение к сказанному могу только отметить - когда со всем этим копаешься, справедливый гнев застилает глаза и тяжелые предметы начинают лететь в монитор и особенно - в жесткий диск, на котором этот DOS записан... :) :(... Смерть мелкомягким !!!, которые "пишут" такие "операционные системы"...
Что же касается приведенного резидента, тут хочется отметить следующее:
1. А зачем вызывать DOS для вывода на экран ?
Не делай этого, не надо... :))) (c) "Белое солнце пустыни" И прямой доступ к видеопамяти тут не лучшее решение. Вызывай просто BIOS, с ним проблем не будет.
2. Я так понял этот резидент - это что-то вроде записывателя - воспроизводителя макропоследовательности. Но если я правильно понял, то ведь толку от вывода макропоследовательности на экран реально никакого :) Нужно ее в буфер клавиатуры воспроизводить, тогда будет то что надо...

Oleg Hohloff aka LonelyWolf

(С) Изобретателей фонариков на солнечных батарейках 2001
Низкоуровневое программирование для дZенствующих
http://hi-tech.nsys.by/

Составитель: Софронов П.Н. (Lonely L)
Все права сохранены
30.11.2001
Харьков 2001
© Софронов П.Н. 2001

Тематические ссылки
Ваша ссылка Ваша ссылка

Обмен кнопками, ведение статистики, реклама.