I can't find in the documentation the exactly implementation of label(not in modern assemblies) To where does it points? I had in my mind that's the address of first instruction,for example:
global _start
section .text
_start:
call exit
exit:
mov eax,1
mov ebx,20
int 0x80
section .data
list:
dd exit
the list shouldn't be same address as exit that's the first seen by label?
I want to do something like this:
mov eax,list
call eax
it's a try to make function-pointer-like in assembly.
The label is just a mnemonic referring to the address of the first instruction AFTER the label. e.g. exit: points to wherever the mov eax,1 physically exists in ram.
Related
In the following code after calling 'access' system call, 0xfffffffe is present in EAX. While in case of success, 'access' system call returns 0. Here I am trying to access the memory which is part of the data section. Then why 'access' is returning 0xfffffffe ?
global _start
section .text
_start:
mov eax, 0x21 ; Access system call
mov ebx, message
mov ecx, 0 ; F_OK
int 0x80
section .data
message:dd 0,0,0,0,0,0,0
I am following the below-mentioned paper.
http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf I am copy pasting the following lines from page number 7 and 8 of the paper. 'access' system call is preferred because
"the pathname pointer is the argument that will be used to do the
address validation. Since pathname is the first argument, it means that the ebx register will need to point to the address that needs to be validated."
And if we see in the following code author has used 'access' system call to validate EBX register. Following code is present on page number 8 of the paper.
mov ebx,0x50905090
xor ecx,ecx
mul ecx
or dx,0xfff
inc edx
pusha
lea ebx,[edx+0x4]
mov al,0x21
int 0x80
cmp al,0xf2
popa
jz 0x9
cmp [edx],ebx
jnz 0xe
cmp [edx+0x4],ebx
jnz 0xe
jmp edx
Here's my code:
section .data
digit db 0,10
section .text
global _start
_start:
call _printRAXDigit
mov rax, 60
mov rdx, 0
syscall
_printRAXDigit:
add rax, 48
mov [digit], al
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 2
syscall
ret
I have a question about the difference between [digit] and digit.
I have learned that labels (like digit in the code), represent the memory address of the data, and the operator "[]" acts like something to dereference the pointer, so it will load the value that the label points at to the destination.
For instance, mov rax, [digit] will throw 0 to the rax register because digit points at the first element of the data (in this case, the integer 0).
However, in my code, it works when I write mov [digit], al, which means "load the value stored in al to the memory address digit", but I have no idea why we should use "[]" in this case. The first argument of mov must be a destination (like a register or a memory address), so I think it should be mov digit, al rather than mov [digit], al. It doesn't make sense to me why we use a value to get the value from another place rather than use a memory address to get the value.
So that's all of my question. Please give me any response about where my thinking is wrong or any correction about my concept of labels.
In NASM syntax (there are assemblers which use different notation, e.g. MASM/TASM use a different flavor of Intel syntax, and gas uses AT&T syntax) the following x86 instructions ...
mov esi, someAddress
mov esi, [someAddress]
mov [someAddress], esi
mov someAddress, esi ; see below
... (would) have the following meaning:
mov esi, someAddress
Write the number that represents the address where someAddress is stored to the register esi. So if someAddress is stored at address 1234 the value 1234 is written to esi.
mov esi, [someAddress]
Write the content of the memory to esi. So if someAddress is stored at address 1234 and the value stored at address 1234 is 5678 the value 5678 is written to esi.
You might also say: The value of the variable someAddress (a variable normally is nothing but the content of the memory at a certain address) is written to the esi register.
mov [someAddress], esi
Write the content of esi to the memory at address someAddress.
You might also say: Write the value of esi to the variable someAddress.
mov someAddress, esi
Would mean: Change the constant number which represents the address someAddress to esi.
So if someAddress is located at address 1234 and esi contains the value 5678 the instruction would mean:
Change the mathematical constant 1234 in a way that 1234 = 5678 after that change.
This is of course stupid because the mathematical constants 1234 and 5678 will never be equal. For this reason the x86 CPU has no such instruction.
(There are CPUs having similar instructions. On the SPARC CPUs for example instructions assigning a value to the zero register (which means: "assign a value to the constant zero") are used if you only want to have the instruction's side effects - like setting the flags - but you are not interested in the result itself.)
The tutorial I am following is for x86 and was written using 32-bit assembly, I'm trying to follow along while learning x64 assembly in the process. This has been going very well up until this lesson where I have the following simple program which simply tries to modify a single character in a string; it compiles fine but segfaults when ran.
section .text
global _start ; Declare global entry oint for ld
_start:
jmp short message ; Jump to where or message is at so we can do a call to push the address onto the stack
code:
xor rax, rax ; Clean up the registers
xor rbx, rbx
xor rcx, rcx
xor rdx, rdx
; Try to change the N to a space
pop rsi ; Get address from stack
mov al, 0x20 ; Load 0x20 into RAX
mov [rsi], al; Why segfault?
xor rax, rax; Clear again
; write(rdi, rsi, rdx) = write(file_descriptor, buffer, length)
mov al, 0x01 ; write the command for 64bit Syscall Write (0x01) into the lower 8 bits of RAX
mov rdi, rax ; First Paramter, RDI = 0x01 which is STDOUT, we move rax to ensure the upper 56 bits of RDI are zero
;pop rsi ; Second Parameter, RSI = Popped address of message from stack
mov dl, 25 ; Third Parameter, RDX = Length of message
syscall ; Call Write
; exit(rdi) = exit(return value)
xor rax, rax ; write returns # of bytes written in rax, need to clean it up again
add rax, 0x3C ; 64bit syscall exit is 0x3C
xor rdi, rdi ; Return value is in rdi (First parameter), zero it to return 0
syscall ; Call Exit
message:
call code ; Pushes the address of the string onto the stack
db 'AAAABBBNAAAAAAAABBBBBBBB',0x0A
This culprit is this line:
mov [rsi], al; Why segfault?
If I comment it out, then the program runs fine, outputting the message 'AAAABBBNAAAAAAAABBBBBBBB', why can't I modify the string?
The authors code is the following:
global _start
_start:
jmp short ender
starter:
pop ebx ;get the address of the string
xor eax, eax
mov al, 0x20
mov [ebx+7], al ;put a NULL where the N is in the string
mov al, 4 ;syscall write
mov bl, 1 ;stdout is 1
pop ecx ;get the address of the string from the stack
mov dl, 25 ;length of the string
int 0x80
xor eax, eax
mov al, 1 ;exit the shellcode
xor ebx,ebx
int 0x80
ender:
call starter
db 'AAAABBBNAAAAAAAABBBBBBBB'0x0A
And I've compiled that using:
nasm -f elf <infile> -o <outfile>
ld -m elf_i386 <infile> -o <outfile>
But even that causes a segfault, images on the page show it working properly and changing the N into a space, however I seem to be stuck in segfault land :( Google isn't really being helpful in this case, and so I turn to you stackoverflow, any pointers (no pun intended!) would be appreciated
I would assume it's because you're trying to access data that is in the .text section. Usually you're not allowed to write to code segment for security. Modifiable data should be in the .data section. (Or .bss if zero-initialized.)
For actual shellcode, where you don't want to use a separate section, see Segfault when writing to string allocated by db [assembly] for alternate workarounds.
Also I would never suggest using the side effects of call pushing the address after it to the stack to get a pointer to data following it, except for shellcode.
This is a common trick in shellcode (which must be position-independent); 32-bit mode needs a call to get EIP somehow. The call must have a backwards displacement to avoid 00 bytes in the machine code, so putting the call somewhere that creates a "return" address you specifically want saves an add or lea.
Even in 64-bit code where RIP-relative addressing is possible, jmp / call / pop is about as compact as jumping over the string for a RIP-relative LEA with a negative displacement.
Outside of the shellcode / constrained-machine-code use case, it's a terrible idea and you should just lea reg, [rel buf] like a normal person with the data in .data and the code in .text. (Or read-only data in .rodata.) This way you're not trying execute code next to data, or put data next to code.
(Code-injection vulnerabilities that allow shellcode already imply the existence of a page with write and exec permission, but normal processes from modern toolchains don't have any W+X pages unless you do something to make that happen. W^X is a good security feature for this reason, so normal toolchain security features / defaults must be defeated to test shellcode.)
I am trying to understand how to use pointer in assembly. By reading some tutorials around internel,I think had undertantood some concepts. But when I'II go to try it,it did work. Below some attempts to translate C to ASM.
C
const char *s = "foo";
unsigned z = *(unsigned*)s;
if(!(z & 0xFF))
do_something();
if(!(z & 0xFFFF))
do_b_something();
(here's not full code,but it's a word-check,thefore,there is more two stmts which checks 0xFF0000,0xF000000 respectivily.
ASM:
mov ebp,str
mov eax,ebp
mov eax,[eax]
and eax,0xFF
cmp eax,0
je etc
mov eax,[eax]
and eax,0xFFFF
cmp eax,0
je etc
It returns a seg fault.
And the try:
mov eax,dword ptr [eax]
that's generated by gcc compiler and you can see it in some other assemblies code,returns
invalid symbol
on FASM assembler. It isn't really supported by the FASM or am I missing something?
I think this is what you are attempting to do:
mov ebp,str
mov eax,ebp
mov ebx,[eax]
test ebx,0xFF
jz low_byte_empty
do_something:
; some code here...
low_byte_empty:
test ebx,0xFFFF
jz low_word_empty
do_b_something:
; some code here.
low_word_empty:
Explanation:
First, as JasonD already mentions in his answer, you are loading a pointer to eax, then doing a logical and to it, then you are using the result still in eax to address memory (some memory offset in the range 0x0 ... 0xFF).
So what goes wrong in your code: you can't keep in the same register both a pointer to a memory address and a value at the same time. So I chose to load the value from [eax] to ebx, you can also use some other 32-bit general register (ecx, edx, esi, edi) according to your needs.
Then, you don't need to use cmp to check if a register is empty, because all cmp does is that it does the subtraction and sets the flags. But ZF (zero flag) is already set by and, so cmp is absolutely unnecessary here. Then, as cmp is not needed here and we do not need the result either, we only want to update the flags, it's better to use test. test does exactly the same logical AND as and does, the only difference being that test does not store the result, it only updates the flags.
It's not at all clear what you're trying to do in the original code - doesn't look right.
However this:
mov eax,[eax]
and eax,0xFF
cmp eax,0
je etc
mov eax,[eax]
Isn't going to work. You're overwriting the contents of EAX with the value stored at the address in EAX, manipulating that value, and then trying to reload it after the branch without restoring the original pointer.
Following variant is simpler, smaller, faster and uses only one register.
mov eax, str
mov eax,[eax]
test al, al
jz low_byte_empty
do_something_byte:
; some code here...
low_byte_empty:
test ah, ah
jz low_word_empty
do_something_word:
; some code here
low_word_empty:
Trying my hand at Linux assembly and I'm running into the following problem. I'm just starting out so my program is a relatively simple one derived from some examples I found over at linuxassembly. It takes the first argument passed to the command line and prints it out. Here is what I have so far...
section .bss
test_string: resb 3
section .text
global _start
_start:
pop ebx ;argument number
pop ebx ;program name
pop ebx ;first argument
mov [test_string],ebx
mov eax,4
mov ebx,1
mov ecx,test_string
mov edx,3
int 80h
mov eax,1
mov ebx,0
int 80h
I know that this is poorly written, but since I'm new to this, I'm just looking to better understand how assembly instructions/variables work before I move on. I assemble and link using...
nasm -f elf first.asm
ld -m elf_i386 -s -o first first.o
Then I run using..
./first one two
I was thinking that it would print out one but it prints out gibberish like Y*&. What am I doing wrong? Is my test_string the wrong type?
You're trying to print out the value of the pointer to the string instead of printing the string. You want to do this instead.
pop ebx ;argument number
pop ebx ;program name
pop ebx ;pointer to the first argument
mov ecx,ebx ;load the pointer into ecx for the write system call
mov eax,4 ;load the other registers for the write system call
mov ebx,1
mov edx,3
int 80h
mov eax,1
mov ebx,0
int 80h