Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Converting goasm code to masm

74 views
Skip to first unread message

Andy

unread,
Oct 2, 2009, 11:24:10 PM10/2/09
to

I am converting some goasm code to masm, and am having some
difficulties.
I have commented the lines with problems.

Can someone help me?

Thanks.


PUSH OFFSET HANDLER ; )on the
;FS PUSH [0] ; )stack
push dword ptr fs:[0] ; line 68 error A2108: use of register assumed
to ERROR

;FS MOV [0],ESP ;point to structure just established on the
stack
mov dword ptr fs:[0],esp ; line 71 error A2108: use of register
assumed to ERROR


;
;*********************** and now lets cause the exception ..

XOR ECX,ECX ;set ecx to zero
DIV ECX ;divide by zero, causing exception

;*********************** because of the exception the code never gets
to here


SAFE_PLACE: ;but the handler will jump to here ..

;FS POP [0] ;restore original exception handler from stack
pop dword ptr fs:[0] ; line 86 error A2108: use of register assumed
to ERROR

Tim Roberts

unread,
Oct 3, 2009, 9:48:55 PM10/3/09
to

Andy <chocolate...@MUNGED.microcosmotalk.com> wrote:
>
>I am converting some goasm code to masm, and am having some
>difficulties.
>I have commented the lines with problems.
>
>Can someone help me?

Yes. Somewhere near the top of your source file, add this:

assume fs: @data

In 32-bit code, MASM sets the segment register assumes so that CS is
assumed to @code, DS, ES, and SS are assumed to @data, and FS and GS are
assumed to error, to prevent accidental use. To use them, you just have to
override the assumption.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Mint

unread,
Oct 4, 2009, 11:34:23 AM10/4/09
to

On Oct 3, 8:48=A0pm, Tim Roberts <t...@MUNGED.microcosmotalk.com> wrote:

> Andy <chocolatemint77...@MUNGED.microcosmotalk.com> wrote:
>
> >I am converting some goasm code to masm, and am having some
> >difficulties.
> >I have commented the lines with problems.
>
> >Can someone help me?
>
> Yes. =A0Somewhere near the top of your source file, add this:
>
> =A0 =A0 =A0 =A0 assume =A0fs: @data

>
> In 32-bit code, MASM sets the segment register assumes so that CS is
> assumed to @code, DS, ES, and SS are assumed to @data, and FS and GS are
> assumed to error, to prevent accidental use. =A0To use them, you just hav=

e to
> override the assumption.
> --
> Tim Roberts, t...@probo.com
> Providenza & Boekelheide, Inc.

; Written by Jeremy Gordon 2002
; except.asm Conversion of except1.asm (Goasm) to masm code
;
;
.386
.MODEL FLAT, STDCALL
OPTION CASEMAP: NONE

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc
include \masm32\include\shlwapi.inc
include \masm32\macros\macros.asm

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\shlwapi.lib

.DATA

HappyStr db "Except1,This is a very happy ending",0

Except db "Except1,There was an exception - do you want me to
swallow it?",0

Except1 db "Except1",0

Except2 db "Except1 - well it's all over for now.",0

Unwind db "The system calling the handler again for more clearing up
(unwinding)",0

FATALMESS DB "I thoroughly enjoyed it and I have already tidied
everything up - "
DB "you know, completed records, closed file handles, "
DB "released memory, that sort of thing .."
DB "Glad this was by design - bye, bye .."
DB ".. but first, I expect the system will do an unwind ..",
0
.CODE

ASSUME fs:NOTHING ; This statement generates this

; Microsoft (R) Macro Assembler Version 6.14.8444
; Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
;
; Assembling: C:\masm32\SOURCE\except.asm
; Microsoft (R) Incremental Linker Version 5.12.8078
; Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
;
; LINK : error LNK2001: unresolved external symbol _WinMainCRTStartup
; except.exe : fatal error LNK1120: 1 unresolved externals
;
; Link error

START:

; Lets make our final handler which would do all clearing up if the
program has to close

;ASSUME fs:NOTHING

PUSH offset FINAL_HANDLER
CALL SetUnhandledExceptionFilter
CALL PROTECTED_AREA
CALL CLEAR_UP ;here the program clears up normally
PUSH 40h ;exclamation sign + ok button only
push offset Except1
PUSH offset HappyStr
push 0
CALL MessageBoxA ;wait till ok pressed
PUSH 0 ;code meaning a succesful conclusion
CALL ExitProcess ;and finish with aplomb!

; PROGRAM END

PROTECTED_AREA:

;PUSH EBP,0,0 ; )create the
push ebp
push 0
push 0
PUSH OFFSET SAFE_PLACE ; )ERR structure


PUSH OFFSET HANDLER ; )on the
;FS PUSH [0] ; )stack

push dword ptr fs:[0] ; line 71 error A2108: use of register assumed
to ERROR

;FS MOV [0],ESP ;point to structure just established on the
stack

mov dword ptr fs:[0],esp ; line 74 error A2108: use of register
assumed to ERROR

;*********************** and now lets cause the exception ..

XOR ECX,ECX ;set ecx to zero
DIV ECX ;divide by zero, causing exception

;*********************** because of the exception the code never gets
to here

SAFE_PLACE: ;but the handler will jump to here ..

;FS POP [0] ;restore original exception handler from stack
pop dword ptr fs:[0] ; line 86 error A2108: use of register assumed
to ERROR

ADD ESP,14h ;throw away remainder of ERR structure made
earlier
RET

;This simple handler is called by the system when the divide by zero
;occurs.In this handler the user is given a choice of swallowing the
;exception by jumping to the safe-place, or not dealing with it at
all,
;in which case the system will send the exception to the FINAL_HANDLER

HANDLER:

;save registers as required by Windows

PUSH EBX
PUSH EDI
PUSH ESI
MOV EBX,[EBP+8] ;get exception record in ebx
MOV EAX,[EBX+4] ;get flag sent by the system
TEST AL,1h ;see if its a non-continuable exception
JNE short nodeal

;JNZ >.nodeal ;yes, so not allowed by system to touch it
TEST AL,2h ;see if its the system unwinding
JNE short unwind ;yes
PUSH 24h ;question mark + YES/NO buttons
PUSH offset Except1
push offset Except
CALL MessageBoxA ;wait till button pressed
CMP EAX,6 ;see if yes clicked
JNE short nodeal ;no -line 113 orig. jnz

; go to SAFE_PLACE

MOV ESI,[EBP+10h] ;get register context record in esi
MOV EDI,[EBP+0Ch] ;get pointer to ERR structure in edi
MOV [ESI+0C4h],EDI ;insert new esp (happens to be pointer to ERR)
MOV EAX,[EDI+8] ;get address of SAFE_PLACE given in ERR
structure
MOV [ESI+0B8h],EAX ;insert that as new eip in register context
MOV EAX,[EDI+14h] ;get ebp at safe place given in ERR structure
MOV [ESI+0B4h],EAX ;insert that as new ebp in register context
XOR EAX,EAX ;eax=3D0 reload context and return to system

jmp short fin
;JMP > fin

unwind:

PUSH 40h ;exclamation sign + ok button only
PUSH offset Except1
PUSH offset Unwind
PUSH 0
CALL MessageBoxA ;wait till ok pressed, then return eax=3D1

nodeal:

MOV EAX,1 ;eax=3D1 system to go to next handler

fin:

POP ESI
POP EDI
POP EBX
RET

CLEAR_UP: ;all clearing up would be done here


RET
;
FINAL_HANDLER: ;system passes EXCEPTION_POINTERS

PUSH EBX
PUSH EDI
PUSH ESI ;save registers as required by Windows
CALL CLEAR_UP
PUSH 40h ;exclamation sign + ok button only
PUSH offset Except2
PUSH offset FATALMESS
CALL MessageBoxA ;wait till ok pressed
MOV EAX,1 ;terminate process without showing system
message box
POP ESI
pop EDI
pop EBX
RET

end

Mint

unread,
Oct 4, 2009, 11:35:21 AM10/4/09
to

On Oct 3, 8:48=A0pm, Tim Roberts <t...@MUNGED.microcosmotalk.com> wrote:
> Andy <chocolatemint77...@MUNGED.microcosmotalk.com> wrote:
>
> >I am converting some goasm code to masm, and am having some
> >difficulties.
> >I have commented the lines with problems.
>
> >Can someone help me?
>
> Yes. =A0Somewhere near the top of your source file, add this:
>
> =A0 =A0 =A0 =A0 assume =A0fs: @data

>
> In 32-bit code, MASM sets the segment register assumes so that CS is
> assumed to @code, DS, ES, and SS are assumed to @data, and FS and GS are
> assumed to error, to prevent accidental use. =A0To use them, you just hav=
e to
> override the assumption.
> --
> Tim Roberts, t...@probo.com
> Providenza & Boekelheide, Inc.

I got the source to compile.

When I ran it through the debugger,
it stops at the div instruction.

Ollydbg won't let me "step into" or "step over."

I don't know what to try next.

Tadas

unread,
Oct 5, 2009, 11:18:44 AM10/5/09
to

On Oct 4, 11:35=A0am, Mint
<chocolatemint77...@MUNGED.microcosmotalk.com> wrote:
> On Oct 3, 8:48=3DA0pm, Tim Roberts <t...@MUNGED.microcosmotalk.com> wrote=

:
>
>
>
> > Andy <chocolatemint77...@MUNGED.microcosmotalk.com> wrote:
>
> > >I am converting some goasm code to masm, and am having some
> > >difficulties.
> > >I have commented the lines with problems.
>
> > >Can someone help me?
>
> > Yes. =3DA0Somewhere near the top of your source file, add this:
>
> > =3DA0 =3DA0 =3DA0 =3DA0 assume =3DA0fs: @data

>
> > In 32-bit code, MASM sets the segment register assumes so that CS is
> > assumed to @code, DS, ES, and SS are assumed to @data, and FS and GS ar=
e
> > assumed to error, to prevent accidental use. =3DA0To use them, you just=
hav=3D

> e to
> > override the assumption.
> > --
> > Tim Roberts, t...@probo.com
> > Providenza & Boekelheide, Inc.
>
> I got the source to compile.
>
> When I ran it through the debugger,
> it stops at the div instruction.
>
> Ollydbg won't let me "step into" or "step over."
>
> I don't know what to try next.
>
> ;*********************** and now lets cause the exception ..
>
> XOR ECX,ECX =A0 =A0 =A0 =A0 =A0 =A0 ;set ecx to zero
> DIV ECX =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ;divide by zero, causing exceptio=
n

Well, I guess the OllyDbg is not very smart. Try this:

Trace till you reach the DIV instruction. Then add the breakpoint on
your
SEH handler and hit F9 or whichever button it is to continue program's
execution.

Tadas

Wolfgang Kern

unread,
Oct 5, 2009, 11:19:32 AM10/5/09
to

Mint wrote :
...


> When I ran it through the debugger,
> it stops at the div instruction.

> Ollydbg won't let me "step into" or "step over."

> I don't know what to try next.


> ;*********************** and now lets cause the exception ..
>
> XOR ECX,ECX ;set ecx to zero
> DIV ECX ;divide by zero, causing exception

Yeah, a debugger may not recognise a hooked exception handler
and will just avoid crashes by using its own handler here.

And a DIV-exception can came from various sized instructions and
also depend on parameters (as result overflow), so it will need
a disassembler and several response-solutions to skip-over/ignore
DIV errors and set the result/remainder to default values.

ie:
F7 F1 DIV ecx
or:
D4 00 EXC0 ;(modified AAM) a classical 'force DIV/0'
vs:
F7 B1 67 45 23 01 DIV dword [ecx+01234567h]
65 F7 B4 88 67 45 23 01 DIV dword GS:[eax+ecx*4+01234567h]

I once wrote a DIV-ignore hook for 16-bit code, but now I try to
avoid DIV whenever possible and check parameters in advance, so
a DIV-exception will only show up if I coded a bug :)
__
wolfgang

Bob Masta

unread,
Oct 5, 2009, 11:20:14 AM10/5/09
to

On 04 Oct 2009 15:35:21 GMT, Mint
<chocolate...@MUNGED.microcosmotalk.com>
wrote:

I haven't attempted to analyze your code in
detail, but just want to point out that it *may*
matter what you are running it on. I had used
similar exception handling code for years, and it
worked fine on all Win32 systems. But I could
never get it to work on WOW64. See the thread
"SEH on WOW64 (Vista)" Aug 14, 2009. It may be
just due to my odd program structure which uses
combined code and data, but Win32 never
complained.

Best regards,


Bob Masta

DAQARTA v4.51
Data AcQuisition And Real-Time Analysis
www.daqarta.com
Scope, Spectrum, Spectrogram, Sound Level Meter
FREE Signal Generator
Science with your sound card!

Mint

unread,
Oct 6, 2009, 4:05:50 AM10/6/09
to

On Oct 5, 10:18=A0am, Tadas <vilkeliski...@MUNGED.microcosmotalk.com>
wrote:
> On Oct 4, 11:35=3DA0am, Mint
>
> <chocolatemint77...@MUNGED.microcosmotalk.com> wrote:
> > On Oct 3, 8:48=3D3DA0pm, Tim Roberts <t...@MUNGED.microcosmotalk.com> w=
rote=3D

> :
>
> > > Andy <chocolatemint77...@MUNGED.microcosmotalk.com> wrote:
>
> > > >I am converting some goasm code to masm, and am having some
> > > >difficulties.
> > > >I have commented the lines with problems.
>
> > > >Can someone help me?
>
> > > Yes. =3D3DA0Somewhere near the top of your source file, add this:
>
> > > =3D3DA0 =3D3DA0 =3D3DA0 =3D3DA0 assume =3D3DA0fs: @data

>
> > > In 32-bit code, MASM sets the segment register assumes so that CS is
> > > assumed to @code, DS, ES, and SS are assumed to @data, and FS and GS =
ar=3D
> e
> > > assumed to error, to prevent accidental use. =3D3DA0To use them, you =
just=3D
> =A0hav=3D3D

> > e to
> > > override the assumption.
> > > --
> > > Tim Roberts, t...@probo.com
> > > Providenza & Boekelheide, Inc.
>
> > I got the source to compile.
>
> > When I ran it through the debugger,
> > it stops at the div instruction.
>
> > Ollydbg won't let me "step into" or "step over."
>
> > I don't know what to try next.
>
> > ;*********************** and now lets cause the exception ..
>
> > XOR ECX,ECX =3DA0 =3DA0 =3DA0 =3DA0 =3DA0 =3DA0 ;set ecx to zero
> > DIV ECX =3DA0 =3DA0 =3DA0 =3DA0 =3DA0 =3DA0 =3DA0 =3DA0 ;divide by zero=
, causing exceptio=3D

>
> n
>
> Well, I guess the OllyDbg is not very smart. Try this:
>
> Trace till you reach the DIV instruction. Then add the breakpoint on
> your
> SEH handler and hit F9 or whichever button it is to continue program's
> execution.
>
> Tadas

I have tried the following with no luck:

1. replaced div with a nop
2. replaced the div with a cli

Mint

unread,
Oct 6, 2009, 4:06:16 AM10/6/09
to

On Oct 5, 10:19=A0am, "Wolfgang Kern" <nowh...@never.at> wrote:
> Mint wrote :
> ...
>
> > When I ran it through the debugger,
> > it stops at the div instruction.
> > Ollydbg won't let me "step into" or "step over."
> > I don't know what to try next.
> > ;*********************** and now lets cause the exception ..
>
> > XOR ECX,ECX =A0 =A0 =A0 =A0 =A0 =A0 ;set ecx to zero
> > DIV ECX =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ;divide by zero, causing except=

ion
>
> Yeah, a debugger may not recognise a hooked exception handler
> and will just avoid crashes by using its own handler here.
>
> And a DIV-exception can came from various sized instructions and
> also depend on parameters (as result overflow), so it will need
> a disassembler and several response-solutions to skip-over/ignore
> DIV errors and set the result/remainder to default values.
>
> ie:
> F7 F1 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0DIV ecx
> or:
> D4 00 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0EXC0 ;(modified AAM) a class=
ical 'force DIV/0'
> vs:
> F7 B1 67 45 23 01 =A0 =A0 =A0 =A0DIV dword [ecx+01234567h]
> 65 F7 B4 88 67 45 23 01 =A0DIV dword GS:[eax+ecx*4+01234567h]

>
> I once wrote a DIV-ignore hook for 16-bit code, but now I try to
> avoid DIV whenever possible and check parameters in advance, so
> a DIV-exception will only show up if I coded a bug :)
> __
> wolfgang

I thought a Per-Thread Exception Handler would be good to look at.

But if the code is written to where each condition is check for, then
exceptions
should be a rarity.

Andy

Mint

unread,
Oct 6, 2009, 4:06:42 AM10/6/09
to

> I haven't attempted to analyze your code in
> detail, but just want to point out that it *may*

> matter what you are running it on. =A0I had used


> similar exception handling code for years, and it

> worked fine on all Win32 systems. =A0But I could
> never get it to work on WOW64. =A0See the thread
> "SEH on WOW64 (Vista)" Aug 14, 2009. =A0It may be


> just due to my odd program structure which uses
> combined code and data, but Win32 never

> complained. =A0
>
> Best regards,
>
> Bob Masta


I think you are right.
I found this that assembles and works fine.

Andy


; seh.asm by samael Structured exception handling
;
.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

include \masm32\include\comctl32.inc
include \masm32\include\gdi32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\masm32.lib

FinalExceptionHandler PROTO :DWORD

.DATA

szPTEHMessage DB "I'm displayed from SafeOffset, because an exception
occured inside the area guarded by the Per-Thread Exception
Handler...",0
szPTEHCaption DB "Per-thread EH",0

szFEHMessage DB "I'm displayed against all odds, tearing my way
through bad code... ;)",0
szFEHCaption DB "Y-e-e-e-e-h-a !!!",0

.CODE

EntryPoint:

;Install Universal (Final) EH.

INVOKE SetUnhandledExceptionFilter, OFFSET FinalExceptionHandler

;Install per-thread EH

ASSUME FS:NOTHING ; We use the ASSUME FS:NOTHING directive because
MASM by default
; assumes the use of FS register to
ERROR

PUSH OFFSET PTExceptionHandler
PUSH FS:[0]
MOV FS:[0], ESP


; The code between installation and de-installation of the Per-
Thread Exception
; Handler is guarded by the handler.If exception occurs anywhere
inside the guarded area,
; we will go to the SafeOffset.


; Cause an exception by writing to a forbidden address in order to
activate the per-thread EH
; The program flow will be redirected to SafeOffset
XOR EAX,EAX
MOV DWORD PTR [EAX], EAX ;Exception Access Violation

@UninstallPerThreadSEH:

;Uninstall per-thread EH

POP FS:[0]
ADD ESP,4

; Having uninstalled the Per-Thread Exception Handler, the code
below is guarded by the
; "final" handler.
; Note that we could setup the "final" handler, to do an attempt
to continue executing
; the program, rather than just terminating it...


; Cause more exceptions in order to activate the Universal
(Final) EH.

CLI ;Lets execute a privilaged instruction.. Instruction length =3D 1
; [This instruction is going ot be patched to NOP by the
Final Exception Handler]
INT 3 ;Lets cause a breakpoint exception.. Instruction length =3D 1
; [This instruction is going ot be patched to NOP by the
Final Exception Handler]
CLI ;Lets execute a privilaged instruction.. Instruction length =3D 1
; [This instruction is going ot be patched to NOP by the
Final Exception Handler]
INT 3 ;Lets cause a breakpoint exception.. Instruction length =3D 1
; [This instruction is going ot be patched to NOP by the
Final Exception Handler]

;Will this part ever be executed ?
INVOKE MessageBox, NULL, ADDR szFEHMessage, ADDR szFEHCaption,MB_OK
INVOKE ExitProcess,NULL

PTExceptionHandler proc C pExcept:DWORD, pFrame:DWORD, pContext:DWORD,
pDispatch:DWORD
MOV EAX, pContext
MOV [EAX].CONTEXT.regEip, OFFSET SafeOffset
MOV EAX,ExceptionContinueExecution
RET
PTExceptionHandler endp

FinalExceptionHandler proc lpExceptionInfo:DWORD

LOCAL dwExceptionAddress : DWORD
LOCAL dwExceptionCode : DWORD

.CONST

LINE_BREAK EQU 0Dh,0Ah
DEFAULT_BUFFER_SIZE EQU 1024

.DATA
szErrorCaption DB "Universal (Final) EH",0
szErrorMessage DB "Cannot continue the normal execution of this
program.",LINE_BREAK,\
"An exception was generated at address 0x%0.8lX.",LINE_BREAK,\
"Exception type: %s.",LINE_BREAK,\
"This application will now terminate.",LINE_BREAK,LINE_BREAK,\
"Or perhaps not... ;)",0

szACCESS_VIOLATION DB "EXCEPTION_ACCESS_VIOLATION",0
szARRAY_BOUNDS_EXCEEDED DB "EXCEPTION_ARRAY_BOUNDS_EXCEEDED",0
szBREAKPOINT DB "EXCEPTION_BREAKPOINT",0
szDATATYPE_MISALIGNMENT DB "EXCEPTION_DATATYPE_MISALIGNMENT",0
szFLT_DENORMAL_OPERAND DB "EXCEPTION_FLT_DENORMAL_OPERAND",0
szFLT_DIVIDE_BY_ZERO DB "EXCEPTION_FLT_DIVIDE_BY_ZERO",0
szFLT_INEXACT_RESULT DB "EXCEPTION_FLT_INEXACT_RESULT",0
szFLT_INVALID_OPERATION DB "EXCEPTION_FLT_INVALID_OPERATION",0
szFLT_OVERFLOW DB "EXCEPTION_FLT_OVERFLOW",0
szFLT_STACK_CHECK DB "EXCEPTION_FLT_STACK_CHECK",0
szFLT_UNDERFLOW DB "EXCEPTION_FLT_UNDERFLOW",0
szILLEGAL_INSTRUCTION DB "EXCEPTION_ILLEGAL_INSTRUCTION",0
szIN_PAGE_ERROR DB "EXCEPTION_IN_PAGE_ERROR",0
szINT_DIVIDE_BY_ZERO DB "EXCEPTION_INT_DIVIDE_BY_ZERO",0
szINT_OVERFLOW DB "EXCEPTION_INT_OVERFLOW",0
szINVALID_DISPOSITION DB "EXCEPTION_INVALID_DISPOSITION",0
szNONCONTINUABLE_EXCEPTION DB "EXCEPTION_NONCONTINUABLE_EXCEPTION",0
szPRIV_INSTRUCTION DB "EXCEPTION_PRIV_INSTRUCTION",0
szSINGLE_STEP DB "EXCEPTION_SINGLE_STEP",0
szSTACK_OVERFLOW DB "EXCEPTION_STACK_OVERFLOW",0
szUNKNOWN_EXCEPTION DB "EXCEPTION_UNKNOWN_EXCEPTION",0

.DATA?

hHeap HANDLE ?
pBuffer LPVOID ?
dwPreviousProtect DWORD ?

.CODE
PUSHAD
INVOKE GetProcessHeap
MOV hHeap, EAX
INVOKE HeapAlloc, hHeap , HEAP_ZERO_MEMORY, DEFAULT_BUFFER_SIZE
MOV pBuffer,EAX
MOV EAX, [lpExceptionInfo]
MOV EAX, [EAX] ; lpEXCEPTION_RECORD
MOV edi, [EAX+12] ; ExceptionAddress;
MOV dwExceptionAddress,edi
MOV edi, [EAX] ; ExceptionCode
MOV dwExceptionCode,edi

.if dwExceptionCode =3D=3D EXCEPTION_ACCESS_VIOLATION
MOV ESI, OFFSET szACCESS_VIOLATION
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_ARRAY_BOUNDS_EXCEEDED
MOV ESI, OFFSET szARRAY_BOUNDS_EXCEEDED
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_BREAKPOINT
MOV ESI, OFFSET szBREAKPOINT
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_DATATYPE_MISALIGNMENT
MOV ESI, OFFSET szDATATYPE_MISALIGNMENT
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_FLT_DENORMAL_OPERAND
MOV ESI, OFFSET szFLT_DENORMAL_OPERAND
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_FLT_DIVIDE_BY_ZERO
MOV ESI, OFFSET szFLT_DIVIDE_BY_ZERO
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_FLT_INEXACT_RESULT
MOV ESI, OFFSET szFLT_INEXACT_RESULT
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_FLT_INVALID_OPERATION
MOV ESI, OFFSET szFLT_INVALID_OPERATION
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_FLT_OVERFLOW
MOV ESI, OFFSET szFLT_OVERFLOW
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_FLT_STACK_CHECK
MOV ESI, OFFSET szFLT_STACK_CHECK
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_FLT_UNDERFLOW
MOV ESI, OFFSET szFLT_UNDERFLOW
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_ILLEGAL_INSTRUCTION
MOV ESI, OFFSET szILLEGAL_INSTRUCTION
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_IN_PAGE_ERROR
MOV ESI, OFFSET szIN_PAGE_ERROR
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_INT_DIVIDE_BY_ZERO
MOV ESI, OFFSET szINT_DIVIDE_BY_ZERO
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_INT_OVERFLOW
MOV ESI, OFFSET szINT_OVERFLOW
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_PRIV_INSTRUCTION
MOV ESI, OFFSET szPRIV_INSTRUCTION
.ELSEIF dwExceptionCode =3D=3D EXCEPTION_SINGLE_STEP
MOV ESI, OFFSET szSINGLE_STEP
.ELSE
MOV ESI, OFFSET szUNKNOWN_EXCEPTION
.ENDIF

INVOKE wsprintf, ADDR pBuffer, ADDR szErrorMessage,
dwExceptionAddress, ESI
INVOKE MessageBox, NULL, ADDR pBuffer, ADDR szErrorCaption,
MB_ICONERROR OR MB_OK OR MB_APPLMODAL
INVOKE HeapFree,hHeap,NULL,pBuffer

;Try to patch our way through the bad code ;)

MOV EAX, [lpExceptionInfo]
MOV EAX, [EAX].EXCEPTION_POINTERS.ContextRecord
MOV esi, [EAX].CONTEXT.regEip

; A length disassembler could be used to determine the size of code
to be patched...
; Now I set the instruction length to 1 (constant) because i know it
will work
; with the "bad" opcodes in this program... (They all have one-byte
instructions)

INVOKE VirtualProtect,ESI,1,PAGE_EXECUTE_WRITECOPY,ADDR
dwPreviousProtect ;Override the
;READONLY attribute
of the Code segment

MOV byte ptr [ESI], 090h ;Patch the bad instruction with the NOP
opcode
;INC ESI ;INC EIP (NOT REALLY NECESSARY, SINCE WE PATCH THE BAD
INSTRUCTIONS...)
MOV EAX, [lpExceptionInfo]
MOV EAX, [EAX].EXCEPTION_POINTERS.ContextRecord
MOV [EAX].CONTEXT.regEip,ESI
POPAD
MOV EAX,-1 ; Reload the context record into the processor and
continue execution
; from the eip given in the context.
RET

FinalExceptionHandler ENDP

;--------------------------------------------------------------------------=
-------------------------------------------
; Safe Offset for PTEH
;--------------------------------------------------------------------------=
-------------------------------------------
SafeOffset:
INVOKE MessageBox, NULL, ADDR szPTEHMessage, ADDR szPTEHCaption,MB_OK
jmp @UninstallPerThreadSEH

end EntryPoint


chocolatemint77581169

unread,
Dec 10, 2012, 8:37:28 PM12/10/12
to
Thanks Wolfgang.

Andy


chocolatemint77581169

unread,
Dec 10, 2012, 8:37:56 PM12/10/12
to
Thanks, I got the code running.

; Code from samael at http://www.winasm.net/
; Help from Tim, Wolfgang,
;
.386
.model flat,stdcall
option casemap:none


include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
include \masm32\include\gdi32.inc
include \masm32\include\masm32.inc


includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\masm32.lib


FinalExceptionHandler PROTO :DWORD


.DATA

szPTEHMessage DB "I'm displayed from SafeOffset, because an exception occured inside the area guarded by the Per-Thread Exception Handler...",0
szPTEHCaption DB "Per-thread EH",0

szFEHMessage DB "I'm displayed against all odds, tearing my way through bad code... ;)",0
szFEHCaption DB "Y-e-e-e-e-h-a !!!",0

.CODE

EntryPoint:
;int 3
;-------------------------------------------------------------------------------------
;Install Universal (Final) EH.
;-------------------------------------------------------------------------------------
INVOKE SetUnhandledExceptionFilter, OFFSET FinalExceptionHandler

;-------------------------------------------------------------------------------------
;Install per-thread EH
;-------------------------------------------------------------------------------------
ASSUME FS:NOTHING ; We use the ASSUME FS:NOTHING directive because MASM by default assumes the use of FS register to ERROR
PUSH OFFSET PTExceptionHandler
PUSH FS:[0]
MOV FS:[0], ESP


;-------------------------------------------------------------------------------------
; The code between installation and de-installation of the Per-Thread Exception
; Handler, is guarded by the handler. If exception occurs anywhere inside the guarded area,
; we will go to the SafeOffset.
;-------------------------------------------------------------------------------------


; Cause an exception by writting to a forbidden address in order to activate the per-thread EH...
; The program flow will be redirected to SafeOffset
XOR EAX,EAX
MOV DWORD PTR [EAX], EAX ;Exceptio Access Violation

@UninstallPerThreadSEH:

;-------------------------------------------------------------------------------------
;Uninstall per-thread EH
;-------------------------------------------------------------------------------------
POP FS:[0]
ADD ESP,4

;-------------------------------------------------------------------------------------
; Having uninstalled the Per-Thread Exception Handler, the code below is guarded by the
; "final" handler.
; Note that we could setup the "final" handler, to do an attempt to continue executing
; the program, rather than just terminating it...
;-------------------------------------------------------------------------------------


;Cause more exceptions in order to activate the Universal (Final) EH.

CLI ;Lets execute a privilaged instruction... ; Instruction length = 1 [This instruction is going ot be patched to NOP by the Final Exception Handler]
INT 3 ;Lets cause a breakpoint exception... ; Instruction length = 1 [This instruction is going ot be patched to NOP by the Final Exception Handler]
CLI ;Lets execute a privilaged instruction... ; Instruction length = 1 [This instruction is going ot be patched to NOP by the Final Exception Handler]
INT 3 ;Lets cause a breakpoint exception... ; Instruction length = 1 [This instruction is going ot be patched to NOP by the Final Exception Handler]
.if dwExceptionCode == EXCEPTION_ACCESS_VIOLATION
MOV ESI, OFFSET szACCESS_VIOLATION
.ELSEIF dwExceptionCode == EXCEPTION_ARRAY_BOUNDS_EXCEEDED
MOV ESI, OFFSET szARRAY_BOUNDS_EXCEEDED
.ELSEIF dwExceptionCode == EXCEPTION_BREAKPOINT
MOV ESI, OFFSET szBREAKPOINT
.ELSEIF dwExceptionCode == EXCEPTION_DATATYPE_MISALIGNMENT
MOV ESI, OFFSET szDATATYPE_MISALIGNMENT
.ELSEIF dwExceptionCode == EXCEPTION_FLT_DENORMAL_OPERAND
MOV ESI, OFFSET szFLT_DENORMAL_OPERAND
.ELSEIF dwExceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO
MOV ESI, OFFSET szFLT_DIVIDE_BY_ZERO
.ELSEIF dwExceptionCode == EXCEPTION_FLT_INEXACT_RESULT
MOV ESI, OFFSET szFLT_INEXACT_RESULT
.ELSEIF dwExceptionCode == EXCEPTION_FLT_INVALID_OPERATION
MOV ESI, OFFSET szFLT_INVALID_OPERATION
.ELSEIF dwExceptionCode == EXCEPTION_FLT_OVERFLOW
MOV ESI, OFFSET szFLT_OVERFLOW
.ELSEIF dwExceptionCode == EXCEPTION_FLT_STACK_CHECK
MOV ESI, OFFSET szFLT_STACK_CHECK
.ELSEIF dwExceptionCode == EXCEPTION_FLT_UNDERFLOW
MOV ESI, OFFSET szFLT_UNDERFLOW
.ELSEIF dwExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION
MOV ESI, OFFSET szILLEGAL_INSTRUCTION
.ELSEIF dwExceptionCode == EXCEPTION_IN_PAGE_ERROR
MOV ESI, OFFSET szIN_PAGE_ERROR
.ELSEIF dwExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO
MOV ESI, OFFSET szINT_DIVIDE_BY_ZERO
.ELSEIF dwExceptionCode == EXCEPTION_INT_OVERFLOW
MOV ESI, OFFSET szINT_OVERFLOW
.ELSEIF dwExceptionCode == EXCEPTION_PRIV_INSTRUCTION
MOV ESI, OFFSET szPRIV_INSTRUCTION
.ELSEIF dwExceptionCode == EXCEPTION_SINGLE_STEP
MOV ESI, OFFSET szSINGLE_STEP
.ELSE
MOV ESI, OFFSET szUNKNOWN_EXCEPTION
.ENDIF

INVOKE wsprintf, ADDR pBuffer, ADDR szErrorMessage, dwExceptionAddress, ESI
INVOKE MessageBox, NULL, ADDR pBuffer, ADDR szErrorCaption, MB_ICONERROR OR MB_OK OR MB_APPLMODAL
INVOKE HeapFree,hHeap,NULL,pBuffer

;Try to patch our way through the bad code ;)

MOV EAX, [lpExceptionInfo]
MOV EAX, [EAX].EXCEPTION_POINTERS.ContextRecord
MOV esi, [EAX].CONTEXT.regEip

; A length disassembler could be used to determine the size of code to be patched...
; Now i set the instruction length to 1 (constant) because i know it will work
; with the "bad" opcodes in this program... (They all have one-byte instructions)

INVOKE VirtualProtect,ESI,1,PAGE_EXECUTE_WRITECOPY,ADDR dwPreviousProtect ;Override the READONLY atrribute of the Code segment
MOV byte ptr [ESI], 090h ;Patch the bad instruction with the NOP opcode
;INC ESI ;INC EIP (NOT REALLY NECESSARY, SINCE WE PATCH THE BAD INSTRUCTIONS...)
MOV EAX, [lpExceptionInfo]
MOV EAX, [EAX].EXCEPTION_POINTERS.ContextRecord
MOV [EAX].CONTEXT.regEip,ESI
POPAD
MOV EAX,-1 ; Reload the context record into the processor and continue execution from the eip given in the context.
RET


;INVOKE ExitProcess, NULL
FinalExceptionHandler ENDP

;---------------------------------------------------------------------------------------------------------------------
; Safe Offset for PTEH
;---------------------------------------------------------------------------------------------------------------------
SafeOffset:
INVOKE MessageBox, NULL, ADDR szPTEHMessage, ADDR szPTEHCaption,MB_OK
jmp @UninstallPerThreadSEH

end EntryPoint

Andy

--http://compgroups.net/comp.lang.asm.x86/converting-goasm-code-to-masm/197610


andrew_kennedy7

unread,
Dec 10, 2012, 8:38:19 PM12/10/12
to
Thanks,
Andy


0 new messages