Discussion:
VirtualAlloc
(too old to reply)
mr.sir bossman
2005-07-17 11:17:01 UTC
Permalink
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.

I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."

struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};

class CWndProcThunk
{
public:
CWndProcThunk()
{
thunk = (_WndProcThunk *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
}

_WndProcThunk *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk->m_mov = 0x042444C7; //C7 44 24 0C
thunk->m_this = (DWORD)pThis;
thunk->m_jmp = 0xe9;
thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};

WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pProc);
Bo Persson
2005-07-17 12:15:19 UTC
Permalink
Post by mr.sir bossman
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.
I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."
struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};
No, you haven't considered alignment, this is more probably 16 bytes, as
there will likely be 3 unused bytes between m_jmp and m_relproc.

Check what sizeof(_WndProcThunk) really returns!


And, what are you trying to hack in the first place? :-)

Bo Persson
mr.sir bossman
2005-07-17 13:25:04 UTC
Permalink
Post by Bo Persson
Post by mr.sir bossman
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.
I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."
struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};
No, you haven't considered alignment, this is more probably 16 bytes, as
there will likely be 3 unused bytes between m_jmp and m_relproc.
Check what sizeof(_WndProcThunk) really returns!
I did a trace and sizeof(_WndProcThunk) = 13 bytes
Post by Bo Persson
And, what are you trying to hack in the first place? :-)
Toying around trying to fix ATL for AMD.
mr.sir bossman
2005-07-17 13:30:01 UTC
Permalink
Post by mr.sir bossman
Post by Bo Persson
Post by mr.sir bossman
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.
I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."
struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};
No, you haven't considered alignment, this is more probably 16 bytes, as
there will likely be 3 unused bytes between m_jmp and m_relproc.
Check what sizeof(_WndProcThunk) really returns!
I did a trace and sizeof(_WndProcThunk) = 13 bytes
NM, 16 your correct.
Post by mr.sir bossman
Post by Bo Persson
And, what are you trying to hack in the first place? :-)
Toying around trying to fix ATL for AMD.
test
2010-02-23 04:48:01 UTC
Permalink
Post by mr.sir bossman
Post by Bo Persson
Post by mr.sir bossman
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.
I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."
struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};
No, you haven't considered alignment, this is more probably 16 bytes, as
there will likely be 3 unused bytes between m_jmp and m_relproc.
Check what sizeof(_WndProcThunk) really returns!
I did a trace and sizeof(_WndProcThunk) = 13 bytes
Post by Bo Persson
And, what are you trying to hack in the first place? :-)
Toying around trying to fix ATL for AMD.
Severian [MVP]
2005-07-17 14:32:26 UTC
Permalink
On Sun, 17 Jul 2005 04:17:01 -0700, "mr.sir bossman"
Post by mr.sir bossman
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.
I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."
struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};
class CWndProcThunk
{
CWndProcThunk()
{
thunk = (_WndProcThunk *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
}
_WndProcThunk *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk->m_mov = 0x042444C7; //C7 44 24 0C
thunk->m_this = (DWORD)pThis;
thunk->m_jmp = 0xe9;
thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pProc);
Besides the structure alignment issues covered by Bo, here are some
drawbacks to, and problems with, this approach:

1) Each thunk will require at least a physical page of memory (the
granularity of VirtualAlloc).

2) When do you call Init()? Is there a guarantee that it is the first
message processed by the window?

3) Each WindowProc must load pThis.

4) It is processor-specific, and will have to be redone for 64-bit
Windows.

FWIW, MFC does this by maintaining a map of handles to addresses, and
uses a CBT hook.

--
Phillip Crews aka Severian
Microsoft MVP, Windows SDK
Posting email address is real, but please post replies on the newsgroup.
mr.sir bossman
2005-07-17 16:15:01 UTC
Permalink
Any help on how to use virtualalloc to do a proper thunk is greatly
appreciated.
Post by Severian [MVP]
Post by mr.sir bossman
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.
I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."
struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};
class CWndProcThunk
{
CWndProcThunk()
{
thunk = (_WndProcThunk *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
}
_WndProcThunk *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk->m_mov = 0x042444C7; //C7 44 24 0C
thunk->m_this = (DWORD)pThis;
thunk->m_jmp = 0xe9;
thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pProc);
Besides the structure alignment issues covered by Bo, here are some
Use #pragma pack?
Post by Severian [MVP]
1) Each thunk will require at least a physical page of memory (the
granularity of VirtualAlloc).
True. Need to allocate slab for more then one window, allocate as you need
it.
Post by Severian [MVP]
2) When do you call Init()? Is there a guarantee that it is the first
message processed by the window?
Yes. Use global to hold threadID for first Windowproc and then just use
Setprop/getprop.
Post by Severian [MVP]
3) Each WindowProc must load pThis.
No different than using setprop/getprop
Post by Severian [MVP]
4) It is processor-specific, and will have to be redone for 64-bit
Windows.
True.
Post by Severian [MVP]
FWIW, MFC does this by maintaining a map of handles to addresses, and
uses a CBT hook.
I usually do it with global-setprop/getprop.

I just wanted to fool around and see if I could do it. No good examples on
the web. Again, Any help greatly appreciated.

BTW, I have already converted my ATL files to were I can turn thunking off/on.
Severian [MVP]
2005-07-17 16:33:04 UTC
Permalink
On Sun, 17 Jul 2005 09:15:01 -0700, "mr.sir bossman"
Post by mr.sir bossman
Any help on how to use virtualalloc to do a proper thunk is greatly
appreciated.
Post by Severian [MVP]
Post by mr.sir bossman
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.
I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."
struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};
class CWndProcThunk
{
CWndProcThunk()
{
thunk = (_WndProcThunk *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
}
_WndProcThunk *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk->m_mov = 0x042444C7; //C7 44 24 0C
thunk->m_this = (DWORD)pThis;
thunk->m_jmp = 0xe9;
thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pProc);
Besides the structure alignment issues covered by Bo, here are some
Use #pragma pack?
Personally, I would use a simple array of bytes, but that comes down
to personal taste.
Post by mr.sir bossman
Post by Severian [MVP]
1) Each thunk will require at least a physical page of memory (the
granularity of VirtualAlloc).
True. Need to allocate slab for more then one window, allocate as you need
it.
Yes, and the thunks may execute more quickly if manually aligned (just
as compilers often insert NOPs before function entry points to align
them).

Also, you need to maintain a free list of thunks lest the memory grow
continuously as windows are created.
Post by mr.sir bossman
Post by Severian [MVP]
2) When do you call Init()? Is there a guarantee that it is the first
message processed by the window?
Yes. Use global to hold threadID for first Windowproc and then just use
Setprop/getprop.
I still don't understand when you call Init()?
Post by mr.sir bossman
Post by Severian [MVP]
3) Each WindowProc must load pThis.
No different than using setprop/getprop
True.
Post by mr.sir bossman
Post by Severian [MVP]
4) It is processor-specific, and will have to be redone for 64-bit
Windows.
True.
Post by Severian [MVP]
FWIW, MFC does this by maintaining a map of handles to addresses, and
uses a CBT hook.
I usually do it with global-setprop/getprop.
I just wanted to fool around and see if I could do it. No good examples on
the web. Again, Any help greatly appreciated.
BTW, I have already converted my ATL files to were I can turn thunking off/on.
Cool. Is there a noticeable performance difference?

--
Phillip Crews aka Severian
Microsoft MVP, Windows SDK
Posting email address is real, but please post replies on the newsgroup.
mr.sir bossman
2005-07-17 16:59:02 UTC
Permalink
Post by Severian [MVP]
Post by mr.sir bossman
Any help on how to use virtualalloc to do a proper thunk is greatly
appreciated.
Personally, I would use a simple array of bytes, but that comes down
to personal taste.
I tryed that, again got same error. See below.

class CWndProcThunk
{
public:

BYTE *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk = (BYTE *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );

memcpy(reinterpret_cast<void*>(thunk[0]),reinterpret_cast<void*>(0x042444C7),4);
memcpy(reinterpret_cast<void*>(thunk[4]),reinterpret_cast<void*>(pThis),4);
memcpy(reinterpret_cast<void*>(thunk[8]),reinterpret_cast<void*>(0xe9),1);
memcpy(reinterpret_cast<void*>(thunk[9]), reinterpret_cast<void*>((int)proc
- ((int)thunk + 16)),4);

FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
#endif
pThis->m_thunk.Init(WindowProc2, pThis);
WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pProc);
Post by Severian [MVP]
Also, you need to maintain a free list of thunks lest the memory grow
continuously as windows are created.
Thats what I was thinking. Global Thunk pool. Ugh, globals make me cringe. :)
Post by Severian [MVP]
I still don't understand when you call Init()?
I call it during the first window message. WM_NCCREATE(I guess, don't really
check).
Post by Severian [MVP]
Cool. Is there a noticeable performance difference?
No real differance. Note: Have not tested for mass windows. Normal size app
it is about the same/the same. Note: Pentium 2ghz 3gig ram.
Severian [MVP]
2005-07-17 17:30:59 UTC
Permalink
On Sun, 17 Jul 2005 09:59:02 -0700, "mr.sir bossman"
Post by mr.sir bossman
Post by Severian [MVP]
Post by mr.sir bossman
Any help on how to use virtualalloc to do a proper thunk is greatly
appreciated.
Personally, I would use a simple array of bytes, but that comes down
to personal taste.
I tryed that, again got same error. See below.
Where does the crash occur? In the thunk (on the JMP) or in your
window proc?
Post by mr.sir bossman
class CWndProcThunk
{
BYTE *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk = (BYTE *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
memcpy(reinterpret_cast<void*>(thunk[0]),reinterpret_cast<void*>(0x042444C7),4);
memcpy(reinterpret_cast<void*>(thunk[4]),reinterpret_cast<void*>(pThis),4);
memcpy(reinterpret_cast<void*>(thunk[8]),reinterpret_cast<void*>(0xe9),1);
memcpy(reinterpret_cast<void*>(thunk[9]), reinterpret_cast<void*>((int)proc
- ((int)thunk + 16)),4);
Is 16 correct here?
Post by mr.sir bossman
FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
#endif
pThis->m_thunk.Init(WindowProc2, pThis);
WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pProc);
Post by Severian [MVP]
Also, you need to maintain a free list of thunks lest the memory grow
continuously as windows are created.
Thats what I was thinking. Global Thunk pool. Ugh, globals make me cringe. :)
While it's useful to avoid them, globals -- like gotos -- have
appropriate uses.

Also, access to the thunk pool will need to be synchronized between
threads (or create a separate pool for each thread), in case of
applications with multiple UI threads.
Post by mr.sir bossman
Post by Severian [MVP]
I still don't understand when you call Init()?
I call it during the first window message. WM_NCCREATE(I guess, don't really
check).
I checked a top-level window on XP, and its WindowProc received
WM_GETMINMAXINFO before WM_NCCREATE. Depending on the O/S and window
style, there may be other orders (and other messages before NCCREATE).
I guess that's why MFC uses a CBT hook to detect window creation.
Post by mr.sir bossman
Post by Severian [MVP]
Cool. Is there a noticeable performance difference?
No real differance. Note: Have not tested for mass windows. Normal size app
it is about the same/the same. Note: Pentium 2ghz 3gig ram.
--
Phillip Crews aka Severian
Microsoft MVP, Windows SDK
Posting email address is real, but please post replies on the newsgroup.
mr.sir bossman
2005-07-17 18:09:01 UTC
Permalink
Post by Severian [MVP]
Where does the crash occur? In the thunk (on the JMP) or in your
window proc
memcpy(reinterpret_cast<void*>(thunk[0]),reinterpret_cast<void*>(0x042444C7),4);
Post by Severian [MVP]
Is 16 correct here?
16 was typo. When I was using structure I used #pragma pack(push,1) so it
was also 13.
Post by Severian [MVP]
While it's useful to avoid them, globals -- like gotos -- have
appropriate uses.
Agree.
Post by Severian [MVP]
Also, access to the thunk pool will need to be synchronized between
threads (or create a separate pool for each thread), in case of
applications with multiple UI threads.
yea.
Post by Severian [MVP]
I checked a top-level window on XP, and its WindowProc received
WM_GETMINMAXINFO before WM_NCCREATE. Depending on the O/S and window
style, there may be other orders (and other messages before NCCREATE).
I guess that's why MFC uses a CBT hook to detect window creation.
Global easier. I used map(thread id/hwnd).
mr.sir bossman
2005-07-17 18:39:02 UTC
Permalink
DWORD buff = 0x042444C7;
memcpy(reinterpret_cast<void*>(&thunk[0]),reinterpret_cast<void*>(&buff),4);
memcpy(reinterpret_cast<void*>(&thunk[4]),reinterpret_cast<void*>(&pThis),4);
DWORD buff2 = 0xe9;
memcpy(reinterpret_cast<void*>(&thunk[8]),reinterpret_cast<void*>(&buff2),1);


What should this line look like?
memcpy(reinterpret_cast<void*>(&thunk[9]), reinterpret_cast<void*>((int)proc
- ((int)thunk + 13)),4);

ATL looks like this.
thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
Severian [MVP]
2005-07-17 19:18:58 UTC
Permalink
On Sun, 17 Jul 2005 11:39:02 -0700, "mr.sir bossman"
Post by mr.sir bossman
DWORD buff = 0x042444C7;
memcpy(reinterpret_cast<void*>(&thunk[0]),reinterpret_cast<void*>(&buff),4);
memcpy(reinterpret_cast<void*>(&thunk[4]),reinterpret_cast<void*>(&pThis),4);
DWORD buff2 = 0xe9;
memcpy(reinterpret_cast<void*>(&thunk[8]),reinterpret_cast<void*>(&buff2),1);
What should this line look like?
memcpy(reinterpret_cast<void*>(&thunk[9]), reinterpret_cast<void*>((int)proc
- ((int)thunk + 13)),4);
Assuming the opcodes and computation are correct:

DWORD buff3 = (int)proc - ((int)thunk + 13);
memcpy(&thunk[9], &buff3);

(Casts neglected for readability. Sometimes C is a much more readable
language. :)
Post by mr.sir bossman
ATL looks like this.
thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
--
Phillip Crews aka Severian
Microsoft MVP, Windows SDK
Posting email address is real, but please post replies on the newsgroup.
mr.sir bossman
2005-07-17 20:16:02 UTC
Permalink
OHHHHH MY GODDDDD IT WORKS!!!!. Thx a bizzillion Severian. Couldn't have done
it without you.

Now my ATL File will get another upgrade/fix. Why doesn't Microsoft open
source ATL?

Code is below--Rough draft. Now with this as a template I can set up for
different processors/ global memory thunk pool. I love it.

Link for why code is needed.
http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2mempr.mspx

class CWndProcThunk
{
public:
BYTE *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk = (BYTE *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );

DWORD buff = 69485767;//hex 0x042444C7
memcpy((void *)(&thunk[0]),(void *)(&buff),4);

DWORD buff1 = (DWORD)pThis;
memcpy((void *)(&thunk[4]),(void *)(&buff1),4);

DWORD buff2 = 233;//hex 0xe9
memcpy((void *)(&thunk[8]),(void *)(&buff2),1);

DWORD buff3 = (int)proc - ((int)thunk + 13);
memcpy((void *)(&thunk[9]), (void *)(&buff3),4);

FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
Ivan Brugiolo [MSFT]
2005-07-17 21:05:43 UTC
Permalink
You mentioned earlier you were `fixing ATL for AMD`.
Were you trying to bypass the Data Execution Prevention of the AMD64/EM64T
CPUs ?
Isn't the ATL code shipped with the version of Visual Studio ?
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by mr.sir bossman
OHHHHH MY GODDDDD IT WORKS!!!!. Thx a bizzillion Severian. Couldn't have done
it without you.
Now my ATL File will get another upgrade/fix. Why doesn't Microsoft open
source ATL?
Code is below--Rough draft. Now with this as a template I can set up for
different processors/ global memory thunk pool. I love it.
Link for why code is needed.
http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2mempr.mspx
class CWndProcThunk
{
BYTE *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk = (BYTE *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
DWORD buff = 69485767;//hex 0x042444C7
memcpy((void *)(&thunk[0]),(void *)(&buff),4);
DWORD buff1 = (DWORD)pThis;
memcpy((void *)(&thunk[4]),(void *)(&buff1),4);
DWORD buff2 = 233;//hex 0xe9
memcpy((void *)(&thunk[8]),(void *)(&buff2),1);
DWORD buff3 = (int)proc - ((int)thunk + 13);
memcpy((void *)(&thunk[9]), (void *)(&buff3),4);
FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
mr.sir bossman
2005-07-17 21:37:02 UTC
Permalink
Post by Ivan Brugiolo [MSFT]
You mentioned earlier you were `fixing ATL for AMD`.
Were you trying to bypass the Data Execution Prevention of the AMD64/EM64T
CPUs ?
You get a perfomance hit using old time thunks.
http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2mempr.mspx
Thats why they tell you to use VirtualAlloc.
Post by Ivan Brugiolo [MSFT]
Isn't the ATL code shipped with the version of Visual Studio ?
Dunno, I am using Visual C++ 6.0. <-Love it, see no need to change.
Post by Ivan Brugiolo [MSFT]
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
I have done nothing wrong. Just doing what Microsoft has told me to do. Read
my link above.
Ivan Brugiolo [MSFT]
2005-07-17 22:28:35 UTC
Permalink
Sorry, probably I did not pose the question correctly.

As far as I can remember, the ALT code was fixed in service packs for
supported version of Visual Studio to correctly set the execute permission
on the thunk code generated by ATL to perform
the WNDPROC-to-member-finction conversion.
Thad code has to necessarely go through VirtualAlloc/VirtualProtect.

My question was why you were in the need to re-implement that functionality.
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by mr.sir bossman
Post by Ivan Brugiolo [MSFT]
You mentioned earlier you were `fixing ATL for AMD`.
Were you trying to bypass the Data Execution Prevention of the AMD64/EM64T
CPUs ?
You get a perfomance hit using old time thunks.
http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2mempr.mspx
Thats why they tell you to use VirtualAlloc.
Post by Ivan Brugiolo [MSFT]
Isn't the ATL code shipped with the version of Visual Studio ?
Dunno, I am using Visual C++ 6.0. <-Love it, see no need to change.
Post by Ivan Brugiolo [MSFT]
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
I have done nothing wrong. Just doing what Microsoft has told me to do. Read
my link above.
mr.sir bossman
2005-07-18 12:11:02 UTC
Permalink
Post by Ivan Brugiolo [MSFT]
As far as I can remember, the ALT code was fixed in service packs for
supported version of Visual Studio to correctly set the execute permission
on the thunk code generated by ATL to perform
the WNDPROC-to-member-finction conversion.
Thad code has to necessarely go through VirtualAlloc/VirtualProtect.
Does that cover Visual c++ 6.0?
a***@club-internet.fr
2005-07-18 08:56:58 UTC
Permalink
Post by mr.sir bossman
Dunno, I am using Visual C++ 6.0. <-Love it, see no need to change.
If you're playing with ATL, I beg you like to do a lot of template
stuff, and in this case there is a lot of reasons to switch to VC7.1(
template support in VC6 is at best poor).

Arnaud
MVP - VC
mr.sir bossman
2005-07-18 12:05:09 UTC
Permalink
Post by a***@club-internet.fr
Post by mr.sir bossman
Dunno, I am using Visual C++ 6.0. <-Love it, see no need to change.
If you're playing with ATL, I beg you like to do a lot of template
stuff, and in this case there is a lot of reasons to switch to VC7.1(
template support in VC6 is at best poor).
It gets me from point a to b. Plus I can't really afford 800+ plus to
upgrade. It Would be nice if Microsoft still sold VC++ as an individual Item
and not force people to buy Visual studia as a whole....But, I Guess Bill
needs the money.
Alex Blekhman
2005-07-18 13:13:54 UTC
Permalink
[...] Plus I can't really afford
800+ plus to upgrade. It Would be nice if Microsoft still
sold VC++ as an individual Item and not force people to
buy Visual studia as a whole....But, I Guess Bill needs
the money.
VC++ Standard edition can be purchased as stand-alone
product without any problem:

http://msdn.microsoft.com/howtobuy/visualc/default.aspx
mr.sir bossman
2005-07-18 20:31:10 UTC
Permalink
Post by Alex Blekhman
[...] Plus I can't really afford
800+ plus to upgrade. It Would be nice if Microsoft still
sold VC++ as an individual Item and not force people to
buy Visual studia as a whole....But, I Guess Bill needs
the money.
VC++ Standard edition can be purchased as stand-alone
100 bucks for a better compilier/ buggy Ide. Dunno if it is worth it. Maybe
try Dev-C++ first.
Post by Alex Blekhman
No optimizing compiler....Is Microsoft really that desperate for money?
Alex Blekhman
2005-07-19 08:50:42 UTC
Permalink
Post by mr.sir bossman
Post by Alex Blekhman
[...] Plus I can't really afford
800+ plus to upgrade. It Would be nice if Microsoft
still sold VC++ as an individual Item and not force
people to buy Visual studia as a whole....But, I Guess
Bill needs the money.
VC++ Standard edition can be purchased as stand-alone
100 bucks for a better compilier/ buggy Ide. Dunno if it
is worth it. Maybe try Dev-C++ first.
Post by Alex Blekhman
No optimizing compiler....Is Microsoft really that
desperate for money?
I see that you can't be pleased by anything. Here's
optimizing compiler for free:

"Microsoft Visual C++ Toolkit 2003"
http://msdn.microsoft.com/visualc/vctoolkit2003/

You can choose any (less buggy) IDE you wish for it.
mr.sir bossman
2005-07-19 14:00:03 UTC
Permalink
Post by Alex Blekhman
Post by Alex Blekhman
No optimizing compiler....Is Microsoft really that
desperate for money?
I see that you can't be pleased by anything.
Didn't say that. Just seems Microsoft is bringing less and less to the table
in their upgrades--at least for C++ crowd that is.
Post by Alex Blekhman
You can choose any (less buggy) IDE you wish for it.
That is what I was planning on doing--later on. Visual C++ 6.0 is still
getting it done for me.
Post by Alex Blekhman
(less buggy)
I have heard that the .net IDEs are buggy, am i wrong?
Alex Blekhman
2005-07-19 15:06:44 UTC
Permalink
Post by mr.sir bossman
Post by Alex Blekhman
(less buggy)
I have heard that the .net IDEs are buggy, am i wrong?
Look, we are at a danger to start endless flame "IDE X vs
IDE Y". I hear many people complain about new IDE and say
VC60 IDE was better. I ascribe it to the newness of VC7 IDE,
which requires to get used to it, rather than usability
deterioration. Personally, I enjoy both VC7.1 IDE and
compiler much more than those of VC60.

Currently, I can't see any other IDE for C++ development
(either from MS or other vendor) that could compete
successfully with VC7.1 as far as programmer's needs go.
Alexander Grigoriev
2005-07-18 03:02:31 UTC
Permalink
You really don't have to do those gratitious casts to void*. They make code
less readable, and actually can introduce bugs (suppose, you forgot to put
'&' before buff).
Post by mr.sir bossman
OHHHHH MY GODDDDD IT WORKS!!!!. Thx a bizzillion Severian. Couldn't have done
it without you.
Now my ATL File will get another upgrade/fix. Why doesn't Microsoft open
source ATL?
Code is below--Rough draft. Now with this as a template I can set up for
different processors/ global memory thunk pool. I love it.
Link for why code is needed.
http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2mempr.mspx
class CWndProcThunk
{
BYTE *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk = (BYTE *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
DWORD buff = 69485767;//hex 0x042444C7
memcpy((void *)(&thunk[0]),(void *)(&buff),4);
DWORD buff1 = (DWORD)pThis;
memcpy((void *)(&thunk[4]),(void *)(&buff1),4);
DWORD buff2 = 233;//hex 0xe9
memcpy((void *)(&thunk[8]),(void *)(&buff2),1);
DWORD buff3 = (int)proc - ((int)thunk + 13);
memcpy((void *)(&thunk[9]), (void *)(&buff3),4);
FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
mr.sir bossman
2005-07-18 12:16:12 UTC
Permalink
Post by Alexander Grigoriev
You really don't have to do those gratitious casts to void*. They make code
less readable, and actually can introduce bugs (suppose, you forgot to put
'&' before buff).
Agree.
Alexander Grigoriev
2005-07-17 17:04:26 UTC
Permalink
I think you actually wanted:
thunk->m_mov = 0x042444C7 // should it be 0x0C2444C7 ???
thunk->m_relproc = (int)proc - ((int)thunk+sizeof(_WndProcThunk));

I suggest you do single step in the debugger into your thunks
Post by mr.sir bossman
I am new to using VirtualAlloc and was wondering if someone could tell me
what I am doing wrong.
I get a "First-chance exception in XXXX.exe: 0xC0000005: Access Violation."
struct _WndProcThunk
{
DWORD m_mov; //32bits
DWORD m_this; //32bits
BYTE m_jmp; //8 bits
DWORD m_relproc; //32bits 13 bytes?
};
class CWndProcThunk
{
CWndProcThunk()
{
thunk = (_WndProcThunk *)VirtualAlloc(NULL,13,MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
}
_WndProcThunk *thunk;
void Init(WNDPROC proc, void* pThis)
{
thunk->m_mov = 0x042444C7; //C7 44 24 0C
thunk->m_this = (DWORD)pThis;
thunk->m_jmp = 0xe9;
thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
FlushInstructionCache(GetCurrentProcess(), thunk, 13);
}
};
WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pProc);
mr.sir bossman
2005-07-17 17:50:02 UTC
Permalink
Post by Alexander Grigoriev
thunk->m_mov = 0x042444C7 // should it be 0x0C2444C7 ???
thunk->m_relproc = (int)proc - ((int)thunk+sizeof(_WndProcThunk));
0x042444C7 is ok. 0x0C2444C7 is error.
Post by Alexander Grigoriev
I suggest you do single step in the debugger into your thunks
I am no good at ASM, All I know is I get an error after thread has left the
thunked wndproc. My thunked wndproc has the correct window handle and
everything. I dunno.

Basically after my second message and before my 3rd message I get an error.
mr.sir bossman
2005-07-17 17:54:02 UTC
Permalink
Check that, crash happens because of thunk. thunked proc is never called.
Post by mr.sir bossman
Post by Alexander Grigoriev
thunk->m_mov = 0x042444C7 // should it be 0x0C2444C7 ???
thunk->m_relproc = (int)proc - ((int)thunk+sizeof(_WndProcThunk));
0x042444C7 is ok. 0x0C2444C7 is error.
Post by Alexander Grigoriev
I suggest you do single step in the debugger into your thunks
I am no good at ASM, All I know is I get an error after thread has left the
thunked wndproc. My thunked wndproc has the correct window handle and
everything. I dunno.
Basically after my second message and before my 3rd message I get an error.
Alexander Grigoriev
2005-07-17 17:56:18 UTC
Permalink
What commands are you trying to inject in the stream? Did you invent them
yourself, or it's just the same as ATL does?
You could have the calling conventions mismatched, for example.
Post by mr.sir bossman
Post by Alexander Grigoriev
thunk->m_mov = 0x042444C7 // should it be 0x0C2444C7 ???
thunk->m_relproc = (int)proc - ((int)thunk+sizeof(_WndProcThunk));
0x042444C7 is ok. 0x0C2444C7 is error.
Post by Alexander Grigoriev
I suggest you do single step in the debugger into your thunks
I am no good at ASM, All I know is I get an error after thread has left the
thunked wndproc. My thunked wndproc has the correct window handle and
everything. I dunno.
Basically after my second message and before my 3rd message I get an error.
mr.sir bossman
2005-07-17 18:16:04 UTC
Permalink
It's my ATL file. Just rewritting thunk. Nothing else.
Code fails after first wndproc.
Loading...