· Начало · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› SEH на fasm

. 1 . 2 . >>

Посл.отвђт Сообщенiе


Дата: Июл 13, 2004 03:32:37

Как енто реализовать? Что-то я не видле примеров. Всякие FS:[0] фасму не нравятся.


Дата: Июл 13, 2004 03:39:44

Так вроде ничего, ему нравится :-)))
mov [fs:0], eax


Дата: Июл 13, 2004 03:52:12

Asterix
В очередной раз СПАСИБО-)


Дата: Июл 14, 2004 03:28:30

Asterix
Не. Не помогло. Примерчика у вас нету??


Дата: Июл 14, 2004 08:54:49

Marazm
А чем отличается SEH на fasm от, скажем, того же SEH на масме? SEH он и в африке SEH. Ну а примерчик пусть будет такой:
sub ebx, ebx
call Add_SEH

proc handler, pExcept, pFrame, pContext, pDispatch
enter
				
sub eax, eax
			
return
				
Add_SEH:
push dword [fs:ebx]
mov dword [fs:ebx], esp


Дата: Июл 14, 2004 09:11:17

; SEH example by Asterix, 2004
; a_sterix_44_1@mail.ru

format PE GUI 4.0
entry start

include '%fasminc%\win32a.inc'
include 'struct.inc'

struc _SEH
 {
     .SafeEip   dd   ?       ; The offset where it's safe to continue execution
     .PrevEsp   dd   ?       ; The previous value of esp
     .PrevEbp   dd   ?       ; The previous value of ebp
 }
struct _SEH


section '.data' data readable writeable

szCaption       db "MMX Info",0
szSupported     db "CPU supports MMX !",0
szNotSupported  db "CPU not supports MMX !",0
align 4
_seh   _SEH

section '.code' code readable executable

align 4
cproc DefaultExceptionHandler, pExcept, pFrame, pContext, pDispatch
enter
   lea eax, [_seh]
     virtual at eax
                sh   _SEH
     end virtual
   push [sh.SafeEip]
   push [sh.PrevEsp]
   push [sh.PrevEbp]

   mov eax, [pContext]
     virtual at eax
                con   CONTEXT
     end virtual
   pop [con.Ebp]
   pop [con.Esp]
   pop [con.Eip]

   ; reload context & continue execution
   xor eax, eax     ; return ExceptionContinueExecution
   return
endp

align 4
proc MMX_test
.fMMX  dd  ?
enter
   and [.fMMX], FALSE
;  _try
   push DefaultExceptionHandler
   push DWORD [fs:0]
   mov [fs:0], esp
   mov [_seh.SafeEip], .SafePlace
   mov [_seh.PrevEbp], ebp
   mov [_seh.PrevEsp], esp
;int 3
   emms
   inc [.fMMX]
;  _finally
.SafePlace:
   pop DWORD [fs:0]
   add esp, 4
   mov eax, [.fMMX]
   return
endp

align 4
start:
   call MMX_test
   test eax, eax
   jnz @F
   mov eax, szNotSupported
   jmp @message
@@:
   mov eax, szSupported
@message:
   invoke MessageBox, NULL, eax, szCaption, MB_OK or MB_ICONINFORMATION
   invoke ExitProcess, 0


section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

include '%fasminc%\APIA\KERNEL32.INC'
include '%fasminc%\APIA\USER32.INC'



_322880222__SEH.rar


Дата: Июл 14, 2004 10:47:38

Hangatyr
Кстати, SEHHandler должен быть cdecl.


Дата: Июл 14, 2004 19:26:05
Правка

Кстати, а кто-нибудь скажет, откуда взялся такой синтаксис при работе с сегментными регистрами? Кажется, в доках Intel'а или AMD такого не было.


Дата: Июл 14, 2004 21:55:53

На бис, модный сейчас, вариант без прыжков ;-)
; SEH example by Asterix, 2004
; a_sterix_44_1@mail.ru

format PE GUI 4.0
entry start

include '%fasminc%\win32a.inc'
include 'struct.inc'

struc _SEH
 {
     .SafeEip   dd   ?       ; The offset where it's safe to continue execution
     .PrevEsp   dd   ?       ; The previous value of esp
     .PrevEbp   dd   ?       ; The previous value of ebp
 }
struct _SEH


section '.data' data readable writeable

szCaption       db "MMX Info",0
szSupported     db "CPU supports MMX !",0
szNotSupported  db "CPU not supports MMX !",0
align 4
_seh   _SEH

section '.code' code readable executable

align 4
cproc DefaultExceptionHandler, pExcept, pFrame, pContext, pDispatch
enter
   lea eax, [_seh]
     virtual at eax
                sh   _SEH
     end virtual
   push [sh.SafeEip]  ; здесь можно без virtual так:  push [eax+_SEH.SafeEip]
   push [sh.PrevEsp]
   push [sh.PrevEbp]

   mov eax, [pContext]
     virtual at eax
                con   CONTEXT
     end virtual
   pop [con.Ebp]
   pop [con.Esp]
   pop [con.Eip]

   ; reload context & continue execution
   xor eax, eax     ; return ExceptionContinueExecution
   return
endp

align 4
proc MMX_test
.fMMX  dd  ?
enter
   and [.fMMX], FALSE
;  _try
   push DefaultExceptionHandler
   push DWORD [fs:0]
   mov [fs:0], esp
   mov [_seh.SafeEip], .SafePlace
   mov [_seh.PrevEbp], ebp
   mov [_seh.PrevEsp], esp
; int 3
   emms
   inc [.fMMX]
;  _finally
.SafePlace:
   pop DWORD [fs:0]
   add esp, 4
   mov eax, [.fMMX]
   return
endp

align 4
start:
   call MMX_test
   mov ecx, (szNotSupported-szSupported)
   cmp eax, 1
   sbb eax, eax
   and ecx, eax
   lea eax, [szSupported+ecx]
   invoke MessageBox, NULL, eax, szCaption, MB_OK or MB_ICONINFORMATION
   invoke ExitProcess, 0


section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

include '%fasminc%\APIA\KERNEL32.INC'
include '%fasminc%\APIA\USER32.INC'


Дата: Июл 14, 2004 22:07:15 · Поправил: Asterix

И окончательный вариант:
start:
   call MMX_test
   mov ecx, (szNotSupported-szSupported)
   dec eax
   and ecx, eax
   lea eax, [szSupported+ecx]
   invoke MessageBox, NULL, eax, szCaption, MB_OK or MB_ICONINFORMATION
   invoke ExitProcess, 0


Дата: Июл 15, 2004 14:12:47

Вариант с использованием макросов try & finally, по аналогии с макросами Four-F.
Теоретически можно использовать вложенные конструкции, но это как следует ещё не тестировалось :)

format PE GUI 4.0
entry start


include '%fasminc%\win32a.inc'
include '%fasminc%\macro\struct.inc'


struc	SEH
{
	.SafeEip   dd	?	; The offset where it's safe to continue execution
	.PrevEsp   dd	?	; The previous value of esp
	.PrevEbp   dd	?	; The previous value of ebp
}
struct	SEH

struc	CONTEXT
{
	.ContextFlags	dd ?	; The flags values within this flag control the contents of a CONTEXT record.

	; This section is specified/returned if CONTEXT_DEBUG_REGISTERS is set in ContextFlags
	.Dr0	dd ?
	.Dr1	dd ?
	.Dr2	dd ?
	.Dr3	dd ?
	.Dr6	dd ?
	.Dr7	dd ?

	; This section is specified/returned if the ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
	.FloatSave	rb 80+8*4	; FLOATING_SAVE_AREA

	; This section is specified/returned if the ContextFlags word contians the flag CONTEXT_SEGMENTS.
	.SegGs	dd ?
	.SegFs	dd ?
	.SegEs	dd ?
	.SegDs	dd ?

	; This section is specified/returned if the ContextFlags word contians the flag CONTEXT_INTEGER.
	.Edi	dd ?
	.Esi	dd ?
	.Ebx	dd ?
	.Edx	dd ?
	.Ecx	dd ?
	.Eax	dd ?

	; This section is specified/returned if the ContextFlags word contians the flag CONTEXT_CONTROL.
	.Ebp	dd ?
	.Eip	dd ?
	.SegCs	dd ?		; MUST BE SANITIZED
	.EFlags	dd ?		; MUST BE SANITIZED
	.Esp	dd ?
	.SegSs	dd ?

	; This section is specified/returned if the ContextFlags word contains the flag CONTEXT_EXTENDED_REGISTERS.
	; The format and contexts are processor specific
	MAXIMUM_SUPPORTED_EXTENSION = 512
	.ExtendedRegisters	rb MAXIMUM_SUPPORTED_EXTENSION
}
struct	CONTEXT;


macro	.assume	reg, structure
{
	virtual	at reg
		.#reg structure
	end virtual
}


macro	try	ExceptionHandler
{
	local	..SafePlace
	macro	finally
	_^
		..SafePlace:		
		popd	[fs:0]
		add	esp, 4
	^_
	if ExceptionHandler eq
		push	DefaultExceptionHandler
	else
		push	ExceptionHandler
	end if
	pushd	[fs:0]
	mov	[fs:0], esp
	mov	[seh.SafeEip], ..SafePlace
	mov	[seh.PrevEbp], ebp
	mov	[seh.PrevEsp], esp
}

_^	fix {
^_	fix }


start:
	mov	eax, szExeption

try
	int3
	mov	eax, szNoExeption	
	
finally
	invoke	MessageBox, NULL, eax, szCaption, MB_OK or MB_ICONINFORMATION
	invoke	ExitProcess, 0


DefaultExceptionHandler:
;	.pExcept	equ esp+04h
;	.pFrame		equ esp+08h
	.pContext	equ esp+0Ch
;	.pDispatch	equ esp+10h

	mov	eax, seh
	.assume	eax, SEH
	push	[.eax.SafeEip]
	push	[.eax.PrevEsp]
	push	[.eax.PrevEbp]

	mov	eax, [.pContext+3*4]
	.assume	eaX, CONTEXT	; X заглавная, чтобы не было конфликта с предыдущим .assume
	pop	[.eaX.Ebp]
	pop	[.eaX.Esp]
	pop	[.eaX.Eip]

	; reload context & continue execution
	xor	eax, eax     ; return ExceptionContinueExecution
	retn



szCaption	db "SEH test",0
szExeption	db "Exeption occured",0
szNoExeption	db "No exeption occured",0
align 4
seh	SEH


data import
	library kernel32,'KERNEL32.DLL',\
		  user32,'USER32.DLL'

	include '%fasminc%\APIA\KERNEL32.INC'
	include '%fasminc%\APIA\USER32.INC'
end data


Дата: Июл 15, 2004 14:48:05

S_T_A_S_

Прицепи свой исходник в аттач пожалуйста, а то из-за табуляции его нельзя нормально скопировать через clipboard, не терплю табуляцию, пробелы нужно юзать ;-)

У Four-F там конечно посложнее и многое учитывается, но нужно ж с чего-то начинать :-)


Дата: Июл 15, 2004 15:26:37

Asterix

Вот, скопировал сам :)

А что у Four-F ещё учитывается, а то я не сильно понимаю макроязак MASM?
Вроде проверяется на вложенность SEH-фреймов, а так же использование finally без try.
Но у меня макрос finally не существует в принципе, пока не использован try.
Ещё SafePlace у меня нельзя явно указывать, но я не совсем понял, зачем это нужно :(
В общем-то добавить не долго, современем можно улучшить :)

По поводу вложенности - пока необходимо делать так:
finally
purge finally
Последняя строка необходима, что бы вернуться на уровень вверх, т.е. следующий finally будет соответствовать предыдущему try и т.п.
Privalov говорил, что возможно сделает расширение для команды fix, так что тогда это ограничение будет снято.
Если вложенные try/finally не используются, то purge можно не писать - смысла нет.


_1848160404__seh.zip


Дата: Июл 15, 2004 21:29:06

S_T_A_S_
> Вот, скопировал сам :)

Спасибо! Может оно в 2k/XP и нормально копируется не знаю, в 98-й всё слепляется..

> а то я не сильно понимаю макроязак MASM?

Я тоже :-)

> Вроде проверяется на вложенность SEH-фреймов, а так же использование finally без try.

Да, вроде так, ещё мессаги наверно должны выдаваться об ошибках(не знаю в fasm это реализовано?), кажется ещё выравнивается структура SEH автоматом, но в этом я не уверен.


Дата: Июл 16, 2004 11:01:16

Дык мессаги тоже будут выдаваться, родные FASM'овские, если будут try без finally, finally без try или 2 раза finally.
В общем, смысл такой, что каждому try должен соответствовать свой finally, иначе FASM будет ругаться что символ не определён или наоборот уже определён, указывая строку с ошибкой.

Можно было бы свои сообщения написать, используя DISPLAY, но тогда будет выдаваться несколько сообщений сразу
и в них можно будет запутаться :).


Кстати, по поводу названий.
Four-F использовал названия по аналогии с MSVC, но там есть ещё макрос __exept, определяющий обработчик исключений.
В данном случае он как бы объединён с _try, так что может выглядеть несколько нелогично учитывая смысл этого слова.
Может как-нибудь по-другому их назвать?
Вроде instal_SEH / remove_SEH - это imho лучше отображает суть, но писанины больше =)

. 1 . 2 . >>