I am trying to learn assembly language in my spare time to help me in my role as a developer using high level languages.
I have followed the NASM tutorial here: http://leto.net/writing/nasm.php.
I am able to create and run a simple program that prints HelloWorld to the screen. I am confused by the following paragraph in the link above:
mov eax,5 ; the syscall number for open()
So where do find out all of the semantics for all of the various system calls?
Well first, the numbers are listed in asm/unistd.h in Linux, and sys/syscall.h
in the *BSD's
I assume that this means that: if there is a 5 in the eax register, then it is a system call for open. Are the rest of the system calls documented somewhere?
I am using NASM on a Windows 7 PC.
List of Windows API calls
If and when you use NASM on Linux,
http://asm.sourceforge.net/syscall.html#1
http://syscalls.kernelgrok.com/
Related
I'm currently persuing to create a compiler. Because of that I am learning nasm x86 assembly.
I never really coded in c++ or c so I never really used the winapi. When I used ld I could successfully link and create a 32 bit executable but it doesn't use "the real winapi" since it uses a libkernel32.a file internally.
Now, I know this might sound like a silly question but where are files like kernel32.dll located on a default installation of windows 10 64 bit? Maybe the one in the C:\Windows\System32 folder but these somehow won't work with neither ld nor golink.
I am new to assembly language, and I am using macOS. The book I read uses DOS's debug instruction, which could see the values in registers at any time without set breakpoints in some executable programs like lldb, and could execute basic assemble instructions like mov ax, 2000. I know that macOS runs on a x86_64 machine, which is different from DOS. I simply want a way that can inspect and interact with registers/memory in terminal without an formal assembly program.(For example, in DOS, type in debug -r and I can see all the values stored in registers).
In lldb - the stock MacOS debugger
register read
will show you all register values
Also possible with shortened syntax for quicker typing
re r
If you want the floating point registers (xmm* for x86-64) too included
re r --all
If you want particular register value
re r rax
lldb is used in current versions of Xcode the MacOS free programming IDE from Apple which allows you to target MacOS & iOS.
You can also go with the terminal route when you would run your program with:
lldb ./yourProgram
But this approach will require a lot of typing and knowledge about your binary, so I don't recommend it for starters.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I really need some help here. I've been searching online for about 2 days now and can't seem to find an answer to the problems that I got.
I downloaded nasm and installed it it seems to work but I can't seem to find any example code that works on windows 64bit (it would be awesome if you could make a simple hello world example for me or something).
(And how to compile it)
How would I turn the .o file into a .exe?
How would I accesses the screen or gpu memory (I think) to print stuff on the screen (like some sort of console application)?
There a a few things to consider when programming in assembly using NASM under Windows:
NASM is just an assembler
A linker is needed to create an executable.
Windows API are implemented as a user space library.
The library is not entirely in user space, some functions cross the boundary, but the interface to the application is a set of DLL, most notably: kernel32.dll, user32.dll and so on.
Windows' executables can have different subsystems.
Among the others the IMAGE_SUBSYSTEM_WINDOWS_GUI and IMAGE_SUBSYSTEM_WINDOWS_CUI are the most used, the former being used by applications that create windows and the latter by applications that use a console1.
The linker takes to COFF object (.obj) file generated by the assembler, takes a set of library definitions (.lib) and perform these important steps:
It resolves the call to external functions found in the object file.
A function marked as external is meant to be found in one of the library definition, the linker then fixes the call instruction to point to a location where the address of the function will be found at run-time.
It add the dependency libraries to the final executable.
This is done with the help of the PE file format, basically if F if found on the library L then L is added to the dependencies list along with a location where to write the address of F.
The loader will do the rest.
The linking is actually more complex than that.
It is also responsible for setting the various PE flags and settings, including the subsytem and the entrypoint.
To write an executable using NASM with need:
A linker.
The set of library definitions.
These can be found in the Windows SDK2.
The linker we will use in this example is the Microsoft LINK linker.
As #CodyGray pointed out in its comment (quoting because I'm lazy):
The Windows 7 version of the SDK that you linked does include all of the build tools. The Windows 8 SDK changed and no longer ships with the command-line build tools, forcing you to download a Visual Studio package
Once we have the tools, we can start programming.
We will use WriteFile to write a string to the standard output (like we would in Linux assembly).
The handler to the standard output must be retrieved with GetStdHandle though.
In Windows you can exit a process with a ret even with no CRT (C run-time) linked (i.e. in a bare process).
I won't explain the Window 64 ABI nor the trickery of programming in 64-bit.
BITS 64
DEFAULT REL ;RIP relative addressing by default
GLOBAL main ;Main must be visible to the linker
;Function the linker will look for in other modules (libs or objs)
EXTERN WriteFile
EXTERN GetStdHandle
STD_OUTPUT_HANDLE EQU -11
SECTION .data
strHelloWorld db "Hello world!", 13, 10, 0
lenHelloWorld dd $-strHelloWorld
hOut dd 0 ;Will store STDOUT handler
SECTION .text
main:
sub rsp, 30h ;20h (Home space) + 10h (params)
;Get STDOUT handler (Handler are 32-bit values)
mov ecx, STD_OUTPUT_HANDLE
call GetStdHandle
mov DWORD [hOut], eax ;Useless as now, for future reuse
;Write strHelloWorld to STDOUT
mov ecx, eax
lea rdx, [strHelloWorld]
mov r8d, DWORD [lenHelloWorld]
xor r9, r9
mov QWORD [rsp+20h], r9
call WriteFile
add rsp, 30h
ret
To create an executable from this source, we first assemble it into a 64-bit object file:
nasm -fwin64 hello.asm -o hello.obj
then we link it against the kernel32 library (the only one we need):
link /MACHINE:X64 /SUBSYSTEM:CONSOLE /OUT:hello.exe /NODEFAULTLIB /ENTRY:main kernel32.lib hello.obj
the CLI switches are pretty straightforward, NODEFAULTLIB avoid linking with MSVCVRXX.lib, the Microsoft CRT.
Those are the minimal switches necessary to build an executable in this example.
I assume you are smart enough to fix the path issues when issuing the commands above, particularly you can tell link where to find the lib files.
For this example I just copied them from the SDK installation folder.
As proposed in other answers, you can use other assemblers that may came with a linker.
Another possible developing environment is to use gcc (either inside cygwin or as mingw) to perform the linker step.
1 In this case Windows automatically create a console for the application and set the standard handlers appropriately. GUI application can recreate the console too (or more than one), so IMAGE_SUBSYSTEM_WINDOWS_GUI must be intended as "No console by default".
2 The version linked is the first Google result, invest more time in finding a suitable version. Also, I'm not sure if there is a linker in the Windows SDK or you need to download a Visual Studio instead.
Download Flat Assembler.(Download->flat assembler for windows)
http://flatassembler.net/
Extract zip.
Goto 'examples/win64/pe64demo/'
open 'pe64demo.exe'
(source code is in 'pe64demo.asm')
I was trying to make my program accept input without the user having to press enter, so I tried the following:
mov ah,01h
int 21h
But it just crashes my program over an unhandled exception. This seems to be the way to do it according to much that I have read, so why isn't it working for me?
Now, I am fairly new to this language so I still do not exactly understand the process of how this piece of code works, so I would also appreciate what the logic is behind accepting input by pressing enter and accepting input without the user having to press enter.
MY OS is Windows, by the way.
Your code looks like MS-DOS-era assembly. VS2010 doesn't support generating DOS executables, and modern versions of Windows (the 64-bit kind) don't support running them, either. Looks like you were going by some old book or site, one that was written in late 80'es-early 90's. Back at that time, assembly was way more relevant and marketable as a job skill. Not so much these days, although some assembly knowledge won't hurt.
Decide what do you want to learn. If you want to learn modern assembly (and target Windows), get some recent guidance. The techniques are quite different, and int21h isn't among them :) If you're indeed after DOS-era assembly, set up a DOS virtual machine with DOSBox, and find some old free assembler. Visual Studio 2010 won't help you here. The latest version of Visual C++ that generated 16-bit executables was v1.5x.
Specifically why does your program crash. Int21h was how MS-DOS exposed its applciation program interface (API). Windows doesn't support it for Windows executables - there are other ways of invoking the API. When you assemble with Visual Studio 2010, you end up with a Windows executable, not a DOS one, and there's no option to generate a DOS one. As for the Windows executables, they're not supposed to invoke interrupts at all - that's a crash condition.
You need to obtain a tool set that can generate 16 MS-DOS programs. These should run on DOSBOX, or on a Virtual PC with MS-DOS installed on it. Microsoft included 16 bit tool sets up to Visual C / C++ 1.52, but Visual C / C++ 4.0 and 4.1 also contain the 1.52 16 bit tool set. The older version of the compilers would be named Microsoft C 8.xx or earlier version. I don't know if any the early versions of Visual Studio (2002 or 2003) include the 16 bit tool set.
Use the linker version 5.60 to generate 16-bit DOS applications. You can get this from:
http://download.microsoft.com/download/vc15/Update/1/WIN98/EN-US/Lnk563.exe
Dirk
Subject: PPC Assembly Language - Linux Loadble Kernel Module
Detail: How access local TOC area (r2) when called from kernel in syscall table hook?
I have written a loadable kernel module for Linux that uses syscall table hooking to intercept system calls and log information about them before passing the call on to the original handler. This is part of a security product. My module runs well and is in production code running on a large variety of Linux kernel versions and distributions with both 32 and 64 bit kernels all running on x86 hardware.
I am trying to port this code to run on Linux for PPC processors and ran into a few problems. Using the Linux kernel source, it is easy enough to see how the system call table is implemented differently on PPC. I can replace entries in the table with function addresses from my own compiled handlers, no problem.
But, here's the issue I'm having trouble with. The PPC ABI uses this thing called a Table Of Contents (TOC) address which is stored in the CPU's R2 register and expects to address a module's global and local data by using an offset from the address (TOC address) contained in that register. This works fine in normal cases where a function call is made because the compiler knows to load the module's TOC address into the register before making the call (or its already there becasue normally your functions are called by your own code).
However, when I place the address of my own function (from my loaded kernel module at runtime) into the system call table, the kernel calls my handler with an R2 value that is not the one my compiled C code expects, so my code gets control without being able to access its data.
Does anybody know of any example code out there showing how to handle this situation? I cannot recompile the kernel. This should be a straightforward case of runtime syscall table hooking, but I have yet to figure it out, or find any examples specific to PPC.
Ideas include:
Hand coding an assembly language stub that saves the R2 value, loads the register with my local TOC address, executes my code, then restores the old value before calling the original handler. I don't have the depth of PPC assembly experience to do this, nor am I sure it would work.
Some magic gcc option that will generate my code without using TOC. There is a documented gcc option "-mno-toc" that doesn't work on my PPC6 Linux. It looks like it may only be an option for system V.4 and embedded PowerPC.
Any help is greatly appreciated !
Thanks!
Linux has a generic syscall audit infrastructure which works on powerpc and you can access from user space. Have you considered using that rather than writing a kernel module?
You need a stub to load r2. There are examples in the kernel source.