Creating/removing directory using assembler (tasm) on windows - windows

I have to write a TASM program which creates and removes directory, but I found example of creating file only.
model small
.data
handle dw 0
filename db "file2.txt",0
.stack 256
.code
main:
mov ax,#data
mov ds,ax
mov ah,3ch
mov cx,1
lea dx,filename
int 21h
jc exit
mov handle,ax
exit:
mov ax,4c00h
int 21h
end main
How i can modify this code for creating directory instead of file? And how I can remove created firectory?

I had to use masm and winapi. Here is the my sample code
.586
.model flat, stdcall
option casemap:none
includelib kernel32.lib
includelib shell32.lib
include windows.inc
include kernel32.inc
.const
sDir db 'folder', 0
.code
Main PROC
invoke CreateDirectoryA, OFFSET sDir, NULL
invoke Sleep, 2000d
invoke RemoveDirectoryA, OFFSET sDir
invoke Sleep, 2000d
invoke ExitProcess, NULL
Main ENDP
end Main

Related

How to find out the age of a file in ASM?

Greetings to all the geniuses of the digital age
Yesterday's task is still on the agenda: "Use the GetOpenFileName function to select a file. Check if the file is less than 3 days old, execute it. Otherwise, display a dialog asking to delete the file. If the user needs it, wipe." (Note: If a task is told to use a structure, it must be placed in dynamically allocated memory)"
I figured out how to open the file and now everything works like a Swiss watch. But another trouble arose.
How to determine the age of a file?
In general, I first thought to use GetFileTime to extract all data about the file time, then use FileTimeToLocalFileTime to convert it to local time, and using FileTimeToSystemTime - to system time. Then subtract one from the other using sub, and so on as per the task.
Here, the FileTimeToLocalFileTime function requires a FILETIME structure with the following parameters:
DWORD dwLowDateTime;
DWORD dwHighDateTime;
And the FileTimeToSystemTime function requires a SYSTEMTIME structure with the following parameters:
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
And how to be then? How to find the age of a file? Is there any alternative way? And if my method works, then what exactly and from what should I take it?
File.inc
include WINDOWS.inc
include user32.inc
include kernel32.inc
include comdlg32.inc
includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib
.data
Time_title db ' Lab_3',0
format db 'More than 3 days. Delete file?', 0
buf db 255 dup(0)
hFile dd 0
readed dd 0
hmem dd 0
File.asm
.386
.model flat,STDCALL
option casemap :none ;case sensitive
include Third.inc
include RADbg.inc
Mem_Alloc PROC Buf_Size:DWORD
add Buf_Size,4
invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,Buf_Size
push eax
invoke GlobalLock,eax
pop [eax]
add eax,4
Mem_Alloc endp
Mem_Free PROC DATA:DWORD
mov eax,DATA
sub eax,4
mov eax,[eax]
push eax
push eax
call GlobalUnlock
call GlobalFree
Mem_Free endp
.code
Begin:
call main
invoke ExitProcess,NULL
main proc
LOCAL ftCreate, ftLocale: FILETIME;
LOCAL stUTC, stLocal: SYSTEMTIME;
invoke Mem_Alloc, 1000h
mov hmem, eax
invoke Mem_Alloc, sizeof OPENFILENAME
mov edi, eax
assume edi: ptr OPENFILENAME
xor eax, eax
mov [edi].lStructSize, sizeof OPENFILENAME
mov [edi].lpstrFile, offset buf
mov [edi].nMaxFile, 255
invoke GetOpenFileName, edi
invoke CreateFile, [edi].lpstrFile, GENERIC_READ,\
FILE_SHARE_READ, NULL, OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL, NULL
mov hFile,eax ;
invoke GetFileTime, hFile, addr ftCreate, NULL, NULL
invoke FileTimeToLocalFileTime, addr ftCreate, addr ftLocale
invoke FileTimeToSystemTime, addr ftCreate, addr stUTC
cmp eax, 1
jz l1
invoke ReadFile, hFile, hmem, 1000h, addr readed, 0
invoke MessageBox, 0, hmem, addr Time_title, MB_OKCANCEL
jmp l2
l1:
invoke MessageBox, 0, addr format, addr Time_title, MB_OKCANCEL
cmp eax, IDOK
jne l2
invoke DeleteFile, addr [edi].lpstrFile
l2:
assume edi: dword
invoke CloseHandle, hFile
invoke Mem_Free, hmem
invoke Mem_Free, edi
ret
main endp
end Begin
As FILETIME and RtlTimeToSecondsSince1970 said, You should copy the low- and high-order parts of the file time to a ULARGE_INTEGER structure, perform 64-bit arithmetic on the QuadPart member.
So, subtract the 64-bit value in the ULARGE_INTEGER structure initialized with the file time from the 64-bit value of the ULARGE_INTEGER structure initialized with the current system time.

Strange behaviour with a simple MASM32 program

I want to write a MASM program similar to the following C++ program :
#include <Windows.h>
#include <iostream>
typedef UINT (_stdcall *FuncPtr)(LPCSTR lpCmdLine, UINT uCmdShow);
int main(void)
{
HMODULE hDll = LoadLibrary(TEXT("Kernel32.dll"));
FuncPtr func_addr = reinterpret_cast<FuncPtr>(GetProcAddress(hDll, "WinExec"));
(*func_addr)("C:\\WINDOWS\\system32\\calc.exe", SW_SHOWDEFAULT);
FreeLibrary(hDll);
return (0);
}
As you can see, this code execute the microsoft calculator. I just want to do the same thing using MASM but the execution fails.
Here's the MASM source code :
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\msvcrt.lib
.data
LpFileName db "kernel32.dll", 0
procName db "WinExec", 0
display db "addr_func = 0x%x", 0
.data?
hModule HMODULE ?
procAddr FARPROC ?
.code
start:
invoke LoadLibrary, offset LpFileName
mov hModule, eax
invoke GetProcAddress, hModule, ADDR procName
mov procAddr, eax
INVOKE crt_printf, ADDR display, procAddr
mov esi, procAddr
call esi
db "C:\WINDOWS\system32\calc.exe"
invoke FreeLibrary, hModule
invoke ExitProcess, NULL
end start
The crt_printf output is correct. The same address is printed like withe the C++ program. So the address passed to call is the same one. However the execution fails.
Here's a MASM32 code which works but this time the address of the function WinExec is hardcoded like this :
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
.code
start:
jmp _Debut
_Final:
TCHAR 233
dword 42424242h
_Suite:
mov esi, 779e304eh
call esi
jmp _Final
_Debut:
xor eax, eax
push eax
call _Suite
db "C:\WINDOWS\system32\calc.exe"
end start
See the line mov esi, 779e304eh. But dynamically, there is a problem. If I disassemble the code just above we can see that the order of bytes is reversed.
8EEH047E379
Maybe it's not the case dynamically and maybe I need a keyword in the following line (between the comma and procAddr):
mov esi, procAddr
I cannot find the solution. I'm lost. Can anyone help me?
Thanks a lot in advance for your help.
The execution fails because you are not passing it's parameters.
Here you just call the function without any arguments or rather with invalid arguments (because whatever is currently on the stack will be taken and the stack is corrupted in the process).
mov esi, procAddr
call esi
You should do
push SW_SHOWDEFAULT
push offset YourPathToCalc
mov esi, procAddr
call esi
In your samplecode this is what is done here implicitly
xor eax, eax
push eax ; uCmdShow
call _Suite ; Returnadress is the address of the commandline so this is bascially the "push path"
Another thing you are missing is, that when WinExec returns, it will start executing the path in your case so you need a jmp somewhere after the call.
And as Gunner pointed out, the path must be 0 terminated.
To add to the correct answer Devolus posted, your path to calc is not NULL terminated.
This
"C:\WINDOWS\system32\calc.exe" is not correct!
Instead it should be:
"C:\WINDOWS\system32\calc.exe", 0
Also, if you are going to put strings in the code section to use, you need to give them a label in order to use them and you need to jump over them otherwise the CPU will try to execute the bytes.
INVOKE crt_printf, ADDR display, procAddr
mov esi, procAddr
push SW_SHOWDEFAULT
push offset Calc
call esi
jmp #F
Calc db "C:\WINDOWS\system32\calc.exe", 0
##:
invoke FreeLibrary, hModule
invoke ExitProcess, NULL
* EDIT *
To convert that code to Assembly using MASM, all that is needed is this:
.data
LpFileName db "kernel32", 0
procName db "WinExec", 0
Calc db "calc", 0
.code
start:
invoke LoadLibrary, offset LpFileName
push eax
invoke GetProcAddress, eax, ADDR procName
push SW_SHOWDEFAULT
push offset Calc
call eax
call FreeLibrary
invoke ExitProcess, NULL
end start

64-bit Program - Windows "Shadow Space" Trouble

I am trying to create a program in x64 assembly language but I am having problems understanding the x64 calling convention. I believe that the problem is that I do not know how much shadow space I have to reserve for the call to the CopyFile function. When, I run the program, it just crashes. I created this program using MASM. Please help me fix this code. Thank you.
includelib \Masm64\Lib\Kernel32.lib
includelib \Masm64\Lib\User32.lib
extrn GetProcessHeap : proc
extrn MessageBoxA : proc
extrn HeapAlloc : proc
extrn GetModuleFileNameA : proc
extrn ExitProcess : proc
extrn CopyFileA : proc
dseg segment para 'DATA'
file db 'C:\CopyThisFile.txt', 0
file2 db 'C:\ThisFileWasCopied.txt', 0
succ db 'Success!', 0
capt db 'Debug', 0
dseg ends
cseg segment para 'CODE'
start proc
sub rsp, 28h
xor r8, r8
mov rdx, qword ptr file2
mov rcx, qword ptr file
call CopyFileA
xor ecx, ecx
call ExitProcess
start endp
cseg ends
end
This has nothing to do with space reservation on the stack.
Your mistake instead lies in getting the string's address incorrectly. mov gets the contents (first 8 bytes) instead of the pointer to the string, hence raises a AccessViolation exception. To fix this, use lea.
format PE64 GUI 5.0
entry start
include 'WIN64A.INC'
section '.data' data readable writeable
fileStr db 'C:\\CopyThisFile.txt', 0
file2Str db 'C:\\ThisFileWasCopied.txt', 0
succ db 'Success!', 0
section '.text' code readable executable
start:
sub rsp, 28
xor r8, r8
lea rdx, qword ptr file2Str
lea rcx, qword ptr fileStr
call [CopyFileA]
xor ecx, ecx
call [ExitProcess]
section '.idata' import data readable
library kernel32,'kernel32.dll',user32,'user32.dll'
import kernel32, \
GetProcessHeap,'GetProcessHeap', \
HeapAlloc,'HeapAlloc', \
GetModuleFileNameA,'GetModuleFileNameA', \
ExitProcess,'ExitProcess', \
CopyFileA,'CopyFileA'
import user32, \
MessageBoxA,'MessageBoxA'

FindWindow returns zero in MASM32 program even if the window exists

I'm trying to write a program in assembly and one of the first things that I need is the handle of the main window of a specific process. I've been trying to get it using FindWindow, but no luck so far; FindWindow apparently keeps returning zero. Can anyone point out what am I missing here? Thanks.
.486
.model flat, stdcall
option casemap :none
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
NtpTitle db "Untitled - Notepad",0
MsgNoNtp db "Notepad not found.",0
MsgNtp db "Found Notepad.",0
NullString db 0
hWndNtp dd 0
.code
start:
invoke FindWindow, offset NullString, offset NtpTitle
mov hWndNtp, eax
jz noNotepad
invoke MessageBox, 0, offset MsgNtp, 0, 40h
invoke ExitProcess, 0
noNotepad:
invoke MessageBox, 0, offset MsgNoNtp, 0, 10h
invoke ExitProcess, 1
end start
You should set lpClassName to NULL, not the address to an empty string.
invoke FindWindow, 0, offset NtpTitle
You are not testing the return value of FindWindow; mov does not modify flags.
test eax,eax
jz noNotepad

Anti-debug using prefetch queue doesn't work with my cpu

Why does this code enable me to detect a debugger?
The link above told me the way to use prefetch queue to anti-debug, then I tried to use the code below to test, but I failed. Can anyone help me point out if my code is wrong. My cpu is Intel(R) Core(TM) i7-2630QM 2.00GHz. Thanks a lot
ML: D:\Programs\masm32\Bin\ML.EXE /c /coff /Cp /nologo /I"D:\Programs\masm32\Include" "AntiDebug.asm"
Link: D:\Programs\masm32\Bin\LINK.EXE /SECTION:.text,RWE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /LIBPATH:"D:\Programs\masm32\Lib" /OUT:"AntiDebug.exe" "AntiDebug.obj"
It always executes the debug label no matter I am debugging or not, and it will never execute 'jmp normal'.
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib
.data
szDebug db 'Hey, you are debugging!!!',0
szError db 'Error',0
szNormal db 'You are running it without debugging',0
szPrompt db 'Prompt',0
.code
start:
call IsDebug
debug:
invoke MessageBox, NULL, addr szDebug, addr szError, MB_OK
invoke ExitProcess, -1
normal:
invoke MessageBox, NULL, addr szNormal, addr szPrompt, MB_OK
invoke ExitProcess, 0
IsDebug:
mov al, 0c3h
mov edi, offset IsDebug
mov cx, 20h
rep stosb
jmp normal
end start
i don't know what does your isdebug proc doing.
here is my code and it work fine in my computer.
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\user32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\user32.lib
.data
szDebug db 'Hey, you are debugging!!!',0
szError db 'Error',0
szNormal db 'You are running it without debugging',0
szPrompt db 'Prompt',0
.code
start:
call IsDebug
debug:
invoke MessageBox, NULL, addr szDebug, addr szError, MB_OK
invoke ExitProcess, -1
normal:
invoke MessageBox, NULL, addr szNormal, addr szPrompt, MB_OK
invoke ExitProcess, 0
IsDebug:
invoke IsDebuggerPresent
test eax,eax
je normal
ret
end start

Resources