MASM errors on Build in VS10 - visual-studio-2010

The attached code is a supplied source for a SaveGame cleaner.
The only thing that is not clear is the entry point, which has been set as main.
But the decompiler at [http://www.onlinedisassembler.com/odaweb/] gave something like _start.
The first codeblock is
; SaveTool V 1.13
_______________________________________________________________________________________
[true 1 false 0 NULL 0]
[FilterStrings: B$ 'Save Files', 0, '*.ess', 0
0,0,0]
*Error 6 error A2044: invalid character in file SaveCleaner.asm 12 1* SaveCleanerNextline
[UserFileFilter: 0 #50] [ChoosenFile: 0 #64]
[OFN_FILEMUSTEXIST 01000 OFN_PATHMUSTEXIST 0800 OFN_LONGNAMES 0200000
OFN_EXPLORER 080000 OFN_HIDEREADONLY 04]
[OFN_FLAGS OFN_FILEMUSTEXIST+OFN_PATHMUSTEXIST+OFN_LONGNAMES+OFN_HIDEREADONLY+OFN_EXPLORER]
[OpenFileNameStructure: len hwndFileOwner: 0 OF_hInstance: 0 FilterStrings
0 0 1 FullChoosenFile 200 ChoosenFile
80 NULL OpenFileTitle OFN_FLAGS
nFileOffsetinChoosenFile: W$ 0 nFileExtensioninChoosenFile: 0
DefaultExtension: D$ NULL
HookCustomData: NULL HookProcPtr: NULL HookTemplateName: 0 0 0 0 ]
[OpenFileTitle: 'Open .ess file' 0]
*Error 6 error A2044: invalid character in file SaveCleaner.asm 12 1 SaveCleanerNextline*
[FullChoosenFile: 0 #64] [<16 algn: 0]
__________________________________________________________________________________________
The complete codeblock is too large for posting here so it can be downloaded (right click) at [http://www.ozemail.com.au/~lmstearn/files/SaveTool-source.asm]
The config has been set correctly to compile the code but comes up with a mass of errors.
SaveCleaner.asm(142): error A2008: syntax error :
SaveCleaner.asm(156): error A2044: invalid character in file
SaveCleaner.asm(158): fatal error A1012: error count exceeds 100; stopping assembly
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\BuildCustomizations\masm.targets(49,5): >error MSB3721: The command "ml.exe /c /nologo /Zi /Fo"Debug\SaveCleaner.obj" /I >"C:\masm32\lib" /I "C:\masm32\include" /I "C:\masm32\macros" /W3 /errorReport:prompt >/TaSaveCleaner.asm" exited with code 1.
What is missed in the VS setup?

It looks that your asm source is a RosASM source code and you will have no chance to compile it under MASM / Visual Studio.
RosASM is a win32 assembler that used a quite original design that let it store the source code inside the compiled executable (in a dedicated section) and many other features like an integrated IDE, integrated debugger, some powerful macros, a resource editor, a dialog editor, an original source navigation style that does not need scrolling bar, the possibility to divide the source in chapters called "titles"... Quite a surprising tool that need some practice to get comfortable with it, that I still use for asm win32 programming.
I have checked that the code assembles with RosASM, but I get neither an error nor a result as I do not have the corresponding game.
The original RosASM web site is now vanished, but there is a dedicated forum recently back online and I maintain an archive site where you can get binaries, and a lot of examples and fully functional applications (even a working NES emulator) made with RosASM that could help you to learn RosASM usage. FYI, SpASM is RosASM ancestor and BUASM was a revamping of RosASM that is unfinished.
Concerning the executable entry point, you can get it by looking at the Proc Main int the TITLE MAIN, that reads:
Proc Main:
call 'KERNEL32.HeapCreate' 0 0 0 | mov D$Heap eax
call 'Kernel32.GetModuleHandleA' 0 | mov D$hInstance eax
call 'USER32.DialogBoxParamA' eax IDD_MAINDIALOG &NULL DialogProc &NULL
call 'KERNEL32.HeapDestroy' D$Heap
call 'KERNEL32.ExitProcess' 0
EndP
HTH.

Related

Debug:: Writing a bootloader to an external drive directly from debug

Title says it all.... so let's go directly into ASSEMBLY :)
-A 100
1454:0100 mov ah,9
1454:0102 mov dx,109
1454:0105 int 21
1454:0107 int 20
1454:0109 db "Booting...$"
1454:0114
-rcx
CX0016
14
My goal is to use that simple code as a bootloader of an external hard drive.
I tried to write it to the current drive
-w 0 0 0 1
but obviosly it's protecting sector 0 so I want to write it to another drive without saving it to a bin file and use external softwares.
Small tweak needed here :D

Need to run .exe file for 7 seconds and then kill the exe while performing input and output in text files

I want to create a batch file which runs a program for 7 seconds, irrespective of the completion of execution of the other program. I also want that the program should take input and save the output in an external file. This is what I tried:
start program.exe
ping 1.1.1.1 -n 1 -w 7000 > nul
taskkill /im program.exe /f
rem continue here
The above works fine, but when I replace line 1 with:
start program.exe < in.txt > out.txt
then input from file and output in file doesn't work.
cmd doesn't set the STARTF_USESTDHANDLES flag of the CreateProcess STARTUPINFO structure. Instead, it temporarily redirects its own standard handles and relies on inheritance. This approach works even if cmd has to call ShellExecuteEx, which lacks a way to explicitly set the standard handles.
However, redirecting its own standard handles doesn't work when CREATE_NEW_CONSOLE is set in the process creation flags, which is the default for the start command. To avoid this problem, use the /b option to prevent creating a new console.
You may also want to redirect stderr to stdout or a file. This prevents errors from being written to the console. For example:
start /b program.exe <in.txt >out.txt 2>&1
start /b program.exe <in.txt >out.txt 2>err.txt
start /b program.exe <in.txt >out.txt 2>nul
Example using Debugging Tools for Windows
(test) C:\>cdb -Goxi ld cmd
Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
CommandLine: cmd
Symbol search path is: symsrv*symsrv.dll*
C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
(ed0.1770): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00000000`77848700 cc int 3
0:000> .reload /f
Reloading current modules
.....
0:000> bp CreateProcessW
0:000> g
Run where.exe in a new console.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
(test) C:\>start /w where.exe <nul >nul
Breakpoint 0 hit
kernel32!CreateProcessW:
00000000`775a0660 4883ec68 sub rsp,68h
Note that cmd.exe redirects its StandardOutput before calling CreateProcess:
0:000> ?? ((ntdll!_PEB *)#$peb)->ProcessParameters->StandardOutput
void * 0x00000000`00000060
0:000> !handle 60 3
Handle 60
Type File
Attributes 0
GrantedAccess 0x120196:
ReadControl,Synch
Write/Add,Append/SubDir/CreatePipe,WriteEA,ReadAttr,WriteAttr
HandleCount 2
PointerCount 3
The process creation flags, i.e. dwCreationFlags, the 6th parameter:
0:000> dd (#rsp + 6*8) l1
00000000`00182c58 00080410
is passed as 0x80410, which is a bitwise OR of the following flags:
EXTENDED_STARTUPINFO_PRESENT
CREATE_UNICODE_ENVIRONMENT
CREATE_NEW_CONSOLE
Because a new console is created, where.exe doesn't inherit cmd's standard handles:
0:000> g
Symbol search path is: symsrv*symsrv.dll*
C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
(1550.1a80): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00000000`77848700 cc int 3
1:001> ?? ((ntdll!_PEB *)#$peb)->ProcessParameters->StandardOutput
void * 0x00000000`00000007
Note: in Windows 8+ a console handle is just a regular file handle, so you'll have to look deeper.
I'm using Windows 7 for this example, so console handles are fake handles tagged by setting the lower 2 bits (e.g. 3, 7, 11 => 0b0011, 0b0111, 0b1011). By 'fake' I mean they're not in the process handle table used for kernel object handles. Thus, for example, you can't use the debugger !handle command to inspect handle 7:
1:001> !handle 7 f
Could not duplicate handle 7, error 87
In Windows 7, console handles are allocated and managed by the console host process, conhost.exe. They're tagged so Windows base functions can make the required LPC call to conhost.exe via NtRequestWaitReplyPort.
The above example demonstrated how creating a new console overrides inheriting cmd's redirected standard handles. Now let's add the /b option to prevent creating a new console.
1:001> g
(test) C:\>start /b /w where.exe <nul >nul
Breakpoint 0 hit
kernel32!CreateProcessW:
00000000`775a0660 4883ec68 sub rsp,68h
dwCreationFlags is 0x80600:
0:000> dd (#rsp + 6*8) l1
00000000`00182c58 00080600
which is a bitwise OR of the following creation flags:
EXTENDED_STARTUPINFO_PRESENT
CREATE_UNICODE_ENVIRONMENT
CREATE_NEW_PROCESS_GROUP
(A side effect of specifying /b is to create the process as the leader of a new process group. If it's a console process, this allows generating a Ctrl+Break event that targets the group.)
In this case, where.exe does inherit the redirected standard handles from cmd.exe:
0:000> g
Symbol search path is: symsrv*symsrv.dll*
C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
(1508.1534): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00000000`77848700 cc int 3
1:001> ?? ((ntdll!_PEB *)#$peb)->ProcessParameters->StandardOutput
void * 0x00000000`00000064
1:001> !handle 64 3
Handle 64
Type File
Attributes 0
GrantedAccess 0x120196:
ReadControl,Synch
Write/Add,Append/SubDir/CreatePipe,WriteEA,ReadAttr,WriteAttr
HandleCount 3
PointerCount 4
Again, in Windows 7 it's easy to spot a console pseudo handle because it's tagged by setting the low 2 bits of the handle value. For Windows 8+, a quick check is to look at the low nibble (4 bits) of the file's granted access, for which read data access is 1, write data access is 2, and append data access is 4. A file opened for a console buffer has both read and write access, whereas cmd's redirection uses either read (<) or write (>), but not both. The above is the redirected output, and you can see the file is opened with write and append access (2+4), but not read access. That's a quick check, but if you want to be certain you can use a kernel debugger such as kd.exe, or a tool such as Sysinternals Process Explorer or handle.exe. These can show you the NT kernel object path, such as \Device\ConDrv\Input for a Windows 8+ console input handle.

Ghostscript 'offending input'

When searching for an occurrence of text in a PostScript file, I receive the following error:
gsapi_run_string_continue returns -21
The API documentation specifies that return codes > 0 are "Error" but doesn't describe it any more specifically. Full error console output below - error occurs twice identically, only one occurrence displayed here.
GPL Ghostscript 9.15 (2014-09-22)
Copyright (C) 2014 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Displaying DSC file C:/Users/c-toothm/Desktop/PRDFlow12_30_2014_050307/1230ouptut.ps
Displaying page 1
%%[ ProductName: GPL Ghostscript ]%%
%%[ LastPage ]%%
Extracting text using pstotext...
Ghostscript returns error code -21`
--- Begin offending input ---
evice /pop , d
initmatrix [1 0 0 1 0 0] concat colspSet`
0.00 43.32 +
0.94 0.95 +S
(XSFT2200041.img) run
EPSFILE2200041 restore
;
0 0 0 sco 5 Lw N 4950 4742 M 4800 4742 I K
0 0 0 sco 5 Lw N 4950 4752 M 4800 4752 I K
0 0 0 sco 5 Lw N 4950 4762 M 4800 476
--- End offending input ---
gsapi_run_string_continue returns -21`
[duplicate error redacted]
Our production output creates a giant .ps file every day and this error occurs in many, but not all, .ps files when searching for text. Randomly selected .ps files from the web do not throw the error, so this GS build seems OK - definitely a problem with my file.
What "offending input" is being referred to here and what can I do to address it?
I'd need to see the PostScript file to tell you exactly what is wrong, but 'evice' is not a PostScript operator and so that is likely the problem. Also, from ghostpdl/gs/psi/ierrors.h error code -21 is e_undefined which means the interpreter has encountered an undefined token, which is some confirmation that this is the problem.
This could be because the file contains a 'typo' like that (perhaps it should be setpagedevice or something), or it could be because a filter is improperly terminated, or has insufficient data, and consumes extra bytes from the input stream, chewing up your program.
You should start by using the Ghostscript executable and reproduce the error with that (you might also try the display device, to see whether the problem is related to pstotext), that will allow you to give a command line which other people can then duplicate. With that, and a copy of the offending file I can tell you exactly what's wrong, without it, not much hope.
Bear in mind that PostScript is an interpreted programming language, so its pretty much impossible to tell you what's wrong with your program without seeing the code.
FWIW you might like to try the Ghostscript txtwrite device instead of pstotext, the device doesn't rely on tinkering with the language like pstotext does. pstotext is also really old (the last release is coming up on its 11th birthday) and unsupported.....

Is CreateProcessW deprecated?

I couldn't find a precise answer so I've decided to ask.
I've been reading the "Inside Windows Debugging" and in the sample it tells me to set a breakpoint on the kernel32!CreateProcessW.
But before that it uses the .symfix debugger command to set the debugger symbols search path to point to the Microsoft online symbols server. When I try to set the breakpoint I get an error that it cannot resolve the function (or something like that). It looks like this.
0:000> bp kernel32!CreateProcessW
Couldn't resolve error at 'kernel32!CreateProcessW'
It's probably because there's no "kernel32!CreateProcessW" in the list below.
0:000> x kernel32!CreateProcess*
76b90cb9 KERNEL32!CreateProcessWithTokenW (void)
76b90d84 KERNEL32!CreateProcessAsUserW (void)
76b90d84 KERNEL32!CreateProcessWithLogonW (void)
76b4e225 KERNEL32!CreateProcessWStub = <no type information>
76b72e04 KERNEL32!CreateProcessInternalAStub = <no type information>
76b72e15 KERNEL32!CreateProcessInternalWStub = <no type information>
76b72de2 KERNEL32!CreateProcessAStub = <no type information>
76b72df3 KERNEL32!CreateProcessAsUserWStub = <no type information>
Everything goes fine if I set the breakpoint to kernel32!CreateProcessWStub but I wondered why I couldn't find and set the breakpoint to the kernel32!CreateProcessW.
This book probably focuses on a reader who's using Windows 7. I'm using Windows 8.1 and thought maybe that kernel32!CreateProcessW got deprecated...
I'm extremely new to this field and apologize if this is a completely stupid question. But thanks for reading it anyway.
CreateProcessW is definitely NOT deprecated. Furthermore, the only documented entry point is still in kernel32.dll, so for all intents and purposes, you should continue calling CreateProcessW through kernel32.dll, and not through kernelbase.dll.
Here is some more details to help understand what you are observing. Windows team often moves code around, and for the last few releases they had strong habit of breaking larger DLL's into smaller ones, which includes kernel32, ole32, user32, gdi32 to name a few. It is not new, Raymond Chen wrote about this in 2006. However the mechanism Raymond describes is based on forwarders, while what you see here with kernel32!CreateProcessW is a stub, i.e. the function that calls kernelbase!CreateProcessW and then returns:
0:014> u kernel32!CreateProcessWStub l14
KERNEL32!CreateProcessWStub:
00007ffd`83cf58a8 4c8bdc mov r11,rsp
00007ffd`83cf58ab 4883ec58 sub rsp,58h
00007ffd`83cf58af 488b8424a8000000 mov rax,qword ptr [rsp+0A8h]
00007ffd`83cf58b7 498943f0 mov qword ptr [r11-10h],rax
... skip ...
00007ffd`83cf58f5 ff1555871100 call qword ptr [KERNEL32!_imp_CreateProcessW (00007ffd`83e0e050)]
00007ffd`83cf58fb 4883c458 add rsp,58h
00007ffd`83cf58ff c3 ret
The function called as you can see is kernelbase!CreateProcessW
0:014> ln poi kernel32!_imp_CreateProcessW
(00007ffd`82f92604) KERNELBASE!CreateProcessW | (00007ffd`82f926d0) KERNELBASE!MakeLocHashNode
Exact matches:
KERNELBASE!CreateProcessW (no parameter info)
I this case I don't know why Windows folks decided to use a stub rather than a forwarder, to me it seems it would be more efficient to simply forward a call, like most of the other refactoring, was done.
Kernel32.dll in Windows 8.1 still contains export symbol CreateProcessW. Command link /dump /exports prints out all export symbols:
c:\>link /dump /exports c:\Windows\System32\kernel32.dll | findstr CreateProcessW
220 DB 000058A8 CreateProcessW = CreateProcessWStub
You can use the same command to determine where you should set a breakpoint to. Similarly for forwarded exports:
c:\>link /dump /exports c:\Windows\System32\kernel32.dll | findstr EnterCriticalSection
298 129 EnterCriticalSection (forwarded to NTDLL.RtlEnterCriticalSection)
1418 589 TryEnterCriticalSection (forwarded to NTDLL.RtlTryEnterCriticalSection)
The reason why WinDbg cannot resolve symbol kernel32!CreateProcess, is probably just a bug in WinDbg. In this case, the symbols is not part of .PDB file, but contained in a special section in PE image, and apparently WinDbg does not handle that. What is interesting is that if .PDB file is not available, WinDbg is happy to use export table of PE image:
0:014> .sympath .
0:014> .reload
Reloading current modules ....
0:014> x kernel32!CreateProcessW
00007ffd`83cf58a8 <b>KERNEL32!CreateProcessW</b> (no parameter info)
Apparently, WinDbg decides to use either PDB symbols or export symbols, but not both.

Windows copy command return codes?

I would like to test for the success/failure of a copy in a batch file, but I can't find any documentation on what if any errorlevel codes are returned. For example
copy x y
if %errorlevel%. equ 1. (
echo Copy x y failed due to ...
exit /B
) else (
if %errorlevel% equ 2. (
echo Copy x y failed due to ...
exit /B
)
... etc ...
)
I'd opt for xcopy in this case since the error levels are documented (see xcopy documentation, paraphrased below):
Exit code Description
========= ===========
0 Files were copied without error.
1 No files were found to copy.
2 The user pressed CTRL+C to terminate xcopy.
4 Initialization error occurred. There is not
enough memory or disk space, or you entered
an invalid drive name or invalid syntax on
the command line.
5 Disk write error occurred.
In any case, xcopy is a far more powerful solution. The equivalent documentation for copy does not document the error levels.
As an aside, you may want to rethink your use of the %errorlevel% variable. It has unexpected results, at least in some versions of Windows, if someone has explicitly done something silly like:
set errorlevel=22
In those cases, the actual variable will be used rather than grabbing the actual error level. The "normal" way of doing this is (in decreasing order since errorlevel is a "greater than or equal to" check):
if errorlevel 2 (
echo Copy x y failed due to reason 2
exit /B
)
if errorlevel 1 (
echo Copy x y failed due to reason 1
exit /B
)
In addition, if you are running Win7 or Win Server 2008 or later, you should look into Robocopy, which is now the preferred mass-copy solution.
It might also be worth pointing out that xcopy doesn't always return the error code you expect.
For example when trying to copy multiple files with a wildcard but there are no files to copy you expect a return error code of 1 ("No files were found to copy"), but it actually returns 0 ("Files were copied without error")
C:\Users\wilson>mkdir bla
C:\Users\wilson>mkdir blert
C:\Users\wilson>xcopy bla\* blert\
0 File(s) copied
C:\Users\wilson>echo %ERRORLEVEL%
0
I believe Copy only returns 0 for success or 1 for failure.
XCopy has documented return codes:
0 = Files were copied without error.
1 = No files were found to copy.
2 = The user pressed CTRL+C to terminate xcopy.
4 = Initialization error occurred. There is not enough memory or disk space, or you entered an invalid drive name or invalid syntax on the command line.
5 = Disk write error occurred.
There is also one point I would like to emphasize: xcopy as well as robocopy can only copy files, but they can't rename them.
While looking at the original situation (copy x y, which looks like a rename to me), I have the impression that the copy command still is the only one suitable for this purpose.
Error# Description
0 No error
1 Not owner
2 No such file or directory
3 Interrupted system call
4 I/O error
5 Bad file number
6 No more processes
7 Not enough core memory
8 Permission denied
9 Bad address
10 File exists
11 No such device
12 Not a directory
13 Is a directory
14 File table overflow
15 Too many open files
16 File too large
17 No space left on device
18 Directory not empty
999 Unmapped error (ABL default)

Resources