News:

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

Assembly thunking in MASM

Started by gwapo, April 20, 2006, 06:07:13 AM

Previous topic - Next topic

gwapo

Hi,

So far, I already completed a simple control, thanks to tutorial in catch22 for a the great article in writting win32 control from scratch. One of the method mentioned from the article is assembly thunking, I tried, but I got no luck making it to work, this is where I'm asking for some help.

Probably, some of you already managed to do this:
http://www.pluralsight.com/articlecontent/cpprep0399.htm

The idea is to change the first parameter (hWnd) of WndProc, into a pointer to window's properties (struct), then jumping to the real WndProc, something like this:



WndProperties struct
   __hwnd  dd ?
   __backcolor COLORREF ?
   __forecolor COLORREF ?
WndProperties ends

ThunkBlock:

   mov [esp+4], 0ffffffffh  ; <-- replace 0ffffffffh with pointer to hWnd properties
   jmp  RealWndProc

ThunkBlockEnd:

StartupWndProc proc hWnd:HWND, uMsg:dword, wParam:WPARAM, lParam:LPARAM

  ; This WndProc will be executed only once
  .if eax==WM_NCCREATE

     ; Create a new assembly thunk here, copying ThunkBlock to ThunkBlockEnd
     ; And then subclass the window to the new created assembly thunk

  .endif

StartupWndProc endp

RealWndProc proc hWnd:HWND, uMsg:dword, wParam:WPARAM, lParam:LPARAM

   push ebx
   mov ebx, hWnd
   assume ebx: ptr WndProperties

   ; [ebx] contains a pointer to WndProperties instance for this hWnd
   ; we can use it to easily get/set property values, when the
  ; appropriate message is called
 
   invoke DefWindowProc, [ebx].__hwnd, uMsg, wParam, lParam

   pop ebx
   assume ebx: nothing
   ret

RealWndProc endp



The problem is, if I catch WM_NCCREATE message (from StartupWndProc) to install the assembly thunk for my control, then it is throwing an exception that there's an illegal code executed, thi happens because I'm creating the assembly thunk to the process heap. But if I created the assembly thunk somewhere to a predefined area in the .code section (I have to patch the executable to allow write to .code section by doing this), everything works fine. I am thinking that the process heap has no execute permission...

Any suggestion into where is the best place to store created assembly thunk?

I was wondering how ATL managed to do this...  ::)

Thanks in advance,

-chris

Biterider

Hi
You can place it in the .data section, but you have to deactivate DEP on modern machines that supports it on hardware.
Basically you can put it on the heap but you must set the PAGE_EXECUTE_READWRITE attribute using the VirtualProtect API.

Biterider

gwapo

Thanks biterider for the hint on using VirtualProtect API, but I can't make it work; can I ask for a small isnipet on how to enable execute in the heap. I'm doing it like this:



  invoke GetProcessHeap
  mov    _pheap, eax
  invoke VirtualProtect, _pheap, sizeof WndProperties, PAGE_EXECUTE_READWRITE, addr _oldProtect



The code above seems okay, but when I allocate some heap for executable code, the program is shutdown by windows due to protection fault. Any more hint?


Regards,

-chris


Biterider

I have an alternative to the current OA32 Event calling based on thunking. It was not developed by me so I can not make it public, but I can send it to you by email if you get it to me. Be avare that it is not well commented since it is an experimental code but the thunking part works OK.

Regards,

Biterider

gwapo

Thanks for the reply, I think I already managed to make it work  :U
Although I'm still solving some area, but I think it should be fine.

I'll post the working code when my control is fully working, thanks again.

Cheers,

-chris

zooba

gwapo,

The Virtual* functions don't use a heap. You need to specify the actual address of the allocated memory there. I don't believe it is possible to enable execute in the heap, you'll have to allocate memory using VirtualAlloc instead.

Cheers,

Zooba

gwapo

Thanks zooba, (sorry for the long response)

That's actually what I did, using VirtualAlloc function to store my dynamically created thunks, but eventually when there are already instances of my custom control that implement thunking, the size grow and I have to pull some linked list to maintain it.

Regards,

-chris

ramguru

gwapo,
please post full source-code of that example in your starting post!

How do you allocate WndProperties structure ?
How do you pass that returned pointer here   ?  |mov [esp+4], 0ffffffffh  ; <-- replace 0ffffffffh with pointer to hWnd properties|

ramguru

Behold!
This is a pure "ATL thunking" example adapted for assembly projects.
After a long day of debugging, tracing, reading listing files I made it.
The demonstration is based by control that I made in three minutes.

[attachment deleted by admin]

gwapo

It's already morethan a year since I posted this. But it's not too late to say thanks!
Thanks ramguru for this great demo on thunking., this give me another reason to work with custom controls again  :wink

Cheers,
-chris

ramguru

It took me a while, but I've made 64bit version of the ATL thunking (used goasm syntax). Now I can get started with some controls :}
And it seems SetWndowLongPtr is not supported in Window 7 (7201build) (not appear in user32.dll export list) - what a pain..

[attachment deleted by admin]

feicong

64bit version ? thanks ,but i don't know how to build it?

ramguru

I'm using gorc,goasm,golink.
I have a bat file (it's assumed that goasm resides in C:\goasm dir &
that donkey's include (*.h) files reside in C:\goasm\inc dir:

@echo off
set INCLUDE=C:\GoASM\inc

if not exist rsrc.rc goto over1
C:\GOASM\bin\gorc /o /machine X64 rsrc.rc
:over1

if exist "%1.obj" del "%1.obj"
if exist "%1.exe" del "%1.exe"

C:\GOASM\bin\goasm /x64 "%1.asm"
if errorlevel 1 goto errasm

if not exist rsrc.obj goto nores

C:\GOASM\bin\golink "%1.obj" rsrc.obj
if errorlevel 1 goto errlink

dir "%1.*"
goto TheEnd

:nores
C:\GOASM\bin\golink "%1.obj"
if errorlevel 1 goto errlink
dir "%1.*"
goto TheEnd

:errlink
echo _
echo Link error
goto TheEnd

:errasm
echo _
echo Assembly Error
goto TheEnd

:TheEnd
del "%1.obj"
del rsrc.obj


build example:

C:\GOASM\projects\dummy_control64>c:\goasm\bin\bldallx64.bat dummy_control

GoRC.Exe Version 0.90.4 - Copyright Jeremy Gordon 1998/2009 - JG@JGnet.co.uk
Output file: rsrc.obj format: X64

GoAsm.Exe Version 0.56.6b - Copyright Jeremy Gordon 2001/9 - JG@JGnet.co.uk
Output file: dummy_control.obj

GoLink.Exe Version 0.26.10 - Copyright Jeremy Gordon 2002/9 - JG@JGnet.co.uk
Output file: dummy_control.exe
Format: X64 size: 5,120 bytes
Volume in drive C has no label.
Volume Serial Number is FC38-E563

Directory of C:\GOASM\projects\dummy_control64

06/11/2009  12:52 AM             4,390 dummy_control.asm
06/26/2009  07:22 PM             5,120 dummy_control.exe
06/26/2009  07:22 PM             4,061 dummy_control.obj
               3 File(s)         13,571 bytes
               0 Dir(s)  395,880,914,944 bytes free