watch a directory for changes using masm assembly - windows

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.

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.

How to find code for crash

I have some 64-bit code that runs in release mode on a server. There's no Visual studio on the server, only on my dev-machine. The program has been written by many authors now (me latest), and some code in it I'm still not familiar with, and its quite big.
The program crashes now and then with a nullpointer. The instruction at 0xwhatever (latest 0x40066c19) referenced memory at 0x00000000 - click on OK to terminate the program. I have all the source and PDB files for the EXE, but when i run it and attach the process, the memory 0x40066c19 is completely out of range. There is only ?? in that area. How do you use the info about "the instruction at ..." ?
The disassembly window displays something like (example) - but as you see there are simply too far from 00000001403CB888 to 0x40066c19
if (LastKickIdle > GetTickCount())
00000001403CB882 call qword ptr [__imp_GetTickCount (0140688310h)]
00000001403CB888 cmp dword ptr [LastKickIdle (0140888DF8h)],eax
00000001403CB88E ja CMainDlg::OnKickIdle+281h (01403CBAB1h)
return 1;
LastKickIdle = GetTickCount() + 500;
00000001403CB894 mov qword ptr [__formal],rbx
00000001403CB89C call qword ptr [__imp_GetTickCount (0140688310h)]
00000001403CB8A2 add eax,1F4h
00000001403CB8A7 mov dword ptr [LastKickIdle (0140888DF8h)],eax
I run into similar situations at work. I created a log class that takes a string arg and writes it to a file with some other useful info. I make entries at the beginning of methods or at places that I think something may be or may later be problematic. With this, I have at least been able to narrow down my search for problems.
Hope this helps.

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().

Endless loop with assember

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.

When and why use CoLoadLibrary?

The description of CoLoadLibrary() says it does pretty much the same as LoadLibraryEx() - loads a DLL into the process. COM classes creation functions - CoCreateInstance() and CoGetClassObject() - both do load the necessary DLL into the process too.
Then why is CoLoadLibrary() needed in the first place and how should it be used?
Have a look at the code:
mov edi,edi
push ebp
mov ebp,esp
push 8
push 0
push dword ptr [ebp+8]
call dword ptr [ole32!_imp__LoadLibraryExW (71eb1214)]
pop ebp
ret 8
So it just calls:
LoadLibraryEx( FileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ).
Presumably, the routine merely exists for backwards compatibility -- it probably has its roots in Win16.
Perhaps if you were writing your own regsvr32.exe? But JP's disassembly doesn't really support my guess, because you could just use LoadLibraryEx instead. Maybe in the olden days, Microsoft planned on COM DLLs someday being loaded in a different way than regular DLLs (D-COM?), so this was a way of ensuring future compatibility.

Resources