Hello,
I have a problem with the stack addresses for local variables.
test proc a:DWORD
mov eax, a ;address of a is ebp - 4
ret
test endp
main:
push 0
call test
end main
I think this should be alright, but doesn't the stack address has to get incremented, like this:
test2 proc b:DWORD
mov eax, b ;address of b is ebp - 8
ret
test2 endp
test proc a:DWORD
mov eax, a ;address of a is ebp - 4
push 0
call test2
ret
test endp
main:
push 0
call test
end main
So the stack address is relative to the caller or is it absolute in every proc?
Thanks!
Assemble your program and run it with OllyDbg, step by step using F7. Watch what esp and ebp are doing. Everything will be crystal clear...
So (for example) the first parameter is always ebp - 4, the second is ebp - 8, etc. since EBP always points to the stack-room, which is actually used?
Quote from: n00b! on October 05, 2008, 07:49:57 PM
So the stack address is relative to the caller or is it absolute in every proc?
Hello
It is absolute in every proc. Your test2 proc b:DWORD
....
ret
test2 endp
would be
push ebp
mov ebp, esp
....
pop ebp
ret 4
Rui
Quote from: n00b! on October 05, 2008, 08:52:37 PM
So (for example) the first parameter is always ebp - 4, the second is ebp - 8, etc. since EBP always points to the stack-room, which is actually used?
Exactly:
mov ebp, esp creates a stack frame, i.e. a fixed temporary memory range relative to ebp, the base pointer. ebp remains constant, esp can be modified by push & pop.
Ohh, I got it, Thanks :bg
But I don't see this stack frame when debugging the sample application...
There's only an ENTER 0, 0 with a LEAVE
ebp remains constant, esp can be modified by push & pop.
I don't get what you say :-/
Btw: For what is ESP? What value does it hold?
noob!
Tell me: is this code where you "see" ENTER 0,0 your code or you are reversing somebody else's code?
You ask questions that are suspicious and apparently way above your understanding of ASM as a newbie.
You also ask questions that are too vague and with little or no details about your project and why you think that you need to do things this way.
You should do more simple things first and I am sure that MASM does handle LOCAL variables, arguments and stack frames quite OK for what you need. Hard coding EBP+xxx values is not the right way to go for a newbie. Maybe if you explain why you need this info we can direct you to other more safe and more sane ways of obtaining the very same results.
Answer my question about who's code it is....
Quote from: BogdanOntanu on October 06, 2008, 02:33:08 AM
noob!
Tell me: is this code where you "see" ENTER 0,0 your code or you are reversing somebody else's code?
You ask questions that are suspicious and apparently way above your understanding of ASM as a newbie.
You also ask questions that are too vague and with little or no details about your project and why you think that you need to do things this way.
You should do more simple things first and I am sure that MASM does handle LOCAL variables, arguments and stack frames quite OK for what you need. Hard coding EBP+xxx values is not the right way to go for a newbie. Maybe if you explain why you need this info we can direct you to other more safe and more sane ways of obtaining the very same results.
Answer my question about who's code it is....
He might just use Tasm instead of Masm. Tasm prefers the ENTER 0,0 opcode to initialize the stack frame.
There is nothing suspicious with noob!'s questions.
Hi, sorry I used pasm to assemble this.
It's the code from above.
And I want to know about ebp because I have a bunch of local variables, like:
foo proc
local a:DWORD
local x:DWORD
local y:DWORD
local m:BYTE, n:BYTE, o:BYTE
local val:WORD
endp
And I don't want to initialize them like this:
mov a, 0
mov x, 0
mov y, 0
mov m, 0
mov n, 0
mov o, 0
mov val, 0
I thought it would be nicer to create a loop which goes from offset of a to offset of val and writes zeros there :-/
PS: And this ENTER 0, 0 does the mov ebp, esp, too?
I read opcodes.chm but I understand it only a bit abstract (It creates a stack frame... but how?) and I don't know what it does exactly...
Thank you very much :U
Quote from: n00b! on October 06, 2008, 10:50:54 AM
I thought it would be nicer to create a loop which goes from offset of a to offset of val and writes zeros there :-/
ClearLocVars proc ; first instruction after LOCALS - eax will be zero on exit
pop ClvEsp ; save the return address to a global variable - now
; the stack is identical to the calling procedure
xchg eax, ecx ; save ecx
mov ecx, ebp ; base page of calling procedure
sub ecx, esp ; ebp - esp = No. of bytes in locals
mov esp, ebp ; discard existing locals
shr ecx, 2 ; divide by four
@@: push 0 ; dwords on stack
loop @B
xchg eax, ecx ; restore ecx, 0 to eax
push ClvEsp ; restore the return address
ret
ClearLocVars endp
Quote
Hi, sorry I used pasm to assemble this.
It's the code from above.
And I want to know about ebp because I have a bunch of local variables, like:
Code:
foo proc
local a:DWORD
local x:DWORD
local y:DWORD
local m:BYTE, n:BYTE, o:BYTE
local val:WORD
endp
And I don't want to initialize them like this:
Code:
mov a, 0
mov x, 0
mov y, 0
mov m, 0
mov n, 0
mov o, 0
mov val, 0
I thought it would be nicer to create a loop which goes from offset of a to offset of val and writes zeros there :-/
PS: And this ENTER 0, 0 does the mov ebp, esp, too?
I read opcodes.chm but I understand it only a bit abstract (It creates a stack frame... but how?) and I don't know what it does exactly...
Thank you very much ThumbsUp
OK then but still I can not find this "pasm" assembler :P what purpose do you ahve in using it?
If you are using TASM as a noob then maybe it is better to switch to MASM or Japeth's JWASM that is almost fully compatible with MASM and has a "commercial free" license. This way we could help you better and faster.
TASM has some strange bugs. As experienced programmers we can work arround that bugs but for a newbie they can block you for weeks or months or even worst point you into the wrong conceptual direction. Besides TASM is not free and you have to buy it to be correct and we can not answer questions about it if you did not buy it. (Yes I did buy it with invoice)
Hence IF you just want to clear the LOCALS then you should be aware that:
1) Yes ENTER also makes mov ebp,esp and sub esp,size_of_locals. hence fisrt local is at ebp-4 next local at ebp-8 and so on...
2) ENTER also makes something extra but only IF the second parameter is not zero and this is rare
3)Take care with jj2007 code because MASM and other compilers will generate the PROLOGUE at first instruction they find in PROC's body.
Hence if USES ebx,esi,edi is present THEN you will also erase the saved registers because at the first instruction ESP will point after the PUSH for USES.
However this location might depend on the compiler/assembler because is is their duty to make the stack frame in PROC and each assembler can have small variations. Oh...and saving a stack return address to a global variable is not a good idea.
In this case maybe it is better that you manage your own Stack FRAME (for locals, arguments and uses) like this:
start:
push ebp
mov ebp,esp
add esp, size_of_locals
... your code here
end:
mov esp,ebp
pop ebp
ret size_of_arguments
This way you can control things "better" but you will have to do extra work by hand. PROC usually does this work for you.
What you could also do it to get the address ot first local and the address of last local and do a REP STOSB or STOSD with zero there.
lea edi, last_local
mov eax,edi
lea ecx, first_local
sub ecx,eax ; size of locals
xor eax, eax
rep stosb
Observe that the first local is at a higher address that last local ;)
Of course you could also shr ecx,2 ... stosd :P
To japeth Quote
He might just use Tasm instead of Masm. Tasm prefers the ENTER 0,0 opcode to initialize the stack frame.
There is nothing suspicious with noob!'s questions.
Yes I know but it is my "job" to ask the "bad" questions here and get the blame for it. Somebody has to do it and I can take "the hit" :D If people answer nicely and decent then nothing "happens" ...
Besides did he buy TASM? and as I have said above TASM might be OK for me and for you but for a newbie it is a hard bumpy ride.
Quote from: BogdanOntanu on October 06, 2008, 04:42:16 PM
3)Take care with jj2007 code because MASM and other compilers will generate the PROLOGUE at first instruction they find in PROC's body.
Hence if USES ebx,esi,edi is present THEN you will also erase the saved registers because at the first instruction ESP will point after the PUSH for USES.
Bogdan is right, there should be a warning. There is a simple workaround - instead of
uses esi edi, do the push & pop manually:
MyProc proc arg1:DWORD ....
LOCAL a, b, c
LOCAL chrg:CHARRANGE
call ClearLocVars
push esi
push edi
...
pop edi
pop esi
ret
MyProc endp
This works fine.
n00b!,
Pasm : Is it the PARADIGM C++ ASSEMBLER (http://www.devtools.com/pcpp/assembler.htm)?
Uff, thanks for your elaborate answers :D
Pasm is Paradigm Assembler :P
"If you are using TASM as a noob"
Newb[ie] means that you're simply not experienced but you'll learn it.
Noob means that you're not experienced and you won't learn it because you're an unskilled idiot.
Thanks for this :P
PS: I'm just looking trough the assembled codes in OllyDbg, it's very enlightening :0
invoke hello, 5, 0
pushes the 0 to the stack, then the 5, after that the eip of the next instruction and then comes a jump to offset hello.
That means, that the parameters of a procedure are not in the stack frame.
After the procedure follows a ret with the size of the parameters to correct the stack.
some kind like this:
00002C - esp
000030 - local d:DWORD
000034 - local c:BYTE
000038 - local b:DWORD
00003C - local a:DWORD
000040 - ebp
And the distance between the stack addresses are always 4Byte long. (Why? )
Means, even if you write local a:BYTE, b:DWORD it will produce a = ebp - 4, b = ebp - 8 (not 5...)
address of b is equal to ebp - 8 what is equal to esp + 4, esp defines the upper bound of the stack frame, ebp the lower.
But esp and ebp points to unused stack locations, isn't this wastage of Memory, to reserve Bytes on the stack which won't be used?
ENTER 4, 0
(Shouldn't the first value ever be a power of 4? )
reserves 4 Bytes on the stack. means "local mylocvar"
equal to add esp, 4
LEAVE
equal to sub esp, 4
Is this by then correct?
n00b!,
Take it easy, nobody wants to hurt you here. People are trying to help you. Using Tasm requires some additional level of experience and I am sure you will reach this point after doing some practices with Masm.
It was only a joke, see the smilie :lol
But, are the 'experiences' I made with the stack alright or wrong? ._.
And what's with the questions in it? :P
noob,
Just a note on the two instructions, ENTER and LEAVE. They were originally designed to make stack frames for procedures in high level languages, C among others but particularly the ENTER instruction is very slow and is rarely used these days, even in compilers. MASM terminates its stack frames with LEAVE and this works OK as it tests about as fast as the normal ESP/EBP code but is smaller.
Its no big deal to write procedures without a stack frame as long as you understand what is happening when you use ESP addressing directly. The main factor is you must correct ESP every time you modify the stack with PUSH or POP. This can be tedious if you have a number of function calls in the procedure which push arguments onto the stack but effectively after every PUSH you add 4 bytes to ESP until the CALL is made. If the function you call is STDCALL, it corrects the stack for you but if its a C calling convention, you must manually corect ESP after the function has returned.
Quote from: hutch-- on October 06, 2008, 07:31:14 PM
Its no big deal to write procedures without a stack frame as long as you understand what is happening when you use ESP addressing directly. The main factor is you must correct ESP every time you modify the stack with PUSH or POP. This can be tedious if you have a number of function calls in the procedure which push arguments onto the stack...
Here is a particularly cute example of the traps you can find without a stack frame. GetRtfStream saves a piece of text from a RichEdit control to a buffer with a pointer SelXXL$:
GetRtfStream proc ; buffer is SelXXL$
LOCAL editstream:EDITSTREAM
mov editstream.pfnCallback, StreamToXXL
sme EQU invoke SendMessage, hRichEdit,
sme EM_STREAMOUT, SF_RTFNOOBJS or SFF_SELECTION, addr editstream
ret
GetRtfStream endp
OPTION PROLOGUE:NONE ; this disables ENTER/LEAVE and is
OPTION EPILOGUE:NONE ; recommended only if you do not need LOCALs
; With stack frame: cookie=esp+8, pBuffer=esp+12, NumBytes=esp+16 etc
; Without: cookie=esp+4, pBuffer=esp+8, NumBytes=esp+12 etc
StreamToXXL proc cookie:DWORD,pBuffer:DWORD, NumBytes:DWORD, pBytesWritten:DWORD
invoke RtlMoveMemory, SelXXL$, [esp+12], [esp+12] ; dest, source, count
ret 4*4
StreamToXXL endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
Oops - wasn't pBuffer=esp+8 ?
Good example, but I think most beginners will need more then just a vague hint.
Quote from: japheth on October 06, 2008, 08:04:26 PM
...
I see. However, it's my job to annoy the "hobby prosecutors" in this forum and make their job a bit harder. You won't understand, so I spare myself any explanations, but believe me, this my job is absolutely necessary ... :U
I do understand everything do not worry for me... and I will not spare the explanations I am already there and hence I have all the eternity for this.
I am not prosecuting nobody. My questions and advices come from my own hands on experience. It is the truth that I know to be correct from my experience. However IF noob thinks that knows better than me then I will not stop him from following his own path. I honestly think he has the right to be wrong.
I only remove stuff that is related to malware or VX wittings because it is the rule of this forums. If he does not do such things then he has nothing to fear from me... anyway he has nothing to fear from me .... but the fact that he/she will not be able to understand or learn and will waste his time.
Checking noob!'s posts and seeing his path of questioning do you honestly think that he is on the right path of learning?.
I will be honest: I do NOT think he is... but this is my own oppinion and of course I can be wrong. And I choose to express it and i think i am free to do so even if it is perceived as "harsh" .
He ignores answers and immediately jumps to new questions that show he did NOT understood or digest the previous answers.
This is highly problematic...not against the rules of course but IMHO not good for him. Kind of trowing a stone in the lake and then 10 wise mans try to take the stone out of the bottom of the lake. Of course people answer gently but have you checked his improvements after each answer he receives?
He asks for pure information and then he rejects "structured information" and this kind of attitude is not helping IMHO. Information without structure is not a transformation. He will continue to ask dummy questions for years this way. I just want to learn him how to fish instead of giving him a fish every other day of his life.
But feel free to disagree and continue to do your job here. I can agree to disagree with you because I see that you know your own path whatever that might be and you have great skills... Hence I have no problems with you or what you do even if you somehow think you are making my job harder...
As for noob!... let us see how he evolves "in time" until now it does not look right. Have you forgotten that he IS THE ONE that at certain point did erased all of his questions here leaving answers that could not be understood by others? A very fair and honest act ... is it not?
Quote from: MichaelW on October 06, 2008, 08:26:44 PM
Good example, but I think most beginners will need more then just a vague hint.
invoke RtlMoveMemory, SelXXL$, [esp+12], [esp+12]
translates to:
push [esp+12] ; <--- this decreases the stack by 4
push [esp+12] ; therefore +8 is no longer +8 but rather +12 :wink
push SelXX$
call RtlMoveMemory
:bg
There are some things in this world that are not a democracy, how the team run this forum being one of them. The forum publishes its rules and the method by which it interprets them and enforces them and this will never be subject to debate. To run a web site you must register a domain name which by international law must identify the owner and to set up a web site on a commercial server you have to fully identify yourself and this means the webmaster is subject to all of the laws where the server is established.
US DMCA, copyright laws at an international level, a raft of legislation around the world on malicious code are all appropriate when running an open web site and as a consequence the rules of the forum are designed to ensure that our members are not subject to porn, virus code, cracking techniques, hacking technology and the like and this is not going to change.
There are other venues that lurk in the shadows for this range of crap and if anyone really and truly must play in the sh*tpit then they can go to site of that type but this one will never go down that path.
When one of the admin team ask the question on content of a posting, the choice is to either answer the question or see the post removed, that is not going to change either as we have years of practice dealing with people posting virus and trojan code or related questions, trying to sneak in cracking questions, web hacking techniques and the like with the same old pile of crap trying to justify their freedm of choice to trash other peoples computers.
We are in fact broad and tolerant and encourage low level programming but with hundreds of years of member experience available across our members and team, there will be no nonsence suffered here at all.
The topic has been edited according to the forum rules. If anyone is interested in debate, do so in the Colosseum.