News:

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

how do i get the Address of a Procedure ?

Started by Rainstorm, January 18, 2008, 03:24:19 PM

Previous topic - Next topic

Rainstorm

how do i get the address of a Procedure ?  - for example i need the address of the wndproc of a window to supbclass it in the SetWindowLong Function.
Also,.. in the SetWindowLong Function what is nIndex exactly ?

- I'll be using the GWL_WNDPROC  for nIndex while subclassing a window .
it says
QuoteGWL_WNDPROC   -  Sets a new address for the window procedure.
is it that what they really mean there, is that it sets a flag that allows the new address to be set ? - since the new address itself seems to be supplied in the next argument dwNewLong

thanks!

Rainstorm.

-

hutch--

 :bg

There is a toy in the masm32 project called "subclass".


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

; ---------------------------------------------------
; Prototype
; ~~~~~~~~~
; CtrlProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
;
; .DATA? section entries
; ~~~~~~~~~~~~~~~~~~~~~
; lpCtrlProc           dd ?
; hCtrl                dd ?
;
; The following API call should be placed on the line
; following the function call that creates the control
;
; invoke SetWindowLong,hCtrl,GWL_WNDPROC,CtrlProc
; mov lpCtrlProc, eax
; ---------------------------------------------------

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

CtrlProc proc hCtl   :DWORD,
              uMsg   :DWORD,
              wParam :DWORD,
              lParam :DWORD


  ; -----------------------------
  ; Process control messages here
  ; -----------------------------

    invoke CallWindowProc,lpCtrlProc,hCtl,uMsg,wParam,lParam

    ret

CtrlProc endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««


With SetWindowLong() all you need to supply is the window handle as the function can find the messge handling procedure from the handle. The constant "GWL_WNDPROC" just tells the function WHAT is being changed.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Rainstorm

hutch, thanks for the example & clearing up those questions.
I made a mistake..Its how to find the address of the new wndproc, (i.e. the pointer that needs to be supplied in dwNewLong in the SetWindowLong Function) that I wanted to know. - however your example cleared that up.. from which i gather, i need to just put the name of the new wndproc for the dwNewLong parameter,.. & that name itself is the pointer to the address of the new wndproc. like..invoke SetWindowLong,hCtrl,GWL_WNDPROC,MyNewWndProcName

Rainstorm.

-

jdoe


All the same...


invoke SetWindowLong, hCtrl, GWL_WNDPROC, MyNewWndProcName



invoke SetWindowLong, hCtrl, GWL_WNDPROC, addr MyNewWndProcName



mov eax, offset MyNewWndProcName

push eax
push GWL_WNDPROC
push hCtrl
call SetWindowLong



Rainstorm

jdoe wrote..All the same...
Code:
invoke SetWindowLong, hCtrl, GWL_WNDPROC, MyNewWndProcName

Code:
invoke SetWindowLong, hCtrl, GWL_WNDPROC, addr MyNewWndProcName


Oh!!.......I didn't know that.

so you could do this too then..? mov eax,  MyNewWndProcName

-

jdoe

Quote from: Rainstorm on January 18, 2008, 08:03:26 PM
so you could do this too then..? mov eax,  MyNewWndProcName

Yes, but for readability, I think "addr MyNewWndProcName" or "offset MyNewWndProcName" make more sense.

:U


Rainstorm

after assembling i got an error saying MyNewWndProc is  not a valid symbol or something.. so i defined it in my .Data section. after which the whole thing assembled proper

MyNewWndProc        dd    0

now what happens when i call SetWindowLong ? , '0' gets added there ?

invoke SetWindowLong, hCtrl, GWL_WNDPROC, MyNewWndProcName

to be honest i don't understand the whole thing.. & also how both the following statements can be the same.
invoke SetWindowLong, hCtrl, GWL_WNDPROC, MyNewWndProcName

invoke SetWindowLong, hCtrl, GWL_WNDPROC, addr MyNewWndProcName


-

jdoe

Quote from: Rainstorm on January 21, 2008, 07:25:45 PM
after assembling i got an error saying MyNewWndProc is  not a valid symbol or something.. so i defined it in my .Data section. after which the whole thing assembled proper

MyNewWndProc        dd    0

Rainstorm,

Don't put MyNewWndProc in the data section, it doesn't belong there. MyNewWndProc is a procedure and unless MyNewWndProc is defined before the call of SetWindowLong, you just need to create a prototype for it at the beginning of the source and the problem is solved.

MyNewWndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD



Quote from: Rainstorm on January 21, 2008, 07:25:45 PM
to be honest i don't understand the whole thing.. & also how both the following statements can be the same.

invoke SetWindowLong, hCtrl, GWL_WNDPROC, MyNewWndProcName
invoke SetWindowLong, hCtrl, GWL_WNDPROC, addr MyNewWndProcName

See it as a label. You can get the address of a label and it's the same for a procedure.

:wink


Rainstorm

jdoe wrote..
QuoteMyNewWndProc is a procedure and unless MyNewWndProc is defined before the call of SetWindowLong, you just need to create a prototype for it at the beginning of the source and the problem is solved.
jdoe, I had made a prototype at the beginning but it still wouldn't assemble proper. the MyNewWndProc procedure itself is below down in the source after the SetWindowLong call.

thankyou
-

donkey

Quote from: Rainstorm on January 21, 2008, 07:25:45 PM
after assembling i got an error saying MyNewWndProc is  not a valid symbol or something.. so i defined it in my .Data section. after which the whole thing assembled proper

MyNewWndProc        dd    0

You could do this but you would have to set the value to the offset of the actual procedure...

pMyNewWndProc        dd   offset MyNewWndProc

Quotenow what happens when i call SetWindowLong ? , '0' gets added there ?

invoke SetWindowLong, hCtrl, GWL_WNDPROC, MyNewWndProcName

From the line I showed you above it would change to

invoke SetWindowLong, hCtrl, GWL_WNDPROC, pMyNewWndProc

Quoteto be honest i don't understand the whole thing.. & also how both the following statements can be the same.
invoke SetWindowLong, hCtrl, GWL_WNDPROC, MyNewWndProcName

invoke SetWindowLong, hCtrl, GWL_WNDPROC, addr MyNewWndProcName


-
They are not the same, the first one passes the dereferenced value at the address of MyNewWndProcName and the second passes the actual address. This would be equivalent to ByVal and ByRef in VB, as you probably know they are very different. The SetWindowLong procedure requires an address when using GWL_WNDPROC so the first example is completely wrong and will probably cause your program to generate an exception.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Rainstorm

donkey wrote..
QuoteThis would be equivalent to ByVal and ByRef in VB, as you probably know they are very different.
Don't know anything about VB but yes i know in assembler, one is the value & the other is the address of the value.

donkey wrote..
QuoteThe SetWindowLong procedure requires an address when using GWL_WNDPROC ..
yes that's why my question was how to find the address of a procedure

MyNewWndProc        dd    0
pMyNewWndProc        dd   offset MyNewWndProc


just to know;.. is this the only way of doing it(getting the address of the procedure in my code) or are there some other ways ?

thanks.
-

jdoe

Quote from: donkey on January 22, 2008, 02:31:03 AM

invoke SetWindowLong, hCtrl, GWL_WNDPROC, MyNewWndProcName

invoke SetWindowLong, hCtrl, GWL_WNDPROC, addr MyNewWndProcName


They are not the same, the first one passes the dereferenced value at the address of MyNewWndProcName and the second passes the actual address. This would be equivalent to ByVal and ByRef in VB, as you probably know they are very different. The SetWindowLong procedure requires an address when using GWL_WNDPROC so the first example is completely wrong and will probably cause your program to generate an exception.
Quote


Sorry to contradict you but both are correct with MASM. Although using offset or addr make more sense, there is no exception generated.



.code

start:

mov eax, Main
mov ecx, offset Main

invoke ExitProcess, 0

Main Proc

    ret

Main endp

end start




00401000                    start:
00401000 B811104000             mov     eax,401011h
00401005 B911104000             mov     ecx,401011h
0040100A 6A00                   push    0
0040100C E801000000             call    fn_00401012
00401011 C3                     ret
00401012                    fn_00401012:
00401012 FF2500204000           jmp     dword ptr [ExitProcess]



hutch--

Rainstorm,

The trick is to understand what the SetWindowlong() function does. When you create a window "class" you must fill out the characteristics you need in a WNDCLASSEX structure. that structure is stored by the operating system in conjunction with the window that you create so that the window has its settings and characteristics available when the OS is asked to do something like resize it or if another window overlaps it.

SetWindowLong() modifies the data that you put in the WNDCLASSEX structure so that the window then has different characteristics. Now some parts of the WNDCLASSEX structure need to have an offset specified so you can change some parts of it but with the more common parts tha are changed Windows provides a number of constants that indicate which offset is changed.

The GWL_WNDPROC constant tells tha function which offset is to be changed.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php