Why does osx 64-bit asm syscall segfault - macos

I'm trying to write an x86-64 hello world in assembly on OSX, but whenever I make a syscall to write, it's segfaulting. I've tried the equivalent syscall via Gnu C inline assembly and it works, so I'm thoroughly confused:
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main:
.cfi_startproc
movq 0x2000004, %rax
movq 1, %rdi
leaq _hi(%rip), %rsi
movq 12, %rdx
syscall
xor %rax, %rax
ret
.cfi_endproc
.section __DATA,__data
.globl _hi
_hi:
.asciz "Hello world\n"
This is based off of the following Gnu C, which works:
#include <string.h>
int main() {
char *hw = "Hello World\n";
unsigned long long result;
asm volatile ("movq %1, %%rax\n"
"movq %2, %%rdi\n"
"movq %3, %%rsi\n"
"movq %4, %%rdx\n"
"syscall\n"
: "=rax" (result)
: "Z" (0x2000004),
"Z" (1),
"r" (hw),
"Z" (12)
: "rax", "rdi", "rsi", "rdx");
}
The C block when compiled generates the following asm:
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main: ## #main
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
leaq L_.str(%rip), %rcx
movq %rcx, -8(%rbp)
## InlineAsm Start
movq $33554436, %rax
movq $1, %rdi
movq %rcx, %rsi
movq $12, %rdx
syscall
## InlineAsm End
movq %rcx, -16(%rbp)
xorl %eax, %eax
popq %rbp
ret
.cfi_endproc
.section __TEXT,__cstring,cstring_literals
L_.str: ## #.str
.asciz "Hello World\n"

Your problem is on these few lines:
movq 0x2000004, %rax
movq 1, %rdi
leaq _hi(%rip), %rsi
movq 12, %rdx
Be aware that with at&t syntax that if you want to use constants you MUST prefix them with a $ (dollar sign) otherwise you are referencing memory addresses. Without a $ sign your value is an immediate indirect address.
For instance:
movq 0x2000004, %rax
attempts to move the quadword from memory address 0x2000004 and place it in %rax.
You probably just have to modify your code to look like:
movq $0x2000004, %rax
movq $1, %rdi
leaq _hi(%rip), %rsi
movq $12, %rdx
Notice that I have added a dollar sign to the beginning of each constant.

Here is a simple 64-bit "Hello World" (or Hello StackOverflow) in this case. It should build on OSX. Give it a try:
section .data
string1 db 0xa, " Hello StackOverflow!!!", 0xa, 0xa, 0
len equ $ - string1
section .text
global _start
_start:
; write string to stdout
mov rax, 1 ; set write to command
mov rsi, string1 ; string1 to source index
mov rdi, rax ; set destination index to 1 (stdout) already in rax
mov rdx, len ; set length in rdx
syscall ; call kernel
; exit
xor rdi,rdi ; zero rdi (rdi hold return value)
mov rax, 0x3c ; set syscall number to 60 (0x3c hex)
syscall ; call kernel
; **Compile/Output**
;
; $ nasm -felf64 -o hello-stack_64.o hello-stack_64.asm
; $ ld -o hello-stack_64 hello-stack_64.o
; $ ./hello-stack_64
;
; Hello StackOverflow!!!

Related

Macos get pointer being realloc'd was not allocated error in gas assembly

I am writing a simple compiler for gas assembly on macos which generated this assembly:
.section __TEXT, __text
.globl _print
_print:
pushq %rbp
movq %rsp, %rbp
movb $0, %al
call _printf
xorl %eax, %eax
popq %rbp
retq
str0:
.asciz ""
.globl _main
_main:
pushq %rbp
movq %rsp, %rbp
leaq str0(%rip), %rax
movq %rax, 0(%rbp)
movq ___stdinp#GOTPCREL(%rip), %rax
movq $0, 1(%rbp)
movq (%rax), %rdx
leaq 2(%rbp), %rdi
leaq 1(%rbp), %rsi
callq _getline
movq 0(%rbp), %rsi
movq 0(%rbp), %rdi
callq _print
xorl %eax, %eax
popq %rbp
retq
.subsections_via_symbols
And run it using:
gcc -c main.s -o main.o
gcc main.o -o main
./main
But whenever I use ./main I get: main(13366,0x1132f8e00) malloc: *** error for object 0x5f00000000000000: pointer being realloc'd was not allocated main(13366,0x1132f8e00) malloc: *** set a breakpoint in malloc_error_break to debug
I don't know what I could do to fix this and have no idea what is going wrong so any help would be appreciated!

String hidden inside .s assembly source code

I've been really stuck with a challenge at our "hacking" class. A string (password) needs to be found, and the only file provided is a .s assembly file.
Based on my extremely small knowledge of assembly, I compiled the file with gcc -S Program.s, with an a.outexecutable file being output. I tried to run the file with ./a.out in Mac Terminal, to no success — after pressing enter at the end of the command, cursor just jumps to a new line with nothing in stdout, and echo $? returns 0.
At the end of the assembly file, there's a .asciz "zja4heit5k7", so I figured it might be the correct string, but to no success.
I would be eternally thankful if anyone can provide any steps to help me solve the problem.
Program.s
.
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 13
.globl _r
.p2align 4, 0x90
_r: ## #r
.cfi_startproc
## BB#0:
pushq %rbp
Lcfi0:
.cfi_def_cfa_offset 16
Lcfi1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Lcfi2:
.cfi_def_cfa_register %rbp
movq %rdi, -8(%rbp)
movl $0, -12(%rbp)
movl $0, -12(%rbp)
LBB0_1: ## =>This Inner Loop Header: Depth=1
xorl %eax, %eax
movb %al, %cl
cmpq $0, -8(%rbp)
movb %cl, -13(%rbp) ## 1-byte Spill
je LBB0_3
## BB#2: ## in Loop: Header=BB0_1 Depth=1
movq -8(%rbp), %rax
movslq -12(%rbp), %rcx
movsbl (%rax,%rcx), %edx
cmpl $0, %edx
setne %sil
movb %sil, -13(%rbp) ## 1-byte Spill
LBB0_3: ## in Loop: Header=BB0_1 Depth=1
movb -13(%rbp), %al ## 1-byte Reload
testb $1, %al
jne LBB0_4
jmp LBB0_9
LBB0_4: ## in Loop: Header=BB0_1 Depth=1
movq -8(%rbp), %rax
movslq -12(%rbp), %rcx
movsbl (%rax,%rcx), %edx
cmpl $97, %edx
jl LBB0_7
## BB#5: ## in Loop: Header=BB0_1 Depth=1
movq -8(%rbp), %rax
movslq -12(%rbp), %rcx
movsbl (%rax,%rcx), %edx
addl $13, %edx
cmpl $122, %edx
jg LBB0_7
## BB#6: ## in Loop: Header=BB0_1 Depth=1
movq -8(%rbp), %rax
movslq -12(%rbp), %rcx
movsbl (%rax,%rcx), %edx
addl $13, %edx
movb %dl, %sil
movq -8(%rbp), %rax
movslq -12(%rbp), %rcx
movb %sil, (%rax,%rcx)
LBB0_7: ## in Loop: Header=BB0_1 Depth=1
jmp LBB0_8
LBB0_8: ## in Loop: Header=BB0_1 Depth=1
movl -12(%rbp), %eax
addl $1, %eax
movl %eax, -12(%rbp)
jmp LBB0_1
LBB0_9:
popq %rbp
retq
.cfi_endproc
.globl _main
.p2align 4, 0x90
_main: ## #main
.cfi_startproc
## BB#0:
pushq %rbp
Lcfi3:
.cfi_def_cfa_offset 16
Lcfi4:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Lcfi5:
.cfi_def_cfa_register %rbp
subq $16, %rsp
leaq _an(%rip), %rdi
movl $0, -4(%rbp)
callq _r
xorl %eax, %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
.section __DATA,__data
.globl _an ## #an
_an:
.asciz "zja4heit5k7"
.subsections_via_symbols

Bus Error in OS X x86_64 in Execve call

I am trying to mimic Security Tubes execve tutorial (http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html) in 64bit Asm. I am not sure where the bus error is coming from. I stepped through through the app in GDB but the error didn't occur until after I was out of frame. If anyone knows what is happening, I would love to hear from you.
.section __DATA,__data
.section __TEXT,__text
.globl _start
_start:
xor %rax, %rax
push %rax
movabsq $0x68732f6e69622f2f, %rdi
push %rax
mov %rsp, %rsi
push %rdi
mov %rsp, %rdx
mov $0x2000059, %rax
syscall
The following should work better but I don't have osx to test:
.globl _start
_start:
xor %edx, %edx ; NULL for env
movabsq $0x0068732f6e69622f, %rax ; /bin/sh<0>
push %rax
mov %rsp, %rdi ; filename
push %rdx ; NULL for argv terminator
push %rdi ; argv[0] = filename
mov %rsp, %rsi ; argv
mov $0x200003b, %eax ; I think 59 is decimal
syscall

Does text from cli argument need to be formatted in assembly? x86_64

In this application, I am trying to print a character passed through command line arguments (Intel Mac OS X). EX:
./thisapp q
Desired output:
q
However, it prints out a bunch of symbols and nonsense, but what is interesting is that different characters produce different gibberish. This leads me to believe that I am close. Does this need to be "formatted" for it to produce the correct letter?
.section __DATA,__data
.section __TEXT,__text
.globl _start
_start:
push %rbp
mov %rsp,%rbp
lea -32(%rsp), %r10 #<--- should be argv
add $8, %r10 #<--- should be argv[1]
movl $0x2000004, %eax
mov $1, %edi
mov %r10, %rsi
mov $16, %edx
syscall
xor %rax, %rax
mov $0x2000001, %eax
mov $0, %edi
syscall
Thanks to everyone's help I was able to get this working. Here is the code in the event someone else is looking to do this:
.section __DATA,__data
.section __TEXT,__text
.globl _start
_start:
push %rbp
mov %rsp,%rbp
lea 24(%rbp), %r10
movl $0x2000004, %eax
mov $1, %edi
mov (%r10), %rsi
mov $1, %edx
syscall
xor %rax, %rax
mov $0x2000001, %eax
mov $0, %edi
syscall
I would like to point out that this will only print 1 element (letter/number). I still need to figure out how to get the length(size?) of whatever was passed.

Where does C function's TAN return its value in 64-bit GCC?

I am linking my assembly function with GCC on linux 64-bit. The library I use is TAN from math.h. I link it with;
gcc -s prog.o -o prog -lm
The program works but the return value is 0.0000000 (for 3.4 radian). I use extrn in my assembly code;
extrn tan
extrn printf
I use xmm0 to pass the argument (in radian) to the TAN function. Now I am not sure which register is used to return the value from TAN. Is it xmm0, st0 or in RAX? I can't find a decent reference on this.
For my gcc, it's xmm0.
Here's a C program:
#include <stdio.h>
#include <math.h>
int main () {
double x = tan(M_PI/4.0);
// RESULT: x=1.000000
printf ("x=%f\n", x);
return 0;
}
And here's the corresponding "gcc -S":
.Ltext0:
.section .rodata
.LC1:
.string "x=%f\n"
.text
.globl main
.type main, #function
main:
.LFB0:
.file 1 "x.cpp"
.loc 1 4 0
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
.LBB2:
.loc 1 6 0
movabsq $4607182418800017407, %rax
movq %rax, -8(%rbp)
.loc 1 8 0
movq -8(%rbp), %rax
movq %rax, -24(%rbp)
movsd -24(%rbp), %xmm0
movl $.LC1, %edi
movl $1, %eax
call printf
.loc 1 9 0
movl $0, %eax
.LBE2:
.loc 1 10 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc

Resources