Assembly _start function for Windows 10+ - windows

I am trying to make a Compiler and I don't know how to make _start function for windows.
Compiler compiles successfully but only for linux, for windows it waits 2 s and exits.
I've tried
.globl _WinMain#16
_WinMain#16:
; Code here

Related

How can I debug executables for Windows using GDB in WSL?

I'm frankly not even sure if this is a thing GDB can do, but no amount of searching I've done so far has given me a 'yes' or 'no'.
When I attempt to debug an application using a GDB installation built for Linux and opened in WSL, it is unable to insert a breakpoint anywhere in the program, claiming it can not access the memory at that address. If I do this from Windows with a GDB built for Windows, this error does not happen (and before you ask why I don't just use the Windows build, it's because I'm having other miscellaneous issues with that one. I may open a question for that as well)
I've got an internal error from GDB as well, but unfortunately, I can't seem to recreate it right now.
I've tried rebuilding GDB, as well as switching to another version of GDB (the same as my Windows build)
I'm using a WSL installation of Ubuntu 20.04 and GDB 10.2, configured as follows:
(gdb) show configuration
This GDB was configured as follows:
configure --host=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu
--with-auto-load-dir=$debugdir:$datadir/auto-load
--with-auto-load-safe-path=$debugdir:$datadir/auto-load
--without-expat
--with-gdb-datadir=/usr/local/share/gdb (relocatable)
--with-jit-reader-dir=/usr/local/lib/gdb (relocatable)
--without-libunwind-ia64
--without-lzma
--without-babeltrace
--without-intel-pt
--without-mpfr
--without-xxhash
--without-python
--without-python-libdir
--without-debuginfod
--without-guile
--disable-source-highlight
--with-separate-debug-dir=/usr/local/lib/debug (relocatable)
To see if this was an issue with the particular program I was debugging, I made a very minimal program in NASM (my original project was also in NASM) and compiled it as follows:
nasm -f win32 -gcv8 Test.asm
gcc -m32 -g Test.obj -o Test.exe
The source assembly is very simple. It just calls printf with a string and integer.
; Test.asm
global _main
extern _printf
section .data
fmt: db "%s, %d", 0x0
string: db "Testing...", 0x0
section .bss
num: resd 1
section .text
_main:
mov dword [num], 28
push dword [num]
push string
push fmt
call _printf
add esp, 12
ret
When attempting to debug this with GDB in WSL, this is the output I get:
(gdb) file Test.exe
Reading symbols from Test.exe...
(gdb) set architecture i386:x86-64
The target architecture is set to "i386:x86-64".
(gdb) start
Temporary breakpoint 1 at 0x401520
Starting program: /mnt/c/NASM/Test.exe
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x401520
EDIT: After poking at it some more, I discovered something that seems important. GDB is only unable to access the memory and place breakpoints when the program is running. Before I've started the program, I can place breakpoints and disassemble freely.
(gdb) disas main
Dump of assembler code for function main:
0x00401520 <+0>: mov DWORD PTR ds:0x405028,0x1c
0x0040152a <+10>: push DWORD PTR ds:0x405028
0x00401530 <+16>: push 0x40300b
0x00401535 <+21>: push 0x403004
0x0040153a <+26>: call 0x40249c <printf>
0x0040153f <+31>: add esp,0xc
0x00401542 <+34>: ret
0x00401543 <+35>: xchg ax,ax
0x00401545 <+37>: xchg ax,ax
0x00401547 <+39>: xchg ax,ax
0x00401549 <+41>: xchg ax,ax
0x0040154b <+43>: xchg ax,ax
0x0040154d <+45>: xchg ax,ax
0x0040154f <+47>: nop
End of assembler dump.
(gdb) b *main+26
Breakpoint 1 at 0x40153a
(gdb) run
Starting program: /mnt/c/NASM/Test.exe
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x40153a
(gdb) disas main
Dump of assembler code for function main:
0x00401520 <+0>: Cannot access memory at address 0
EDIT 2:
I don't know how useful this information might be, but I did find a method that consistently causes an internal error for GDB. Starting execution of the program, then setting the architecture to auto causes an internal error every time I've tried it.
(gdb) file Test.exe
Reading symbols from Test.exe...
(gdb) start
Temporary breakpoint 1 at 0x401520
Starting program: /mnt/c/NASM/Test.exe
warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
warning: Architecture rejected target-supplied description
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x401520
(gdb) set architecture auto
warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
/mnt/c/Users/Joshua/gdb-10.2/gdb/arch-utils.c:503: internal-error: could not select an architecture automatically
A problem internal to GDB has been detected,
further debugging may prove unreliable.
If the answer to this really is as simple as "GDB built for Linux can't debug applications built for Windows"... I'll be very sad, and also quite annoyed that I was unable to find that info anywhere.

File format not recognized when trying build an exe from obj in windows

I was trying to build an exe from asm file. The asm file looks like this:
global main
extern puts
section .data
msg:
db "Hello, world!",10,0
section .text
main:
sub rsp, 28h
mov rcx, msg
call puts
add rsp, 28h
ret
Then I assembled it using NASM and tried to link it using GCC. But it is showing this error.
> nasm -fwin64 asmtest.asm
> gcc asmtest.obj
asmtest.obj: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status
I am unable to figure out what is going on. My NASM version 2.14.02 and GCC version 8.1.0. I have followed this tutorial (at the bottom). I am doing this on my Windows 10 64-bit machine.
I have also seen this question, but it didn't help me.
You have installed mingw for 32 bit binaries. You need to install a version of mingw configured to make 64 bit binaries to compile and/or link 64 bit binaries.

Is it true that .exe can't run without .bss section in 64bit windows?

I came across this problem when I noticed some of my old programs failed to run under modern Windows.
Here is a miniature example, built via mingw64
.text
.global start
start:
subq $0x48,%rsp
xorl %ecx,%ecx
call *__imp_ExitProcess(%rip)
addq $0x48,%rsp
ret
gcc a.s -nostdlib -nostartfiles -lkernel32 -Wl,-e,start,-s
A message box says the exe is not valid Win32 program when I open it. However the program runs successfully when I add .lcomm a,1 or
.bss
.int 0
to the source file, both effectively inserting .bss section into the exe file. Adding .data section does not solve the problem.
Is this an inherent restriction of Windows or a bug inside ld?
EDIT:
Ok. I've found many exe files without .bss or any section with uninitialized data but run well nevertheless. But this does not fully answer my question. Why my program with only .data , .text and .idata unable to run?
EDIT V2:
I think I have found the cause. The value of OptionalHeader.SizeOfImage is incorrect. Changing it to correct value solves the problem. So this is most likely a bug inside ld.

I get the error Undefined reference to WinMain#16 when i link assembly code

I'm trying to link a simple assembly code using gcc but i get the compile error Undefined reference to "WinMain#16". I'm currently using Windows and NASM to compile.
Compile command using nasm defaults
nasm -fwin32 C:\Users\james\Desktop\hello.asm
link command gcc using defaults
gcc C:\Users\james\Desktop\hello.o -o hello.exe
installed using Mingw
code:
extern _printf
global _main
section .data
msg: db "Hello, world!",10,0
section .text
_main:
push msg
call _printf
add esp,4
ret
using win os 10 Toshiba laptop.

x86 assembly create Win32 executable NASM

I want to create a valid Win32 executable, that can be run as standalone application.
For example, this simple program:
bits 32
mov eax,1
ret
I compiled it using NASM with
nasm test.asm -o test.exe
Then I ran that program.
It started NTVDM and it told me "The NTVDM CPU encountered illegal instruction" and some technical details, probably dump, and registers.
So, I want to create a standalone Win32 application in assembly language. I don't want to create COM file, like in DOS.
[section] .text
global _start
_start:
mov eax, 1
ret
can be assembled like this:
nasm -fwin32 file.asm (this should give you file.obj)
and
link /subsystem:windows /entry:start file.obj
(or)
ld -e _start file.obj
whatever linker you choose should give you your .exe
At least Windows XP refuses to load an application that does not use any DLL files. I didn't test with Windows 7 up to now!
The reason is that there are no official interfaces but the DLLs that come with Windows and that a program that has neither inputs nor outputs makes no sense.

Resources