forked from KolibriOS/kolibrios
b34f9856cb
git-svn-id: svn://kolibrios.org@9353 a494cfbc-eb01-0410-851d-a64ba20cac60
2912 lines
71 KiB
NASM
2912 lines
71 KiB
NASM
use32
|
|
db 'MENUET01'
|
|
dd 1
|
|
dd Start
|
|
dd I_END
|
|
MemSize dd Mem
|
|
dd StackTop
|
|
dd 0,AppPath
|
|
|
|
VERSION equ '0.01+'
|
|
|
|
;-----------------------------------------------------------------------------
|
|
Bitness equ 32
|
|
;-----------------------------------------------------------------------------
|
|
bit equ 1 shl
|
|
by equ shl 8 +
|
|
|
|
%B = 32
|
|
|
|
macro even Value { rb (Value-1)-($+Value-1) mod Value }
|
|
|
|
macro ifc Opc&
|
|
{
|
|
local ..L
|
|
jnc ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifa Opc&
|
|
{
|
|
local ..L
|
|
jna ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifae Opc&
|
|
{
|
|
local ..L
|
|
jnae ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifb Opc&
|
|
{
|
|
local ..L
|
|
jnb ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifbe Opc&
|
|
{
|
|
local ..L
|
|
jnbe ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifg Opc&
|
|
{
|
|
local ..L
|
|
jng ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifge Opc&
|
|
{
|
|
local ..L
|
|
jnge ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifl Opc&
|
|
{
|
|
local ..L
|
|
jnl ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifle Opc&
|
|
{
|
|
local ..L
|
|
jnle ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifno Opc&
|
|
{
|
|
local ..L
|
|
jo ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifnp Opc&
|
|
{
|
|
local ..L
|
|
jp ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifns Opc&
|
|
{
|
|
local ..L
|
|
js ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifnz Opc&
|
|
{
|
|
local ..L
|
|
jz ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifo Opc&
|
|
{
|
|
local ..L
|
|
jno ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifp Opc&
|
|
{
|
|
local ..L
|
|
jnp ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifs Opc&
|
|
{
|
|
local ..L
|
|
jns ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro ifz Opc&
|
|
{
|
|
local ..L
|
|
jnz ..L
|
|
Opc
|
|
..L:
|
|
}
|
|
|
|
macro lea Dst,Src
|
|
{
|
|
local ..L,..H
|
|
virtual at 0
|
|
mov al,byte Src
|
|
load ..L byte from 0x0
|
|
if ..L = 0xA0
|
|
load ..H dword from 0x1
|
|
end if
|
|
end virtual
|
|
if ..L = 0xA0
|
|
mov Dst,..H
|
|
else
|
|
lea Dst,Src
|
|
end if
|
|
}
|
|
|
|
include 'kosfuncs.inc'
|
|
include '../../macros.inc'
|
|
|
|
include 'font.inc'
|
|
include 'tools.inc'
|
|
include 'kernel.inc'
|
|
|
|
virtual at rsp
|
|
All:
|
|
.edi dd ?
|
|
.esi dd ?
|
|
.ebp dd ?
|
|
.res dd ?
|
|
.ebx dd ?
|
|
.edx dd ?
|
|
.ecx dd ?
|
|
.eax dd ?
|
|
end virtual
|
|
|
|
macro jecxnz Target
|
|
{
|
|
inc ecx
|
|
loop Target
|
|
}
|
|
|
|
TestFile db '/rd/1/develop/scancode',0
|
|
|
|
MinWidth = 90
|
|
MaxWidth = 255
|
|
MinHeight = 75
|
|
MaxHeight = 255
|
|
|
|
DATA_WIDTH = 88 ; in characters, multiple of 4
|
|
|
|
CMD_WIDTH = DATA_WIDTH
|
|
|
|
CursorNormSize = 2
|
|
CursorBigsSize = FontHeight
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Fast load test file event
|
|
DoLoad: mov esi,TestFile
|
|
mov edi,LoadName
|
|
jmp OnLoadInit
|
|
;-----------------------------------------------------------------------------
|
|
; Load executable event
|
|
OnLoad: mov esi,[CurArg]
|
|
OnLoadInit:
|
|
mov edi,LoadName
|
|
or [PrgNameLen],-1
|
|
mov [PrgNamePtr],edi
|
|
.CopyName:
|
|
lodsb
|
|
stosb
|
|
inc [PrgNameLen]
|
|
cmp al,'/'
|
|
jnz @F
|
|
or [PrgNameLen],-1
|
|
mov [PrgNamePtr],edi
|
|
@@:
|
|
cmp al,' '
|
|
ja .CopyName
|
|
mov byte [edi-1],0
|
|
and [LoadParams],0
|
|
dec esi
|
|
call GetArg.SkipSpaces
|
|
cmp al,0
|
|
jz @F
|
|
mov [LoadParams],esi
|
|
@@:
|
|
;and [DumpPos],0
|
|
mov ecx,[Symbols]
|
|
jecxz DoReLoad
|
|
mcall 68,13
|
|
and [Symbols],0
|
|
and [NumSymbols],0
|
|
DoReLoad:
|
|
mcall 18,7
|
|
mov [DbgWnd],eax
|
|
xchg ecx,eax
|
|
mcall 70,FN70LoadBlock
|
|
test eax,eax
|
|
jns .Loaded
|
|
|
|
.LoadErr:
|
|
push eax
|
|
mov esi,LoadErrMsg
|
|
call PutMessage
|
|
pop eax
|
|
not eax
|
|
cmp eax,0x20
|
|
jae .UnkErr
|
|
mov esi,[LoadErrMsgs+eax*4]
|
|
test esi,esi
|
|
jnz PutMessage
|
|
|
|
.UnkErr:
|
|
mov esi,UnkErrMsg
|
|
inc eax
|
|
push eax
|
|
call PutMessageNoDraw
|
|
jmp DrawMessages
|
|
|
|
.Loaded:
|
|
mov [DebuggeePID],eax
|
|
mov [bSuspended],1
|
|
mcall 5,20
|
|
push ecx
|
|
call GetContext
|
|
mov edi,OldContext
|
|
mov ecx,(CtxEnd-Context)/4
|
|
rep movsd
|
|
; activate debugger window
|
|
pop ecx
|
|
mcall 18,3
|
|
call GetDump
|
|
if 1
|
|
push dword [ShowNames]
|
|
mov [ShowNames],-1
|
|
end if
|
|
mov [AfterKey],0
|
|
call ShowImage
|
|
mov esi,LoadSuccMsg
|
|
push [DebuggeePID]
|
|
call PutMessageNoDraw
|
|
call DrawMessages
|
|
; try to load symbols
|
|
mov esi,LoadName
|
|
mov edi,SymbolsFile
|
|
push edi
|
|
@@:
|
|
lodsb
|
|
stosb
|
|
test al,al
|
|
jnz @B
|
|
lea ecx,[edi-1]
|
|
@@:
|
|
dec edi
|
|
cmp edi,SymbolsFile
|
|
jb @F
|
|
cmp byte [edi],'/'
|
|
jz @F
|
|
cmp byte [edi],'.'
|
|
jnz @B
|
|
mov ecx,edi
|
|
@@:
|
|
mov dword [ecx],'.dbg'
|
|
mov byte [ecx+4],0
|
|
pop esi
|
|
mov ebp,esi
|
|
push ecx esi
|
|
call OnLoadSymbols.Silent ; Try to load .dbg file
|
|
pop esi ecx
|
|
xor eax,eax
|
|
cmp [NumSymbols],eax
|
|
jne @F
|
|
mov dword [ecx],'.map' ; If failed, try .map file too
|
|
call OnLoadSymbols.Silent
|
|
@@:
|
|
if 1
|
|
pop eax
|
|
mov [ShowNames],al
|
|
call DrawMessages
|
|
end if
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Working with debug context
|
|
GetNewContext:
|
|
mov esi,Context
|
|
mov edi,OldContext
|
|
mov ecx,(CtxEnd-Context)/4
|
|
rep movsd
|
|
|
|
GetContext:
|
|
mcall 69,1,[DebuggeePID],CtxEnd-Context,Context
|
|
ret
|
|
|
|
SetContext:
|
|
mcall 69,2,[DebuggeePID],28h,Context
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Resume process event
|
|
DoResume:
|
|
mcall 69,5,[DebuggeePID]
|
|
mov [bSuspended],0
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Breakpoints manipulation
|
|
OnBp: mov esi,[CurArg]
|
|
call CalcExpression
|
|
jc .Ret
|
|
xchg eax,ebp
|
|
push eax
|
|
call FindBreakPoint
|
|
inc eax
|
|
pop eax
|
|
jz .NotFound
|
|
mov esi,aDuplicateBreakpoint
|
|
jmp .SayErr
|
|
.NotFound:
|
|
mov bl,1
|
|
call AddBreakPoint
|
|
jnc .Ret
|
|
mov esi,aBreakpointLimitExceeded
|
|
.SayErr:
|
|
call PutMessage
|
|
.Ret:
|
|
jmp DrawMessages;DrawDisAsm
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Dump memory event
|
|
OnDump: mov esi,[CurArg]
|
|
cmp byte [esi],0
|
|
jnz .Param
|
|
;add [DumpPos],DUMP_HEIGHT*10h
|
|
add [DataAddr],8*8
|
|
jmp .DoIt
|
|
|
|
.Param:
|
|
call CalcExpression
|
|
jc .Ret
|
|
;mov [DumpPos],ebp
|
|
mov [DataAddr],ebp
|
|
.DoIt:
|
|
;call GetDump
|
|
;call DrawDump.Redraw
|
|
call DrawMessages
|
|
.Ret:
|
|
ret
|
|
|
|
OnBpmb: mov dh,0011b
|
|
jmp DoBpm
|
|
|
|
OnBpmw: mov dh,0111b
|
|
jmp DoBpm
|
|
|
|
OnBpmd: mov dh,1111b
|
|
|
|
DoBpm: mov esi,[CurArg]
|
|
cmp byte [esi],'w'
|
|
jnz @F
|
|
and dh,not 2
|
|
inc esi
|
|
@@:
|
|
push edx
|
|
call CalcExpression
|
|
pop edx
|
|
jnc @F
|
|
ret
|
|
; ebp = expression, dh = flags
|
|
@@:
|
|
movzx eax,dh
|
|
shr eax,2
|
|
test ebp,eax
|
|
jz @F
|
|
mov esi,aUnaligned
|
|
jmp PutMessage
|
|
@@:
|
|
mov eax,ebp
|
|
mov bl,0Bh
|
|
call AddBreakPoint
|
|
jnc @F
|
|
mov esi,aBreakpointLimitExceeded
|
|
jmp PutMessage
|
|
; now find index
|
|
@@:
|
|
push eax
|
|
xor ecx,ecx
|
|
.L1:
|
|
cmp [DrXBreak+ecx*4],0
|
|
jnz .L2
|
|
push ecx
|
|
mov dl,cl
|
|
mov esi,ebp
|
|
mcall 69,9,[DebuggeePID]
|
|
test eax,eax
|
|
jz .OK
|
|
pop ecx
|
|
.L2:
|
|
inc ecx
|
|
cmp ecx,4
|
|
jb .L1
|
|
pop eax
|
|
call ClearBreakPoint
|
|
mov esi,aBreakpointLimitExceeded
|
|
jmp PutMessage
|
|
.OK:
|
|
pop ecx
|
|
pop eax
|
|
and byte [edi],not 2 ; breakpoint is enabled
|
|
shl dl,6
|
|
or dl,dh
|
|
mov byte [edi+1],dl
|
|
inc eax
|
|
mov [DrXBreak+ecx*4],eax
|
|
ret
|
|
|
|
OnBc: mov esi,[CurArg]
|
|
@@:
|
|
call GetHexNumber
|
|
jc OnBp.Ret
|
|
call ClearBreakPoint
|
|
jmp @B
|
|
OnBd:
|
|
mov esi,[CurArg]
|
|
@@:
|
|
call GetHexNumber
|
|
jc OnBp.Ret
|
|
call DisableBreakPoint
|
|
jmp @B
|
|
OnBe:
|
|
mov esi,[CurArg]
|
|
@@:
|
|
call GetHexNumber
|
|
jc OnBp.Ret
|
|
push eax
|
|
call FindEnabledBreakPoint
|
|
pop eax
|
|
jz .Err
|
|
call EnableBreakPoint
|
|
jmp @B
|
|
.Err:
|
|
mov esi,OnBeErrMsg
|
|
jmp PutMessage
|
|
|
|
GetHexNumber:
|
|
call GetArg.SkipSpaces
|
|
xor ecx,ecx
|
|
xor edx,edx
|
|
@@:
|
|
lodsb
|
|
call IsHexDigit
|
|
jc .Ret
|
|
shl edx,4
|
|
or dl,al
|
|
inc ecx
|
|
jmp @B
|
|
.Ret:
|
|
dec esi
|
|
cmp ecx,1
|
|
xchg eax,edx
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Breakpoints list event
|
|
OnBl: mov esi,[CurArg]
|
|
cmp byte [esi],0
|
|
jz .ListAll
|
|
call GetHexNumber
|
|
jc .Ret
|
|
cmp eax,BreakPointsN
|
|
jae .Err
|
|
push eax
|
|
add eax,eax
|
|
lea edi,[BreakPoints+eax+eax*2]
|
|
pop eax
|
|
test byte [edi+4],1
|
|
jz .Err
|
|
call ShowBreakInfo
|
|
.Ret:
|
|
ret
|
|
.Err:
|
|
mov esi,aInvalidBreak
|
|
jmp PutMessage
|
|
|
|
.ListAll:
|
|
mov edi,BreakPoints
|
|
xor eax,eax
|
|
@@:
|
|
test byte [edi+4],1
|
|
jz .Cont
|
|
push edi eax
|
|
call ShowBreakInfo
|
|
pop eax edi
|
|
.Cont:
|
|
add edi,6
|
|
inc eax
|
|
cmp eax,BreakPointsN
|
|
jb @B
|
|
ret
|
|
|
|
ShowBreakInfo:
|
|
push edi
|
|
test byte [edi+4],8
|
|
jnz .DR
|
|
push dword [edi]
|
|
push eax
|
|
mov esi,aBreakNum
|
|
call PutMessageNoDraw
|
|
jmp .CMN
|
|
.DR:
|
|
push eax
|
|
mov esi,aMemBreak1
|
|
call PutMessageNoDraw
|
|
pop edi
|
|
push edi
|
|
mov esi,aMemBreak2
|
|
test byte [edi+5],2
|
|
jz @F
|
|
mov esi,aMemBreak3
|
|
@@:
|
|
call PutMessageNoDraw
|
|
pop edi
|
|
push edi
|
|
mov esi,aMemBreak6
|
|
test byte [edi+5],8
|
|
jnz @F
|
|
mov esi,aMemBreak5
|
|
test byte [edi+5],4
|
|
jnz @F
|
|
mov esi,aMemBreak4
|
|
@@:
|
|
call PutMessageNoDraw
|
|
pop edi
|
|
push edi
|
|
push dword [edi]
|
|
mov esi,aMemBreak7
|
|
call PutMessageNoDraw
|
|
.CMN:
|
|
pop edi
|
|
test byte [edi+4],2
|
|
jz @F
|
|
push edi
|
|
mov esi,aDisabled
|
|
call PutMessageNoDraw
|
|
pop edi
|
|
@@:
|
|
test byte [edi+4],4
|
|
jz @F
|
|
mov esi,aOneShot
|
|
call PutMessageNoDraw
|
|
@@:
|
|
mov esi,NewLine
|
|
jmp PutMessage
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Unpack executable event
|
|
OnUnpack:
|
|
; program must be loaded - checked when command was parsed
|
|
; program must be stopped
|
|
mov esi,aRunningErr
|
|
cmp [bSuspended],0
|
|
jz PutMessage
|
|
; all breakpoints must be disabled
|
|
mov edi,BreakPoints
|
|
@@:
|
|
test byte [edi+4],1
|
|
jz .Cont
|
|
test byte [edi+4],2
|
|
jnz .Cont
|
|
mov esi,aEnabledBreakErr
|
|
jmp PutMessage
|
|
.Cont:
|
|
add edi,6
|
|
cmp edi,BreakPoints+BreakPointsN*6
|
|
jb @B
|
|
; ok, now do it
|
|
; set breakpoint on 0xC dword access
|
|
push 9
|
|
pop ebx
|
|
mov ecx,[DebuggeePID]
|
|
mov dx,1111b*256
|
|
push 0xC
|
|
pop esi
|
|
@@:
|
|
mcall 69
|
|
test eax,eax
|
|
jz .BreakOK
|
|
inc edx
|
|
cmp dl,4
|
|
jb @B
|
|
.BreakOK:
|
|
call GoOn
|
|
; now wait for event
|
|
.Wait:
|
|
mcall 10
|
|
dec eax
|
|
jz .Redraw
|
|
dec eax
|
|
jz .Key
|
|
dec eax
|
|
jnz .Debug
|
|
; button; we have only one button, close
|
|
or eax,-1
|
|
mcall
|
|
|
|
.Redraw:
|
|
mov [DoDraw],1
|
|
call DrawWindow
|
|
jmp .Wait
|
|
|
|
.Key:
|
|
mov al,2
|
|
mcall
|
|
cmp ah,3 ; Ctrl+C
|
|
jnz .Wait
|
|
|
|
.UserBreak:
|
|
mov esi,aInterrupted
|
|
.X1:
|
|
push edx esi
|
|
call PutMessage
|
|
pop esi edx
|
|
or dh,80h
|
|
mcall 69,9,[DebuggeePID]
|
|
cmp esi,aUnpacked
|
|
jnz OnSuspend
|
|
jmp AfterSuspend
|
|
|
|
.Debug:
|
|
cmp [DbgBufLen],4*3
|
|
jnz .NotOur
|
|
cmp dword [DbgBuf],3
|
|
jnz .NotOur
|
|
test byte [DbgBuf+8],1
|
|
jnz .Our
|
|
|
|
.NotOur:
|
|
mov esi,aInterrupted
|
|
push edx
|
|
call PutMessage
|
|
pop edx
|
|
or dh,80h
|
|
mcall 69,9,[DebuggeePID]
|
|
jmp DebugMsg
|
|
|
|
.Our:
|
|
and [DbgBufLen],0
|
|
push edx
|
|
call GetContext
|
|
push eax
|
|
mcall 69,6,[DebuggeePID],4,0xC,esp
|
|
pop eax
|
|
pop edx
|
|
cmp eax,[_EIP]
|
|
jz .Done
|
|
call DoResume
|
|
jmp .Wait
|
|
|
|
.Done:
|
|
mov esi,aUnpacked
|
|
jmp .X1
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Calculate expression event
|
|
OnCalc: mov esi,[CurArg]
|
|
call CalcExpression
|
|
jc .Ret
|
|
push ebp
|
|
mov esi,CalcString
|
|
call PutMessageNoDraw
|
|
jmp DrawMessages
|
|
.Ret:
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Access to register value event
|
|
OnReg: mov esi,[CurArg]
|
|
call GetArg.SkipSpaces
|
|
call FindReg
|
|
jnc @F
|
|
.Err:
|
|
mov esi,RSyntax
|
|
jmp PutMessage
|
|
@@:
|
|
call GetArg.SkipSpaces
|
|
test al,al
|
|
jz .Err
|
|
cmp al,'='
|
|
jnz @F
|
|
inc esi
|
|
call GetArg.SkipSpaces
|
|
test al,al
|
|
jz .Err
|
|
@@:
|
|
push edi
|
|
call CalcExpression
|
|
pop edi
|
|
jc .Ret
|
|
; now edi=register id, ebp=value
|
|
cmp [bSuspended],0
|
|
mov esi,aRunningErr
|
|
jz PutMessage
|
|
xchg eax,ebp
|
|
cmp edi,24
|
|
jz .EIP
|
|
sub edi,4
|
|
jb .8LO
|
|
sub edi,4
|
|
jb .8HI
|
|
sub edi,8
|
|
jb .16
|
|
mov [_EAX+edi*4],eax
|
|
jmp .Ret
|
|
.16:
|
|
mov word [_EAX+(edi+8)*4],ax
|
|
jmp .Ret
|
|
.8LO:
|
|
mov byte [_EAX+(edi+4)*4],al
|
|
jmp .Ret
|
|
.8HI:
|
|
mov byte [_EAX+(edi+4)*4+1],al
|
|
jmp .Ret
|
|
.EIP:
|
|
mov [_EIP],eax
|
|
;call UpdateDisAsmEIP
|
|
.Ret:
|
|
call SetContext
|
|
jmp DrawMessages;DrawRegisters.ReDraw
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Step execution event
|
|
;Here we get [<number>] argument at do step <number> times
|
|
OnStepMultiple:
|
|
cmp [bSuspended],0
|
|
jz OnStep.Running
|
|
mov [StepNum],1
|
|
mov esi,[CurArg]
|
|
test esi,esi
|
|
jz .Do
|
|
cmp byte [esi],0
|
|
jz .Do
|
|
call GetHexNumber
|
|
jc .Ret
|
|
or eax,eax ; check if lesser or equal than 0
|
|
jle .Ret
|
|
mov [StepNum],eax
|
|
.Do: call OnStep
|
|
dec [StepNum]
|
|
jnz .Do
|
|
.Ret: ret
|
|
|
|
OnStep:
|
|
cmp [bSuspended],0
|
|
jz .Running
|
|
call GetContext
|
|
or byte [_EFL+1],1 ; set TF
|
|
call SetContext
|
|
and byte [_EFL+1],not 1
|
|
; if instruction at eip is "int xx", set one-shot breakpoint immediately after
|
|
mov eax,[_EIP]
|
|
call FindEnabledBreakPoint
|
|
jnz @F
|
|
cmp byte [edi+5],0xCD
|
|
jz .Int
|
|
@@:
|
|
push 0
|
|
mcall 69,6,[DebuggeePID],3,[_EIP],esp
|
|
cmp eax,edx
|
|
pop eax
|
|
jnz .DoIt
|
|
cmp al,0xCD
|
|
jz .Int
|
|
cmp ax,0x050F
|
|
jz .SysCall
|
|
cmp ax,0x340F
|
|
jz .SysEnter
|
|
; resume process
|
|
.DoIt:
|
|
call GoOn
|
|
cmp [bAfterGo],0
|
|
jz @F
|
|
mov [bAfterGo],2
|
|
@@:
|
|
ret
|
|
|
|
; return address is [ebp-4]
|
|
.SysEnter:
|
|
push 0
|
|
inc edx ; read 4 bytes
|
|
mov esi,[_EBP]
|
|
sub esi,4
|
|
mcall 69
|
|
cmp eax,edx
|
|
pop eax
|
|
jnz .SysCall
|
|
push eax
|
|
and byte [_EFL+1],not 1
|
|
call SetContext
|
|
pop eax
|
|
jmp @F
|
|
|
|
.SysCall:
|
|
and byte [_EFL+1],not 1 ; clear TF - avoid system halt (!)
|
|
call SetContext
|
|
.Int:
|
|
mov eax,[_EIP]
|
|
inc eax
|
|
inc eax
|
|
@@:
|
|
push eax
|
|
call FindEnabledBreakPoint
|
|
pop eax
|
|
jz .DoIt
|
|
; there is no enabled breakpoint yet; set temporary breakpoint
|
|
mov bl,5
|
|
call AddBreakPoint
|
|
jmp .DoIt
|
|
|
|
.Running:
|
|
mov esi,aRunningErr
|
|
jmp PutMessage
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Proceed process event
|
|
;Here we get [<number>] argument at do step <number> times
|
|
OnProceedMultiple:
|
|
cmp [bSuspended],0
|
|
jz OnStep.Running
|
|
mov [ProcNum],1
|
|
mov esi,[CurArg]
|
|
test esi,esi
|
|
jz .Do
|
|
cmp byte [esi],0
|
|
jz .Do
|
|
call GetHexNumber
|
|
jc .Ret
|
|
or eax,eax ; check if lesser or equal than 0
|
|
jle .Ret
|
|
mov [ProcNum],eax
|
|
and [CurArg],0
|
|
.Do:
|
|
call OnProceed
|
|
dec [ProcNum]
|
|
jnz .Do
|
|
.Ret:
|
|
ret
|
|
|
|
OnProceed:
|
|
cmp [bSuspended],0
|
|
jz OnStep.Running
|
|
mov esi,[_EIP]
|
|
|
|
@@:
|
|
call GetByteNoBreak
|
|
jc OnStep
|
|
inc esi
|
|
; skip prefixes
|
|
call IsPrefix
|
|
jz @B
|
|
cmp al,0xE8 ; call
|
|
jnz @f
|
|
add esi,4
|
|
jmp .DoIt
|
|
|
|
; A4,A5 = movs; A6,A7 = cmps
|
|
@@:
|
|
cmp al,0xA4
|
|
jb @F
|
|
cmp al,0xA8
|
|
jb .DoIt
|
|
|
|
; AA,AB = stos; AC,AD = lods; AE,AF = scas
|
|
@@:
|
|
cmp al,0xAA
|
|
jb @F
|
|
cmp al,0xB0
|
|
jb .DoIt
|
|
|
|
; E0 = loopnz; E1 = loopz; E2 = loop
|
|
@@:
|
|
cmp al,0xE0
|
|
jb .NoLoop
|
|
cmp al,0xE2
|
|
ja .NoLoop
|
|
inc esi
|
|
jmp .DoIt
|
|
|
|
; FF /2 = call
|
|
.NoLoop:
|
|
cmp al,0xFF
|
|
jnz OnStep
|
|
call GetByteNoBreak
|
|
jc OnStep
|
|
inc esi
|
|
mov cl,al
|
|
and al,00111000b
|
|
cmp al,00010000b
|
|
jnz OnStep
|
|
; skip instruction
|
|
mov al,cl
|
|
and eax,7
|
|
shr cl,6
|
|
jz .Mod0
|
|
jp .DoIt
|
|
cmp al,4
|
|
jnz @F
|
|
inc esi
|
|
@@:
|
|
inc esi
|
|
dec cl
|
|
jz @F
|
|
add esi,3
|
|
@@:
|
|
jmp .DoIt
|
|
.Mod0:
|
|
cmp al,4
|
|
jnz @F
|
|
call GetByteNoBreak
|
|
jc OnStep
|
|
inc esi
|
|
and al,7
|
|
@@:
|
|
cmp al,5
|
|
jnz .DoIt
|
|
add esi,4
|
|
.DoIt:
|
|
; insert one-shot breakpoint at esi and resume
|
|
call GetByteNoBreak
|
|
jc OnStep
|
|
mov eax,esi
|
|
call FindEnabledBreakPoint
|
|
jz @F
|
|
mov eax,esi
|
|
mov bl,5
|
|
call AddBreakPoint
|
|
jmp OnStep.DoIt
|
|
@@:
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Read next byte of machine code
|
|
GetByteNoBreak:
|
|
mov eax,esi
|
|
call FindEnabledBreakPoint
|
|
jnz .NoBreak
|
|
mov al,[edi+5]
|
|
clc
|
|
ret
|
|
|
|
.NoBreak:
|
|
xor edx,edx
|
|
push edx
|
|
inc edx
|
|
mov edi,esp
|
|
mcall 69,6,[DebuggeePID]
|
|
dec eax
|
|
clc
|
|
jz @F
|
|
stc
|
|
@@:
|
|
pop eax
|
|
ret
|
|
|
|
IsPrefix:
|
|
cmp al,0x64 ; fs:
|
|
jz .Ret
|
|
cmp al,0x65 ; gs:
|
|
jz .Ret
|
|
cmp al,0x66 ; use16/32
|
|
jz .Ret
|
|
cmp al,0x67 ; addr16/32
|
|
jz .Ret
|
|
cmp al,0xF0 ; lock
|
|
jz .Ret
|
|
cmp al,0xF2 ; repnz
|
|
jz .Ret
|
|
cmp al,0xF3 ; rep(z)
|
|
jz .Ret
|
|
cmp al,0x2E ; cs:
|
|
jz .Ret
|
|
cmp al,0x36 ; ss:
|
|
jz .Ret
|
|
cmp al,0x3E ; ds:
|
|
jz .Ret
|
|
cmp al,0x26 ; es:
|
|
.Ret:
|
|
ret
|
|
|
|
OnResume:
|
|
mov esi,[CurArg]
|
|
cmp byte [esi],0
|
|
jz GoOn
|
|
call CalcExpression
|
|
jc .Ret
|
|
.Jmp:
|
|
mov eax,ebp
|
|
push eax
|
|
call FindEnabledBreakPoint
|
|
pop eax
|
|
jz GoOn
|
|
mov bl,5 ; valid enabled one-shot
|
|
call AddBreakPoint
|
|
jnc GoOn
|
|
mov esi,aBreakpointLimitExceeded
|
|
call PutMessage
|
|
.Ret:
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Jump event
|
|
OnJump: mov esi,[CurArg]
|
|
cmp byte [rsi],0
|
|
jz .Ret
|
|
call CalcExpression
|
|
jc .Ret
|
|
mov ecx,[CurrentWindow]
|
|
mov [CodeAddr+rcx*4],ebp
|
|
jecxnz .Next
|
|
mov [CPUYPos],1
|
|
.Next:
|
|
cmp ecx,1 ;Reg Window?
|
|
jnz .NReg
|
|
mov eax,[RegXPtr]
|
|
cmp eax,9
|
|
jae .NReg
|
|
mov eax,[RegRTab+rax*4]
|
|
mov [rax],ebp
|
|
call SetContext
|
|
.NReg:
|
|
mov [AfterKey],1
|
|
call ShowImage
|
|
.Ret: ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Help event
|
|
OnHelp: mov esi,HelpMsg
|
|
mov edi,[CurArg]
|
|
cmp byte [edi],0
|
|
jz .X
|
|
mov esi,HelpGroups
|
|
call FindCmd
|
|
jc .NoCmd
|
|
mov esi,[esi+12]
|
|
.X:
|
|
jmp PutMessage
|
|
|
|
.NoCmd:
|
|
mov esi,aUnknownCommand
|
|
jmp .X
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Detach process event
|
|
OnDetach:
|
|
mcall 69,3,[DebuggeePID]
|
|
and [DebuggeePID],0
|
|
call FreeSymbols
|
|
mov esi,aContinued
|
|
jmp PutMessage
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Reload executable event
|
|
OnReLoad:
|
|
cmp [DebuggeePID],0
|
|
jnz TerminateReLoad
|
|
mov esi,NeedDebuggee
|
|
cmp byte [LoadName],0
|
|
jnz DoReLoad
|
|
jz PutMessage
|
|
|
|
TerminateReLoad:
|
|
mov [bReload],1
|
|
;-----------------------------------------------------------------------------
|
|
; Terminate process event
|
|
OnTerminate:
|
|
mcall 69,8,[DebuggeePID]
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Suspend process event
|
|
AfterSuspend:
|
|
mov [bSuspended],1
|
|
call GetNewContext
|
|
call GetDump
|
|
call ShowImage
|
|
ret
|
|
|
|
OnSuspend:
|
|
mcall 69,4,[DebuggeePID]
|
|
call AfterSuspend
|
|
mov esi,aSuspended
|
|
jmp PutMessage
|
|
GoOn:
|
|
; test for enabled breakpoint at eip
|
|
mov eax,[_EIP]
|
|
call FindEnabledBreakPoint
|
|
jnz .NoBreak
|
|
; temporarily disable breakpoint, make step, enable breakpoint, continue
|
|
inc eax
|
|
mov [TempBreak],eax
|
|
mov [bAfterGo],1
|
|
dec eax
|
|
call DisableBreakPoint
|
|
call GetContext
|
|
or byte [_EFL+1],1 ; set TF
|
|
call SetContext
|
|
and byte [_EFL+1],not 1
|
|
call DoResume
|
|
ret
|
|
.NoBreak:
|
|
call DoResume
|
|
ShowImage:
|
|
pushad
|
|
call InitConsole
|
|
call DrawWindow
|
|
popad
|
|
ret
|
|
|
|
even 4
|
|
InitConsole:
|
|
mov eax,[CurWidth]
|
|
mul [CurHeight]
|
|
mov ecx,eax
|
|
mov edi,ConsoleDataPtr
|
|
mov eax,3F203F20h
|
|
shr ecx,1
|
|
rep stosd
|
|
adc cl,cl
|
|
rep stosw
|
|
;
|
|
mov ebx,MSG_HEIGHT ;dY
|
|
mov ecx,[CurWidth] ;\dX
|
|
sub ecx,2 ;/
|
|
mov esi,1 ;X
|
|
mov edi,MinHeight-MSG_HEIGHT-1 ;Y
|
|
mov edx,87208720h
|
|
call ClearWindow
|
|
;
|
|
call DrawFrame
|
|
ret
|
|
|
|
InitCoords:
|
|
mov [CPUXPos],1
|
|
mov [CPUYPos],1
|
|
mov [CPUXPtr],0
|
|
mov [MemXPos],11
|
|
mov [MemYPos],41
|
|
mov eax,[CurWidth]
|
|
SUB eax,21
|
|
mov [StkXPos],eax
|
|
mov [StkYPos],28
|
|
mov [RegXPos],1
|
|
mov [RegYPos],30
|
|
mov [RegLDat],12
|
|
and [RegXPtr],0
|
|
ret
|
|
|
|
GetDataByte:
|
|
;I: esi - address
|
|
;O: al - byte
|
|
pushad
|
|
mov al,0
|
|
push eax
|
|
mcall 69,6,[DebuggeePID],1,[All.esi+4],esp
|
|
if 1
|
|
mov esi,[All.esi+4]
|
|
mov edi,esp
|
|
call RestoreFromBreaksOne
|
|
end if
|
|
cmp eax,-1 ;invalid PID?
|
|
jz @F ;Yes,CF=0
|
|
cmp eax,1 ;CF=1,eax=1 if OK
|
|
cmc
|
|
@@: pop dword [esp+1Ch]
|
|
popad
|
|
ret
|
|
|
|
SafeStoreDD:
|
|
pushad
|
|
mov eax,69
|
|
mov ebx,7
|
|
mov ecx,[DebuggeePID]
|
|
mov edx,4
|
|
mov esi,edi
|
|
lea edi,[All.eax]
|
|
int 40h
|
|
popad
|
|
ret
|
|
|
|
SafeStore:
|
|
pushad
|
|
mov eax,69
|
|
mov ebx,7
|
|
mov ecx,[DebuggeePID]
|
|
mov edx,1
|
|
mov esi,edi
|
|
lea edi,[All.eax]
|
|
int 40h
|
|
popad
|
|
ret
|
|
|
|
DrawWindow:
|
|
btr dword [DoDraw],0
|
|
jc .CopyDraw
|
|
mov esi,ConsoleDataPtr
|
|
mov edi,ConsoleDataOld
|
|
mov ecx,[CurWidth]
|
|
imul ecx,[CurHeight]
|
|
shr ecx,1
|
|
repz cmpsd
|
|
jnz .CopyDraw
|
|
adc cl,cl
|
|
repz cmpsw
|
|
jz .SkipDraw
|
|
.CopyDraw:
|
|
mov esi,ConsoleDataPtr
|
|
mov edi,ConsoleDataOld
|
|
mov ecx,[CurWidth]
|
|
imul ecx,[CurHeight]
|
|
shr ecx,1
|
|
rep movsd
|
|
adc cl,cl
|
|
rep movsw
|
|
|
|
push SF_REDRAW
|
|
pop eax
|
|
push SSF_BEGIN_DRAW
|
|
pop ebx
|
|
int 40h
|
|
mov al,SF_STYLE_SETTINGS
|
|
mov bl,SSF_GET_SKIN_HEIGHT
|
|
int 40h
|
|
mov [SkinH],eax
|
|
mov ebx,[CurWidth]
|
|
imul ebx,FontWidth
|
|
add ebx,100*65536+5*2-1
|
|
mov ecx,[CurHeight]
|
|
imul ecx,FontHeight
|
|
lea ecx,[eax+ecx+5-1+100*65536]
|
|
xor eax,eax
|
|
mov edx,0x53000000
|
|
|
|
mov edi,HeaderN
|
|
cmp [DebuggeePID],0
|
|
jz @F
|
|
mov edi,HeaderY
|
|
@@: int 40h
|
|
|
|
mov al,SF_DRAW_RECT
|
|
xor edx,edx
|
|
cmp [FillWidth],0
|
|
jz @F
|
|
mov ebx,[WndWidth]
|
|
sub ebx,[FillWidth]
|
|
sub ebx,5-1
|
|
shl ebx,16
|
|
mov bx,word [FillWidth]
|
|
mov ecx,[SkinH-2]
|
|
mov cx,word [WndHeight]
|
|
sub cx,word [SkinH]
|
|
sub cx,5-1
|
|
int 40h
|
|
@@:
|
|
cmp [FillHeight],0
|
|
jz @F
|
|
xor edx,edx
|
|
mov ebx,50000h
|
|
mov bx,word [WndWidth]
|
|
sub ebx,9
|
|
mov ecx,[WndHeight]
|
|
sub ecx,[FillHeight]
|
|
sub ecx,5-1
|
|
shl ecx,16
|
|
mov cx,word [FillHeight]
|
|
int 40h
|
|
@@:
|
|
call DrawImage
|
|
mov al,SF_PUT_IMAGE_EXT
|
|
mov ebx,[MemForImage]
|
|
test ebx,ebx
|
|
jz @F
|
|
mov ecx,[CurWidth]
|
|
imul ecx,FontWidth*10000h
|
|
mov cx,word [CurHeight]
|
|
imul cx,FontHeight
|
|
mov edx,[SkinH]
|
|
add edx,5*10000h
|
|
mov esi,8
|
|
mov edi,ConsoleColors
|
|
xor ebp,ebp
|
|
int 40h
|
|
@@:
|
|
mov al,SF_REDRAW
|
|
push SSF_END_DRAW
|
|
pop ebx
|
|
int 40h
|
|
.SkipDraw:
|
|
ret
|
|
|
|
align 16
|
|
DrawImage:
|
|
mov [bMemForImageValidData],byte 1
|
|
cmp [MemForImage],0
|
|
jnz .Allocated
|
|
; allocate memory for image
|
|
mov ecx,[CurWidth]
|
|
imul ecx,[CurHeight]
|
|
imul ecx,FontWidth*FontHeight
|
|
call PGAlloc
|
|
test eax,eax
|
|
ifz ret
|
|
mov [MemForImage],eax
|
|
mov [bMemForImageValidData],byte 0
|
|
.Allocated:
|
|
push ebp
|
|
and [MaxX],0
|
|
or [MinX],-1
|
|
and [MaxY],0
|
|
or [MinY],-1
|
|
mov eax,[CursorY]
|
|
mul [CurWidth]
|
|
add eax,[CursorX]
|
|
add eax,eax
|
|
add eax,ConsoleDataPtr
|
|
xchg [CurCursorPos],eax
|
|
mov [OldCursorPos],eax
|
|
mov edi,[MemForImage]
|
|
mov esi,ConsoleDataPtr
|
|
mov ecx,[CurHeight]
|
|
.LH:
|
|
push ecx
|
|
mov ecx,[CurWidth]
|
|
.LW:
|
|
push ecx
|
|
mov eax,[CurWidth]
|
|
imul eax,[CurHeight]
|
|
mov ebx,[esi]
|
|
cmp [bMemForImageValidData],0
|
|
jz @F
|
|
cmp esi,[CurCursorPos]
|
|
jz @F
|
|
cmp esi,[OldCursorPos]
|
|
jz @F
|
|
cmp bx,[eax*2+esi]
|
|
jnz @F
|
|
inc esi
|
|
inc esi
|
|
jmp .SkipSymbol
|
|
@@:
|
|
mov [eax*2+esi],bx
|
|
cmp ecx,[MinX]
|
|
ja @F
|
|
mov [MinX],ecx
|
|
@@:
|
|
cmp ecx,[MaxX]
|
|
jb @F
|
|
mov [MaxX],ecx
|
|
@@:
|
|
mov eax,[esp+4]
|
|
mov [MinY],eax
|
|
cmp eax,[MaxY]
|
|
jb @F
|
|
mov [MaxY],eax
|
|
@@:
|
|
push edi
|
|
xor eax,eax
|
|
mov al,[esi+1]
|
|
and al,0xF
|
|
mov ebx,eax
|
|
mov al,[esi+1]
|
|
shr al,4
|
|
mov ebp,eax
|
|
sub ebx,ebp
|
|
lodsb
|
|
inc esi
|
|
if FontWidth > 8
|
|
lea edx,[eax+eax+Font]
|
|
else
|
|
lea edx,[eax+Font]
|
|
end if
|
|
.SH:
|
|
mov ecx,[edx]
|
|
repeat FontWidth
|
|
shr ecx,1
|
|
sbb eax,eax
|
|
and eax,ebx
|
|
add eax,ebp
|
|
mov [edi+%-1],al
|
|
end repeat
|
|
mov eax,[CurWidth]
|
|
if FontWidth = 6
|
|
lea eax,[eax*2+eax]
|
|
lea edi,[edi+eax*2]
|
|
else if FontWidth = 7
|
|
lea edi,[edi+eax*8]
|
|
sub edi,eax
|
|
else if FontWidth = 8
|
|
lea edi,[edi+eax*8]
|
|
else if FontWidth = 9
|
|
lea edi,[edi+eax*8]
|
|
add edi,eax
|
|
else if FontWidth = 10
|
|
lea eax,[eax*4+eax]
|
|
lea edi,[edi+eax*2]
|
|
else
|
|
Unknown FontWidth Value!
|
|
end if
|
|
if FontWidth > 8
|
|
add edx,256*2
|
|
cmp edx,Font+256*2*FontHeight
|
|
else
|
|
add edx,256
|
|
cmp edx,Font+256*FontHeight
|
|
end if
|
|
jb .SH
|
|
pop edi
|
|
.SkipSymbol:
|
|
pop ecx
|
|
add edi,FontWidth
|
|
dec ecx
|
|
jnz .LW
|
|
mov eax,[CurWidth]
|
|
imul eax,(FontHeight-1)*FontWidth
|
|
add edi,eax
|
|
pop ecx
|
|
dec ecx
|
|
jnz .LH
|
|
; cursor
|
|
mov eax,[CursorY]
|
|
inc eax
|
|
jz .NoCursor
|
|
mul [CurWidth]
|
|
imul eax,FontHeight*FontWidth
|
|
mov edx,[CursorX]
|
|
inc edx
|
|
imul edx,FontWidth
|
|
add eax,edx
|
|
add eax,[MemForImage]
|
|
mov edx,[CurWidth]
|
|
imul edx,FontWidth
|
|
neg edx
|
|
mov ecx,[CursorSize]
|
|
.CursorLoop:
|
|
push ecx
|
|
mov ecx,FontWidth
|
|
add eax,edx
|
|
push eax
|
|
@@:
|
|
xor byte [eax-1],7
|
|
sub eax,1
|
|
loop @B
|
|
pop eax
|
|
pop ecx
|
|
loop .CursorLoop
|
|
.NoCursor:
|
|
cmp [MinY],-1
|
|
jz .NoDraw
|
|
mov ecx,[CurWidth]
|
|
mov ebx,[CurHeight]
|
|
mov eax,ebx
|
|
sub ebx,[MaxY]
|
|
sub eax,[MinY]
|
|
sub eax,ebx
|
|
inc eax
|
|
imul ebp,eax,FontHeight
|
|
mov edx,ecx
|
|
sub edx,[MaxX]
|
|
imul edx,FontWidth
|
|
mov eax,edx
|
|
shl edx,16
|
|
imul dx,bx,FontHeight
|
|
imul ebx,[CurWidth]
|
|
mov ecx,[MaxX]
|
|
sub ecx,[MinX]
|
|
inc ecx
|
|
imul ecx,FontWidth*10000h
|
|
add ecx,ebp
|
|
imul ebx,FontWidth*FontHeight
|
|
add ebx,[MemForImage]
|
|
add ebx,eax
|
|
add edx,[SkinH]
|
|
add edx,5*10000h
|
|
imul esi,[CurWidth],FontWidth
|
|
mov ebp,ecx
|
|
shr ebp,16
|
|
sub esi,ebp
|
|
mov ebp,esi
|
|
push SF_PUT_IMAGE_EXT
|
|
pop eax
|
|
mov edi,ConsoleColors
|
|
push 8
|
|
pop esi
|
|
int 40h
|
|
.NoDraw:
|
|
pop ebp
|
|
ret
|
|
even 4
|
|
Redraw:
|
|
mov al,SF_THREAD_INFO
|
|
mov ebx,ProcInfo
|
|
or ecx,-1
|
|
int 40h
|
|
; test if rolled up
|
|
; height of rolled up window is [skinh]+3
|
|
mov eax,[ebx+46]
|
|
sub eax,[SkinH]
|
|
cmp eax,5
|
|
ja @F
|
|
mov al,SF_REDRAW
|
|
push SSF_BEGIN_DRAW
|
|
pop ebx
|
|
int 0x40
|
|
xor eax,eax
|
|
; ebx, ecx, edi are ignored by function 0 after first redraw
|
|
mov edx,0x53000000
|
|
int 0x40
|
|
mov al,SF_REDRAW
|
|
inc ebx
|
|
int 0x40
|
|
jmp WaitEvent
|
|
@@:
|
|
xor ecx,ecx
|
|
mov eax,[ebx+42]
|
|
mov [WndWidth],eax
|
|
sub eax,5*2-1
|
|
jae @F
|
|
xor eax,eax
|
|
@@:
|
|
cdq
|
|
mov esi,FontWidth
|
|
div esi
|
|
cmp eax,MinWidth
|
|
jae @F
|
|
mov al,MinWidth
|
|
mov ch,1
|
|
@@:
|
|
cmp eax,MaxWidth
|
|
jbe @F
|
|
mov eax,MaxWidth
|
|
mov ch,1
|
|
@@:
|
|
cmp eax,[CurWidth]
|
|
mov [CurWidth],eax
|
|
setnz cl
|
|
or cl,ch
|
|
test edx,edx
|
|
mov [FillWidth],edx
|
|
setnz ch
|
|
mov eax,[ebx+46]
|
|
mov [WndHeight],eax
|
|
sub eax,[SkinH]
|
|
sub eax,5-1
|
|
jns @F
|
|
xor eax,eax
|
|
@@:
|
|
cdq
|
|
mov esi,FontHeight
|
|
div esi
|
|
cmp eax,MinHeight
|
|
jae @F
|
|
mov al,MinHeight
|
|
mov cl,1
|
|
@@:
|
|
cmp eax,MaxHeight
|
|
jbe @F
|
|
mov eax,MaxHeight
|
|
mov cl,1
|
|
@@:
|
|
mov [FillHeight],edx
|
|
cmp eax,[CurHeight]
|
|
mov [CurHeight],eax
|
|
jnz .ReSize
|
|
test cl,cl
|
|
jnz .ReSize
|
|
test edx,edx
|
|
setnz cl
|
|
or cl,ch
|
|
jz @F
|
|
test byte [ebx+70],1
|
|
jnz @F
|
|
.ReSize:
|
|
push SF_CHANGE_WINDOW
|
|
pop eax
|
|
or ebx,-1
|
|
or ecx,-1
|
|
mov edx,[CurWidth]
|
|
imul edx,FontWidth
|
|
add edx,5*2-1
|
|
mov esi,[CurHeight]
|
|
imul esi,FontHeight
|
|
add esi,[SkinH]
|
|
add esi,5-1
|
|
int 40h
|
|
.ReSizeDraw:
|
|
mov ecx,[MemForImage]
|
|
call PGFree
|
|
and [MemForImage],0
|
|
call InitConsole
|
|
call InitCoords
|
|
jmp WaitEvent
|
|
@@: mov [DoDraw],1
|
|
call DrawWindow
|
|
jmp WaitEvent
|
|
|
|
even 4
|
|
Start:
|
|
xor eax,eax
|
|
mov edi,NeedZeroStart
|
|
mov ecx,(NeedZeroEnd-NeedZeroStart+3)/4
|
|
rep stosd
|
|
|
|
call DetectCPU
|
|
mov [CPUType],dl
|
|
call DetectFPU
|
|
mov [FPUType],al
|
|
|
|
cmp [CPUType],5
|
|
jb @F
|
|
xor eax,eax
|
|
cpuid
|
|
mov edi,MsgXMMX+4
|
|
mov [edi+0],ebx
|
|
mov [edi+4],edx
|
|
mov [edi+8],ecx
|
|
cmp eax,1
|
|
jl .L1
|
|
xor eax,eax
|
|
inc eax
|
|
cpuid
|
|
xchg eax,edx
|
|
jmp .L2
|
|
.L1: xor eax,eax
|
|
.L2: test eax,00800000h ; CPU have MMX?
|
|
setnz [MMXType]
|
|
test eax,02000000h ; CPU have SSE?
|
|
setnz [XMMType]
|
|
@@:
|
|
|
|
push SF_SYS_MISC
|
|
pop eax
|
|
push SSF_HEAP_INIT
|
|
pop ebx
|
|
int 40h
|
|
|
|
call InitCmdHistBuffer
|
|
call InitDefault
|
|
|
|
call InitCoords
|
|
call ShowImage
|
|
|
|
; set event mask - default events and debugging events
|
|
mcall 40,EVM_REDRAW or EVM_KEY or EVM_BUTTON or EVM_DEBUG
|
|
; set debug messages buffer
|
|
mov ecx,DbgBufSize
|
|
mov dword [ecx],256
|
|
xor ebx,ebx
|
|
mov [ecx+4],ebx
|
|
mov al,69
|
|
mcall
|
|
|
|
call ShowImage
|
|
|
|
WaitEvent:
|
|
push SF_WAIT_EVENT
|
|
pop eax
|
|
int 40h
|
|
|
|
cmp al,9
|
|
jz DebugMsg
|
|
dec eax
|
|
jz Redraw
|
|
dec eax
|
|
jz Key
|
|
sub eax,4
|
|
jz Mouse
|
|
; button - we have only one button, close
|
|
;-----------------------------------------------------------------------------
|
|
; Quit event
|
|
OnQuit:
|
|
or eax,-1
|
|
int 40h
|
|
Key:
|
|
mov al,SF_KEYBOARD
|
|
push SSF_GET_CONTROL_KEYS
|
|
pop ebx
|
|
int 0x40
|
|
and eax,0x3F
|
|
mov [CtrlState],al
|
|
|
|
mov al,SF_GET_KEY
|
|
int 40h
|
|
test al,al
|
|
jnz WaitEvent
|
|
|
|
shr eax,8
|
|
|
|
cmp ah,5Dh
|
|
ifz call DumpScreen
|
|
|
|
cmp [DebuggeePID],0
|
|
jz DoCommandLine
|
|
cmp [CmdLineActive],0
|
|
jnz GetCommandLine
|
|
|
|
jmp WinSwitch
|
|
|
|
F7: cmp [DebuggeePID],0
|
|
jz .No
|
|
call OnStep
|
|
.No:jmp WaitEvent
|
|
|
|
F8: cmp [DebuggeePID],0
|
|
jz F7.No
|
|
call OnProceed
|
|
jmp F7.No
|
|
|
|
even 16
|
|
Mouse:
|
|
if 0
|
|
mov eax,SF_MOUSE_GET
|
|
mov ebx,SSF_BUTTON_EXT
|
|
int 0x40
|
|
mov byte [MouseState],1
|
|
bt eax,24 ;left but. double click
|
|
jc @F
|
|
mov byte [MouseState],0
|
|
bt eax,8 ;left but. down
|
|
jc @F
|
|
jmp WaitEvent
|
|
@@:
|
|
mov eax,SF_MOUSE_GET
|
|
mov ebx,SSF_WINDOW_POSITION
|
|
int 0x40
|
|
end if
|
|
jmp WaitEvent
|
|
|
|
DumpScreen:
|
|
pushad
|
|
mov dword [DumpName+4],'0000'
|
|
.1:
|
|
mov [DumpBlock.Func],SSF_GET_INFO
|
|
mcall 70,DumpBlock
|
|
or eax,eax
|
|
jnz .2
|
|
inc byte [DumpName+7]
|
|
cmp byte [DumpName+7],'9'
|
|
jbe .1
|
|
mov byte [DumpName+7],'0'
|
|
inc byte [DumpName+6]
|
|
cmp byte [DumpName+6],'9'
|
|
jbe .1
|
|
mov byte [DumpName+6],'0'
|
|
popad
|
|
ret
|
|
.2: mov [DumpBlock.Func],SSF_CREATE_FILE
|
|
mcall 70,DumpBlock
|
|
or eax,eax
|
|
jnz .Err
|
|
mov ebx,[CurHeight]
|
|
mov esi,ConsoleDataPtr
|
|
mov edi,ConsoleDataOld
|
|
.3: mov ecx,[CurWidth]
|
|
.4: mov al,[rsi]
|
|
test al,al
|
|
jz .5
|
|
cmp al,0Ah
|
|
jz .5
|
|
cmp al,0Dh
|
|
jz .5
|
|
cmp al,10h
|
|
jb .X
|
|
jmp .6
|
|
.5: mov al,20h
|
|
jmp .6
|
|
.X: mov al,'.'
|
|
.6: mov [rdi],al
|
|
add esi,2
|
|
inc edi
|
|
loop .4
|
|
mov byte [rdi],13
|
|
inc edi
|
|
dec ebx
|
|
jnz .3
|
|
mov ecx,[CurWidth]
|
|
inc ecx
|
|
imul ecx,[CurHeight]
|
|
mov [DumpBlock.Size],ecx
|
|
mov [DumpBlock.Func],SSF_WRITE_FILE
|
|
mcall 70,DumpBlock
|
|
.Err: popad
|
|
ret
|
|
|
|
AfterGoException:
|
|
push eax
|
|
mov eax,[TempBreak]
|
|
dec eax
|
|
push esi
|
|
call EnableBreakPoint
|
|
; in any case, clear TF and RF
|
|
call GetNewContext
|
|
and [_EFL],not 10100h ; clear TF,RF
|
|
call SetContext
|
|
xor edx,edx
|
|
mov [TempBreak],edx
|
|
xchg dl,[bAfterGo]
|
|
pop esi
|
|
pop eax
|
|
cmp dl,2
|
|
jnz @F
|
|
lodsd
|
|
push esi
|
|
call GetDump
|
|
jmp Exception.Done
|
|
@@:
|
|
test eax,eax
|
|
jz .NotInt1
|
|
; if exception is result of single step, simply ignore it and continue
|
|
test dword [esi],0xF
|
|
jnz DbgMsgStart.5
|
|
lodsd
|
|
push esi
|
|
mov esi,OldContext
|
|
mov edi,Context
|
|
mov ecx,28h/4
|
|
rep movsd
|
|
call DoResume
|
|
jmp DbgMsgEnd
|
|
.NotInt1:
|
|
; in other case, work as without temp_break
|
|
lodsd
|
|
push esi
|
|
push eax
|
|
jmp Exception.4
|
|
|
|
.NoTour:
|
|
|
|
DebugMsg:
|
|
neg [DbgBufSize]
|
|
mov esi,DbgBuf
|
|
DbgMsgStart:
|
|
lodsd
|
|
add esi,4
|
|
dec eax
|
|
jz Exception
|
|
dec eax
|
|
jz Terminated
|
|
dec eax
|
|
jnz DbgNotify
|
|
|
|
mov [bSuspended],1
|
|
cmp [bAfterGo],0
|
|
jnz AfterGoException
|
|
push esi
|
|
call GetNewContext
|
|
and [_EFL],not 10100h ; clear TF,RF
|
|
call SetContext
|
|
pop esi
|
|
.5:
|
|
push esi
|
|
call GetDump
|
|
pop esi
|
|
lodsd
|
|
xor ecx,ecx
|
|
.6:
|
|
bt eax,ecx
|
|
jnc .7
|
|
mov ebx,[DrXBreak+ecx*4]
|
|
test ebx,ebx
|
|
jz .7
|
|
pushad
|
|
dec ebx
|
|
push ebx
|
|
mov esi,aBreakStop
|
|
call PutMessageNoDraw
|
|
popad
|
|
.7:
|
|
inc ecx
|
|
cmp cl,4
|
|
jb .6
|
|
push esi
|
|
jmp Exception.DoneDraw
|
|
|
|
DbgNotify:
|
|
int3
|
|
add esi,32
|
|
push esi
|
|
jmp DbgMsgEnd
|
|
|
|
Terminated:
|
|
push esi
|
|
mov esi,TerminatedMsg
|
|
call PutMessage
|
|
and [DebuggeePID],0
|
|
and [TempBreak],0
|
|
mov [bAfterGo],0
|
|
xor eax,eax
|
|
mov ecx,BreakPointsN*6/4+4
|
|
mov edi,BreakPoints
|
|
rep stosd
|
|
cmp [bReload],1
|
|
sbb [bReload],-1
|
|
jnz Exception.Done
|
|
call FreeSymbols
|
|
jmp Exception.Done
|
|
|
|
Exception:
|
|
mov [bSuspended],1
|
|
cmp [bAfterGo],0
|
|
jnz AfterGoException
|
|
lodsd
|
|
push esi
|
|
push eax
|
|
call GetNewContext
|
|
and [_EFL],not 10100h ; clear TF,RF
|
|
call SetContext
|
|
.4:
|
|
call GetDump
|
|
pop eax
|
|
; int3 command generates exception 0x0D, #GP
|
|
push eax
|
|
cmp al,0x0D
|
|
jnz .NotDbg
|
|
; check for 0xCC byte at eip
|
|
push 0
|
|
mcall 69,6,[DebuggeePID],1,[_EIP],esp
|
|
pop eax
|
|
cmp al,0xCC
|
|
je .Int3
|
|
; check for 0xCD03 word at eip
|
|
push 0
|
|
inc edx
|
|
mcall 69;,6,[DebuggeePID],2,[_EIP],esp
|
|
pop eax
|
|
cmp ax,0x03CD
|
|
jne .NotDbg
|
|
mov eax,[_EIP]
|
|
inc [_EIP]
|
|
inc [_EIP]
|
|
jmp .UserINT3
|
|
.Int3:
|
|
; this is either dbg breakpoint or int3 cmd in debuggee
|
|
mov eax,[_EIP]
|
|
call FindEnabledBreakPoint
|
|
jnz .UserINT3
|
|
; dbg breakpoint; clear if one-shot
|
|
pop ecx
|
|
push eax
|
|
mov esi,aBreakStop
|
|
test byte [edi+4],4
|
|
jz .PutMsgEAX
|
|
pop ecx
|
|
call ClearBreakPoint
|
|
jmp .Done
|
|
|
|
.UserINT3:
|
|
mov eax,[_EIP]
|
|
inc [_EIP]
|
|
.UserINT3_:
|
|
pop ecx
|
|
push eax
|
|
call SetContext
|
|
mov esi,aUserBreak
|
|
jmp .PutMsgEAX
|
|
|
|
.NotDbg:
|
|
pop eax
|
|
push eax
|
|
push eax
|
|
mov esi,aException
|
|
call PutMessageNoDraw
|
|
pop eax
|
|
|
|
cmp al,16
|
|
ja .Suspended
|
|
mov esi,[MsgFaultSel+eax*4]
|
|
.ShowMess:
|
|
call PutMessageNoDraw
|
|
.Suspended:
|
|
mov esi,aSuspended
|
|
.PutMsgEAX:
|
|
call PutMessageNoDraw
|
|
.DoneDraw:
|
|
call DrawMessages
|
|
.Done:
|
|
mcall 18,3,[DbgWnd] ; activate dbg window
|
|
call ShowImage
|
|
|
|
DbgMsgEnd:
|
|
pop esi
|
|
mov ecx,[DbgBufLen]
|
|
add ecx,DbgBuf
|
|
cmp esi,ecx
|
|
jnz DbgMsgStart
|
|
and [DbgBufLen],0
|
|
neg [DbgBufSize]
|
|
cmp [bReload],2
|
|
jnz @F
|
|
mov [bReload],0
|
|
call DoReLoad
|
|
@@:
|
|
jmp WaitEvent
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Add breakpoint
|
|
; in: EAX = address; BL = flags
|
|
; out: CF = 1 => error
|
|
; CF = 0 and EAX = breakpoint number
|
|
AddBreakPoint:
|
|
xor ecx,ecx
|
|
mov edi,BreakPoints
|
|
@@:
|
|
test byte [edi+4],1
|
|
jz .Found
|
|
add edi,6
|
|
inc ecx
|
|
cmp ecx,BreakPointsN
|
|
jb @B
|
|
stc
|
|
ret
|
|
.Found:
|
|
stosd
|
|
xchg eax,ecx
|
|
mov [edi],bl
|
|
test bl,2
|
|
jnz @F
|
|
or byte [edi],2
|
|
push eax
|
|
call EnableBreakPoint
|
|
pop eax
|
|
@@:
|
|
clc
|
|
ret
|
|
;-----------------------------------------------------------------------------
|
|
; Remove breakpoint
|
|
ClearBreakPoint:
|
|
cmp eax,BreakPointsN
|
|
jae .Ret
|
|
mov ecx,4
|
|
inc eax
|
|
.1:
|
|
cmp [DrXBreak-4+ecx*4],eax
|
|
jnz @F
|
|
and [DrXBreak-4+ecx*4],0
|
|
@@:
|
|
loop .1
|
|
dec eax
|
|
push eax
|
|
add eax,eax
|
|
lea edi,[BreakPoints+eax+eax*2+4]
|
|
test byte [edi],1
|
|
pop eax
|
|
jz .Ret
|
|
push edi
|
|
call DisableBreakPoint
|
|
pop edi
|
|
mov byte [edi],0
|
|
.Ret:
|
|
ret
|
|
;-----------------------------------------------------------------------------
|
|
; Disable breakpoint
|
|
DisableBreakPoint:
|
|
cmp eax,BreakPointsN
|
|
jae .Ret
|
|
add eax,eax
|
|
lea edi,[BreakPoints+eax+eax*2+5]
|
|
test byte [edi-1],1
|
|
jz .Ret
|
|
test byte [edi-1],2
|
|
jnz .Ret
|
|
or byte [edi-1],2
|
|
test byte [edi-1],8
|
|
jnz .DR
|
|
push esi
|
|
mcall 69,7,[DebuggeePID],1,[edi-5]
|
|
pop esi
|
|
.Ret:
|
|
ret
|
|
.DR:
|
|
mov dl,[edi]
|
|
shr dl,6
|
|
mov dh,80h
|
|
mcall 69,9,[DebuggeePID]
|
|
ret
|
|
;-----------------------------------------------------------------------------
|
|
; Enable breakpoint
|
|
EnableBreakPoint:
|
|
push esi
|
|
cmp eax,BreakPointsN
|
|
jae .Ret
|
|
add eax,eax
|
|
lea edi,[BreakPoints+eax+eax*2+5]
|
|
test byte [edi-1],1
|
|
jz .Ret
|
|
test byte [edi-1],2
|
|
jz .Ret
|
|
and byte [edi-1],not 2
|
|
test byte [edi-1],8
|
|
jnz .DR
|
|
mcall 69,6,[DebuggeePID],1,[edi-5]
|
|
dec eax
|
|
jnz .Err
|
|
push 0xCC
|
|
mov edi,esp
|
|
inc ebx
|
|
mcall 69
|
|
pop eax
|
|
.Ret:
|
|
pop esi
|
|
ret
|
|
.Err:
|
|
or byte [edi-1],2
|
|
mov esi,aBreakErr
|
|
call PutMessage
|
|
pop esi
|
|
ret
|
|
.DR:
|
|
mov esi,[edi-5]
|
|
mov dl,[edi]
|
|
shr dl,6
|
|
mov dh,[edi]
|
|
and dh,0xF
|
|
mcall 69,9,[DebuggeePID]
|
|
test eax,eax
|
|
jnz .Err
|
|
pop esi
|
|
ret
|
|
;-----------------------------------------------------------------------------
|
|
; Find breakpoint
|
|
FindBreakPoint:
|
|
xor ecx,ecx
|
|
xchg eax,ecx
|
|
mov edi,BreakPoints
|
|
@@:
|
|
test byte [edi+4],1
|
|
jz .Cont
|
|
test byte [edi+4],8
|
|
jnz .Cont
|
|
cmp [edi],ecx
|
|
jz .Found
|
|
.Cont:
|
|
add edi,6
|
|
inc eax
|
|
cmp eax,BreakPointsN
|
|
jb @B
|
|
or eax,-1
|
|
.Found:
|
|
ret
|
|
;-----------------------------------------------------------------------------
|
|
;
|
|
FindEnabledBreakPoint:
|
|
xor ecx,ecx
|
|
xchg eax,ecx
|
|
mov edi,BreakPoints
|
|
@@:
|
|
test byte [edi+4],1
|
|
jz .Cont
|
|
test byte [edi+4],2 or 8
|
|
jnz .Cont
|
|
cmp [edi],ecx
|
|
jz .Found
|
|
.Cont:
|
|
add edi,6
|
|
inc eax
|
|
cmp eax,BreakPointsN
|
|
jb @B
|
|
or eax,-1
|
|
.Found:
|
|
ret
|
|
|
|
GetDump:
|
|
if 0
|
|
mov edi,DumpData
|
|
mov esi,[edi-4]
|
|
mov edx,DUMP_HEIGHT*10h
|
|
mov ecx,edx
|
|
xor eax,eax
|
|
push edi
|
|
rep stosb
|
|
pop edi
|
|
mcall 69,6,[DebuggeePID]
|
|
cmp eax,-1
|
|
jnz @F
|
|
mov esi,ReadMemErr
|
|
call PutMessage
|
|
xor eax,eax
|
|
@@:
|
|
mov [edi-8],eax
|
|
; in: edi=buffer,eax=size,esi=address
|
|
RestoreFromBreaks:
|
|
mov ebx,BreakPoints
|
|
@@:
|
|
test byte [ebx+4],1
|
|
jz .Cont ; ignore invalid
|
|
test byte [ebx+4],2 or 8
|
|
jnz .Cont ; ignore disabled and memory breaks
|
|
mov ecx,[ebx]
|
|
sub ecx,esi
|
|
cmp ecx,eax
|
|
jae .Cont
|
|
mov dl,[ebx+5]
|
|
mov [edi+ecx],dl
|
|
.Cont:
|
|
add ebx,6
|
|
cmp ebx,BreakPoints+BreakPointsN*6
|
|
jb @B
|
|
end if
|
|
ret
|
|
|
|
; in: edi=buffer,esi=address
|
|
RestoreFromBreaksOne:
|
|
mov ebx,BreakPoints
|
|
@@:
|
|
test byte [ebx+4],1
|
|
jz .Cont ; ignore invalid
|
|
test byte [ebx+4],2 or 8
|
|
jnz .Cont ; ignore disabled and memory breaks
|
|
mov ecx,[ebx]
|
|
sub ecx,esi
|
|
cmp ecx,1
|
|
jae .Cont
|
|
mov dl,[ebx+5]
|
|
mov [edi+ecx],dl
|
|
jmp .Exit
|
|
.Cont:
|
|
add ebx,6
|
|
cmp ebx,BreakPoints+BreakPointsN*6
|
|
jb @B
|
|
.Exit:
|
|
ret
|
|
|
|
GetCommandLine:
|
|
cmp ah,0x01
|
|
jz .Esc
|
|
cmp al,8
|
|
jz .Backspace
|
|
cmp al,0xB0
|
|
jz .Left
|
|
cmp al,0xB3
|
|
jz .Right
|
|
cmp al,0x0D
|
|
jz .Enter
|
|
cmp al,0xB6
|
|
jz .Del
|
|
cmp al,0xB4
|
|
jz .Home
|
|
cmp al,0xB5
|
|
jz .End
|
|
cmp al,0xB1
|
|
jz .Dn
|
|
cmp al,0xB2
|
|
jz .Up
|
|
mov [CmdHistBuffer.TmpLineFlag],0
|
|
cmp [CmdLineLen],CMD_WIDTH
|
|
jae WaitEvent
|
|
push eax
|
|
call ClearCmdLineEnd
|
|
pop eax
|
|
mov edi,CmdLine
|
|
mov ecx,[CmdLineLen]
|
|
add edi,ecx
|
|
lea esi,[edi-1]
|
|
sub ecx,[CmdLinePos]
|
|
std
|
|
rep movsb
|
|
cld
|
|
stosb
|
|
inc [CmdLineLen]
|
|
call DrawCmdLineEnd
|
|
inc [CmdLinePos]
|
|
call DrawCursor
|
|
jmp WaitEvent
|
|
|
|
|
|
.Esc:
|
|
xor eax,eax
|
|
mov [CmdLinePos],eax
|
|
mov [CmdLineLen],eax
|
|
mov [CmdLineActive],al
|
|
call DrawCursor
|
|
jmp WaitEvent
|
|
|
|
.Backspace:
|
|
mov [CmdHistBuffer.TmpLineFlag],0
|
|
cmp [CmdLinePos],0
|
|
jz WaitEvent
|
|
dec [CmdLinePos]
|
|
|
|
.DelChar:
|
|
mov [CmdHistBuffer.TmpLineFlag],0
|
|
call ClearCmdLineEnd
|
|
mov edi,[CmdLinePos]
|
|
dec [CmdLineLen]
|
|
mov ecx,[CmdLineLen]
|
|
sub ecx,edi
|
|
add edi,CmdLine
|
|
lea esi,[edi+1]
|
|
rep movsb
|
|
call DrawCmdLineEnd
|
|
call DrawCursor
|
|
jmp WaitEvent
|
|
|
|
.Del:
|
|
mov eax,[CmdLinePos]
|
|
cmp eax,[CmdLineLen]
|
|
jae WaitEvent
|
|
jmp .DelChar
|
|
|
|
.Left:
|
|
cmp [CmdLinePos],0
|
|
jz WaitEvent
|
|
call HideCursor
|
|
dec [CmdLinePos]
|
|
call DrawCursor
|
|
jmp WaitEvent
|
|
|
|
.Right:
|
|
mov eax,[CmdLinePos]
|
|
cmp eax,[CmdLineLen]
|
|
jae WaitEvent
|
|
call HideCursor
|
|
inc [CmdLinePos]
|
|
call DrawCursor
|
|
jmp WaitEvent
|
|
|
|
.Home:
|
|
call HideCursor
|
|
and [CmdLinePos],0
|
|
call DrawCursor
|
|
jmp WaitEvent
|
|
|
|
.End:
|
|
call HideCursor
|
|
mov eax,[CmdLineLen]
|
|
mov [CmdLinePos],eax
|
|
call DrawCursor
|
|
jmp WaitEvent
|
|
|
|
.Up:
|
|
xor edx,edx
|
|
jmp .Hist
|
|
.Dn:
|
|
xor edx,edx
|
|
inc edx
|
|
.Hist:
|
|
cmp [CmdHistBuffer.TmpLineFlag],1
|
|
je @F
|
|
mov eax,CmdLine
|
|
mov ecx,[CmdLineLen]
|
|
mov byte [eax+ecx],0
|
|
call AddCmdHistTmpLine
|
|
@@:
|
|
test edx,edx
|
|
jnz .Hist.Next
|
|
cmp [CmdHistBuffer.NFlag],0
|
|
jne @F
|
|
call GetCmdHistLine
|
|
inc [CmdHistBuffer.NFlag]
|
|
jmp .Hist.CPLine
|
|
|
|
@@:
|
|
call PrevCmdHistLine
|
|
jc WaitEvent
|
|
call GetCmdHistLine
|
|
inc [CmdHistBuffer.NFlag]
|
|
jmp .Hist.CPLine
|
|
|
|
.Hist.Next:
|
|
cmp [CmdHistBuffer.NFlag],0
|
|
je WaitEvent
|
|
|
|
call NextCmdHistLine
|
|
call GetCmdHistLine
|
|
jnc .Hist.CPLine
|
|
call GetCmdHistTmpLine
|
|
mov [CmdHistBuffer.TmpLineFlag],0
|
|
mov [CmdHistBuffer.NFlag],0
|
|
|
|
.Hist.CPLine:
|
|
|
|
mov esi,eax
|
|
mov edi,CmdLine
|
|
xor ecx,ecx
|
|
@@:
|
|
inc ecx
|
|
lodsb
|
|
stosb
|
|
test al,al
|
|
jnz @B
|
|
|
|
dec ecx
|
|
mov [CmdLinePos],0
|
|
call ClearCmdLineEnd
|
|
mov [CmdLineLen],ecx
|
|
mov [CmdLinePos],ecx
|
|
call DrawCmdLine
|
|
call DrawCursor
|
|
|
|
jmp WaitEvent
|
|
|
|
; We also trying to execute previous command, if empty command_line
|
|
.Enter:
|
|
mov [CmdLineActive],0
|
|
|
|
mov ecx,[CmdLineLen]
|
|
test ecx,ecx
|
|
jnz .ExecCur
|
|
mov cl,byte [CmdLinePrev]
|
|
cmp cl,0
|
|
jz WaitEvent
|
|
|
|
.ExecPrev:
|
|
mov esi,CmdLinePrev
|
|
jmp .Exec
|
|
|
|
.ExecCur:
|
|
mov esi,CmdLine
|
|
|
|
.Exec:
|
|
mov byte [esi+ecx],0
|
|
|
|
mov eax,esi
|
|
call AddCmdHistLine
|
|
mov [CmdHistBuffer.NFlag],0
|
|
|
|
and [CmdLinePos],0
|
|
push esi
|
|
call ClearCmdLineEnd
|
|
call DrawCursor
|
|
pop esi
|
|
and [CmdLineLen],0
|
|
; skip leading spaces
|
|
call GetArg.SkipSpaces
|
|
cmp al,0
|
|
jz WaitEvent
|
|
; now esi points to command
|
|
push esi
|
|
mov esi,Prompt
|
|
call PutMessageNoDraw
|
|
pop esi
|
|
push esi
|
|
call PutMessageNoDraw
|
|
Z1:
|
|
mov esi,NewLine
|
|
call PutMessage
|
|
pop esi
|
|
push esi
|
|
call GetArg
|
|
mov [CurArg],esi
|
|
pop edi
|
|
mov esi,Commands
|
|
call FindCmd
|
|
mov eax,aUnknownCommand
|
|
jc .X11
|
|
|
|
; check command requirements
|
|
; flags field:
|
|
; &1: command may be called without parameters
|
|
; &2: command may be called with parameters
|
|
; &4: command may be called without loaded program
|
|
; &8: command may be called with loaded program
|
|
mov eax,[esi+8]
|
|
mov ecx,[CurArg]
|
|
cmp byte [ecx],0
|
|
jz .NoArgs
|
|
test byte [esi+16],2
|
|
jz .X11
|
|
jmp @F
|
|
|
|
.NoArgs:
|
|
test byte [esi+16],1
|
|
jz .X11
|
|
@@:
|
|
cmp [DebuggeePID],0
|
|
jz .NoDebuggee
|
|
mov eax,aAlreadyLoaded
|
|
test byte [esi+16],8
|
|
jz .X11
|
|
jmp .X9
|
|
|
|
.NoDebuggee:
|
|
mov eax,NeedDebuggee
|
|
test byte [esi+16],4
|
|
jnz .X9
|
|
.X11:
|
|
xchg esi,eax
|
|
call PutMessage
|
|
; store cmdline for repeating
|
|
.X10:
|
|
mov esi,CmdLine
|
|
mov ecx,[CmdLineLen]
|
|
@@:
|
|
or ecx,ecx
|
|
jle .We
|
|
mov al,[esi+ecx]
|
|
mov [CmdLinePrev+ecx],al
|
|
dec ecx
|
|
jmp @B
|
|
|
|
.We:
|
|
mov [CmdLineLen],0
|
|
jmp WaitEvent
|
|
|
|
.X9:
|
|
call dword [esi+4]
|
|
jmp .X10
|
|
|
|
PutMessage:
|
|
call PutMessageNoDraw
|
|
DrawMessages:
|
|
mov [AfterKey],1
|
|
call ShowImage
|
|
ret
|
|
|
|
include "cmdhist.inc"
|
|
include "parser.inc"
|
|
include "message.inc"
|
|
|
|
HeaderN db 'SunSys Debugger ver ',VERSION,' - No program loaded',0
|
|
HeaderY db 'SunSys Debugger ver ',VERSION,' - ',60 dup 32,0
|
|
HeaderE:
|
|
;
|
|
LoadErrMsg db 'Cannot load program. ',0
|
|
UnkErrMsg db 'Unknown error code -%4X',10,0
|
|
aCannotLoadFile db 'Cannot load file. ',0
|
|
UnkErrMsg2 db 'Unknown error code %4X.',10,0
|
|
LoadErrMsgs:
|
|
dd .1,0,.3,0,.5,.6,0,0,.9,.A,0,0,0,0,0,0
|
|
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,.1E,.1F,.20
|
|
.1 db 'HD undefined.',10,0
|
|
.3 db 'Unknown FS.',10,0
|
|
.5 db 'File not found.',10,0
|
|
.6 db 'Unexpected EOF.',10,0
|
|
.9 db 'FAT table corrupted.',10,0
|
|
.A db 'Access denied.',10,0
|
|
.1E db 'No memory.',10,0
|
|
.1F db 'Not Menuet/Kolibri executable.',10,0
|
|
.20 db 'Too many processes.',10,0
|
|
LoadSuccMsg db 'Program loaded successfully! PID=%4X. Use "g" to run.',10,0
|
|
TerminatedMsg db 'Program terminated.',10,0
|
|
MsgFaultSel dd aDivide,aDebug,aNonMask,aUndefined,aOverflow
|
|
dd aBounds,aInvalid,aCoProcessorNA,aDoubleFault
|
|
dd aUndefined,aInvalidTSS,aSegment,aStack
|
|
dd aProtection,aPageFault,aUndefined,aCoProcessor
|
|
aDivide db '(Divide error)',10,0
|
|
aDebug db '(Single-step/debug exception)',10,0
|
|
aNonMask db '(Nonmaskable interrupt)',10,0
|
|
aOverflow db '(Overflow)',10,0
|
|
aBounds db '(Bounds check)',10,0
|
|
aInvalid db '(Invalid opcode)',10,0
|
|
aCoProcessorNA db '(Coprocessor not available)',10,0
|
|
aDoubleFault db '(Double fault)',10,0
|
|
aUndefined db '(Undefined fault)',10,0
|
|
aInvalidTSS db '(Invalid TSS)',10,0
|
|
aSegment db '(Segment not present)',10,0
|
|
aStack db '(Stack fault)',10,0
|
|
aProtection db '(General protection fault)',10,0
|
|
aPageFault db '(Page fault)',10,0
|
|
aCoProcessor db '(Coprocessor error)',10,0
|
|
aSuspended db 'Suspended',10,0
|
|
aContinued db 'Continuing',10,0
|
|
aRunningErr db 'Program is running',10,0
|
|
aException db 'Debugged program caused an exception %2X. ',0
|
|
aBreakErr db 'Cannot activate breakpoint, it will be disabled',10,0
|
|
aDuplicateBreakpoint db 'Duplicate breakpoint',10,0
|
|
aInvalidBreak db 'Invalid breakpoint number',10,0
|
|
aBreakNum db '%2X: at %8X',0
|
|
aMemBreak1 db '%2X: on ',0
|
|
aMemBreak2 db 'read from ',0
|
|
aMemBreak3 db 'access of ',0
|
|
aMemBreak4 db 'byte',0
|
|
aMemBreak5 db 'word',0
|
|
aMemBreak6 db 'dword',0
|
|
aMemBreak7 db ' at %8X',0
|
|
aOneShot db ', one-shot',0
|
|
aDisabled db ', disabled',0
|
|
aBreakStop db 'Breakpoint #%2X',10,0
|
|
aUserBreak db 'int3 command at %8X',10,0
|
|
ReadMemErr db 'ERROR: cannot read process memory!!!',10,0
|
|
aBreakpointLimitExceeded db 'Breakpoint limit exceeded',10,0
|
|
aUnknownCommand db 'Unknown command',10,0
|
|
NeedDebuggee db 'No program loaded. Use "load" command.',10,0
|
|
aAlreadyLoaded db 'Program is already loaded. Use "terminate" or "detach" commands',10,0
|
|
aParseError db 'Parse error',10,0
|
|
aDivByZero db 'Division by 0',10,0
|
|
CalcString db '%8X',10,0
|
|
aNoMemory db 'No memory',10,0
|
|
aSymbolsLoaded db 'Symbols loaded',10,0
|
|
aUnaligned db 'Unaligned address',10,0
|
|
aEnabledBreakErr db 'Enabled breakpoints are not allowed',10,0
|
|
aInterrupted db 'Interrupted',10,0
|
|
aUnpacked db 'Unpacked successful!',10,0
|
|
OnBeErrMsg db 'There is already enabled breakpoint on this address',10,0
|
|
|
|
DumpPath db '/TMP0/1/'
|
|
DumpName db 'DUMP0000.TXT',0
|
|
|
|
even 4
|
|
ConsoleColors dd 0x000000,0x000080,0x008000,0x008080
|
|
dd 0x800000,0x800080,0x808000,0xC0C0C0
|
|
dd 0x1D272F,0x0000FF,0x00FF00,0x00FFFF;0x808080,0x0000FF,0x00FF00,0x00FFFF
|
|
dd 0xFF0000,0xFF00FF,0xFFFF00,0xFFFFFF
|
|
|
|
CurWidth dd MinWidth
|
|
CurHeight dd MinHeight
|
|
FillWidth dd 0
|
|
FillHeight dd 0
|
|
|
|
MemForImage dd 0
|
|
|
|
bWasE0 db 0
|
|
CtrlState db 0
|
|
MouseState db 0
|
|
bMemForImageValidData db 0
|
|
|
|
bReload db 0
|
|
bAfterGo db 0
|
|
bSuspended db 0
|
|
CodeType db 32
|
|
|
|
DoDraw db 0
|
|
SymbolSection db 0
|
|
CmdLineActive db 0,?
|
|
|
|
CursorX dd -1
|
|
CursorY dd -1
|
|
CursorSize dd CursorNormSize
|
|
CurCursorPos dd -1
|
|
OldCursorPos dd -1
|
|
|
|
DebuggeePID dd 0
|
|
|
|
DumpBlock:
|
|
.Func dd 0
|
|
dd 0
|
|
dd 0
|
|
.Size dd 0
|
|
dd ConsoleDataOld
|
|
db 0
|
|
dd DumpPath
|
|
|
|
FN70LoadBlock: dd 7
|
|
dd 1
|
|
LoadParams dd 0
|
|
dd 0
|
|
dd 0
|
|
LoadName: db 0
|
|
rb 255
|
|
|
|
FN70ReadBlock: dd 0
|
|
rq 1
|
|
dd ?
|
|
dd ?
|
|
db 0
|
|
dd ?
|
|
|
|
FN70AttrBlock: dd 5
|
|
dd 0,0,0
|
|
dd FileAttr
|
|
db 0
|
|
dd ?
|
|
|
|
IncludeAllGlobals
|
|
|
|
DbgWnd dd ?
|
|
TempBreak dd ?
|
|
|
|
WndWidth dd ?
|
|
WndHeight dd ?
|
|
|
|
MinY dd ?
|
|
MaxY dd ?
|
|
MinX dd ?
|
|
MaxX dd ?
|
|
|
|
Tmp dd ?
|
|
SkinH dd ?
|
|
StdColors rd 10
|
|
|
|
AppPath rb 4096
|
|
ProcInfo rb 1024
|
|
|
|
even 16
|
|
ConsoleDataPtr rw (MaxWidth+0)*MaxHeight
|
|
even 16
|
|
ConsoleDataOld rw (MaxWidth+1)*MaxHeight
|
|
|
|
even 16
|
|
NeedZeroStart:
|
|
|
|
DbgBufSize dd ?
|
|
DbgBufLen dd ?
|
|
DbgBuf rb 256
|
|
|
|
FileAttr rb 40
|
|
|
|
even 4
|
|
Context:
|
|
_EIP dd ?
|
|
_EFL dd ?
|
|
_EAX dd ?
|
|
_ECX dd ?
|
|
_EDX dd ?
|
|
_EBX dd ?
|
|
_ESP dd ?
|
|
_EBP dd ?
|
|
_ESI dd ?
|
|
_EDI dd ?
|
|
|
|
_CTX_FLAGS:
|
|
dd ?
|
|
dd ?
|
|
|
|
_SSE_FLAGS:
|
|
|
|
_FCW dw ?
|
|
_FSW dw ?
|
|
_FTW db ?
|
|
db ?
|
|
_FOP dw ?
|
|
_FPU_IP dd ?
|
|
dw ?
|
|
dw ?
|
|
|
|
_FPU_DP dd ?
|
|
dw ?
|
|
dw ?
|
|
|
|
_MXCSR dd ?
|
|
_MXCSRM dd ?
|
|
|
|
FPU_CONTEXT:
|
|
MMX_CONTEXT:
|
|
_ST0:
|
|
_MM0: rq 2
|
|
_ST1:
|
|
_MM1: rq 2
|
|
_ST2:
|
|
_MM2: rq 2
|
|
_ST3:
|
|
_MM3: rq 2
|
|
_ST4:
|
|
_MM4: rq 2
|
|
_ST5:
|
|
_MM5: rq 2
|
|
_ST6:
|
|
_MM6: rq 2
|
|
_ST7:
|
|
_MM7: rq 2
|
|
|
|
SSE_CONTEXT:
|
|
_XMM0 rq 2
|
|
_XMM1 rq 2
|
|
_XMM2 rq 2
|
|
_XMM3 rq 2
|
|
_XMM4 rq 2
|
|
_XMM5 rq 2
|
|
_XMM6 rq 2
|
|
_XMM7 rq 2
|
|
CtxEnd:
|
|
|
|
OldContext rb (CtxEnd-Context)
|
|
|
|
Plus = (OldContext-Context)
|
|
|
|
StepNum dd ?
|
|
ProcNum dd ?
|
|
if 0
|
|
DUMP_HEIGHT = 6 ; in text lines
|
|
;
|
|
DumpRead dd ?
|
|
DumpPos dd ?
|
|
DumpData rb DUMP_HEIGHT*10h
|
|
end if
|
|
|
|
CmdLine rb CMD_WIDTH+1
|
|
CmdLineLen dd ?
|
|
CmdLinePos dd ?
|
|
CurArg dd ?
|
|
|
|
CmdLinePrev rb CMD_WIDTH+1
|
|
|
|
SymbolsFile rb 260
|
|
|
|
PrgNamePtr dd ?
|
|
PrgNameLen dd ?
|
|
|
|
Symbols dd ?
|
|
NumSymbols dd ?
|
|
|
|
CmdHistBuffer:
|
|
.Ptr dd ?
|
|
.Size dd ?
|
|
.LastNodeOffset dd ?
|
|
.NewNodeOffset dd ?
|
|
.CurNodeOffset dd ?
|
|
.TmpLineFlag db ?
|
|
.NFlag db ?
|
|
|
|
; breakpoint structure:
|
|
; dword +0: address
|
|
; byte +4: flags
|
|
; bit 0: 1 <=> breakpoint valid
|
|
; bit 1: 1 <=> breakpoint disabled
|
|
; bit 2: 1 <=> one-shot breakpoint
|
|
; bit 3: 1 <=> DRx breakpoint
|
|
; byte +5: overwritten byte
|
|
; for DRx breaks: flags + (index shl 6)
|
|
BreakPointsN = 256
|
|
BreakPoints rb BreakPointsN*6
|
|
DrXBreak rd 4
|
|
;-----------------------------------------------------------------------------
|
|
CurrentWindow dd ?
|
|
CPUXPos dd ? ; coordinates of cursor in windows
|
|
CPUYPos dd ?
|
|
CPUXPtr dd ?
|
|
MemXPos dd ?
|
|
MemYPos dd ?
|
|
StkXPos dd ?
|
|
StkYPos dd ?
|
|
RegXPos dd ?
|
|
RegYPos dd ?
|
|
RegLDat dd ?
|
|
RegXPtr dd ?
|
|
CPUType db ?
|
|
FPUType db ?
|
|
MMXType db ?
|
|
XMMType db ?
|
|
JumpTaken db ?
|
|
AfterKey db ?
|
|
;-----------------------------------------------------------------------------
|
|
TmpB rb 0
|
|
Temp dd ?
|
|
;-----------------------------------------------------------------------------
|
|
CodeAddr dd ? ;0 order
|
|
RegsAddr dd ? ;1
|
|
DataAddr dd ? ;2
|
|
StckAddr dd ? ;3
|
|
OriginPtr: rd 2
|
|
AddrBuffer: rd 30
|
|
;-----------------------------------------------------------------------------
|
|
NeedZeroEnd:
|
|
;-----------------------------------------------------------------------------
|
|
BufferI: rb 1024
|
|
BufferO: rb 1024
|
|
;-----------------------------------------------------------------------------
|
|
; stack
|
|
even 4
|
|
rb 32768
|
|
StackTop:
|
|
;-----------------------------------------------------------------------------
|
|
Mem:
|
|
;-----------------------------------------------------------------------------
|
|
I_END = UDataStr ;%v
|
|
;-----------------------------------------------------------------------------
|