I am trying to implement atoi in assembly (the netwide assembler). I have verified that my approach is valid by inspecting the register values with a debugger. The problem is that the application will crash when it is about to exit. I am afraid my program is corrupting the stack somehow. I am linking against the GCC stdlib to allow the use of the printf function. I noticed it mutated the registers which caused unexpected behaviour (extensive iterations over values I did not recognize), however I solved this by storing the value of EAX inside EBX (not modified by printf) and then restoring the value after the function call. This is why I have been able to confirm that the program now behaves as it is supposed to by singlestepping through the algorithm AND confirm that the program crashes as it is about to terminate.
Here is the code:
global _main
extern _printf
section .data
_str: db "%d", 0
section .text
_main:
mov eax, 1234
mov ebx, 10
call _itoa
_terminate:
ret
_itoa:
test eax, eax
jz _terminate
xor edx, edx
div ebx
add edx, 30h
push eax
push edx
push _str
call _printf
add esp, 8
pop eax
jmp _itoa
And here is the stackdump:
Exception: STATUS_ACCESS_VIOLATION at eip=00402005
eax=00000000 ebx=00000000 ecx=20000038 edx=61185C40 esi=612A3A7C edi=0022CD84
ebp=0022ACF8 esp=0022AC20 program=C:\Cygwin\home\Benjamin\nasm\itoa.exe, pid 3556, thread main
cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023
Stack trace:
Frame Function Args
0022ACF8 00402005 (00000000, 0022CD84, 61007120, 00000000)
End of stack trace
EDIT: Please note that the stackdump really is not that relevant anymore as the program no longer crashes, it just displays an incorrect value.
I'm not familiar with your platform, but I would expect you need to restore the stack by popping off the pushed values after calling printf().
Since printf() doesn't know how many arguments will be passed, it can't restore the stack. Your code pushes arguments that are never popped off. So when your procedure returns, it gets the return address from the data that was pushed on the stack, which are not going to point to valid code. And that would be your access violation.
Related
I'm quite new to x86 assembly, and I'm trying to build off a hello world program. I'm trying to make a subroutine, that writes a single byte to stdout, but i've hit a problem.
The line mov ebx, [esp+1] (to load the byte passed, when I call the subroutine) causes a segfault.
I've tried xoring the ebx register with itself, to make sure that it is empty, to make sure, that it doesn't mess with the syscall
_start:
push 32h
call _writeByte
; This just jumps to an exit routine
jmp _exit
_writeByte:
; This line causes the problem. If I remove it the program works fine
mov ebx, [esp+1]
xor ebx, ebx
mov eax, 1
mov edi, 1
mov esi, tmp
mov edx, 1
syscall
ret
Why is the program segfaulting?
I'm in x64 mode, and like a bunch of people suggested in the comments using mov ebx, [rsp+8] worked, because esp are just the 4 lower bytes of the register. The stack is outside the low 4 GiB of virtual address space, so ESP != RSP and [esp] will be an unmapped page.
Note that x86-64 calling conventions pass the first few args in register, not on the stack, so you normally don't want to do this at all (unless your function has lots of args).
Im pretty new to assembly, and am trying my best to learn it. Im taking a course to learn it and they mentioned a very remedial Hello World example, that I decomplied.
original c file:
#include <stdio.h>
int main()
{
printf("Hello Students!");
return 0;
}
This was decompiled using the following command:
C:> objdump -d -Mintel HelloStudents.exe > disasm.txt
decompliation (assembly):
push ebp
mov ebp, esp
and esp, 0xfffffff0
sub esp, 0x10
call 401e80 <__main>
mov DWORD PTR [esp], 0x404000
call 4025f8 <_puts>
mov eax, 0x0
leave
ret
Im having issues mapping this output from the decompliation, to the original C file can someone help?
Thank you very much!
The technical term for decompiling assembly back into C is "turning hamburger back into cows". The generated assembly will not be a 1-to-1 translation of the source, and depending on the level of optimization may be radically different. You will get something functionally equivalent to the original source, but how closely it resembles that source in structure is heavily variable.
push ebp
mov ebp, esp
and esp, 0xfffffff0
sub esp, 0x10
This is all preamble, setting up the stack frame for the main function. It aligns the stack pointer (ESP) by 16 bytes then reserves another 16 bytes of space for outgoing function args.
call 401e80, <___main>
This function call to ___main is how MinGW arranges for libc initialization functions to run at the start of the program, making sure stdio buffers are allocated and stuff like that.
That's the end of the pre-amble; the part of the function that implements the C statements in your source starts with:
mov DWORD PTR [esp], 0x404000
This writes the address of the string literal "Hello Students!" onto the stack. Combined with the earliersub esp, 16, this is like apush` instruction. In this 32-bit calling convention, function args are passed on the stack, not registers, so that's where the compiler has to put them before function calls.
call 4025f8 <_puts>
This calls the puts function. The compiler realized that you weren't doing any format processing in the printf call and replaced it with the simpler puts call.
mov eax, 0x0
The return value of main is loaded into the eax register
leave
ret
Restore the previous EBP value, and tear down the stack frame, then exit the function. ret pops a return address off the stack, which can only work when ESP is pointing at the return address.
I'm learning assembly and I have a very basic loop here
segment .data
msg: db '%d',10,0
segment .text
global _asm_main
extern _printf
_asm_main:
push DWORD 5 ; Should loop 5 times
call dump_stack
add esp,4
ret
dump_stack:
push ebp
mov ebp, esp
mov ecx, 0
loop_start:
cmp ecx,[ebp+8] ;compare to the first param of dump_stack, (5)
jnle loop_end
push ecx ;push the value of my loop onto the stack
push DWORD msg ;push the msg (%d) should just print the value of my loop
call _printf
add esp, 8 ;clear the stack
inc ecx ;increment ecx
jmp loop_start ; go back to my loop start
loop_end:
mov esp, ebp
pop ebp
ret
My output looks something like this
program.exe
0
Just 0, then a newline. I tried to verify the loop was executing by moving my printf to the loop_end part, and it came out with ecx as 6, which is correct. So the loop is executing but printf is not... What am I doing wrong?
(Also, the function is called dump stack because it was initially supposed to dump the details of the stack, but that didn't work because of the same reason here)
And I am compiling with nasm -f win32 program.asm -o program.o
Then I have a cpp file that includes windows.h, and I compiled it with gcc -c include
and finally I linked them with gcc -o program program.o include.o
and I run program.exe
My guess is that printf() modifies ecx, it becomes >= [ebp+8] and your loop body executes only once. If that's the case, you need to read up on the calling conventions used in your compiler and manually preserve and restore the so-called volatile registers (which a called function can freely modify without restoring). Note that there may be several different calling conventions. Use the debugger!
I just noticed some strange assembly language code of empty main method.
//filename: main.c
void main()
{
}
disassembly:
push ebp
mov ebp,esp
sub esp,0C0h; why on the earth is it reserving 192 bytes?
push ebx
push esi
push edi ; good compiler. Its saving ebx, esi & edi values.
lea edi,[ebp-0C0h] ; line 1
mov ecx,30h ; line 2
mov eax,0CCCCCCCCh ; line 3
rep stos dword ptr es:[edi] ; line 4
xor eax,eax ; returning value 0. Code following this line is explanatory.
pop edi ; restoring the original states of edi,esi & ebx
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
why on the earth is it reserving 192 bytes for function where there aren't any variables
whats up with the four lines: line 1, line 2, line 3, line 4? what is it trying to do & WHY?
Greg already explained how the compiler generates code to diagnose uninitialized local variables, enabled by the /RTCu compile option. The 0xcccccccc value was chosen to be distinctive and easily recognized in the debugger. And to ensure the program bombs when an uninitialized pointer is dereferenced. And to ensure it terminates the program when it is executed as code. 0xcc is pretty ideal to do all of these jobs well, it is the instruction opcode for INT3.
The mysterious 192 bytes that are allocated in the stack frame are there to support the Edit + Continue feature, /ZI compile option. It allows you to edit the code while a breakpoint is active. And add local variables to a function those 192 bytes are available to provide the space for those added locals. Exceeding that space will make the IDE force you to rebuild your program.
Btw: this can cause a problem if you use recursion in your code. The debug build will bomb with this site's name a lot quicker. Not normally much of an issue, you debug with practical dataset sizes.
The four code lines you've indicated are the debug build clearing out the local variable space with the "clear" special value (0xCCCCCCCC).
I'm not sure why there are 192 bytes of seemingly dead space, but that might be VC++ building some guard space into your local variable area to try to detect stack smashing.
You will probably get a very different output if you switch from Debug to Release build.
The following code
int _main() {return 0;}
Compiled using the command:
gcc -s -nostdlib -nostartfiles 01-simple.c -o01-simple.exe
gcc version 4.4.1 (TDM-1 mingw32)
OllyDbg produced this output:
Can you explain what happens here?
Analysis so far:
// these two seems to be an idiom:
PUSH EBP // places EBP on stack
MOV EBP, ESP // overwrites EBP with ESP
MOV EAX, 0 // EAX = 0
LEAVE // == mov esp, ebp
// pop ebp
// according to
// http://en.wikipedia.org/wiki/X86_instruction_listings
What is the meaning of all this?
This creates a stack frame.
PUSH EBP
MOV EBP, ESP
In the calling convention being used, the return value is sent back via EAX (so the 0 is there because you wrote return 0; - try changing that to return 1; and see how that affects the code).
MOV EAX, 0
And this tells the processor to clean up the stack frame (it's the equivalent of MOV ESP, EBP followed by POP EBP which is the opposite of what was done when creating the stack frame):
LEAVE
The instructions sets up the stack frame upon the runtime loader entering the int _main() function,
PUSH EBP
MOV EBP, ESP
Stack frame is set up and to access the parameters if any were supplied would be offset from EBP + the size of the parameter (WORD, BYTE, LONG, etc).
Usually the EAX register is the normal register to return an exit status from the runtime environment to the operating system loader,
MOV EAX, 0
LEAVE
in other words, to say the program has exited successfully returning a 0 to the Operating system.
Where a return is used, the stack frame is restored upon runtime execution prior to handing control back to the Operating system.
POP EBP
The general consensus is, if an error has occurred, the value would be non-zero, and can be used both from batch files (harking back to the old DOS days) and unix scripts where it checks if the program ran successfully or not and proceed onwards depending on the nature of the batch file or script.
The 'MOV EAX,0' instruction is the body of your function. The header code is for setting up space for your code to run in.
The 'LEAVE' instruction returns your code to where it came. Even though you said no standard libraries, there is plenty of other code in there that the linker puts into place.