Endless loop with assember - windows

OK, I'm new to PC Assembler. I"m trying to write an program, but it won't stop looping. I'm guessing the ECX register is being modified? How can I fix this? Thanks.
DATA SECTION
;
KEEP DD 0 ;temporary place to keep things
;
CODE SECTION
;
START:
MOV ECX,12
TOPOFLOOP:
PUSH -11 ;STD_OUTPUT_HANDLE
CALL GetStdHandle ;get, in eax, handle to active screen buffer
PUSH 0,ADDR KEEP ;KEEP receives output from API
PUSH 5,'bruce' ;5=length of string
PUSH EAX ;handle to active screen buffer
CALL WriteFile
XOR EAX,EAX ;return eax=0 as preferred by Windows
LOOP TOPOFLOOP
ENDLABEL:
RET

In most x86 calling convention, including the stdcall convention used by Windows API functions, ECX is a caller-save register -- the called function is not required to make sure the value of the register is the same when it returns as when it was called. You have to save it somewhere safe in your own code.

Related

x64 calling createthread from asm

push 0 //tid
push 0 //flag
sub rsp, 20
mov r9,0 //parameter
mov rcx,0 //security attribute
mov rdx, 0 //stacksize
mov r8,threadmem //address
call kernel32.createthread
I'm calling createthread in this way.
But if I put any address in parameter, my code doesn't work.
Just making my PC lag and nothing happens, seems like thread is created but my code isn't executed.
However, if I don't put parameter and leave itself for 0 it works.
Can anyone help me?
You are not strictly following the x64 calling convention. Push and sub rsp may only occur in the prolog.
Windows disassembles your code and unreachable code can still hang because of it. I had to give up altogether.

FASM assembly program waits before exiting

This is the code that I use with FASM:
format PE console
entry main
include '..\MACRO\import32.inc'
section '.data' data readable writeable
msg db "привіт!",0dh,0ah,0 ;hi
lcl_set db ?
section '.code' code readable executable
main:
;fail without set locale
push msg
call [printf]
pop ecx
;succeed with set locale
push msg
call _liapnuty
pop ecx
push 0
call [ExitProcess]
_liapnuty:
push ebp
mov ebp, esp
;sub esp, 0
mov ebx,[ebp+8] ; 1st arg addr
mov al, [lcl_set]
or al, al
jnz _liapnuty_rest
call __set_locale
_liapnuty_rest:
push ebx
call [printf]
pop ebx
mov esp, ebp
pop ebp
ret 0
__set_locale:
mov al, [lcl_set]
or al, al
jnz __set_locale_rest
push 1251
call SetConsoleCP
call SetConsoleOutputCP
pop ecx
mov [lcl_set], 1
;push lcl
;call [system]
; pop ecx
; mov [lcl_set], 1
;push cls
;call [printf]
; pop ecx
__set_locale_rest:
ret 0
section '.idata' import data readable
library kernel,'kernel32.dll',\
msvcrt,'msvcrt.dll'
import kernel,\
SetConsoleCP,'SetConsoleCP',\
SetConsoleOutputCP,'SetConsoleOutputCP',\
ExitProcess,'ExitProcess'
import msvcrt,\
printf,'printf'
It works almost perfectly, except that before exiting it waits for like a second for some reason. It outputs data almost instantly, yet it fails to shut down quickly. If the reason is using these libraries or not clearing the stack after calling ExitProcess (which obviously can't be done), then let me know and I will mostly gladly accept this answer, but I want to be 100% sure I'm doing everything correctly.
The reason for all of it was because kernel32 functions pop their parameters themselves on return. If I remove unnecessary pops it starts working fast again. Of course, the program still runs with damaged stack but it does a lot of damage control at the end. That's why it was slow, but still worked. For everyone facing this issue, make sure to be careful with the calling convention.
To debug the application and find the error I used OLLYDBG. It's free and it works. It helps you debug EXEs and DLLs, allowing to step one command at a time. Also it shows the memory, the stack and all of the registers and flags.
Using the stack I was able to find out that it gets corrupted.

Register ESI causes RunTime-Check Failure #0 error

I've spend lot of time trying to solve this problem and I don't understand, why it doesn't work. Problem's description is in comments below:
.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
.NOLIST
.NOCREF
INCLUDE \masm32\include\windows.inc
.LIST
.CODE
DllEntry PROC hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax, TRUE
ret
DllEntry ENDP
caesarAsm proc string: DWORD, key: DWORD, stringLength : DWORD
mov esi, 1 ; I cannot use this register, mov esi, (anything) causes Crash:
; Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention
mov eax, string
ret
caesarAsm endp
END DllEntry
I searched "whole" Internet, I found that the problem is connected with stack, but no operation on stacks helped me to solve it.
I'm using Microsoft Visual Studio 2012
I assume the error does not occur in this function, rather, it is triggered elsewhere. The esi register is a callee-saved register. You must make sure its value is the same at function exit as it was at entry. You can use it in your function, but you must save and restore its value. Such as:
push esi
mov esi, 1
mov eax, string
pop esi
ret
This is all well documented. You may only use eax, ecx and edx without saving.
Side note: you are using high-level features of your assembler, you might want to check the actual generated code or refrain from using them until you are confident in what the result is going to be. Incidentally masm has a USES keyword which would do the save/restore for you.

watch a directory for changes using masm assembly

I have been only programming in assembly for 2 weeks now so I am kind of new to assembly and I need some help.
I need to watch a directory and all sub directories for changes. The only changes I need to be notified of are file creation and when a file is edited, but if you include others that is fine.
I need to be notified of the file who made the changes to a message box. I do not need to know what change the file made, I just need the file path to a message box. I tried to search the web but cant find anything for how to do this in assembly particular masm.The only stuff I could find was this code that I think was written for masm and I tried it but it message boxes A or other letters and that is it and it blocks me from changing the name of any file in that directory, and i do not want it to do that.
.data
FolderPath3 db "C:\users",0
.data ?
hFile dd ?
FileBuffer DB 200 DUP(?)
ThreadProc PROC uses edi esi Param:DWORD
LOCAL lpBytesReturned:dword
invoke CreateFile,addr FolderPath3,GENERIC_READ,FILE_SHARE_DELETE or FILE_SHARE_READ,0,\
OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0
mov hFile,eax
invoke ReadDirectoryChangesW,hFile,addr FileBuffer,sizeof FileBuffer,TRUE,FILE_NOTIFY_CHANGE_LAST_ACCESS,\
addr lpBytesReturned,0,0
.if eax==0
invoke MessageBoxA,0,0,0,MB_OK
.else
xor ecx,ecx
##:
add edi,ecx
lea edi,FileBuffer
mov esi,[edi].FILE_NOTIFY_INFORMATION.Action
.if esi==FILE_ACTION_MODIFIED
invoke MessageBoxA, NULL, addr [edi].FILE_NOTIFY_INFORMATION.FileName, offset BoxCaption, NULL
.elseif esi==0
invoke CloseHandle,hDir
ret
.endif
mov ecx,[edi].FILE_NOTIFY_INFORMATION.NextEntryOffset
.if ecx==0
invoke RtlZeroMemory,addr FileBuffer,sizeof FileBuffer
jmp ThreadProc
.endif
jmp #B
.endif
ret
ThreadProc ENDP
if anyone can fix the above code or show me different code that works it would be great,
thank you
The essence of the task is the operating system specific services and handling the notifications.
If you are lost doing this in assembly, code it in a high level language (C, C++, Perl, etc.) and get that working. It should not be hard to find examples of doing just this from MSDN. Once you have learned how to do that, it will then be pretty clear what the assembly language has to do.

Having problems with GdiGradientFill in FASM

I'm trying to write an ASM version of a Java app I developed recently, as a project in Win32 ASM, but as the title states, I'm having problems with GdiGradientFill; I'd prefer, for the moment, to use FASM, and avoid higher level ASM constructs, such as INVOKE and the use of the WIN32 includes.
What I have, atm:
PUSH [hWnd]
CALL [User32.GetWindowDC]
MOV [hDC], EAX
PUSH rectClient
PUSH [hWnd]
CALL [User32.GetClientRect]
PUSH [rectClient.left]
POP [colorOne.xPos]
PUSH [rectClient.top]
POP [colorOne.yPos]
MOV [colorOne.red], 0xC000
MOV [colorOne.green], 0xC000
MOV [colorOne.blue], 0xC000
MOV [colorOne.alpha], 0x0000
PUSH [rectClient.right]
POP [colorTwo.xPos]
PUSH [rectClient.bottom]
POP [colorTwo.yPos]
MOV [colorTwo.red], 0x0000
MOV [colorTwo.green], 0x2800
MOV [colorTwo.blue], 0x7700
MOV [colorTwo.alpha], 0x0C00
MOV [gRect.UpperLeft], 0
MOV [gRect.LowerRight], 1
PUSH GRADIENT_FILL_RECT_H
PUSH 1
PUSH gRect
PUSH 2
PUSH colorOne
PUSH [hDC]
CALL [GDI32.GdiGradientFill]
However, the code returns only a FALSE, and after going through both MSDN
(http://msdn.microsoft.com/en-us/library/windows/desktop/dd373585(v=vs.85).aspx)
and some other examples (http://www.asmcommunity.net/board/index.php?topic=4100.0), I still can't see what I am doing wrong, can anyone see the flaw here?
An additional problem has been with my attempts to use Msimg32's GradientFill, as this always leads to a crash, however, I have seen some reports that Win2K+ OS's simply pass the parameters from Msimg32 to GDI32; is this accurate, or has anyone else experienced problems with this form?
Pastebin link for whole code: http://pastebin.com/GEHDw6Qe
Thanks for any help, SS
EDIT:
Code is now working, honestly, I have no idea what has changed, I can't see anything different between the previous and now working data, other than changing the PUSH / POP sequence to MOV EAX, [rectClient.left], ect (The PUSH / POP method works, also) - Many thanks to those who offered assistance!
You're passing what looks like a RECT as the 4th parameter to GdiGradientFill. The function expects a GRADIENT_TRIANGLE.
Also, PUSH/POP is a very weird way to copy from one memory location to another. You're doing 4 memory accesses instead of two. Copy via a register; this is not Java.
Are you sure GetWindowDC is what you need? That one returns the DC for the whole window, title and border and all. For just the client area, people normally use GetDC(). When done, call ReleaseDC().

Resources