I used to think when using a integer as a constant, I always need to append a "$" sign, unless the number is interpreted as an address, so I had:
.data
a=$2
.equ b,3
.text
.globl _start
_start:
movl $a,%ebx
movl $b,%ecx
movl $1,%eax
int $0x80
This code is compiled into:
0: bb 00 00 00 00 mov $0x0,%ebx
5: b9 03 00 00 00 mov $0x3,%ecx
a: b8 01 00 00 00 mov $0x1,%eax
f: cd 80 int $0x80
I don't know how as compiler deal with a=$2, why $2 is compiled into 0x0?
Then I removed "$",
.data
a=2
.equ b,3
.text
.globl _start
_start:
movl $a,%ebx
movl $b,%ecx
movl $1,%eax
int $0x80
This time, the compiled code is correct:
0: bb 02 00 00 00 mov $0x2,%ebx
5: b9 03 00 00 00 mov $0x3,%ecx
a: b8 01 00 00 00 mov $0x1,%eax
f: cd 80 int $0x80
So my question is, what's the difference between '2' and '$2' here?
Related
Sorry, if question is too naive but I didn't get why my disassembly don't have that hello world string, or how it's loading that string into memory while executing.
section .data
msg: db "Hello, World!",0xa
len: equ $-msg
global _start
section .text
_start:
mov rax,0x01
mov rdi,1
mov rsi,msg
mov rdx,len
syscall
mov rax, 0x3c
mov rdi, 0
syscall
Objdump -d
a.out: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <_start>:
401000: b8 01 00 00 00 mov $0x1,%eax
401005: bf 01 00 00 00 mov $0x1,%edi
40100a: 48 be 00 20 40 00 00 movabs $0x402000,%rsi
401011: 00 00 00
401014: ba 0e 00 00 00 mov $0xe,%edx
401019: 0f 05 syscall
40101b: b8 3c 00 00 00 mov $0x3c,%eax
401020: bf 00 00 00 00 mov $0x0,%edi
401025: 0f 05 syscall
If it is moving address of msg string into $rsi then how it decide that address even before executing is this all done by linker? if yes can you give little bit insights?I know each program have there own virtual memory, but is that linker while linking put that string somewhere in memory?
I'm using ubuntu64 + gas
I use AT&T assembly, I tried to assign al register with a 'e', and compile it into 32 bit program
$ cat c2.s
.code32
.globl _start
_start:
movb 'e',%al # Problem here!!!!
mov $1,%eax
mov $0,%ebx
int $0x80
$ as -g c2.s -o c2.o && ld c2.o -o c2
$ c2
Segmentation fault(SIGSEGV)
I used gdb to debug c2, and found it crash at movb 'e',%al. So weird, how could a "movb" crash?
Then I switched my syntax to use intel same content:
$ cat b2.s
.intel_syntax noprefix
.code32
.section .text
.global _start
_start:
mov al,'e'
mov eax,1
mov ebx,0
int 0x80
$ as -g b2.s -o b2.o && ld b2.o -o b2
$ b2
This time, no problem. But why, is my usage of AT&T assembly has something wrong?
Isn't that interesting. AS produces this object code for AT&T syntax
400078: a0 65 00 00 00 b8 01 movabs 0x1b800000065,%al
40007f: 00 00
400081: 00 bb 00 00 00 00 add %bh,0x0(%rbx)
400087: cd 80 int $0x80
obviously, location 0x1b800000065 is not mapped, but Intel;
400078: b0 65 mov $0x65,%al
40007a: b8 01 00 00 00 mov $0x1,%eax
40007f: bb 00 00 00 00 mov $0x0,%ebx
400084: cd 80 int $0x80
remove .code32 from AT&T and you get this.
400078: 8a 04 25 65 00 00 00 mov 0x65,%al
40007f: b8 01 00 00 00 mov $0x1,%eax
400084: bb 00 00 00 00 mov $0x0,%ebx
400089: cd 80 int $0x80
Notice how it wants to move the contents of memory location 0x64 into AL.
movb $'e',%al
fixes that problem. In any event, developing 32 bit code on a 64 bit system will probably give you grief at some point in time, especially when you start dealing with stack.
The disassembly of nanosleep in libc-2.7.so on 64-bit Linux looks like this:
Disassembly of section .text:
00000000000bd460 <__nanosleep>:
cmpl $0x0,__libc_multiple_threads
jne 10
00000000000bd469 <__nanosleep_nocancel>:
mov $0x23,%eax
syscal
10: cmp $0xfffffffffffff001,%rax
jae 40
retq
sub $0x8,%rsp
callq __libc_enable_asynccancel
mov %rax,(%rsp)
mov $0x23,%eax
syscal
mov (%rsp),%rdi
mov %rax,%rdx
callq __libc_disable_asynccancel
mov %rdx,%rax
add $0x8,%rsp
40: cmp $0xfffffffffffff001,%rax
jae 40
retq
mov _DYNAMIC+0x2e0,%rcx
neg %eax
mov %eax,%fs:(%rcx)
or $0xffffffffffffffff,%rax
retq
Near the bottom of this assembly code, there is this polling loop:
40: cmp $0xfffffffffffff001,%rax
jae 40
How would the value of rax change while this loop is executing? Wouldn't it either loop forever or not at all? What is this loop meant to accomplish?
I suspect this is related to the syscall instruction since the return value of syscall is put into register rax, but I'm not sure how this is related exactly. The way the code is written makes it look like syscall doesn't block and the value in rax changes spontaneously but that doesn't seem right.
I'm interested to know what's going on here.
I don't see these spin loops.
Here's what I get from objdump -d /lib/x86_64-linux-gnu/libc.so.6, with what you show as loops highlighted with ** and the address they jump to with ->.
00000000000c0f10 <__nanosleep>:
c0f10: 83 3d 5d 31 30 00 00 cmpl $0x0,0x30315d(%rip) # 3c4074 <argp_program_version_hook+0x1cc>
c0f17: 75 10 jne c0f29 <__nanosleep+0x19>
c0f19: b8 23 00 00 00 mov $0x23,%eax
c0f1e: 0f 05 syscall
c0f20: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
** c0f26: 73 31 jae c0f59 <__nanosleep+0x49>
c0f28: c3 retq
c0f29: 48 83 ec 08 sub $0x8,%rsp
c0f2d: e8 3e 72 04 00 callq 108170 <pthread_setcanceltype+0x80>
c0f32: 48 89 04 24 mov %rax,(%rsp)
c0f36: b8 23 00 00 00 mov $0x23,%eax
c0f3b: 0f 05 syscall
c0f3d: 48 8b 3c 24 mov (%rsp),%rdi
c0f41: 48 89 c2 mov %rax,%rdx
c0f44: e8 87 72 04 00 callq 1081d0 <pthread_setcanceltype+0xe0>
c0f49: 48 89 d0 mov %rdx,%rax
c0f4c: 48 83 c4 08 add $0x8,%rsp
c0f50: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
** c0f56: 73 01 jae c0f59 <__nanosleep+0x49>
c0f58: c3 retq
-> c0f59: 48 8b 0d 08 cf 2f 00 mov 0x2fcf08(%rip),%rcx # 3bde68 <_IO_file_jumps+0x7c8>
c0f60: f7 d8 neg %eax
c0f62: 64 89 01 mov %eax,%fs:(%rcx)
c0f65: 48 83 c8 ff or $0xffffffffffffffff,%rax
c0f69: c3 retq
c0f6a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
The rest of the code is similar. Maybe it's an issue with the disassembly?
I've been reading and studying assembly code. Code is below
Disassembly of section .text:
08048510 <main>:
8048510: 8d 4c 24 04 lea 0x4(%esp),%ecx
8048514: 83 e4 f0 and $0xfffffff0,%esp
8048517: ff 71 fc pushl -0x4(%ecx)
804851a: 55 push %ebp
804851b: 89 e5 mov %esp,%ebp
804851d: 51 push %ecx
804851e: 83 ec 08 sub $0x8,%esp
8048521: 68 e0 93 04 08 push $0x80493e0
8048526: 68 c0 93 04 08 push $0x80493c0
804852b: 68 c9 93 04 08 push $0x80493c9
8048530: e8 7a 07 00 00 call 8048caf <eos_printf>
8048535: c7 04 24 d6 93 04 08 movl $0x80493d6,(%esp)
804853c: e8 6e 07 00 00 call 8048caf <eos_printf>
8048541: a1 38 c0 04 08 mov 0x804c038,%eax
8048546: bc 00 00 00 00 mov $0x0,%esp
804854b: ff e0 jmp *%eax
804854d: 8b 4d fc mov -0x4(%ebp),%ecx
8048550: 31 c0 xor %eax,%eax
8048552: c7 05 34 c0 04 08 00 movl $0x0,0x804c034
8048559: 00 00 00
804855c: c9 leave
804855d: 8d 61 fc lea -0x4(%ecx),%esp
8048560: c3 ret
Disassembly of section .data:
0804c030 <_irq_mask>:
804c030: ff (bad)
804c031: ff (bad)
804c032: ff (bad)
804c033: ff 01 incl (%ecx)
0804c034 <_eflags>:
804c034: 01 00 add %eax,(%eax)
...
0804c038 <_vector>:
804c038: 1d 8d 04 08 1d sbb $0x1d08048d,%eax
804c03d: 8d 04 08 lea (%eax,%ecx,1),%eax
804c040: 1d 8d 04 08 37 sbb $0x3708048d,%eax
804c045: 8d 04 08 lea (%eax,%ecx,1),%eax
At 0x8048541, EAX register is set to 0x804c038
At 0x804854b, process jump to the address pointed by EAX register
At 0x804c048, the instruction is < sbb $0x1d08048d, %eax>
By the instruction manual, sbb is stand for dest = dest - (src+carry flag). So we can replace 0x804c048 instruction to %eax = $eax - ($0x1d08048d + carry flag).
Then.... at that time, what value is set to carry flag value?
I didn't find any carry flag setting instruction previous to the 0x804c048 line. Is the carry flag is initially set to 0?
And the second question is, at 0x804854b, process jump to *%eax value. After that, how the process return to main function? there is nothing return instruction in _vector section.
I'll be glad to your help. Thanks.
Oh........ #MarkPlotnick You are God to me...... I was totally trapped in the < sbb $0x1d08048d, %eax >.
In the assembly source code, _vector array and _os_reset_handler function is defined as below.
.data
.global _vector
_vector:
.long _os_reset_handler
.long _os_reset_handler
.long _os_reset_handler
.long _os_irq_handler
.text
.global _os_reset_handler
_os_reset_handler:
_CLI
lea _os_init_stack_end, %esp
call _os_initialization
jmp _os_reset_handler
-----------------------
_CLI is defined in another c header file as macro
#define _CLI \
movl $0, _eflags;
I was consistently wondering why _vector array is not contain _os_reset_handler address. I read the disassembled code again and found that the objdump misaligned the hexcode at _vector data. "0x1d (address at 0x804c03c)" didn't go to new line, so it interpreted to irrelevant assembly code. (I'm very unhappy. I didn't do any other work to catch this problem for 10 hours...)
Anyway. At the address 0x8048d1d, there is _os_reset_handler function.
08048d1d <_os_reset_handler>:
8048d1d: c7 05 34 c0 04 08 00 movl $0x0,0x804c034
8048d24: 00 00 00
8048d27: 8d 25 48 d0 04 08 lea 0x804d048,%esp
8048d2d: e8 07 01 00 00 call 8048e39 <_os_initialization>
8048d32: e9 e6 ff ff ff jmp 8048d1d <_os_reset_handler>
No more questions. Thanks.
I want to convert this assembly program to shellcode.
This program just creates a file , my purpose is how I should convert assembly to shellcode when I using extern command in it
My assmbly code is :
extern _fopen,_fclose
global main
section .text
main:
xor r10,r10
push r10
mov r13, 0x6277
push r13
mov rsi,rsp
push r10
mov r13, 0x726964656b616d
push r13
mov rdi,rsp
call _fopen
mov r14, rax
mov rdi, r14
call _fclose
mov rax, 0x2000001 ; exit
mov rdi, 0
syscall
I used this command to compile it :
nasm -f macho64 test2.asm
ld -o test -e main test2.o -lSystem
and I used objdum -d test to create shellcode
...........$ objdump -d test
test: file format mach-o-x86-64
Disassembly of section .text:
0000000000001f93 <main>:
1f93: 4d 31 d2 xor %r10,%r10
1f96: 41 52 push %r10
1f98: 41 bd 77 62 00 00 mov $0x6277,%r13d
1f9e: 41 55 push %r13
1fa0: 48 89 e6 mov %rsp,%rsi
1fa3: 41 52 push %r10
1fa5: 49 bd 6d 61 6b 65 64 movabs $0x726964656b616d,%r13
1fac: 69 72 00
1faf: 41 55 push %r13
1fb1: 48 89 e7 mov %rsp,%rdi
1fb4: e8 1d 00 00 00 callq 1fd6 <_fopen$stub>
1fb9: 49 89 c6 mov %rax,%r14
1fbc: 4c 89 f7 mov %r14,%rdi
1fbf: e8 0c 00 00 00 callq 1fd0 <_fclose$stub>
1fc4: b8 01 00 00 02 mov $0x2000001,%eax
1fc9: bf 00 00 00 00 mov $0x0,%edi
1fce: 0f 05 syscall
Disassembly of section __TEXT.__stubs:
0000000000001fd0 <_fclose$stub>:
1fd0: ff 25 3a 00 00 00 jmpq *0x3a(%rip) # 2010 <_fclose$stub>
0000000000001fd6 <_fopen$stub>:
1fd6: ff 25 3c 00 00 00 jmpq *0x3c(%rip) # 2018 <_fopen$stub>
Disassembly of section __TEXT.__stub_helper:
0000000000001fdc <__TEXT.__stub_helper>:
1fdc: 68 00 00 00 00 pushq $0x0
1fe1: e9 0a 00 00 00 jmpq 1ff0 <_fopen$stub+0x1a>
1fe6: 68 0e 00 00 00 pushq $0xe
1feb: e9 00 00 00 00 jmpq 1ff0 <_fopen$stub+0x1a>
1ff0: 4c 8d 1d 11 00 00 00 lea 0x11(%rip),%r11 # 2008 <>
1ff7: 41 53 push %r11
1ff9: ff 25 01 00 00 00 jmpq *0x1(%rip) # 2000 <>
1fff: 90 nop
In normal condition i used opcode in "main" section and conveted it to shellcode and used this code to run it
#include <sys/mman.h>
#include <inttypes.h>
#include <unistd.h>
char code[] = "\x4d\x31\xd2\x41\x52\x41...For Example ...";
int main()
{
int (*ret)() = (int (*)())code;
void *page = (void *)((uintptr_t)code & ~(getpagesize() - 1));
mprotect(page, sizeof code, PROT_EXEC);
ret();
return 0;
}
but in this case it dosen't work and I know I should used other sections opcodes mentioned below the main section , but I don't know the arrange of calling them.
Please guide me.
your assmbly code is written in x64 mode,are you sure that the loader-'main' program is also compile to x64?
This one I've tried with an Macho64-Binary
for i in $( otool -t test2.o | cut -d ' ' -f 2- | grep ' '); do echo -n '\\x'$i; done; echo