Unhandled exception at 0x00000005 in : 0xC0000005: Access violation reading location 0x00000005. when making a ret call - visual-studio-2010

My program is supposed to read an integer n from the user and then calculate all the divisors and if they are prime or not. I am using the Irvine 32 library. Now this is the weird part, when I enter in an even number my program executes as it is supposed to. When I enter in and odd number my program gets the error which is the title of this post.
My main Proc:
main PROC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This block displays greeting and newline;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov edx, OFFSET greeting
call Writestring
call Crlf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This block gets the integer from the user;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call GetInt
call Crlf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This block gets calculates the divsiors and prime divisors.;
; It then puts them in to an array to get ready to display. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call CalcDivisors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This block displays the results to the screen. ;
; in an n-1 by 3 table. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call Display_Results
exit
main ENDP
Now the Proc that has produces the error:
CalcDivisors PROC uses eax ebx ecx edx esi edi
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function calculates divisors then pushes them on to an array;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax,0
mov ecx,0
mov ebx,0
mov edx,0
mov esi,0
mov edi,0
mov ecx,n
sub ecx,1
mov eax,n
mov ebx,divisors
mov esi,OFFSET prime_arr
mov edi,OFFSET div_arr
push eax
Calc_Div:
call dumpregs
div ebx
call dumpregs
cmp edx,0
jz Calc_Prime_Div
inc ebx
mov edx,0
mov eax,n
loop Calc_Div
Calc_Prime_Div:
cmp ebx,2
jz Push_2_array
push ebx
push ecx
mov eax,0
mov eax,ebx
mov ecx,ebx
mov divisor_counter,ebx
sub ecx,2
mov ebx,0
mov ebx,prime_divisors
P1:
call dumpregs
div ebx
call dumpregs
cmp edx,0
jz Push_div_array
inc ebx
mov eax,divisor_counter
mov edx,0
loop P1
jmp Push_prime_array
Jump_above:
call dumpregs
loop Calc_div
call dumpregs
jmp foo
Push_prime_array:
pop ecx
pop ebx
mov [esi],ebx
mov eax,[esi]
call writedec
add esi,4
mov eax,0
mov eax,n
call dumpregs
inc ebx
call dumpregs
jmp jump_above
call dumpregs
Push_div_array:
pop ecx
pop ebx
mov [edi],ebx
mov eax,[edi]
call writedec
add edi,4
mov eax,0
mov eax,n
call dumpregs
inc ebx
jmp Jump_above
Push_2_array:
mov [esi],ebx
add esi,4
inc ebx
pop eax
jmp Jump_above
foo:
ret
CalcDivisors ENDP
Now the line that is giving me the exact error is the following:
foo:
ret
It is boggling my mind as to why it is crashing when I enter in an odd number for n and not crashing when n is even. Any suggestions?

It looks like you forget to pop some values from the stack. Check the number of push and pop instructions executed.

Related

when writing 64bit reverse shell in assembly got stuck at createrprocessA api

hello i am writing windows 64bit reverse shell in assembly and after gett connected to the targetmachine ip, i want to create process to spwan a shell, fistly i try to write startinfo struct for createprocess api, but after then i pass all the parameters to the function but it doesn't work, and here is full code https://pastebin.com/6Ft2jCMX
;STARTUPINFOA+PROCESS_INFORMATION
;----------------------------------
push byte 0x12 ; We want to place (18 * 4) = 72 null bytes onto the stack
pop rcx ; Set ECX for the loop
xor r11,r11
push_loop:
push r11 ; push a null dword
loop push_loop ; keep looping untill we have pushed enough nulls
lea r12,[rsp]
mov dl,104
xor rcx,rcx
mov [r12],dword edx
mov [r12+4],rcx
mov [r12+12],rcx
mov [r12+20],rcx
mov [r12+24],rcx
xor rdx,rdx
mov dl,255
inc rdx
mov [r12+0x3c],edx
mov [r12+0x50],r14 ; HANDLE hStdInput;
mov [r12+0x58],r14 ; HANDLE hStdOutput;
mov [r12+0x60],r14 ;HANDLE hStdError;
;createprocessA_calling
sub rsp, 0x70
push 'cmdA'
mov [rsp+3],byte dl
lea rdx,[rsp]
inc rcx
mov [rsp+32],rcx
xor rcx,rcx
xor r8,r8
mov [rsp+40],r8
mov [rsp+48],r8
mov [rsp+56],r8
lea r9,[r12]
mov [rsp+64],r9
lea r9,[r12+104]
mov [rsp+72],r9
xor r9,r9
call rbx ;createprocessA
so at last when i call the createprocessA it got stuck

Finding Smallest Number in List

My goal in this code is to find the smallest number in the list. I used bubble sort method in this case; unfortunately, the code is not giving me the smallest/minimum number. Please take a look, Thanks:
include irvine32.inc
.data
input byte 100 dup(0)
stringinput byte "Enter any string: ",0
totallength byte "The total length is: ",0
minimum byte "The minimum value is: ",0
.code
stringLength proc
push ebp
mov ebp, esp
push ebx
push ecx
mov eax, 0
mov ebx, [ebp+8]
L1:
mov ecx, [ebx] ;you can use ecx, cx, ch, cl
cmp ecx, 0 ;you can use ecx, cx, ch, cl
JE L2
add ebx, 1
add eax, 1
jmp L1
L2:
pop ecx
pop ebx
mov ebp, esp
pop ebp
ret 4
stringLength endp
BubbleSort PROC uses ECX
push edx
xor ecx,ecx
mov ecx, 50
OUTER_LOOP:
push ecx
xor ecx,ecx
mov ecx,14
mov esi, OFFSET input
COMPARE:
xor ebx,ebx
xor edx,edx
mov bl, byte ptr ds:[esi]
mov dl, byte ptr ds:[esi+1]
cmp bl,dl
jg SWAP1
CONTINUE:
add esi,2
loop COMPARE
mov esi, OFFSET input
pop ecx
loop OUTER_LOOP
jmp FINISHED
SWAP1:
xchg bl,dl
mov byte ptr ds:[esi+1],dl
mov byte ptr ds:[esi],bl
jmp CONTINUE
FINISHED:
pop edx
ret 4
BubbleSort ENDP
main proc
call clrscr
mov edx, offset stringinput
call writeString
mov edx, offset input
call writeString
call stringLength
mov edx, offset input
mov ecx, sizeof input
call readstring
call crlf
mov edx,offset totallength
call writestring
call writedec
call crlf
mov edx, offset minimum
call crlf
call writeString
push offset input
call BubbleSort
mov edx, offset input
call writeString
call crlf
exit
main endp
end main
I haven't looked over your code, because sorting is an over complicated method for what you want to do. Not only that, but most of us don't pay too much attention to uncommented code. Just takes to long to figure out what you're trying to do.
Simply iterate through the entire list and start with 255 (FFH) in AL let's say. Each time you come across a number that is smaller than the one in AL, then replace it with that value and then when loop is finished, AL will have the lowest value.
If you need to know where it is in the list, you could maybe use AH which would be the difference between start address and current address. Knowledge of the instruction set is essential as finding the length of the string can be simplified by;
mov di, input ; Point to beginning of buffer
mov cx, -1 ; for a maximum of 65535 characters
xor al, al ; Looking for NULL
rep scasb
neg cx
dec cx ; CX = length of string.
Remember, ES needs to point to #DATA

masm call procedure access violation

So I am working on an assignment in assembly to generate a fibonacci sequence. I've written the code successfully in the main procedure but when I try to wrap it in it's own procedure and call that procedure I run into an access violation error. Here's my code:
INCLUDE Irvine32.inc
.data
array DWORD 47 DUP(?)
.code
main proc
mov esi, OFFSET array
call generate_fibonacci
invoke ExitProcess,0
main endp
generate_fibonacci PROC
mov DWORD PTR [esi], 1h
add esi, 4
mov DWORD PTR [esi], 1h
push [esi]
push [esi - 4]
add esi, 4
mov ecx, 45
L1:
pop eax
pop ebx
add eax, ebx
mov DWORD PTR [esi], eax
add esi, 4
push [esi - 4]
push [esi - 8]
loop L1
ret
generate_fibonacci ENDP
end main
The error looks like this: "Exception thrown at some memory location in Project...: Access violation executing location same memory location.
I noticed that the memory location listed in the error message was being loaded onto the EIP register when the call generate_fibonacci instruction is executed. I'm not sure how to fix this.
The pushes and pops in your PROC are not balanced.
Before loop L1: you make 2 pushes. Within the loop L1: you make 2 pops and 2 pushes. When loop L1: ends, that leaves 2 items still on the stack when ret attempts to pull off the return address. So the code tries to resume execution somewhere that causes an access violation.
Please add two lines of code before the ret instruction to clean up the stack
pop eax
pop eax
ret
If the same code worked when it was in main, it worked because main does not end with ret.
EDIT. You could simplify it considerably by keeping the recent terms in registers. The last three terms will be in eax, ebx, edx.
generate_fibonacci PROC
mov eax, 1 ;init first two terms
mov DWORD PTR [esi], eax ;store first two terms
add esi, 4
mov DWORD PTR [esi], eax
add esi, 4
mov ebx, eax
mov ecx, 45 ;init loop count
L1:
mov edx, ebx ;move terms along
mov ebx, eax
add eax, edx ;sum last two terms
mov DWORD PTR [esi], eax
add esi, 4
loop L1
ret
generate_fibonacci ENDP

How to sort signed numbers using assembly language?

I have this homework wherein I need to make a program that asks three SIGNED numbers from the user and my program should be able to sort these numbers in ascending order. I can do it in C++ but I am not that familiar with NASM/Assembly Language.
Here's my code so far:
%include "asm_io.inc"
segment .data
;
; Output strings
;
prompta db "Enter the 1st number: ", 0
promptb db "Enter the 2nd number: ", 0
promptc db "Enter the 3rd number: ", 0
promptd db "The sorted list is: ", 0
segment .bss
input resd 1
segment .text
global _asm_main
_asm_main:
enter 0,0 ; setup routine
pusha
mov eax, prompta
call print_string
call read_int
push eax
mov eax, promptb
call print_string
call read_int
push eax
mov eax, promptc
call print_string
call read_int
push eax
call add_stack
mov ebx, eax
mov eax, promptd
call print_string
mov eax, ebx
call print_int
call print_nl
sub esp, 16
popa
mov eax, 0 ; return back to C
leave
ret
segment .data
; no need for .data
segment .bss
; no need for variables
segment .text
add_stack:
enter 0,0
mov ecx, [ebp+8]
mov ebx, [ebp+12]
mov eax, [ebp+16]
cmp eax, ebx
jg A
cmp ebx, ecx
jg B
cmp ecx, eax
jg C
A:
push eax
B:
push ebx
C:
push ecx
popa
leave
ret
In C++ you cannot change the arguments inside of a function and use it later by the caller, but in assembly you can do everything. You pushed the input onto the stack for later using as arguments for the function add_stack. What about to sort these values and store them back to the original place on the stack:
%include "asm_io.inc"
segment .data
;
; Output strings
;
prompta db "Enter the 1st number: ", 0
promptb db "Enter the 2nd number: ", 0
promptc db "Enter the 3rd number: ", 0
promptd db "The sorted list is: ", 0
segment .text
global _asm_main
_asm_main:
enter 0,0 ; setup routine
pusha
mov eax, prompta
call print_string
call read_int
push eax
mov eax, promptb
call print_string
call read_int
push eax
mov eax, promptc
call print_string
call read_int
push eax
call sort_stack ; Three arguments pushed before
mov eax, promptd
call print_string
mov ecx, 3 ; Pop and write the arguments for `sort_stack`
.print_list:
pop eax
call print_int
mov al, 32
call print_char
loop .print_list
call print_nl
popa
mov eax, 0 ; return back to C
leave
ret
sort_stack:
enter 0,0
mov ecx, [ebp+8]
mov ebx, [ebp+12]
mov eax, [ebp+16]
cmp eax, ebx
jg .1
xchg eax, ebx
.1:
cmp ebx, ecx
jg .2
xchg ebx, ecx
.2:
cmp eax, ebx
jg .3
xchg eax, ebx
.3: ; Write back the registers
mov [ebp+8], ecx
mov [ebp+12], ebx
mov [ebp+16], eax
leave
ret
I'm not sure, if your teacher will like this "trick".

Insertion sort in assembler doesn't sort

I'm trying to sort a array of numbers by Insertion sort but it not sort the numbers correctly. I've tried everything but it does not sort them As it should.
I would be happy if you could help me figure out where the problem and on how I can fix it thanks !!
section .rodata
MSG: DB "welcome to sortMe, please sort me",10,0
S1: DB "%d",10,0 ; 10 = '\n' , 0 = '\0'
section .data
array DB 5,1,7,3,4,9,12,8,10,2,6,11 ; unsorted array
len DB 12
section .text
align 16
global main
extern printf
main:
push MSG ; print welcome message
call printf
add esp,4 ; clean the stack
call printArray ;print the unsorted array
push ebp ;save old frame pointer
mov ebp,esp ;create new frame on stack
pusha
mov esi,array
mov ecx,8
OuterLoop:
mov ebx,ecx
InnerLoop:
add esi,ebx ;basically makes array[0] to array[ebx]
mov eax,[esi] ;eax=array[ebx]
sub esi,8
mov edx,[esi] ; edx=array[ebx-1]
add esi,8
cmp eax,edx ; if(eax<edx)
jle skip2 ; skip the loop
;else:
mov [esi],edx ;array[ebx]=array[ebx-1]
sub esi,8
mov [esi],eax ; array[ebx-1]=array[ebx]
add esi,8
sub esi,ebx ; return the array to its original state (array[0])
sub ebx,8
cmp ebx,0
jne InnerLoop
skip1:
add ecx,8
cmp ecx,96
jle OuterLoop
popa ;restore registers
mov esp,ebp ;clean the stack frame
pop ebp
push MSG ; print welcome message (to divide between the unsorted and sorted)
call printf
add esp,4 ; clean the stack
call printArray
mov eax, 1 ;exit system call
int 0x80
printArray:
push ebp ;save old frame pointer
mov ebp,esp ;create new frame on stack
pusha ;save registers
mov eax,0
mov ebx,0
mov edi,0
mov esi,0 ;array index
mov bl,byte[len]
add edi,ebx ; edi = array size
print_loop:
cmp esi,edi
je print_end
mov al ,byte[array+esi] ;set num to print in eax
push eax
push S1
call printf
add esp,8 ;clean the stack
inc esi
jmp print_loop
print_end:
popa ;restore registers
mov esp,ebp ;clean the stack frame
pop ebp ;return to old stack frame
ret
skip2:
sub esi,ebx ; return the array to the original state
jmp skip1
You're horribly mixing 3 sizes!
1. Array of bytes
2. Values of dwords
3. Steps of qwords
Once you've decided what size to use beware of this code. In its current qword form it does an extra iteration! (use jl OuterLoop)
cmp ecx,96
jle OuterLoop
Why don't you use MOVZX to EAX in this line? It's much cleaner.
mov al ,byte[array+esi] ;set num to print in eax
The same applies to
mov bl,byte[len]
By putting mov esi,array right after OuterLoop: you can avoid that ugly detour via SKIP2.

Resources