导航
  • 全部
...

Thunk新思路, x86成功,x64失败,寻求帮助

老邓 2009-03-22 08:45:51
这个链接是Thunk实现的一种新思路:http://www.cppblog.com/proguru/archive/2008/08/24/59831.html
作者将hWnd替换为this指针,回调函数风格变成:
  1. LRESULT CALLBACK wndProc(UINT msg, WPARAM wpa, LPARAM lpa)
  2. {
  3. // hWnd 通过Thunk代码保存到窗口类的第一个数据成员:HWND _wnd; 中
  4. }


于是我在作者思路的基础上改写如下:
  1. struct ThunkData
  2. {
  3. #if defined(_M_IX86)
  4. #pragma pack(push, 1)
  5. unsigned char m_szMachineCode[22];
  6. void* init(DWORD_PTR proc, void* pthis)
  7. {
  8. *((WORD *) &m_szMachineCode[ 0]) = 0xB851;
  9. *((DWORD *) &m_szMachineCode[ 2]) = (DWORD)pthis;
  10. *((DWORD *) &m_szMachineCode[ 6]) = 0x08244C8B;
  11. *((DWORD *) &m_szMachineCode[10]) = 0x44890889;
  12. *((DWORD *) &m_szMachineCode[14]) = 0xE9590824;
  13. *((DWORD *) &m_szMachineCode[18]) = proc - reinterpret_cast<DWORD>(this) - sizeof(ThunkData);
  14. // write block from data cache and flush from instruction cache
  15. FlushInstructionCache(GetCurrentProcess(), this, sizeof(ThunkData));
  16. return this;
  17. }
  18. #pragma pack(pop)

  19. #elif defined(_M_AMD64)
  20. #pragma pack(push, 1)
  21. unsigned char m_szMachineCode[27];
  22. void* init(DWORD_PTR proc, void *pthis)
  23. {
  24. *((WORD *)&m_szMachineCode[0]) =0xB848;
  25. *((INT_PTR*)&m_szMachineCode[2]) =reinterpret_cast<INT_PTR>(pthis);
  26. *((DWORD *)&m_szMachineCode[10]) =0x89480848;
  27. *((DWORD *)&m_szMachineCode[14]) =0x00B848C1;
  28. *((INT_PTR*)&m_szMachineCode[17]) =proc;
  29. *((WORD *)&m_szMachineCode[25]) =0xE0FF;
  30. FlushInstructionCache(GetCurrentProcess(), this, sizeof(ThunkData));
  31. return this;
  32. }
  33. #pragma pack(pop)
  34. #endif

  35. void* getCode()
  36. {
  37. return this;
  38. }

  39. void* operator new(size_t)
  40. {
  41. return VirtualAlloc(NULL, sizeof(ThunkData), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  42. }

  43. void operator delete(void* thunk)
  44. {
  45. VirtualFree(thunk, 0, MEM_RELEASE);
  46. }
  47. };


其中,x86下成功,但x64失败:CreateWindowEx时返回错误码1812,意思是:The specified image file did not contain a resource section.
之后崩溃。

请帮忙:x64的实现哪里出现了问题?应该如何修正呢?
...全文
给本帖投票
538 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
老邓 2009-03-22
  • 打赏
  • 举报
回复
共有两处机器码错误:
mov qword ptr [rax], rcx
这一行的机器码不对,要改成:488908
另,我在x64下用WinDBG调试发现:mov rcx, rax 的机器码应该是:488bc8
但如果用:4889c1 也可以。但我认为还是应该改成:488bc8
jxc25 2009-03-22
  • 打赏
  • 举报
回复
是488908
应该改成mov dword ptr [rax], ecx ;8908
老邓 2009-03-22
  • 打赏
  • 举报
回复
用WinDBG跟踪到CreateWindowEx时抛出异常:内存访问越界了。
因为该Thunk要修改_wnd,所以抛出异常可能是在写该变量时发生。

我现在怀疑:
mov qword ptr [rax], rcx    ; _wnd = [this] = rcx
有问题?
它的机器码是:4808吗?

其机器码对吗?
又如何用WinDBG查看该汇编的机器码呢?我用C++编程。
老邓 2009-03-22
  • 打赏
  • 举报
回复
请帮忙看一下思路及对应代码是否正确:我觉得有可能是编码代码与机器码对应上有问题?
但我不知道怎样才能通过汇编码得到机器码。
WinDBG调试很困难,因为没有真x64机器,只能在qemu下虚拟,速度慢的让人发狂!

/*
For x64 calling convention, rcx hold the 'HWND',copy the 'HWND' to Window object,
then insert 'this pointer' into rcx,so perfectly!!!

Stack frame before modify Stack frame after modify

: : : :
|---------------| |----------------|
| lpa | <-R9(lpa) | lpa | <-R9(lpa)
|---------------| |----------------|
| wpa | <-R8(wpa) | wpa | <-R8(wpa)
|---------------| |----------------|
| msg | <-rdx(msg) | msg | <-rdx(msg)
|---------------| |----------------|
| wnd | <-rcx(wnd) | this | <-rcx(this)
|---------------| |----------------|
| (return addr) | <-rsp | (return addr) | <-rsp
|---------------| |----------------|
: : : :

machine code assembly instruction comment
------------------- ----------------------- ----
48B8 ???????????????? mov rax, pthis
4808 mov qword ptr [rax], rcx ; _wnd = [this] = rcx
4889C1 mov rcx, rax ; rcx = pthis
48B8 ???????????????? mov rax, proc
FFE0 jmp rax
*/

BYTE _machineCode[27];
void* init(DWORD_PTR proc, void *pthis)
{
printf("%d", sizeof(ThunkData));
*((WORD *) &_machineCode[ 0]) = 0xB848;
*((ULONG64*) &_machineCode[ 2]) = reinterpret_cast<ULONG64>(pthis);
*((DWORD *) &_machineCode[10]) = 0x89480848;
*((DWORD *) &_machineCode[14]) = 0x00B848C1;
*((ULONG64*) &_machineCode[17]) = proc;
*((WORD *) &_machineCode[25]) = 0xE0FF;
FlushInstructionCache(GetCurrentProcess(), this, sizeof(ThunkData));
return this;
}
jxc25 2009-03-22
  • 打赏
  • 举报
回复
在x64中用4*的机器码会搞混的
cnzdgs 2009-03-22
  • 打赏
  • 举报
回复
反汇编看看你写的这些指令是什么,机器码可读性太差查了。也可以在64位系统中用WinDbg来调试这段汇编代码。

21,491

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧

手机看
关注公众号

关注公众号

客服 返回
顶部