Hey guys I'm not sure if I'm going about all this the right way. I need the first 12 numbers of Fibonacci sequence to calculate which its doing already I'm pretty sure. But now I need to display the hexadecimal contents of (Fibonacci) in my program using dumpMem. I need to be getting a print out of : 01 01 02 03 05 08 0D 15 22 37 59 90
But I'm only getting: 01 01 00 00 00 00 00 00 00 00 00 00
Any tips or help is much much appreciated.
INCLUDE Irvine32.inc
.data
reg DWORD -1,1,0 ; Initializes a DOUBLEWORD array, giving it the values of -1, 1, and 0
array DWORD 48 DUP(?)
Fibonacci BYTE 1, 1, 10 DUP (?)
.code
main PROC
mov array, 1
mov esi,OFFSET array ; or should this be Fibonacci?
mov ecx,12
add esi, 4
L1:
mov edx, [reg]
mov ebx, [reg+4]
mov [reg+8], edx
add [reg+8], ebx ; Adds the value of the EBX and 'temp(8)' together and stores it as temp(8)
mov eax, [reg+8] ; Moves the value of 'temp(8)' into the EAX register
mov [esi], eax ; Moves the value of EAX into the offset of array
mov [reg], ebx ; Moves the value of the EBX register to 'temp(0)'
mov [reg+4], eax ; Moves the value of the EAX register to 'temp(4)
add esi, 4
; call DumpRegs
call WriteInt
loop L1
;mov ebx, offset array
;mov ecx, 12
;L2:
;mov eax, [esi]
;add esi, 4
;call WriteInt
;loop L2
;Below will show hexadecimal contents of string target-----------------
mov esi, OFFSET Fibonacci ; offset the variables
mov ebx,1 ; byte format
mov ecx, SIZEOF Fibonacci ; counter
call dumpMem
exit
main ENDP
END main
It seems to me that the problem here is with computing the Fibonacci sequence. Your code for that leaves me somewhat...puzzled. You have a bunch of "stuff" there, that seems to have nothing to do with computing Fibonacci numbers (e.g., reg), and others that could, but it seems you don't really know what you're trying to do with them.
Looking at your loop to compute the sequence, the first thing that practically jumps out at me is that you're using memory a lot. One of the first (and most important) things when you're writing assembly language is to maximize your use of registers and minimize your use of memory.
As a hint, I think if you read anything from memory in the course if computing the sequence, you're probably making a mistake. You should be able to do all the computation in registers, so the only memory references will be writing results. Since you're (apparently) producing only byte-sized results, you should need only one array of the proper number of bytes to hold the results (i.e., one byte per number you're going to generate).
I'm tempted to write a little routine showing how neatly this can be adapted to assembly language, but I suppose I probably shouldn't do that...
Your call to dumpMem is correct, but your program is not storing the results of your calculations at the correct location: the region you call "Fibonacci" remains initialized to 1, 1, and ten zeros. You need to make sure that your loop starts writing at the offset of Fibonacci plus 2, and moves ten times in one-byte increments (ten, not twelve, because you provided the two initial items in the initializer).
I'm sorry, I cannot be any more specific, as any question containing the word "Fibonacci" inevitably turns out to be someone's homework :-)
Related
Let's say we work on architecture x86_64 and let's say we have the following string, "123456". In ASCII characters, it becomes 31 32 33 34 35 36 00.
Now, which assembly instructions should I use to move the entire (even if fragmented) content of this string somewhere in a way that %rdi stores the address of that string (points to that)?
Because I am not simply able to move the hex representation of the string into a register, like one can do with unsigned values, how do I do it?
There are a couple of ways to do so.
If you want to move the entire string to another offset first, you would have to do so with a loop.
mov rbx, 0
loop:
mov al, [string+rbx]
mov [copyoffset+rbx], al
inc rbx
cmp al, 0x0
jne loop
... Insert other code here
Then you can use the Lea instruction described below to move it into rdi.
If you just want to load the address of the string and don't care about moving it you can just use lea
lea rdi, [stringoffset]
Edit: Changed rax to al so we only move one byte at a time
Consider the code below. If incrementing SI by 2 gives me the 2nd element of the array, what exactly would incrementing SI by 1 give me?
.data
var dw 1,2,3,4
.code
LEA SI,VAR
MOV AX,[SI]
INC SI
MOV AX,[SI]
Statement var dw 1,2,3,4 tells the assembler to statically define eight bytes in memory at the beginning of .data segment. Layout of the data bytes will be
|01|00|02|00|03|00|04|00|
and the first MOV AX,[SI] will load AL with 01 and AH with 00.
When you increment SI only by 1, the next MOV AX,[SI] will load AL with 00 and AH with 02.
If you want to keep loading AX with the whole 16bit words, increment SI by 2 (ADD SI,2).
You could also replace both MOV AX,[SI] and ADD SI,2 with one single instruction LODSW which does the same and occupies only one byte instead of five. In this case you should be sure to have the Direction flag reset (using the instruction CLD in the beginning of your program).
I had been trying to follow this tutorial (https://paraschetal.in/writing-your-own-shellcode) on how to write your own shellcode. 99% of it makes sense to me but there is just two lingering doubts in my mind - this relates to writing shellcode in general
Firstly, I think I understand why we want to avoid the null byte but how does using the following avoid null bytes?
xor eax, eax
Doesn't eax now contain exactly null bytes? Or does it contain 0s? When we XOR something with itself, it returns False, correct?
Secondly, the tutorial says:
Finally, we’ll load the syscall number(11 or 0xb) to the eax
register. However if we use eax in our instruction, the resulting
shellcode will contain some NULL(\x00) bytes and we don’t want that.
Our eax register already is NULL. So we’ll just load the syscall
number to the al register instead of the entire eax register.
mov byte al, 0x0b
Now I do understand what is going on here, the number 11 (for execve) is being loaded into the first 8 bits of eax register (which is al). But the rest of eax still contains null bytes so what exactly is achieved here?
Please note, I've come here as a last resort after spending most of the day trying to understand this, so please take it easy on me :)
The exploits usually attack C code, and therefore the shell code often needs to be delivered in a NUL-terminated string. If the shell code contains NUL bytes the C code that is being exploited might ignore and drop rest of the code starting from the first zero byte.
This concerns only the machine code. If you need to call the system call with number 0xb, then naturally you need to be able to produce the number 0xb in the EAX register, but you can only use those forms of machine code that do not contain zero bytes in the machine code itself.
xor eax, eax
will invert all the 1 bits in the eax, i.e. zero it. It is a functional equivalent to
mov eax, 0
except that the latter will have the 0 coded as zero bytes in the machine code.
The machine code for
xor eax, eax
mov byte al, 0x0b
is
31 c0 b0 0b
As you can see, there are no embedded zero bytes in it. The machine code for
mov eax, 0xb
is
b8 0b 00 00 00
Both these programs are functionally equivalent in that they set the value of EAX register to 0xb.
If the latter shell code is handled as a null-terminated string by a C program, the rest of it after the b8 0b 00 could be discarded by the program and be replaced by other bytes in the memory, essentially making the shellcode not work.
The instruction mov eax, 0 assembles to
b8 00 00 00 00
which contains NUL bytes. However, the instruction xor eax, eax assembles to
31 c0
which is free of NUL bytes, making it suitable for shell code.
The same applies to mov al, 0x0b. If you do mov eax, 0x0b, the encoding is
b8 0b 00 00 00
which contains NUL bytes. However, mov al, 0x0b encodes to
b0 0b
avoiding NUL bytes.
I have to add two 3*3 arrays of words and store the result in another array. Here is my code:
.data
a1 WORD 1,2,3
WORD 4,2,3
WORD 1,4,3
a2 WORD 4, 3, 8
WORD 5, 6, 8
WORD 4, 8, 9
a3 WORD DUP 9(0)
.code
main PROC
mov eax,0;
mov ebx,0;
mov ecx,0;
mov edx,0;
mov edi,0;
mov esi,0;
mov edi,offset a1
mov esi,offset a2
mov ebx, offset a3
mov ecx,LENGTHOF a2
LOOP:
mov eax,[esi]
add eax,[edi]
mov [ebx], eax
inc ebx
inc esi
inc edi
call DumpRegs
loop LOOP
exit
main ENDP
END main
But this sums all elements of a2 and a1. How do I add them row by row and column by column? I want to display the result of sum of each row in another one dimensional array(Same for columns).
The
a1 WORD 1,2,3
WORD 4,2,3
WORD 1,4,3
will compile as bytes (in hexa):
01 00 02 00 03 00 04 00 02 00 03 00 01 00 04 00 03 00
Memory is addressable by bytes, so if you will find each element above, and count it's displacement from the first one (first one is displaced by 0 bytes, ie. it's address is a1+0), you should see a pattern, how to calculate the displacement of particular [y][x] element (x is column number 0-2, y is row number 0-2... if you decide so, it's up to you, what is column/row, but usually people tend to consider consecutive elements in memory to be "a row").
Pay attention to the basic types byte size, you are mixing it everywhere in every way, reread some lesson/tutorial about how qword/dword/word/byte differ and how you need to adjust your instructions to work with correct memory size, and how to calculate the address correctly (and what is the size of eax and how to use smaller parts of it).
If you have trouble to figure it on your own:
displacement = (y * 3 + x) * 2 => *2 because element is word, each occupies two bytes. y * 3 because single row is 3 elements long.
In ASM instructions that may be achieved for example...
If [x,y] is [eax,ebx], this calculation can be done as lea esi,[ebx+ebx*2] ; esi = y*3 | lea esi,[esi+eax] ; esi = y*3+x | mov ax,[a1+esi*2] ; loads [x,y] element from a1.
Now if you know how to calculate address of particular element, you can do either loop doing all the calculation ahead of each element load, or just do the math in head how the addresses differ and write the address calculation for first element (start of row/column) and then mov + 2x add with hardcoded offsets for next two elements (making loop for 3 elements is sort of more trouble than writing the unrolled code without loop), and repeat this for all three columns/rows and store the results.
BTW, that call DumpRegs ... is not producing what you expected? And it's a bit tedious way to debug the code, may be worth to spend a moment to get some debugger working.
Couldn't help my self, but to write it, as it's such funny short piece of code, but you will regret it later, if you will just copy it, and not dissect it to atoms and understand fully how it works):
column_sums: DW 0, 0, 0
row_sums: DW 0, 0, 0
...
; columns sums
lea esi,[a3] ; already summed elements of a1 + a2
lea edi,[column_sums]
mov ecx,3 ; three columns to sum
sum_column:
mov ax,[esi] ; first element of column
add ax,[esi+6] ; 1 line under first
add ax,[esi+12] ; 2 lines under
mov [edi],ax ; store result
add esi,2 ; next column, first element
add edi,2 ; next result
dec ecx
jnz sum_column
; rows sums
lea esi,[a3] ; already summed elements of a1 + a2
lea edi,[row_sums]
mov ecx,3 ; three rows to sum
sum_row:
mov ax,[esi] ; first element of row
add ax,[esi+2] ; +1 column
add ax,[esi+4] ; +2 column
mov [edi],ax ; store result
add esi,6 ; next row, first element
add edi,2 ; next result
dec ecx
jnz sum_row
...
(didn't debug it, so bugs are possible, plus this expect a3 to contain correct element sums, which your original code will not produce, so you have to fix it first ... this code does contain lot of hints, how to fix each problem of original)
Now I feel guilty of taking the fun of writing this from you... nevermind, I'm sure you can find few more tasks to practice this. The question is, whether you got the principle of it. If not, ask which part is confusing and how you currently understand it.
no no no no this top answer so terrible...
first we have a big memory access issue
change ur array access to be: "memtype ptr [memAddr + (index*memSize)]"
(): must be in a register of dword size im pretty sure, i know for a fact if its in a register it must be dword size, idk if u can do an expression like the way ive written it using the *...
memtype = byte, word (everything is a dword by default)
index = pos in array
memSize: byte = 1, word = 2, dword = 4
IF YOU DO NOT DO THIS, ALL MEMORY ACCESS WILL BE OF TYPE DWORD, AND YOU MIGHT ACCESS OUT OF BOUNDS AND MOST DEFINETELY YOU WILL NOT GET THE CORRECT VALUES BECAUSE IT IS MIXING MEMORY OF DIFFERENT THINGS( dword = word + word, so when u only want the word u have to do a word ptr, otheriwse it will give u the word+word and who knows what that value will be)
your type size is word, and your also trying to put it in a dword register, u can do the word size register of eax(ax) instead, or u can do movzx to place it in eax if you want to use the whole register
next accessing the array in different formats
i mean this part should be fairly obvious if you have done any basic coding, i think ur top error is the main issue
its just a normal array indexs: 0->?
so then you just access the addr [row * colSize + col]
and the way u progress your loop should be fairly self explanatory
The program must calculate the following:
in VP array , each index will have the value of Multiplying V1[INDEX] WITH V2[INDEX]
in VPROD array , the program ADDS all the Values of Array VP
Example:
VP = { V1[0]*V2[0] , V1[1]*V2[1] , V1[2]*V2[2] , V1[3]*V2[3] ,V1[4]*V2[4] }
VPROD = { VP[0] + VP[1] + VP[2] + VP[3] + VP[4] }
The problem is that when the result is bigger than 16 bits (a word), it does not give the right results. But when the result is smaller than 16 bits, it gives the right result.
I thought about Carry and fixed my code, but still it gives me bad results.
My code:
dseg segment
v1 DW 255,5,255,9,21
v2 DW 4,4,255,13,5
vprod DW 10 DUP (0)
vp DW 10 DUP (?)
N DB 5
dseg ends
sseg segment stack
dw 100h dup(?)
sseg ends
cseg segment
assume ds:dseg,cs:cseg,ss:sseg
start: mov ax,dseg
MOV DS,AX
MOV SI,0
MOV CX,0
MOV CL,N
MOV DI, 0
LOVP: MOV AX,v1[si]
MUL v2[si]
MOV vp[di],AX
MOV vp[di+2],DX
ADD SI,2
ADD DI,4
LOOP LOVP
MOV CX,0
MOV CL,N
MOV SI,0
MOV DI,0
LOVPROD: MOV AX,vp[SI]
ADD vprod[DI],AX
ADC VPROD[DI+2],0
ADD SI,2
LOOP LOVPROD
SOF:
mov ah,4ch
int 21h
cseg ends
end start
Since you are getting a 32 bit result from the multiply, you should use 4 bytes for every element of the vp array. You will need to use a separate index for that, and of course store the high word at offset +2 instead of +1. For the summation part, you should add up both low and high words.
Fixed code for the multiplication could look like:
MOV DI, 0
LOVP: MOV AX,v1[si]
MUL v2[si]
MOV vp[di],AX
MOV vp[di+2],DX
ADD SI,2
ADD DI,4
LOOP LOVP
I trust you can do the summation yourself, using ADD and ADC.
UPDATE:
Since your post says you want to sum the vp array, I don't see why you expect the result in another array (vprod). The sum is a scalar value, do something like:
MOV SI, 0
MOV AX, 0
MOV DX, 0
LOVPROD: ADD AX,vp[SI]
ADC DX,vp[SI+2]
ADD SI,4
LOOP LOVPROD
The result will be in DX:AX
Also, for the LOOP to work properly, you should put the number of iterations into CX, not 0 as you are doing.