flat assembler
Message board for the users of flat assembler.
Index
> Windows > [x64] Exception Handling? |
Author |
|
revolution 13 Feb 2012, 06:01
While I am not experienced with 64-bit SEH I can already see that using dword is probably not a good idea. At least try with qword and rsp, rax etc.
|
|||
13 Feb 2012, 06:01 |
|
yoshimitsu 13 Feb 2012, 06:07
Good morning :)
This snippet is just a short x86 SEH-snippet to show what I would like to achieve in x64 |
|||
13 Feb 2012, 06:07 |
|
Feryno 13 Feb 2012, 06:47
|
|||
13 Feb 2012, 06:47 |
|
yoshimitsu 13 Feb 2012, 08:30
man, I've used the forum's internal search & google to search through the forum, but couldn't find one topic of interest..
Guess I was using the wrong keywords.. Thanks Feryno, I'll look into it. Btw. I'm just a noob so it doesn't mean anything, but I enjoy using your neat 64bit debugger :) Edit: I was trying something like Code: db 1+1 shl 3 ;Version 3 & Flags 5 db 0 ;SizeOfProlog db 0 ;CountOfCodes db 00000000b ;FrameRegister 4 & FrameOffset 4 dw 0 ;FrameOffset / CodeOffset + UnwindOp 4 & OpInfo 4 dw 0 ;align dd rva handler ;ExceptionHandler dd 0 ;ExceptionData :s I thought about using VEH, but I assumed SEH had less overhead and therefore chose SEH So as x64 SEH uses a global address table it is logically not per-thread as x86 SEH, is it?.. Then what are the benefits or drawbacks compared to VEH? |
|||
13 Feb 2012, 08:30 |
|
Feryno 14 Feb 2012, 13:12
Hi,
no worry, there is so much info in the fasm forum that sometimes it is hard to find what you need (I found the result because I already posted something you asked for, so I added my nickname to the search filter) And yes, you are right, every thread hits the same exception handler in the above sample. I didn't find any way of exception handling specific to thread. Under x64 everything specific to thread is stored in GS (as under 32 bits everything is under FS), most of these fields expanded from dword to qword, also added some padding so e.g. every qword field is aligned at 8 at FS:[0] for i386 there is struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList but under x64 there is union _KGDTENTRY64 *GdtBase at GS:[0] and nothing concerning exception handling wait, I just now have some crazy idea: the FS:0 is still present under x64 for compatibility mode, there is also an easy way to switch native x64 code from x64 to 32 bit from usermode (no need any driver) and then back from 32 bit compatibility to native x64 you may do quick short research whether it is possible to do something sensefull in exception handling in that way (whether the installed SEH under 32 doesn't disappear when returning back into 64 or whether it works as expected) N.B. that some code will be executed as 32 bit code so then you can't access registers r8-r15 either you can use only low dwords of remaining 8 GPRs (eax, ecx, ... edi), call/ret then operates on dword of stack not qword etc 64-32-64.asm Code: ; ripped from ntdbg.h AMD64_KGDT64_NULL = (0 * 16) ; NULL descriptor AMD64_KGDT64_R0_CODE = (1 * 16) ; kernel mode 64-bit code AMD64_KGDT64_R0_DATA = (1 * 16) + 8 ; kernel mode 64-bit data (stack) AMD64_KGDT64_R3_CMCODE = (2 * 16) ; user mode 32-bit code AMD64_KGDT64_R3_DATA = (2 * 16) + 8 ; user mode 32-bit data AMD64_KGDT64_R3_CODE = (3 * 16) ; user mode 64-bit code AMD64_KGDT64_SYS_TSS = (4 * 16) ; kernel mode system task state AMD64_KGDT64_R3_CMTEB = (5 * 16) ; user mode 32-bit TEB AMD64_KGDT64_LAST = (6 * 16) format PE64 GUI at 400000h on 'nul' entry start section '.text' code readable executable start: sub rsp,8*(4+1) xor eax,eax or rdx,-1 lea rcx,[cont1] mov [rsp+8],ecx mov word [rsp+8+4],AMD64_KGDT64_R3_CODE + 11b lea rcx,[cont0] mov [rsp],ecx mov word [rsp+4],AMD64_KGDT64_R3_CMCODE + 11b jmp pword [rsp] cont0: use32 inc eax nop call subproc jmp pword [esp+8] use64 cont1: xor eax,eax add rsp,8*(4+1) ret use32 subproc: pusha or edx,-1 mov ecx,edx popa ret 32-64-32.asm Code: ; ripped from ntdbg.h AMD64_KGDT64_NULL = (0 * 16) ; NULL descriptor AMD64_KGDT64_R0_CODE = (1 * 16) ; kernel mode 64-bit code AMD64_KGDT64_R0_DATA = (1 * 16) + 8 ; kernel mode 64-bit data (stack) AMD64_KGDT64_R3_CMCODE = (2 * 16) ; user mode 32-bit code AMD64_KGDT64_R3_DATA = (2 * 16) + 8 ; user mode 32-bit data AMD64_KGDT64_R3_CODE = (3 * 16) ; user mode 64-bit code AMD64_KGDT64_SYS_TSS = (4 * 16) ; kernel mode system task state AMD64_KGDT64_R3_CMTEB = (5 * 16) ; user mode 32-bit TEB AMD64_KGDT64_LAST = (6 * 16) format PE GUI at 400000h on 'nul' entry start section '.text' code readable executable start: sub esp,16 xor eax,eax mov dword [esp+8],cont1 mov word [esp+8+4],AMD64_KGDT64_R3_CMCODE + 11b mov dword [esp],cont0 mov word [esp+4],AMD64_KGDT64_R3_CODE + 11b jmp pword [esp] cont0: use64 inc rax nop call subproc jmp pword [esp+8] use32 cont1: xor eax,eax add esp,16 ret use64 subproc: dec rax dec rax ret |
|||
14 Feb 2012, 13:12 |
|
yoshimitsu 14 Feb 2012, 18:26
With 64-32-64.asm, it crashes when trying to access either fs:0 or gs:0 in subproc.
Btw. I now got an apparently working rudimentary exception handler thanks to your topic (I wrote a macro to spare making up names for the begin and end-rvas which go into the exception directory): test.asm Code: format PE64 GUI 4.0 entry start include 'win64a.inc' include 'seh64.inc' seh equ 3 CONTEXT64.Rip = 0F8h section '.code' code readable executable start: sub rsp,8*(4+1) .try handler xor eax,eax mov dword[eax],0 .end safe_place: .try xor eax,eax mov dword[eax],0 .catch mov rsp,rdx xor r9,r9 xor r8,r8 lea rdx,[handler2] xor ecx,ecx call [MessageBox] .end xor r9,r9 xor r8,r8 lea rdx,[k] xor ecx,ecx call [MessageBox] xor ecx,ecx call [ExitProcess] handler: sub rsp,8*(4+1) mov qword [r8+CONTEXT64.Rip],safe_place xor r9,r9 xor r8,r8 lea rdx,[handler1] xor ecx,ecx call [MessageBox] xor eax,eax add rsp,8*(4+1) retn section '.data' data readable writeable k db 'k.',0 handler1 db 'in handler1',0 handler2 db 'in handler2',0 data seh end data section '.idata' import data readable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' import kernel32,\ ExitProcess,'ExitProcess' import user32,\ MessageBox,'MessageBoxA' seh64.inc Code: macro enqueue list,item { match any,list \{ list equ list,item \} match ,list \{ list equ item \} } macro dequeue list,item { done@dequeue equ match first=,rest,list \{ item equ first list equ rest restore done@dequeue \} match :m,done@dequeue:list \{ item equ m list equ restore done@dequeue \} match ,done@dequeue \{ item equ restore done@dequeue \} } macro queue list,index,item { local copy copy equ list rept index+1 \{ dequeue copy,item \} } macro data directory { done@data equ match =3,directory \{ local l_infos,_info,_end l_infos equ align 4 match list,l_handlers \\{ irp _handler,list \\\{ local rva$ rva$ = rva $ enqueue l_infos,rva$ db 19h,0,0,0 dd _handler,0 \\\} \\} data 3 match list,l_begins \\{ irp _begin,list \\\{ dequeue l_ends,_end dequeue l_infos,_info dd _begin dd _end dd _info \\\} \\} restore done@data \} match ,done@data \{ data directory restore done@data \} } l_begins equ l_ends equ l_handlers equ macro .try handler { local ..try __TRY equ ..try local ..end __END equ ..end local ..catch __CATCH equ ..catch __TRY: if ~ handler eq virtual at handler __CATCH: end virtual end if } macro .catch { jmp __END __CATCH: } macro .end { __END: enqueue l_begins,rva __TRY enqueue l_ends,rva __END enqueue l_handlers,rva __CATCH restore __TRY restore __END restore __CATCH } |
|||
14 Feb 2012, 18:26 |
|
revolution 15 Feb 2012, 04:33
Feryno wrote: 32-64-32.asm |
|||
15 Feb 2012, 04:33 |
|
Feryno 15 Feb 2012, 14:37
yoshimitsu - great work with the macro !!!
revolution - The 64 bit code launched from compatibility mode is very limited (32-64-32.asm) its ring3 virtual memory space is limited to 32 bit it doesn't contain anything at GS:[...] DLLs loaded into PE executable are all 32 bit (so if you need to call some windows DLL you need to switch back to 32 bit before calling DLL) ... fortunately it seems that OS saves/restores all 16 GPRs including upper dwords during task switching even the main executable image indicates 32 bit submode... I just had an idea using 32-64-32.asm where it is perhaps possible to install SEH using FS:[0], then switch the CPU to 64 bit submode of long mode and try whether exception handler is still working well There is a way how to obtain CS for 64 as well 32 bit no matter version of windows - if somebody change that in the feature, or if you recompile your own kernel - look for WRK (windows research kernel) - a leak is available when are googling enough I would do it in a way like: [0] If you launch PE32+ executable (=64 bit code), then it must launch PE (32bit executable) which executes something like: ; PE 32 bit executable: mov eax,cs ret then the primary PE32+ executable obtains the value of 32 bit CS using GetExitCode [1] If the primary executable is PE (32 bit), then it must launch PE32+ (64 bit) where PE32+ does only the same 2 instructions: mov eax,cs ret and then the primary executable (PE) gets the 64 bit CS value by GetExitCode Such approach is always compatible among all versions of ms windows (no matter released by microsoft or private compiled research kernel). But MS may still develop a version of OS where exectables have various CS (currently all ring0 executables have the same CS, all ring3 64 bit executables have the same, all ring3 compatibility 32 bit have the same). Or MS may decide to create different GDTs for 64 and 32 bit submodes where they will contain only necessary CS (GDT for 64 won't contain CS for 32 bit submode) etc. More problems than real benefit... |
|||
15 Feb 2012, 14:37 |
|
revolution 15 Feb 2012, 14:50
Feryno wrote: If you launch PE32+ executable (=64 bit code), then it must launch PE (32bit executable) which executes something like: Feryno wrote: Or MS may decide to create different GDTs for 64 and 32 bit submodes where they will contain only necessary CS (GDT for 64 won't contain CS for 32 bit submode) etc. Feryno wrote: More problems than real benefit... |
|||
15 Feb 2012, 14:50 |
|
Tomasz Grysztar 15 Feb 2012, 15:16
revolution wrote:
|
|||
15 Feb 2012, 15:16 |
|
revolution 16 Feb 2012, 01:40
Documentation is silent, or says nothing negative about it --leads to--> assumption that it is a valid technique --leads to--> frustration when it fails to work as assumed --leads to--> --leads to--> --leads to--> spending lots of time updating old code that could have easily been avoided the first time around --leads to--> depression --leads to--> suicide. amirite?
|
|||
16 Feb 2012, 01:40 |
|
Tomasz Grysztar 16 Feb 2012, 10:51
revolution wrote: Documentation is silent, or says nothing negative about it --leads to--> assumption that it is a valid technique --leads to--> frustration when it fails to work as assumed --leads to--> --leads to--> --leads to--> spending lots of time updating old code that could have easily been avoided the first time around --leads to--> depression --leads to--> suicide. amirite? |
|||
16 Feb 2012, 10:51 |
|
JohnFound 16 Feb 2012, 11:05
I am agree with Tomasz here, with one exception - ExitProcess stops all threads of the application, not only the main one. As long, as the main thread is not something special stopping it and leaving the other threads to run will leave the application running.
If you provide decent mechanism to stop all threads before exiting the main thread, "ret 4" seems to be absolutely legal and documented way to finish the main thread. Even more, I think (but never try) that you can make all processing in some secondary thread and terminate the main thread just after the start of the application without any problems. |
|||
16 Feb 2012, 11:05 |
|
f0dder 09 Jul 2012, 17:15
JohnFound wrote: If you provide decent mechanism to stop all threads before exiting the main thread, "ret 4" seems to be absolutely legal and documented way to finish the main thread. The discussion has already taken place in the thread Tomasz refers to, so I'm not going to repeat it here. For the TL;DR version: use ExitProcess when you want to terminate your process. Don't even consider the "RET" approach unless you're writing 512byte intros. _________________ - carpe noctem |
|||
09 Jul 2012, 17:15 |
|
Feryno 10 Jul 2012, 05:48
we are completely off topic
if somebody is interested I also have a sample of exception handling for win x64 drivers using exception directory |
|||
10 Jul 2012, 05:48 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.