Reputation: 21
I'm trying to run a process, wait for it to finish, open the executable file, and write something to it. So i created a small "loader" which does exactly that. This is my code:
;Run the executable
INVOKE GetStartupInfo,OFFSET startInfo
INVOKE CreateProcess, ADDR SomeExecutableFile, \
NULL, NULL, NULL, FALSE, \
NORMAL_PRIORITY_CLASS, NULL,NULL, \
OFFSET startInfo, OFFSET processInfo
INVOKE CloseHandle, processInfo.hThread
;Wait for it to finish & Close handle
INVOKE WaitForSingleObjectEx, processInfo.hProcess, INFINITE, FALSE
INVOKE CloseHandle, processInfo.hProcess
;Try to open the same exe file which just finished executing.
INVOKE CreateFile, OFFSET SomeExecutableFile,GENERIC_WRITE \
,0, 0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL
MOV hFile, EAX
.IF hFile== INVALID_HANDLE_VALUE
INVOKE MessageBox,NULL, OFFSET Problem, OFFSET Problem, MB_ICONWARNING
.ELSE
INVOKE WriteFile, hFile, Buffer, 5, OFFSET BytesWritten , NULL
INVOKE CloseHandle,hFile
.ENDIF
INVOKE ExitProcess,0
As you can see, 'SomeExecutable' file is being ran. After it stops executing it is opened with CreateFile. Create file fails, and i get an INVALID_HANDLE...., Last error- 0x20 - ERROR_SHARING_VIOLATION.
Why does this happen?
Thoughts & Notes: 1) Creating another process from the "loader" which opens the executable file(After waiting for it to finish executing) and write to it - it works. 2) It seems like the process is still open, i.e the file is still mapped which explains the error, but i don't understand why would it be mapped. 3) Debugging with Olly & ProcessExplorer i saw that indeed Olly has a handle of this file open even after the process has terminated, and all handles were closed - I don't understand why, and how the hell can i close it :)
Any ideas are welcome! :)
Upvotes: 2
Views: 695
Reputation: 417
1- Try to use:
invoke CreateProcess, ADDR Process, NULL, NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, ADDR startInfo, ADDR processInfo
CREATE_SUSPENDED should do the trick
2- Do you need to modify the file itself? Loaders usually are used to modify programs in memory. I wrote a loader some time ago with WriteProcessMemory:
.586
.model flat,stdcall
option casemap:none
include D:\masm32\include\windows.inc
include D:\masm32\include\user32.inc
include D:\masm32\include\kernel32.inc
includelib D:\masm32\lib\user32.lib
includelib D:\masm32\lib\kernel32.lib
.data
Process byte "prog.exe",0
Error byte "Error:",0
ErrorMessage byte "Process not loaded",0
ReplaceBy byte 0Fh,82h
ReplaceSize dword 2
AddressToPatch dword 01003B7Ch
Startup STARTUPINFO <>
processinfo PROCESS_INFORMATION <>
.data?
byteswritten dword ?
.code
start:
invoke CreateProcess, ADDR Process, NULL, NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, ADDR Startup, ADDR processinfo
cmp eax, 0
jne ProcessCreated
push 0
push offset Error
push offset ErrorMessage
push 0
call MessageBox
push 0
call ExitProcess
ProcessCreated:
invoke WriteProcessMemory, processinfo.hProcess, AddressToPatch, ADDR ReplaceBy, ReplaceSize, byteswritten
invoke ResumeThread, processinfo.hThread
push 0
call ExitProcess
end start
Upvotes: 2