flat assembler
Message board for the users of flat assembler.
Index
> Windows > SEH to FASM Goto page 1, 2 Next |
Author |
|
ic2 27 Mar 2008, 02:33
The attachment is a old y0da SEH code i use in masm and poasm. The changes I made are gear for fasm. I use to translate MASM code to work for POASM and now I realize since working with FASM most of my MASM to POASM code works for FASM with very few if any modification.
Anyway, I came a long way in my short time using FASM but now you see the mess I made below trying to get this to work and I'm totally loss. I don't really know much about macros but I would like to see this translated to FASM macros and also manually as I been trying to do for days. ASSUME : FS:NOTHING is killing me. I been all over the forum but found nothing that replace it. But I found a lot to get where I got so far and see that a lot match POASM syntax. I would really appreciate help getting this done. It's a bit much to ask but this done totally wore me and I can move on. I don't think I'm missing much. I just don't know what it is Thanks in advance The zip attached is a masm32 working code Code: format PE GUI 4.0 entry start include '\fasm\include\win32a.inc' include '\fasm\include\macro\struct.inc' include '\fasm\include\macro\proc32.inc' include '\fasm\include\macro\UNTIL1.inc' include '\fasm\include\macro\if.inc' include '\fasm\include\macro\com32.inc' include '\fasm\include\macro\import32.inc' include '\fasm\include\macro\export.inc' include '\fasm\include\macro\masm.inc' ;struc CHAR val { match any, val \{ . db val \} ; match , val \{ . db ? \} } SIZE_OF_80387_REGISTERS1 equ 80 MAXIMUM_SUPPORTED_EXTENSION1 equ 512 ExceptionContinueExecution1 equ 0 struct FLOATING_SAVE_AREA1 ControlWord dd ? StatusWord dd ? TagWord dd ? ErrorOffset dd ? ErrorSelector dd ? DataOffset dd ? DataSelector dd ? RegisterArea db SIZE_OF_80387_REGISTERS1 dup(?) Cr0NpxState dd ? ends struct CONTEXT1 ContextFlags dd ? iDr0 dd ? iDr1 dd ? iDr2 dd ? iDr3 dd ? iDr6 dd ? iDr7 dd ? FloatSave FLOATING_SAVE_AREA1 <> regGs dd ? regFs dd ? regEs dd ? regDs dd ? regEdi dd ? regEsi dd ? regEbx dd ? regEdx dd ? regEcx dd ? regEax dd ? regEbp dd ? regEip dd ? regCs dd ? regFlag dd ? regEsp dd ? regSs dd ? ExtendedRegisters db MAXIMUM_SUPPORTED_EXTENSION1 dup(?) ends ;---- STRUCTs ---- struct sSEH OrgEsp dd ? OrgEbp dd ? SaveEip dd ? ends ;---- MACROs ---- ;macro InstSehFrame ContinueAddr ; ; push dd[fs:0];;;assume eax:00h ; IFNDEF SehStruct ; SehStruct EQU 1 ; .DATA ; SEH sSEH <> ; ENDIF ; .CODE ; mov SEH.SaveEip, ContinueAddr ; mov SEH.OrgEbp, EBP ; push OFFSET SehHandler ; push FS:[0] ; mov SEH.OrgEsp, ESP ; mov FS:[0], ESP ;ENDM ;....................................... ;....................................... ;....................................... section '.code' code readable executable start: PUSH 0 PUSH 0 PUSH Just_Here PUSH 0 CALL [MessageBox] ;push SehHandler ; push dword [fs:0] ; mov [fs:0], esp ; some code goes here ;;mov [ContinueAddr], SavePlace2 ;; 1 ; InstSehFrame <OFFSET SavePlace1> ; assume fs: 0 ;;nothing push dword[fs:0] mov [SEH.SaveEip], ContinueAddr mov [SEH.OrgEbp], EBP push SehHandler push dword [fs:0] ; push FS:[0] mov [SEH.OrgEsp], ESP mov [fs:0], esp ; mov FS:[0], ESP XOR eax, eax ; CRASH CODE 1 XCHG DWORD PTR eax, eax ;.............................................. ;.............................................. SavePlace1: ; KillSehFrame pop dword [fs:0] add ESP, 4 PUSH 0 PUSH 0 PUSH One_In_The_Way PUSH 0 CALL [MessageBox] ; InstSehFrame <OFFSET SavePlace2> mov [SEH.SaveEip], ContinueAddr mov [SEH.OrgEbp], EBP push SehHandler push dword [fs:0] ; push FS:[0] mov [SEH.OrgEsp], ESP mov [fs:0], esp ; mov FS:[0], ESP ;push SehHandler ; push dword [fs:0] ; mov [fs:0], esp ; some code goes here XOR EBX, EBX ; CRASH CODE 2 XOR EDX, EDX mov eax, 2 DIV EBX ;............................................................ Success ;............................................................ SavePlace2: ; KillSehFrame pop dword [fs:0] add ESP, 4 PUSH 0 PUSH 0 PUSH Two_Equ_Success PUSH 0 CALL [MessageBox] ;popa ; ###################################################################### ; ###################################################################### proc SehHandler pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD ;mov eax, pContext ;ASSUME eax : PTR CONTEXT1 MOV EAX, [pContext] PUSH [SEH.SaveEip] POP [EAX+CONTEXT1.regEip] ; ASSUME eax : PTR CONTEXT1 PUSH SEH.OrgEsp POP [EAX+CONTEXT1.regEsp] PUSH SEH.OrgEbp POP [EAX+CONTEXT1.regEbp] MOV EAX, 0 ;;ExceptionContinueExecution1 RET endp ;.............................................. ;.............................................. section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '\fasm\include\apia\kernel32.inc' include '\fasm\include\apia\user32.inc' ;....................................... ;....................................... section '.data' data readable writeable Just_Here db 'Just Something to show so I can feel better',0 One_In_The_Way db "Anything",0 Two_Equ_Success db "SEH succeed ",0 ContinueAddr dd 0 SEH sSEH <> section '.Udata' readable writeable
|
|||||||||||
27 Mar 2008, 02:33 |
|
asmfan 27 Mar 2008, 06:53
Quote:
Isn't PrevEsp should be before setting up a seh frame on stack? |
|||
27 Mar 2008, 06:53 |
|
revolution 27 Mar 2008, 07:05
asmfan wrote: Isn't PrevEsp should be before setting up a seh frame on stack? Code: pushd [fs:0] mov [esp+SEH.PrevEsp],esp mov [fs:0],esp |
|||
27 Mar 2008, 07:05 |
|
asmfan 27 Mar 2008, 07:59
I mean this
Code: macro _enter_ seh*, SafeOffset*, CurrentHandler*{ mov [seh+SEH.PrevEsp],esp mov [seh+SEH.PrevEbp],ebp mov [seh+SEH.SafeOffset],SafeOffset mov [seh+SEH.CurrentHandler],CurrentHandler push DWORD [fs:0] pop [seh+SEH.PrevLink] lea eax,[seh] mov [fs:0],eax } where esp saved first before any SEH related stuff is pushed to the stack. We have clean stack pointer saved. Actually I'm not sure about which moment esp should be saved (before new SEH frame installed on stack or after) - i prefer before installation . Anyone have explanations & arguments? |
|||
27 Mar 2008, 07:59 |
|
revolution 27 Mar 2008, 08:08
asmfan wrote: I mean this Also note that your SEH frame must be on the stack else the OS will consider it a corrupted state and will terminate your app. If you use the above macro with memory allocated on the heap (or some other non-stack memory) then it definitely won't work by design. |
|||
27 Mar 2008, 08:08 |
|
asmfan 27 Mar 2008, 08:26
You're totally right - the structure defined as local variable (on procedure's stack) - no problem, but i'm talking about which esp consider as PrevEsp - before setting seh or after. I'm sure your app works when no exceptions but have you tested it if there exception inside? say int3 - then which will be esp? eip will be SafeOffset but esp? it will hold part (or whole) just setted seh frame while stack should(?) be clean(d) of this frame.
|
|||
27 Mar 2008, 08:26 |
|
revolution 27 Mar 2008, 08:59
asmfan wrote: but have you tested it if there exception inside? |
|||
27 Mar 2008, 08:59 |
|
asmfan 27 Mar 2008, 09:49
Yes, the store to PrevEsp must be after new seh frame installed. If any exception occur we return to safe place where we unstall our seh frame which is located in stack obtained by PrevEsp.
|
|||
27 Mar 2008, 09:49 |
|
revolution 27 Mar 2008, 11:02
asmfan wrote: Yes, the store to PrevEsp must be after new seh frame installed. If any exception occur we return to safe place where we unstall our seh frame which is located in stack obtained by PrevEsp. But just to be complete, when I was testing the exception thing (many years ago) I discovered that the OS only cares about the first two parameters in the SEH structure, after that you can do whatever you like. ESP, EBP and SafeOffset can be absent but of course then your handler code will have difficulty recovering if it needs to. Sometimes an exception is fatal and recovery doesn't make sense so a handler in that situation might simply kill the thread and never need the extra parameters. |
|||
27 Mar 2008, 11:02 |
|
ic2 27 Mar 2008, 21:55
http://courses.ece.uiuc.edu/ece390/books/artofasm/CH08/CH08-3.html#HEADING3-98
This is about all I could find about segment override using FS that gave a real clue. http://kos.enix.org/pub/iinfor.html mov ax, fs:[eax] ... and this didn't work for me even in the masm seh example I posted. How would I over ride ASSUME FS : NOTHING to work for masm but mainly for fasm since it seems it don't include it or have a work around? I use keyword [ASSUME FS : NOTHING] and phase has not even been used on this forum. Why? Is everyone that heavy around here? ... If it's not in there they write it ... Well these docs will make good reading someday soon. BTW: All of the above are some great tips. Thanks... I'll be working with them by tonight but I got a feeling not knowing how to do segment overide of FS: is still going to be a problem. It's a lot more to assembler than I ever imagine to explore. So this what they call the nitty gitty asmfan, I now understand how FASM macros works. Glad you posted. |
|||
27 Mar 2008, 21:55 |
|
revolution 27 Mar 2008, 22:33
ic2: There is an "assume" macro in the MASM.INC file. It provides a similar functionality to the masm "assume".
But with fasm you don't need "assume" at all. Just delete it and put your segment overrides directly. |
|||
27 Mar 2008, 22:33 |
|
ic2 28 Mar 2008, 00:01
include '\fasm\include\macro\masm.inc'
assume fs : NOTHING ; assume [fs:0] ;mov ax, [fs:eax] mov [SEH.SaveEip], SavePlace1 mov [SEH.OrgEbp], EBP push SehHandler pushd [fs:0] mov [SEH.OrgEsp], ESP mov [fs:0],esp I used masm.inc and it didn't work. Quote: Just delete it and put your segment overrides directly. What is my segment overrides? |
|||
28 Mar 2008, 00:01 |
|
revolution 28 Mar 2008, 00:06
"fs:" is a segment override, and you are already putting it directly. The "assume fs : NOTHING" has no effect on your code and is not needed.
|
|||
28 Mar 2008, 00:06 |
|
ic2 28 Mar 2008, 00:40
If this is what you mean than Fasm is not letting it work that way.
Code: mov [SEH.SaveEip], SavePlace1 mov [SEH.OrgEbp], EBP push SehHandler pushd [fs:0] mov [SEH.OrgEsp], ESP mov [fs:0],esp .... ..... ...... proc SehHandler ....... mov eax, [pContext] PUSH SEH.SaveEip POP [EAX+CONTEXT1.reg_Eip] PUSH SEH.OrgEsp POP [EAX+CONTEXT1.reg_Esp] PUSH SEH.OrgEbp POP [EAX+CONTEXT1.reg_Ebp] MOV EAX, 0;ExceptionContinueExecution1 RET |
|||
28 Mar 2008, 00:40 |
|
revolution 28 Mar 2008, 00:45
As you can see in my code above it does not need "assume ...". Just ignore the assume thing.
ic2 wrote:
You need a register offset. Something like this: Code: sub esp,sizeof.SEH mov eax,esp mov [eax+SEH.SaveEip], SavePlace1 ... |
|||
28 Mar 2008, 00:45 |
|
ic2 28 Mar 2008, 01:29
What is .catch. If it's a macro what is it listed under. I give up on what I was working on. Nothing worked. Something not right. I'll read the docs to learn about segment override. Right now too many other books (boring stuff) I got to read before HW is due none ASM related. Thanks for taking out the time to deal with a rookie like me. I got your code set up all ready but I don't know about .catch.
|
|||
28 Mar 2008, 01:29 |
|
revolution 28 Mar 2008, 01:49
catch = SavePlace1, this is where execution goes when the exception handler returns.
Segment override is when your put in things like "fs:" to override the default "ds:" segment. |
|||
28 Mar 2008, 01:49 |
|
ic2 28 Mar 2008, 01:50
I'm sure I got everything about your code included here but it's not working. What am I doing wrong again?
Code: format PE GUI 4.0 entry start include '\fasm\include\win32a.inc' SIZE_OF_80387_REGISTERS1 equ 80 MAXIMUM_SUPPORTED_EXTENSION1 equ 512 ExceptionContinueExecution1 equ 0 EXCEPTION_MAXIMUM_PARAMETERS equ 15 struct EXCEPTION_RECORD ExceptionCode dd ? ExceptionFlags dd ? pExceptionRecord dd ? ExceptionAddress dd ? NumberParameters dd ? ExceptionInformation dd EXCEPTION_MAXIMUM_PARAMETERS dup(?) ends struct FLOATING_SAVE_AREA1 ControlWord dd ? StatusWord dd ? TagWord dd ? ; ** ErrorOffset dd ? ErrorSelector dd ? ; ** DataOffset dd ? DataSelector dd ? RegisterArea db SIZE_OF_80387_REGISTERS1 dup(?) Cr0NpxState dd ? ends struct CONTEXT1 ContextFlags dd ? iDr0 dd ? iDr1 dd ? iDr2 dd ? iDr3 dd ? iDr6 dd ? iDr7 dd ? FloatSave FLOATING_SAVE_AREA1 <> reg_Gs dd ? ; gs register reg_Fs dd ? ; fs register reg_Es dd ? ; es register reg_Ds dd ? ; ds register reg_Edi dd ? reg_Esi dd ? reg_Ebx dd ? reg_Edx dd ? reg_Ecx dd ? reg_Eax dd ? reg_Ebp dd ? ; SEH reg_Eip dd ? ; SEH reg_Cs dd ? ; cs register reg_Flag dd ? ; eflags register reg_Esp dd ? ; esp register ; SEH reg_Ss dd ? ; ss register ExtendedRegisters db MAXIMUM_SUPPORTED_EXTENSION1 dup(?) ends struct SEH PrevLink dd ? ;the address of the previous seh structure CurrentHandler dd ? ;the address of the exception handler SafeOffset dd ? ;The offset where it's safe to continue execution PrevEsp dd ? ;the old value in esp PrevEbp dd ? ;The old value in ebp ends ;KillSehFrame MACRO ; pop FS:[0] ; add ESP, 4 ;ENDM section '.data' data readable writeable _title db 'Win32 program template',0 _class db 'FASMWIN32',0 exception_addr dd 0 exception_code dd 0 szGood db "SEH succeed ",0 ; SEH sSEH <0> section '.code' code readable executable start: pushd ebp pushd esp pushd .catch pushd handler pushd [fs:0] mov [fs:0],esp mov [esp+SEH.PrevEsp],esp ; CRASH CODE 1 XOR eax, eax XCHG DWORD PTR eax, eax .catch: mov esp,[fs:0] popd [fs:0] add esp,16 PUSH 0 PUSH 0 PUSH _title PUSH 0 CALL [MessageBox] handler: virtual at esp+4 .pExcept dd ? .pFrame dd ? .pContext dd ? .pDispatch dd ? end virtual mov edx,[.pFrame] mov ecx,[.pContext] mov eax,[edx+SEH.PrevEsp] mov edx,[edx+SEH.SafeOffset] mov [ecx+CONTEXT1.reg_Esp],eax mov eax,[.pExcept] mov eax,[eax+EXCEPTION_RECORD.ExceptionCode] xchg [ecx+CONTEXT1.reg_Eip],edx mov [exception_addr],edx mov [exception_code],eax section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '\fasm\include\apia\kernel32.inc' include '\fasm\include\apia\user32.inc' |
|||
28 Mar 2008, 01:50 |
|
revolution 28 Mar 2008, 02:01
Oh, my handler code was only an example and was not complete, that is why I put the three dots (...) to show that more was needed.
Anyhow this will work okay: Code: format PE GUI 4.0 entry start include '\fasm\include\win32a.inc' SIZE_OF_80387_REGISTERS1 equ 80 MAXIMUM_SUPPORTED_EXTENSION1 equ 512 ExceptionContinueExecution1 equ 0 EXCEPTION_MAXIMUM_PARAMETERS equ 15 struct EXCEPTION_RECORD ExceptionCode dd ? ExceptionFlags dd ? pExceptionRecord dd ? ExceptionAddress dd ? NumberParameters dd ? ExceptionInformation dd EXCEPTION_MAXIMUM_PARAMETERS dup(?) ends struct FLOATING_SAVE_AREA1 ControlWord dd ? StatusWord dd ? TagWord dd ? ; ** ErrorOffset dd ? ErrorSelector dd ? ; ** DataOffset dd ? DataSelector dd ? RegisterArea db SIZE_OF_80387_REGISTERS1 dup(?) Cr0NpxState dd ? ends struct CONTEXT1 ContextFlags dd ? iDr0 dd ? iDr1 dd ? iDr2 dd ? iDr3 dd ? iDr6 dd ? iDr7 dd ? FloatSave FLOATING_SAVE_AREA1 <> reg_Gs dd ? ; gs register reg_Fs dd ? ; fs register reg_Es dd ? ; es register reg_Ds dd ? ; ds register reg_Edi dd ? reg_Esi dd ? reg_Ebx dd ? reg_Edx dd ? reg_Ecx dd ? reg_Eax dd ? reg_Ebp dd ? ; SEH reg_Eip dd ? ; SEH reg_Cs dd ? ; cs register reg_Flag dd ? ; eflags register reg_Esp dd ? ; esp register ; SEH reg_Ss dd ? ; ss register ExtendedRegisters db MAXIMUM_SUPPORTED_EXTENSION1 dup(?) ends struct SEH PrevLink dd ? ;the address of the previous seh structure CurrentHandler dd ? ;the address of the exception handler SafeOffset dd ? ;The offset where it's safe to continue execution PrevEsp dd ? ;the old value in esp PrevEbp dd ? ;The old value in ebp ends ;KillSehFrame MACRO ; pop FS:[0] ; add ESP, 4 ;ENDM section '.data' data readable writeable _title db 'Win32 program template',0 _class db 'FASMWIN32',0 exception_addr dd 0 exception_code dd 0 szGood db "SEH succeed Smile",0 ; SEH sSEH <0> section '.code' code readable executable start: pushd ebp pushd esp pushd .catch pushd handler pushd [fs:0] mov [fs:0],esp mov [esp+SEH.PrevEsp],esp ; CRASH CODE 1 XOR eax, eax XCHG DWORD PTR eax, eax .catch: mov esp,[fs:0] popd [fs:0] add esp,16 PUSH 0 PUSH 0 PUSH _title PUSH 0 CALL [MessageBox] push 0 ;return code call [ExitProcess] handler: virtual at esp+4 .pExcept dd ? .pFrame dd ? .pContext dd ? .pDispatch dd ? end virtual mov edx,[.pFrame] mov ecx,[.pContext] mov eax,[edx+SEH.PrevEsp] mov edx,[edx+SEH.SafeOffset] mov [ecx+CONTEXT1.reg_Esp],eax mov eax,[.pExcept] mov eax,[eax+EXCEPTION_RECORD.ExceptionCode] xchg [ecx+CONTEXT1.reg_Eip],edx mov [exception_addr],edx mov [exception_code],eax mov eax,0 ;0=I handled it ret 16 section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '\fasm\include\apia\kernel32.inc' include '\fasm\include\apia\user32.inc' |
|||
28 Mar 2008, 02:01 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.