News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Local variables not on the stack

Started by bf2, July 28, 2011, 04:52:54 PM

Previous topic - Next topic

mineiro

You can deal with it manually, like Sr Clive sayd:
Quote.386
.model flat,stdcall
.code
start:
sub esp,4   ;LOCAL one:DWORD
mov dword ptr [esp],1234h      ;mov one,1234h
call front
mov eax,[esp-8]   ;5678h   ;mov eax,two
mov ebx,[esp]   ;1234h   ;mov eax,one
add esp,4
ret

front:
sub esp,4   ;LOCAL two:DWORD
mov dword ptr [esp],5678h      ;mov two,5678h
add esp,4
ret
end start
When you insert PROC inside your code, in default way, masm create some stack frame
Quote.386
.model flat,stdcall
.code
start   proc
LOCAL one:DWORD
mov one,1234h
call front
;mov eax,two      ;localtest.asm(10) : error A2006: undefined symbol : two
mov eax,[esp-12]   ;mov eax,two
mov ebx,one
ret
start endp

front proc
LOCAL two:DWORD
mov two,5678h
ret
front endp
end start
Try do debug these codes using "step into"(F7 key) in olly debug.

bf2

Thank you all for the responses. I understand it now. They key term here is 'private global'.

bf2

Another related question: when variables are defined within procedures and the procedures are in separate modules, how exactly is privacy enforced?

For example, my main program is:

MyProc PROTO

.DATA
num DD 10

.CODE
start:

ADD DWORD PTR DS:[403022], 10 ; num2 is loaded at 403022h

CALL MyProc

INVOKE ExitProcess, NULL
END start


And in a separate file I have my procedure:

.DATA
num2 DD 32

.CODE
MyProc PROC
ADD DWORD PTR DS:[403000], 11 ; num is loaded at 403000h

RET

MyProc ENDP
END


So what I was trying to see is if I can access a private global variable through the backdoor. I clearly cannot access it by name  (the assembler would throw a 'symbol not defined' error), so I was trying to get to them by direct memory access.

Admittedly it's a poor hack because there is no guarantee on exactly where the program will be loaded etc, but the point is I still cannot access the variables this way.

The program gets an access violation error each time.

I first thought it's the assembler that hides private global variables, but now it seems like the OS that hides parts of the DATA segment. Is that correct?

dedndave

for starters, what you are trying to do is just wrong - lol

if you are getting an access violation, there is a good reason for it
it is likely that those addresses are not in the data section
at least - assuming your program is reasonably small

when the EXE is loaded, each section of the PE gets a block of memory assigned to it
these sections normally have different access rights
some may be read-only, some may be read-write, the code section is probably read-execute
you are getting access violation (0x00000005) because you are attempting to write to a section that does not allow write access

redskull

Quote from: bf2 on August 01, 2011, 04:43:45 PM
So what I was trying to see is if I can access a private global variable through the backdoor.

I would be my first guess that by ommitting the hexidecimal radix, you are trying to read the wrong address.

More importantly, though, there really is not such thing as "global" or local" when you get to this low of a level.  There is just memory, and it's all global.  As you saw, you can write DS:[nnnn] with any number you feel like, and the CPU will attempt to access it.  Even "local" variables still exist in their location on the stack after the function ends (at least, that is, until a new function overwrites them).  All of the 'protection' is done by the assembler during the build, and there is none at run-time.

That being said, the OS makes the program allocate ranges of memory it wants to use.  Normally this is transparent to you, as the loader reserves you a default stack, heap, data, and code segments, but if you try and access wildly outlandish ranges that haven't been allocated, you get the errors you see.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

dedndave

you are right about the radix, Red   :P

but....
QuoteAll of the 'protection' is done by the assembler during the build, and there is none at run-time.
:eek

the CPU has this stuff built-in
the OS manipulates the priviledge levels

qWord

Quote from: dedndave on August 01, 2011, 07:28:49 PM
the CPU has this stuff built-in
the OS manipulates the priviledge levels
normally this doesn't apply for the stack, the data-section and dynamically allocated memory (of a user mode app.).
FPU in a trice: SmplMath
It's that simple!

bf2

Quote from: dedndave on August 01, 2011, 07:28:49 PM
you are right about the radix, Red   :P

Yes, that was dead silly  :lol

I'll try to access those memory locations *using the hex radix this time* and see what happens.

dedndave

Quote from: qWord on August 01, 2011, 07:37:21 PM
Quote from: dedndave on August 01, 2011, 07:28:49 PM
the CPU has this stuff built-in
the OS manipulates the priviledge levels
normally this doesn't apply for the stack, the data-section and dynamically allocated memory (of a user mode app.).

if you want to test it, it is easy enough
        INCLUDE \masm32\include\masm32rt.inc

        .CODE

_main   PROC

        mov byte ptr CodeLabel,90h
        INVOKE  ExitProcess,0

CodeLabel db 90h

_main   ENDP

        END     _main


the app will crash with an access violation because the code section has an attribute of read-execute
it exists in dynamically allocated memory

the stack, data, and data? sections all have read-write attributes
(normally, these are combined into one section)
no matter how you access them, you can read and write   :P

a const section, if present, has a read-only attribute

qWord

maybe a missunderstanding,
but I was referring to redskulls statment, that there is no protection of the global or local variables at runtime.
There are no mechanisms of the OS, that prevents you from modifying global or locals variables at runtime - all you need, is the address of them.
FPU in a trice: SmplMath
It's that simple!

dedndave

the CPU's use page tables that have entries for all allocated blocks
in these tables, the OS can set the priviledge level - who access has to the block
and the access rights - what priviledge level has which rights - read, write, execute, and a few others
it is similar to windows policy mechanism, in a way

while the data for YOUR application normally has read-write access rights, you CAN change it
the OS offers a mechanism to do this
you just never see it, because - why would you want to change it ? - lol
still, the mechanism exists to do so

also, because of priviledge level, the memory for your program is protected from other user-mode processes

qWord

bf2 was asking about the scope of local and global variables - this is a protecting mechanism at assembly/compile time.
FPU in a trice: SmplMath
It's that simple!

dedndave

i understand that
i also understand that he may not be accessing his own stuff   :P

KeepingRealBusy

Quote from: dedndave on July 28, 2011, 06:30:22 PM

code labels within the same module are local (private) if inside a PROC
otherwise, they are global

Dave,

Watch out! There is a known bug in MASM. You can rename a PROC local code label outside of any PROC and cause wild JMPs to the middle of nowhere from within the original PROC. The Feedback ID is 550808.

Dave.

redskull

My point is that there is no protection for "variables" per say.  The protection level of a segment has nothing to do with the scope of symbols in the source, which is the what the OP seems keen on.  If you can read/write it from one place, you can read/write it from any other place (or vice-versa).

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government