Отладка программ на fasm, спользование vkdebug в fasm
Использование vkdebug в fasm
Отладчик для fasm
Как известно, в состав MASM32 входит отладчик Dbgwin от vkim, позволяющий с помощью макросов PritHex eax, PrintError и тд
выводить отладочную информацию в окно дебагера. Для отладки програм вам необходимо подключить заголовочный файл debug.inc с
предопределенными макросами.
В fasm для отладки программ обычно используют OllyDbg и прерывания int 3 для перехода в отладчик. Но для отладки простых
программ гораздо удобнее использовать Dbgwin.
Я переписал несколько макросов debug.inc для fasm.
Установка.
1. Скопируйте файл debug.inc в каталог fasm, например, c:\fasm
2. Подключите макросы к своей программе, добавив строку вида
include 'c:\fasm\debug.inc'
3. Добавьте в импорт вашей программы дополнительные импортируемые функции, которые используются в отладочных макросах. См.
файл.
3-й пунк самый сырой, правильнее добавить автоматическое добавление импорта. Также переписаны не все макросы, вместо
информации о файле и номера строки исходника выводится заглушка.
Пример.
--------------------------------
format PE GUI 4.0
entry start
include 'c:\fasm\include\win32a.inc'
include 'C:\fasm\INCLUDE\MACRO\MASM.INC'
include 'c:\fasm\debug.inc'
;include 'debug.inc'
IDM_NEW = 101
IDM_EXIT = 102
IDM_ABOUT = 901
SECNUM = 3
MAX_BLOCK = 1
INFINITE equ -1
section '.text' code readable writable executable
hInstance dd 0
proc start
invoke GetModuleHandle,0
mov [hInstance],eax
; invoke GetLastError
;; invoke FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, 0, eax, 0, pDesc, 511, 0
; push 0
; push 0
; push pDesc
; push 0
; push eax
; push 0
; push (FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM)
; call dword[FormatMessage]
; mov eax,[pDesc]
; stdcall DebugPrint, eax
mov eax, 12345h
PrintHex ax
PrintHex eax
PrintHex ax
PrintHex al
PrintDec eax
PrintHex ecx
PrintError
PrintText 'sssssssss' ;stdcall DebugPrint, ofnBuffer
PrintLine
error:
invoke ExitProcess,0
endp
;************************************************************************
section '.idata' import data readable writable
library kernel32, 'kernel32.DLL',\
crtdll, 'crtdll.DLL',\
user, 'USER32.DLL',\
gdi, 'GDI32.DLL',\
comdlg32, 'comdlg32.dll',\
ntdll, 'ntdll.dll'
import kernel32,\
GetModuleHandle, 'GetModuleHandleA',\
GetCommandLineA, 'GetCommandLineA',\
CreateProcess, 'CreateProcessA',\
OpenProcess, 'OpenProcess',\
GetThreadContext, 'GetThreadContext',\
CloseHandle, 'CloseHandle',\
ReadProcessMemory, 'ReadProcessMemory',\
Sleep, 'Sleep',\
ExitProcess, 'ExitProcess',\
GetProcessHeap, 'GetProcessHeap',\
GetModuleFileNameA, 'GetModuleFileNameA',\
WaitForSingleObjectEx, 'WaitForSingleObjectEx',\
GetLastError, 'GetLastError',\
CreateThread, 'CreateThread',\
GetCurrentThread, 'GetCurrentThread',\
WinExec, 'WinExec',\
lstrcpyA, 'lstrcpyA',\
FormatMessage, 'FormatMessageA',\
LocalFree, 'LocalFree',\
lstrlen, 'lstrlen',\
lstrcpy, 'lstrcpy',\
lstrcat, 'lstrcat'
import crtdll,\
printf, 'printf',\
sprintf, 'sprintf'
import comdlg32,\
GetOpenFileName, 'GetOpenFileNameA'
import user,\
RegisterClass,'RegisterClassA',\
CreateWindowEx,'CreateWindowExA',\
DefWindowProc,'DefWindowProcA',\
SetWindowLong,'SetWindowLongA',\
RedrawWindow,'RedrawWindow',\
GetMessage,'GetMessageA',\
TranslateMessage,'TranslateMessage',\
DispatchMessage,'DispatchMessageA',\
SendMessage,'SendMessageA',\
LoadCursor,'LoadCursorA',\
LoadIcon,'LoadIconA',\
LoadMenu,'LoadMenuA',\
GetClientRect,'GetClientRect',\
MoveWindow,'MoveWindow',\
SetFocus,'SetFocus',\
MessageBox,'MessageBoxA',\
MessageBoxW,'MessageBoxW',\
PostQuitMessage,'PostQuitMessage',\
FindWindowA,'FindWindowA',\
FindWindowExA,'FindWindowExA'
section '.rsrc' resource data readable
directory RT_GROUP_ICON,group_icons ,\
RT_ICON,icons
resource icons,\
1,LANG_NEUTRAL,icon_data
resource group_icons,\
17,LANG_NEUTRAL,main_icon
icon main_icon,icon_data,'ico.ico'
debug.inc
;------------------------------------------------------------------------
;Перед использованием убедитесь, что в секцию импорта отлаживаемого файла
;присутствуют следующие строки:
;;section '.idata' import data readable writable
;;
;; library kernel32, 'kernel32.DLL',\
;; crtdll, 'crtdll.DLL',\
;; user, 'USER32.DLL',\
;; comdlg32, 'comdlg32.dll',\
;; ntdll, 'ntdll.dll'
;
; import kernel32,\
; GetLastError, 'GetLastError',\
; WinExec, 'WinExec',\
; lstrcpyA, 'lstrcpyA',\
; FormatMessage, 'FormatMessageA',\
; LocalFree, 'LocalFree',\
; lstrlen, 'lstrlen',\
; lstrcpy, 'lstrcpy',\
; lstrcat, 'lstrcat'
;
; import crtdll,\
; printf, 'printf',\
; sprintf, 'sprintf'
DBGWIN_DEBUG_ON = 1
DBGWIN_EXT_INFO = 0;1
;===================================HELPER MACROS=============================
;macro CTEXT proc,Text
;{
; locals
; szText db Text,0
; endl
; lea eax,[szText]
;}
;-----------------------------------------------------------------------------
;DebugPrint function is written by vkim and optimized by KetilO.
;Rewrite for fasm by inprj21
;-----------------------------------------------------------------------------
szWinClass db 'DbgWinClass', 0
szCommandLine db '\masm32\bin\dbgwin.exe', 0
szCRLF db 13, 10, 0
szEdit db 'Edit', 0
;section '.text' code readable writable executable
proc DebugPrint stdcall, DebugData:DWORD
locals
hwnd dd ?
endl
invoke FindWindowA, szWinClass, NULL
cmp eax, 0
jnz met00001
;.if !eax
invoke WinExec, szCommandLine, SW_SHOWNORMAL
invoke FindWindowA, szWinClass, NULL
;.endif
cmp eax,0
jnz met00001
ret
met00001:
;.if eax
mov [hwnd], eax
invoke FindWindowExA, [hwnd], NULL, szEdit, NULL
mov [hwnd], eax
invoke SendMessage, [hwnd], WM_GETTEXTLENGTH, 0, 0
push eax
invoke SendMessage, [hwnd], EM_SETSEL, -1, -1
pop eax
cmp eax,0 ;.if eax
jz met00002
invoke SendMessage, [hwnd], EM_REPLACESEL, FALSE, szCRLF
;.endif
met00002:
;stdcall [SendMessage], [hwnd], EM_REPLACESEL, FALSE, DebugData ; error
mov eax, dword[DebugData]
push eax
push FALSE
push EM_REPLACESEL
push dword [hwnd]
call [SendMessage]
invoke SendMessage, [hwnd], EM_SCROLLCARET, 0, 0
;.endif
ret
endp
;---------------------------------------------------------------------------
proc dw2hex , dwNum:DWORD, szDebugNum:DWORD
mov edx,dword [szDebugNum] ;[ebp+0Ch]
mov esi,dword [dwNum] ;[ebp+8]
xor eax,eax
xor ecx,ecx
mov byte [edx+8],al
mov cl,7
cikle: mov eax,esi
and al,0fh
cmp al,0ah
sbb al,69h
das
mov byte [ecx+edx],al
shr esi,4
dec ecx
jns short cikle
pop esi
ret
endp
;---------------------------------------------------------------------------
macro PrintLine
{
locals
szLine db '----------------------------------------', 0
endl
if DBGWIN_DEBUG_ON = 1
pushad
;invoke DebugPrint, szLine ; error for local var
lea eax, [szLine]
push eax
call DebugPrint
popad
end if
}
;---------------------------------------------------------------------------
macro PrintText Var
{
locals
info dd ?
szBuff db 512 dup(0)
szText db Var, 0
endl
if DBGWIN_DEBUG_ON = 1
pushad
if DBGWIN_EXT_INFO = 1
lea eax, [szBuff]
push eax
call DebugPrint
else
;invoke DebugPrint, szText
lea eax, [szText]
push eax
call DebugPrint
end if
popad
end if
}
;--------------------------------------------------------------------------
pDesc dd 0
macro PrintError
{
locals
;pDesc dd 0
info dd 0
endl
if DBGWIN_DEBUG_ON = 1
pushad
invoke GetLastError
;invoke FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, 0, eax, 0, pDesc, 511, 0
push 0
push 0
push pDesc
push 0
push eax
push 0
push (FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM)
call dword[FormatMessage]
;FormatMessage returns length of err description in eax
if DBGWIN_EXT_INFO = 1
mov eax, [pDesc]
push eax
call DebugPrint
else
;invoke DebugPrint, pDesc ; не рабoтает из-за переменной на стеке pDesc
mov eax, [pDesc]
push eax
call DebugPrint
end if
;invoke LocalFree, pDesc
;lea eax, [pDesc]
;push eax
;call LocalFree
popad
end if
}
;---------------------------------------------------------------------------
szravno db ' = ',0
szHex db 'h (',0
szFileName db 'SelfFileName',0 ;@FileCur
szLine db ', Line)',0 ;@Line
szDebugNum db 9 dup(0h)
szBuff db 256 dup(0h)
macro PrintHex Var ;, Text
{
locals
szS db `Var,0
;szDebugNum db 9 dup(41h)
info dd 0
;txt
sz dd 1
dwNum dd 0
wNum dw 0
bNum db 0
endl
mov [szDebugNum],0
mov [szDebugNum+4],0
if DBGWIN_DEBUG_ON = 1
pushad
if Var in <al,ah,bl,bh,cl,ch,dl,dh> ; тип Var теперь byte
mov [bNum], Var
movzx eax, byte[bNum]
mov dword[dwNum], eax
shl [dwNum], 24
else if Var in <ax,bx,cx,dx,si,di,sp> ;тип Var теперь word
; m2m wNum, Var
mov [wNum], Var
movzx eax, word[wNum]
mov dword[dwNum],eax
shl [dwNum], 16
else if Var in <eax,ebx,ecx,edx,esi,edi,esp> ;тип Var теперь dword
;m2m ddNum, Var
push Var
pop dword[dwNum]
end if
;invoke dw2hex, dwNum, szDebugNum
push szDebugNum
push dword[dwNum]
call dw2hex
if Var in <al,ah,bl,bh,cl,ch,dl,dh>
mov byte [szDebugNum+2], 0
else if Var in <ax,bx,cx,dx,si,di,sp>
mov byte [szDebugNum+4], 0
end if
;invoke lstrcpy, szBuff, szS ; err for local vars
lea eax, dword[szS]
push eax
push szBuff
call [lstrcpy]
invoke lstrcat, szBuff, szravno
invoke lstrcat, szBuff, szDebugNum
invoke lstrcat, szBuff, szHex
invoke lstrcat, szBuff, szFileName
invoke lstrcat, szBuff, szLine
push szBuff
call DebugPrint
popad
end if
}
;------------------------------------------------------------------
szli db '%li', 0
macro PrintDec Var ;, Text
{
locals
szS db `Var,0
;szDebugNum db 9 dup(41h)
info dd 0
sz dd 1
dwNum dd 0
wNum dw 0
bNum db 0
endl
mov [szDebugNum],0
mov [szDebugNum+4],0
if DBGWIN_DEBUG_ON = 1
pushad
if Var in <al,ah,bl,bh,cl,ch,dl,dh> ; тип Var теперь byte
mov [bNum], Var
movzx eax, byte[bNum]
mov dword[dwNum], eax
shl [dwNum], 24
else if Var in <ax,bx,cx,dx,si,di,sp> ;тип Var теперь word
; m2m wNum, Var
mov [wNum], Var
movzx eax, word[wNum]
mov dword[dwNum],eax
shl [dwNum], 16
else if Var in <eax,ebx,ecx,edx,esi,edi,esp> ;тип Var теперь dword
;m2m ddNum, Var
push Var
pop dword[dwNum]
end if
;invoke wsprintf, addr szDebugNum, CTEXT("%li"), dwNum
push [dwNum]
push szli
push szDebugNum
call [sprintf]
add esp, 12
if Var in <al,ah,bl,bh,cl,ch,dl,dh>
mov byte [szDebugNum+2], 0
else if Var in <ax,bx,cx,dx,si,di,sp>
mov byte [szDebugNum+4], 0
end if
;invoke lstrcpy, szBuff, szS ; err for local vars
lea eax, dword[szS]
push eax
push szBuff
call [lstrcpy]
invoke lstrcat, szBuff, szravno
invoke lstrcat, szBuff, szDebugNum
invoke lstrcat, szBuff, szHex+1
invoke lstrcat, szBuff, szFileName
invoke lstrcat, szBuff, szLine
push szBuff
call DebugPrint
popad
end if
}
;------------------------------------------------------------------