File format not recognized when trying build an exe from obj in windows - 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.

Related

Compiling error whilst using command from NASM and mingw

I want to play a bit with assembly. To get started I've created a little asm script and tried to compile it. In the first step everything went great:
nasm -felf64 hello.asm
But when I tried to use
ld -o hello.o hello
from MinGW an error occured:
hello.o: file not recognized: File format not recognized
What can I do to fix this problem? I've tried it with gcc as well but then the same error plus one other error occurs.
MinGW creates binaries targeting Windows. Windows does not support ELF binaries (or does it? with Windows subsystem for Linux?). Anyway, ld in MinGW will expect that you provide binaries in win64 format not elf64.
nasm -fwin64 hello.asm will most likely work.
No it won't work because I just saw your code, and you are using Linux syscalls under Windows.
Write,
mov rcx, 69
call ExitProcess
instead of,
mov rax, SYS_EXIT
mov rdi, 69
syscall
Leave a comment if it doesn't work.

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.

GNU Assembler in Windows Subsystem for Linux fail

I would like to compile "Hello World" in Windows Subsystem for Linux (WLS) with Debian.
.text
.global _start
_start:
movl $len,%edx
movl $msg,%ecx
movl $1,%ebx
movl $4,%eax
int $0x80
movl $0,%ebx
movl $1,%eax
int $0x80
.data
msg:
.ascii "Hello, world!\n"
len = . - msg
If i compile in a Debian server with
gcc -nostdlib -o hello hello.s
It work, but in WLS return error
/usr/bin/ld: /tmp/cciVVddg.o: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status
I also tried
gcc -fPIC -nostdlib -o hello hello.s
There are two problems with your code:
your code is intended to be 32 bit code but gcc tries to assemble it as 64 bit code. You can fix this by passing -m32 in all stages of assembly and linkage. Please keep in mind that WSL does not actually support 32 bit code so you won't be able to run your program even if you manage to assemble it.
gcc tries to generate a position-indepentent executable. To make your code work in such an executable, you need to write position indepentent code. To do so, you need to avoid any absolute references to the addresses of variables. In 32 bit code, this is a bit tricky and I'm not going to explain this further as 32 bit code won't run on WSL anyway. The compiler advises you to compile with -fpic because that causes the compiler to generate position independent code from C files, but for assembly files it's ineffective. You can fix this issue by linking with -no-pie, causing the linker to generate a normal position-dependent binary. Note that this still doesn't mean that a 32 bit binary is going to run in WSL.

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