flat assembler
Message board for the users of flat assembler.

Index > Main > Please help me to understand stack

Goto page Previous  1, 2
Author
Thread Post new topic Reply to topic
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 12 Jul 2022, 12:10
AsmGuru62 wrote:
It is a Giga-Word! They finally invented the thing! Very Happy

FASM has dt and dp directives which then probably mean tera-words (tera-bytes?) and peta-words (peta-bytes?). Which is quite possible since FASM also supports virtual directive that presumably allows to use virtual memory and since FASM is internally 65-bit which means the maximum addressing space limit is somewhere around 32k petabytes. That also explains why
Code:
dt 33554433 dup(0) ; 32768 * 1024 + 1 terabytes = 32k petabytes + 1 TB    
fails to compile Smile
Post 12 Jul 2022, 12:10
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 28 Feb 2023, 10:02
I have another question about stack.

Let say if I "call subroutine", but in the subroutine, I want to jump to a label in main program WITHOUT returning from subroutine, how do I do it?

Code:
call Write_To_File
....
call [ExitProcess]

write_error:
...
...

Write_To_File:
...
...
add esp, 4   ;is this correct?
jmp write_err
...
...
ret
    


Is addresses in 32-bit PE DWORD in size?
Did I understand correctly that the return address is stored onto stack after calling the subroutine?

ADDED: After I jump to "write_err", the program will quit.

EDIT: The purpose of this question is how to avoid stack imbalance since the code will jump directly to main program and quit.

Please enlighten, thanks!
Post 28 Feb 2023, 10:02
View user's profile Send private message Visit poster's website Reply with quote
Ali.Z



Joined: 08 Jan 2018
Posts: 762
Ali.Z 28 Feb 2023, 12:02
it is not necessary to either get rid of the return address or any additional parameters, as you are going to call ExitProcess.

yes addresses are dword in size when working under protected mode, after a call the current stack pointer points to the return address; you can pop the return address or increase stack pointer by 4.

_________________
Asm For Wise Humans
Post 28 Feb 2023, 12:02
View user's profile Send private message Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 28 Feb 2023, 12:37
Ali.Z wrote:
it is not necessary to either get rid of the return address or any additional parameters, as you are going to call ExitProcess.

yes addresses are dword in size when working under protected mode, after a call the current stack pointer points to the return address; you can pop the return address or increase stack pointer by 4.


Thanks, you made your points clear. I fully understand it now.
Post 28 Feb 2023, 12:37
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2582
Furs 28 Feb 2023, 14:12
I think it would be easier for you to understand if you implement a manual stack. This is 32-bit so I go with 32-bit code (pointer = 4 bytes).

Pick a register, like ebp. Have it be the "stack pointer" in your manual stack.

Allocate some memory, like 64 KB. Make ebp point at the end of this memory.

push something on this stack:
Code:
sub ebp, 4
mov dword [ebp], val_to_push    
pop a value:
Code:
mov dest, dword [ebp]
add ebp, 4    
call a function:
Code:
sub ebp, 4
mov dword [ebp], ret_addr
jmp function
ret_addr:    
return from a function:
Code:
mov tmp, dword [ebp]   ; tmp is an imaginary register, the 'ret' instruction does this in hardware with esp
add ebp, 4
jmp tmp    
It's really nothing special.

Once you understand that a manual stack is just memory with a pointer, you realize the normal stack is the same except it uses specialized instructions to do that (which are smaller and faster) and a hardcoded register (esp).
Post 28 Feb 2023, 14:12
View user's profile Send private message Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 28 Feb 2023, 15:35
Furs, I think I almost there to understand about the manual stack that you described. Thanks!

Furs wrote:
..... you realize the normal stack is the same except it uses specialized instructions to do that (which are smaller and faster)....


Do you mean "push" and "pop"?
Post 28 Feb 2023, 15:35
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2582
Furs 01 Mar 2023, 14:24
FlierMate11 wrote:
Furs, I think I almost there to understand about the manual stack that you described. Thanks!

Furs wrote:
..... you realize the normal stack is the same except it uses specialized instructions to do that (which are smaller and faster)....


Do you mean "push" and "pop"?
Yes, and "call" and "ret".
Post 01 Mar 2023, 14:24
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 23 Mar 2023, 16:02
Can someone explain a decrpytion runtime in an example malware?

The code access stack upward, I wonder is those 32 bytes upward belongs to the program, there is no sign the code allocate stack beforehand.

Is this normal?


Description:
Filesize: 40.22 KB
Viewed: 3331 Time(s)

Screenshot 2023-03-23 233042.png


Post 23 Mar 2023, 16:02
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1052
Location: Russia
macomics 23 Mar 2023, 16:24
Immediately after the call command
Code:
qword [rsp +  0] = rip and call length  = 0xBCF1F165960CEF48 xor (256*$DEx7) = 0x622F2FBB48D23148 (byte [rsp + 1] = the xor cycle is ending)
qword [rsp +  8] = place for rcx arg    = 0x351F96B6ADF1B0B7 xor $DEx8 = 0xEBC14868732F6E69
qword [rsp + 16] = place for rdx arg    = 0x96898E3957968DD6 xor $DEx8 = 0x485750E789485308
qword [rsp + 24] = place for r8 arg     = 0x0000DBD1E56E3857 xor $DEx8 = 0xDEDE050F3BB0E689
qword [rsp + 32] = place for r9 arg
qword [rsp + 40] = frame of the caller or arguments for the callee
...
 byte [rsp + 222] = this is where the xor cycle starts ↑↑↑    
Post 23 Mar 2023, 16:24
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 23 Mar 2023, 19:44
macomics wrote:
Immediately after the call command
Code:
qword [rsp +  0] = rip and call length  = 0xBCF1F165960CEF48 xor (256*$DEx7) = 0x622F2FBB48D23148 (byte [rsp + 1] = the xor cycle is ending)
qword [rsp +  8] = place for rcx arg    = 0x351F96B6ADF1B0B7 xor $DEx8 = 0xEBC14868732F6E69
qword [rsp + 16] = place for rdx arg    = 0x96898E3957968DD6 xor $DEx8 = 0x485750E789485308
qword [rsp + 24] = place for r8 arg     = 0x0000DBD1E56E3857 xor $DEx8 = 0xDEDE050F3BB0E689
qword [rsp + 32] = place for r9 arg
qword [rsp + 40] = frame of the caller or arguments for the callee
...
 byte [rsp + 222] = this is where the xor cycle starts ↑↑↑    


Thanks for helping me to visualize what the code does.
Excellent stuff.
Post 23 Mar 2023, 19:44
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.