Why structures like wndclassex or msg are stored in stack (for example when you use the local directive, for these structures in the "winmain" typical procedure) with their elements stored backwards? I mean the first element in the wndclassex structure (sbsize) is in the lower addresses, but the last element of this structure (iconsm or something like that) is in the higher addresses of the stack, and so on.
Is this some convention of the assembler, windows, the linker or i'm just missing something important about the "processor rules"?
Btw. with lower and higher addresses in the stack i mean memory addresses and not to how the stack grows to lower addresses and decrease to higher ones.
Maybe it have to do with the little endian thing? Well i really want to know and i'm too tired to think now. ;)
Thanks. ;)
Here is a little testbed showing 4 methods to create a RECT structure. Use it with Olly, and watch in particular the stack.
include \masm32\include\masm32rt.inc
.data
MyRect RECT <12h, 34h, 56h, 78h>
.code
MyTest proc uses edi
Local rc:RECT
int 3 ; right-click on esp, "Follow in Dump"
mov rc.left, 11111111h
mov rc.top, 22222222h
mov rc.right, 33333333h
mov rc.bottom, 44444444h
sub esp, RECT
mov edi, esp
rc2 equ [edi.RECT]
mov rc2.left, 11111101h
mov rc2.top, 22222202h
mov rc2.right, 33333303h
mov rc2.bottom, 44444404h
print hex$(MyRect.right), 9, "global right", 13, 10
print hex$(rc.right), 9, "local right", 13, 10
print hex$(rc2.right), 9, "rc2/edi right", 13, 10
push 44404444h
push 33303333h
push 22202222h
push 11101111h
mov edi, esp
print hex$(rc2.right), 9, "manually pushed right", 13, 10
add esp, 2*RECT
ret
MyTest endp
start:
mov eax, offset MyRect ; right-click on eax, "Follow in Dump"
int 3 ; for Olly
call MyTest
exit
end start
Output:00000056 global right
33333333 local right
33333303 rc2/edi right
33303333 manually pushed right
Quote from: felipe on July 20, 2017, 04:32:24 PM
Maybe it have to do with the little endian thing?
I must be very tired :lol:.
Quote from: jj2007 on July 20, 2017, 04:57:32 PM
.code
MyTest proc uses edi
Local rc:RECT
int 3 ; right-click on esp, "Follow in Dump"
mov rc.left, 11111111h
mov rc.top, 22222222h
mov rc.right, 33333333h
mov rc.bottom, 44444444h
Ok so until here we have that situation that i was talking about.
sub esp, RECT
mov edi, esp
rc2 equ [edi.RECT]
mov rc2.left, 11111101h
mov rc2.top, 22222202h
mov rc2.right, 33333303h
mov rc2.bottom, 44444404h
But until here, i'm a little confussed, is this in the stack or not? I think is not, but why doing this if not?: sub esp, RECT
I will continue analyzing this tomorrow, now i have to sleep a little, thanks a lot jj! :t
sub esp, RECT ; create a RECT on the stack
mov edi, esp ; point to it with edi
rc2 equ [edi.RECT] ; define a RECT
mov rc2.left, 11111101h ; use it
You will understand it better when using the debugger.
Note that
push eax
and
sub esp, DWORD
mov [esp], eax
have the same effect.
sub esp, 96 ; create stack space for locals
; -----------------------------------
; manually coded WNDCLASSEX structure
; -----------------------------------
mov DWORD PTR [ebp-96], 48
mov DWORD PTR [ebp-92], CS_VREDRAW or CS_HREDRAW
mov DWORD PTR [ebp-88], OFFSET MyWndProc
mov DWORD PTR [ebp-84], edi
mov DWORD PTR [ebp-80], edi
mov DWORD PTR [ebp-76], esi
mov DWORD PTR [ebp-72], edi
mov DWORD PTR [ebp-68], eax
mov DWORD PTR [ebp-64], COLOR_BTNFACE+1
mov DWORD PTR [ebp-60], edi
mov DWORD PTR [ebp-56], ebx
mov DWORD PTR [ebp-52], edi
lea eax, [ebp-96]
push eax
call RegisterClassEx ; register the window class
not a "little endian thing" but a "bottom up thing" :icon_cool:
Quote from: jj2007 on July 20, 2017, 05:59:51 PM
sub esp, RECT ; create a RECT on the stack
mov edi, esp ; point to it with edi
rc2 equ [edi.RECT] ; define a RECT
mov rc2.left, 11111101h ; use it
You will understand it better when using the debugger.
Note that
push eax
and
sub esp, DWORD
mov [esp], eax
have the same effect.
I guess i was confused about if this were in the stack because olly showed me code like this:
mov ds:[edi],11111101
mov ds:[edi],etc
Quote from: aw27 on July 20, 2017, 10:02:09 PM
not a "little endian thing" but a "bottom up thing" :icon_cool:
Yeah, later in the night i thought that is logical that the first elements of the structures were in the lower addresses. :P
Quote from: hutch-- on July 20, 2017, 09:11:07 PM
sub esp, 96 ; create stack space for locals
; -----------------------------------
; manually coded WNDCLASSEX structure
; -----------------------------------
mov DWORD PTR [ebp-96], 48
mov DWORD PTR [ebp-92], CS_VREDRAW or CS_HREDRAW
mov DWORD PTR [ebp-88], OFFSET MyWndProc
mov DWORD PTR [ebp-84], edi
mov DWORD PTR [ebp-80], edi
mov DWORD PTR [ebp-76], esi
mov DWORD PTR [ebp-72], edi
mov DWORD PTR [ebp-68], eax
mov DWORD PTR [ebp-64], COLOR_BTNFACE+1
mov DWORD PTR [ebp-60], edi
mov DWORD PTR [ebp-56], ebx
mov DWORD PTR [ebp-52], edi
lea eax, [ebp-96]
push eax
call RegisterClassEx ; register the window class
sub esp,76 ; 48 bytes for wc + 28 bytes for msg.
strucclass:
mov dword ptr[ebp-48],48 ; Size of wc.
mov dword ptr[ebp-44],CS_HREDRAW or CS_VREDRAW
mov dword ptr[ebp-40],wndproc
mov dword ptr[ebp-36],NULL
mov dword ptr[ebp-32],NULL
mov eax,[ebp+8] ; hmodule.
mov [ebp-28],eax
push IDI_APPLICATION
push NULL
call LoadIcon
mov [ebp-24],eax
;mov [ebp-4],eax
push IDC_ARROW
push NULL
call LoadCursor
mov [ebp-20],eax
mov dword ptr[ebp-16],COLOR_WINDOW+1
mov dword ptr[ebp-12],NULL
lea eax,classname
mov [ebp-8],eax
mov dword ptr[ebp-4],NULL
lea eax,[ebp-48]
push eax
call RegisterClassEx
:greensml:
jj i will continue with your code in a moment :bgrin:
Btw, which is the current version downloadable of olly?
I got version 1.x :redface:
I can follow esp in the dump but i can't do the same for eax.
Quote from: jj2007 on July 20, 2017, 04:57:32 PM
Here is a little testbed showing 4 methods to create a RECT structure. Use it with Olly, and watch in particular the stack.
include \masm32\include\masm32rt.inc
.data
MyRect RECT <12h, 34h, 56h, 78h>
.code
MyTest proc uses edi
Local rc:RECT
int 3 ; right-click on esp, "Follow in Dump"
mov rc.left, 11111111h
mov rc.top, 22222222h
mov rc.right, 33333333h
mov rc.bottom, 44444444h
sub esp, RECT
mov edi, esp
rc2 equ [edi.RECT]
mov rc2.left, 11111101h
mov rc2.top, 22222202h
mov rc2.right, 33333303h
mov rc2.bottom, 44444404h
print hex$(MyRect.right), 9, "global right", 13, 10
print hex$(rc.right), 9, "local right", 13, 10
print hex$(rc2.right), 9, "rc2/edi right", 13, 10
push 44404444h
push 33303333h
push 22202222h
push 11101111h
mov edi, esp
print hex$(rc2.right), 9, "manually pushed right", 13, 10
add esp, 2*RECT
ret
MyTest endp
start:
mov eax, offset MyRect ; right-click on eax, "Follow in Dump"
int 3 ; for Olly
call MyTest
exit
end start
Output:00000056 global right
33333333 local right
33333303 rc2/edi right
33303333 manually pushed right
Ok, i think i now understand your code:
1) The four ways are those in the .code section and the one in the .data section, right? ;)
2) Seems like the answer of my first question is simply that the first elements of the structure should be stored in the lower addresses.
3) Esp can't be used as an index, so edi will do this job (for the third way).
4) So finally, all this ways store the structure elementes in the same order in memory: First elements in lower addresses.
Ok, i think i get it, but i have one doubt:
The reason for this:
mov ds:[edi],1111etc
Is because ds is pointing to the same place of ss? Because of the flat memory model?
Thanks alot to all like always! :t
Quote from: felipe on July 21, 2017, 03:25:34 AM
Ok, i think i get it, but i have one doubt:
The reason for this:
mov ds:[edi],1111etc
Is because ds is pointing to the same place of ss? Because of the flat memory model?
Oly has in their roadmap to change that to mov edi, 1111
May take another 13 years though. :biggrin:
Quote from: felipe on July 21, 2017, 03:25:34 AM
1) The four ways are those in the .code section and the one in the .data section, right? ;)
Right.
Quote2) Seems like the answer of my first question is simply that the first elements of the structure should be stored in the lower addresses.
Exactly: Little Endian.
Quote3) Esp can't be used as an index, so edi will do this job (for the third way).
mov [esp.RECT.left], 123 works, too. I used edi as a habit because often esp gets changed by a simple push or pop, so having a "stable reference" is often a good idea. But in this specific case you can just use esp instead of edi.
QuoteThe reason for this:
mov ds:[edi],1111etc
Is because ds is pointing to the same place of ss? Because of the flat memory model?
No, it's simply because Options/Code/Show default segments is enabled. Untick the box.
Note this is Olly 2 (http://www.ollydbg.de/version2.html), in version it's under Options/Debugging options/Disasm.
:bgrin:
JJ! Thanks a lot!
:t