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
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!
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
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
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.
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