In NASM, is MOV EBX, AX a valid instruction? - nasm

In NASM, is MOV EBX, AX a valid instruction?
Basically, can you move the contents of a small register into a register bigger than it?

That's not valid anywhere. To get the effect you want, do
MOVZX EBX, AX, or
MOVSX EBX, AX
depending on whether you want to zero or sign extend the source operand.

Related

How to read a file using shellcode without explicitly mentioning syscall (0x0f05) with write permissions disabled?

I'm working on a ctf-like challenge and it is filtering my shellcode to make sure I don't have the hex value encodings of the syscall, sysenter and int instructions 0x0f05 0x0f34 and 0x80cd respectively. It has also disabled write permissions. I have a shellcode that can open a file which uses the sendfile system call but it includes the syscall instruction. The previous challenge was the same but with write permissions enabled. I successfully used a self-modifying shellcode in that challenge to get the flag.
This is the assembly code (with syscall) I used to read the file "flag" (GAS intel syntax):
.globl _start
_start:
.intel_syntax noprefix
mov rbx, 0x67616c66
push rbx
mov rax, 2
mov rdi, rsp
mov rsi, 0
syscall
mov rdi, 1
mov rsi, rax
mov rdx, 0
mov r10, 1000
mov rax, 40
syscall
mov rax, 60
syscall
I have been searching for an alternative way to do a system call in Linux for the past day but it seems impossible (I'm a newbie to assembly).
I read about an alternative way to do system calls by Call Gates method, but it seems to rely on the Global Descriptor Table and I don't think I can access that due to ASLR (Correct me if I'm wrong).
I'm not necessarily looking for an exact answer but just looking for some help understanding a way I can do a system call in this conditions.

Incrementing one to a variable in IA32 Linux Assembly

I'm trying to increment 1 to a variable in IA32 Assembly in Linux
section .data
num: dd 0x1
section .text
global _start
_start:
add dword [num], 1
mov edx, 1
mov ecx, [num]
mov ebx,1
mov eax,4
int 0x80
mov eax,1
int 0x80
Not sure if it's possible to do.
In another literature I saw the follow code:
mov eax, num
inc eax
mov num, eax
Is it possible to increment a value to a var without moving to a register?
If so, do I have any advantage moving the value to a register?
Is it possible to increment a value to a var without moving to a register?
Certainly: inc dword [num].
Like practically all x86 instructions, inc can take either a register or memory operand. See the instruction description at http://felixcloutier.com/x86/inc; the form inc r/m32 indicates that you can give an operand which is either a 32-bit register or 32-bit memory operand (effective address).
If you're interested in micro-optimizations, it turns out that add dword [num], 1 may still be somewhat faster, though one byte larger, on certain CPUs. The specifics are pretty complicated and you can find a very extensive discussion at INC instruction vs ADD 1: Does it matter?. This is partly related to the slight difference in effect between the two, which is that add will set or clear the carry flag according to whether a carry occurs, while inc always leaves the carry flag unchanged.
If so, do I have any advantage moving the value to a register?
No. That would make your code larger and probably slower.

System call reading from file straight to stack, nasm

I am trying to write a PIC code in NASM 32 bit.
For that, I need to read from a file an amount of 4 bytes and check if it is an ELF file.
I did this:
eax has the file descriptor, so I did push eax, and checked that it is not -1, all is good.
But now, I want to use the read, to read 4 bytes, but since I need it as a PIC code, I must read straight into stack as a local variable. I did this (using macro system calls): read [ebp-4 (fd)], [ebp-8] (to this place in stack), 4 (4 bytes) However, returned value is -14 as in it did not read anything.
I made a data section with a buffer, did the same but read into the buffer and it worked.
So, apparently, I can not read straight TO stack. How would I do this to maintain PIC code?
open Filename, RDWR, 0777
push eax ;backup fd, now its at place [ebp-4]
cmp eax, -1 ;if not a good fd
je exit
mov eax, 3 ;sys read
mov ebx, [ebp-4]
mov ecx, [ebp-8]
mov edx, 4
int 0x80

Manually Add Newline To Stack Variable In x86 Linux Assembly

I wrote a simple assembly program that gets two integers from the user via a prompt, multiplies them together and prints that out. I wanted to do this directly with sys_read and not scanf so I could manually convert the input to an integer after removing the LF.
Here's the full source: http://pastebin.com/utnjTvNZ
In particular, what I want to do now is manually add a newline to the result of the multiplication that is now converted back to it's ASCII char equivalent. Initially, I thought I could just left shift 16 bits and add 0xA leaving me with, for example, 0x0034000A on the stack for 2*2 (0x0034 is "4" in ASCII chars), followed by a null terminator and a LF. However, the LF is printing before the result. I figured this was an endianess thing, so I tried the reverse (0x000A0034) and that just printed some other ASCII char instead.
So, simply, how do I properly push a newline to the stack so that this is printed with a newline following the number when using sys_write? What I'm missing is how strings are stored on the stack... which I can't test because normally you just create a variable and push the address onto the stack.
I'm aware some things in here could be done better, cleaner and up-to-standards and whatnot. I understand things intuitively so it's something I just need to do to better understand the stack and Linux system calls in general.
Okay, so to answer my own question thanks to the help of Jester, to add a newline to the 32-bit word I was displaying in memory, I had to understand endianness. Since I compiled for 32-bit, my program is functioning on 32-bit words. These words' bytes are written into memory "backwards". The words themselves are still stored in "normal" order. For example 0x0A290028 0x0A293928 prints (NULL)LF(9)LF. The bytes are backwards but the words are not. Sys_write, since it just uses a void *buf and isn't aware of strings, just reads bytes in endian-order from the buffer and spits them out.
What I was able to do was simply left-shift my single-digit product, for example, 0x00000034 by 8-bits. This left me with 0x00003400. To that, I could add 0x000A0000. This would result in 0x000A3400, and the number "4" being printed followed by a newline.
So, the new procedure looks like this:
multprint:
mov eax, sys_write ;4
mov ebx, stdout ;1
mov ecx, resultstr
mov edx, resultstrLen
dec edx
int 0x80
pop eax ;multiplican't
pop ebx ;multiplicand
mul ebx
add eax, '0'
shl eax, 8 ;make room for () and LF
add eax, 0x0A290028
push eax
mov ecx, esp
;mov [num], eax ;use these two lines if I don't want to use the stack
;mov ecx, num
mov eax, sys_write
mov ebx, stdout
mov edx, 4
int 0x80

How to use LEA with brackets?

I have this ASM function, that takes 4 arguments. The first two arguments are passed by value, the last two are passed by reference. So I'm using this:
PUSH EBP
MOV EBP, ESP
SUB ESP, 20
MOV EAX, [EBP+8]
MOV EBX, [EBP+12]
LEA ECX, [EBP+16]
LEA EDX, [EBP+20]
PUSH EDX
PUSH ECX
PUSH EBX
PUSH EAX
CALL Function
LEAVE
RETN 20
(Note that I'm using this code inside C++ using the VC's __asm statement).
But while searching about the use of LEA to pass arguments as pointers (aka by reference) I found:
[...] Note there are NO brackets in this line. Putting the square brackets around
something means "get the contents of", so you were effectively defeating the
LEA op. [...]
I want to pass both arguments at EBP+16 and EBP+20 by reference, but how can I do that if can't use brackets? If I don't put them, then the compiler throws an error (C2424).
Thanks in advance.
Try
MOV ECX, EBP+16
MOV EDX, EBP+20
lea has one type of operation, so use the syntax that makes your compiler glad (for example, fasm requires brackets always, while masm requires its absence around label arguments).
Note, that:
Windows calling conventions require you to preserve ebx during calls;
I doubt taking addresses of 3rd and 4th arguments was really your intention;
You can use push dword [ebp+xxx] instruction.

Resources