吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 291|回复: 8
收起左侧

[求助] 关于call一个函数报错问题

[复制链接]
WXMJ 发表于 2024-12-22 22:07
我没学过汇编,是一个汇编废物。。
我写了这样的一个函数template_WindowProc image.png

又写了一个类
类里面有个WindowProc函数
image.png

在类初始化里面申请了一块内存,将template_WindowProc拷贝进这块新内存
在这个新内存里面将变量box(类指针template_WindowProc)和proc(类成员函数WindowProc)的值修改成实际的值
以下是初始化的代码
image.png


在初始化中调用了拷贝出来的新的template_WindowProc函数
在template_WindowProc函数中再通过以下代码进行调用类中的WindowProc
其中box是this,proc是WindowProc地址
__asm {

     // 从模板变量中加载类指针
     mov eax, [box]
     mov ecx, eax  // 将类实例指针传递到 ECX (this 指针)

     // 加载成员函数指针
     mov eax, [proc]

     // 将函数调用所需的参数压栈
     push lParam
     push wParam
     push Msg
     push hwnd
     
     // 调用成员函数
     call eax
     //清理栈 4*4
     //add esp, 16
     // 将返回值保存到 result
     mov [result], eax
}

调用之后,确实call进了WindowProc,参数应该是 1,2,3,4 但是参数成了2,3,4,第四个参数lParam成了一个未知的数字
当从WindowProc出去之后,回到新的template_WindowProc中,后面还有个call,但call到的地址我跳转看了看,是无效内存,下面划线的是call到无效内存的位置
image.png

执行过后报错
引发的异常: 0xC0000005: 执行位置 0x02C862B3 时发生访问冲突。

求大佬们看看应该怎么搞

我的本意是拷贝出一个新的函数,当作窗口过程,这个过程调用类成员函数,实现类成员函数窗口过程

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

BrutusScipio 发表于 2024-12-22 23:24
执行位置 0x02C862B3 时发生访问冲突 这不是可以追踪看看这块内存有什么嘛
类成员函数编译后会添加一个类实例指针作为第一个参数,不过看起来不一定与问题有关
yes2 发表于 2024-12-23 09:09
可能是88行错了,你这个call指令是E8开头的call,不能写绝对地址,要计算偏移的
海水很咸 发表于 2024-12-23 11:34
 楼主| WXMJ 发表于 2024-12-23 13:56
BrutusScipio 发表于 2024-12-22 23:24
执行位置 0x02C862B3 时发生访问冲突 这不是可以追踪看看这块内存有什么嘛
类成员函数编译后会添加一个类 ...

0x02C862B3地址啥都没有,全是问号
 楼主| WXMJ 发表于 2024-12-23 13:57
海水很咸 发表于 2024-12-23 11:34
GetWindowLong SetWindowLong   完美解决你的问题

类成员函数需要带类指针当参数,可以吗?
 楼主| WXMJ 发表于 2024-12-23 13:59
yes2 发表于 2024-12-23 09:09
可能是88行错了,你这个call指令是E8开头的call,不能写绝对地址,要计算偏移的

我下断点看了,是跳到了类成员函数WindowProc,从这个函数出去之后报的错
海水很咸 发表于 2024-12-23 16:23
本帖最后由 海水很咸 于 2024-12-23 16:28 编辑
WXMJ 发表于 2024-12-23 13:57
类成员函数需要带类指针当参数,可以吗?

[C++] 纯文本查看 复制代码
WNDPROC oldWndProc; 
// 新的窗口过程 
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 { 
     switch (msg)
    { 
     case WM_CLOSE: 
      MessageBox(hwnd, "窗口即将关闭", "提示", MB_OK); 
     break;
     default: 
     return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam); 
    } 
return 0; 
}
// 替换窗口过程 
oldWndProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)NewWndProc); 
  自己的过程里面你随便做什么事
yes2 发表于 2024-12-23 16:43
WXMJ 发表于 2024-12-23 13:59
我下断点看了,是跳到了类成员函数WindowProc,从这个函数出去之后报的错
0x02C862B3地址啥都没有,全是问号
验证了我的说法。你还是看看你第88行的代码,写跳转目标的地方。
你要不信我也没办法
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-1-2 19:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表