VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 366|回复: 5

[原创] 如何修改函数返回值?或者插入汇编代码获取调用参数?

[复制链接]

8

主题

0

听众

76

积分

初级程序员

Rank: 2Rank: 2

擂点
0
人气
0
威望
0
注册时间
2016-8-1
精华
0
帖子
23
发表于 2017-1-25 13:44:59 |显示全部楼层
本帖最后由 自动化软件开发 于 2017-1-25 14:00 编辑

如何修改函数返回值?或者插入汇编代码获取调用参数?
【其实我现在的问题是在做hook caom ,hook ocx,里面事件或函数的调用时HOOk,COM的函数虚表是4个字节一个地址,连续排放,我修改了这个地址,HOOK就跳 转到了我的函数上,可是没法返回数值给调用方了,问题在于如何修改原来虚表中某个COM对象方法的返回值。】
原来代码:
function jia(a,b)
jia=a+b
end function
现在我加了一个HOOK,可以得到a,b的值了,但是jia返回的却是0了。
有可能是函数过程被改了
function jia(a,b)
call Myjia(a,b)
end function
Function Myjia(ByRef A As Long, ByRef B As Long) As Long
Myjia = A + B
A = A * A
end function

也就是我需要把myjia的计算结果返回给jia,或者直接用汇编写代码,在function jia(a,b)的
第一句代码添加一个拦截参数的代码,跳转到我的一个过程,
并且可以修改参数值,也可以更改原函数的值(中断返回),或者让他继续运行
  1. Sub main()
  2. Dim A As Long, B As Long, A0 As Long, Result As Long
  3. A = 3
  4. B = 4
  5. A0 = A
  6. Result = jia(A, B)
  7. MsgBox "3+4=" & Result & vbCrLf & "A0=" & A0 & ",现在A=" & A
  8. End Sub
  9. Function jia(ByRef A As Long, ByRef B As Long) As Long
  10. Dim C As Long
  11. C = Myjia(A, B)
  12. End Function
  13. Function Myjia(ByRef A As Long, ByRef B As Long) As Long
  14. Myjia = A + B
  15. A = A * A
  16. End Function
复制代码

8

主题

0

听众

76

积分

初级程序员

Rank: 2Rank: 2

擂点
0
人气
0
威望
0
注册时间
2016-8-1
精华
0
帖子
23
发表于 2017-1-25 13:57:00 |显示全部楼层
原函数
  1. function jia(a,b)
  2. jia=a+b
  3. end function
复制代码
改成功能1,更改功能并返回,不继续执行
  1. function jia(a,b)
  2. jia=Myjia(a,b)
  3. exit function

  4. jia=a+b
  5. end function
  6. Function Myjia(ByRef A As Long, ByRef B As Long) As Long
  7. Myjia = A + B
  8. A = A * A
  9. end function
复制代码
改成功能2,更改功能并返回,允许继续执行
  1. Function jia2(ByRef A As Long, ByRef B As Long) As Long
  2. Dim GoNext As Boolean
  3. jia2 = Myjia(A, B, GoNext)
  4. If GoNext = False Then Exit Function

  5. jia2 = A + B
  6. End Function
  7. Function Myjia(ByRef A As Long, ByRef B As Long, GoNext As Boolean) As Long
  8. Myjia = A + B
  9. A = A * A
  10. GoNext = True '继续执行
  11. End Function
复制代码
能够实现功能2就最好了
回复

使用道具 举报

8

主题

0

听众

76

积分

初级程序员

Rank: 2Rank: 2

擂点
0
人气
0
威望
0
注册时间
2016-8-1
精华
0
帖子
23
发表于 2017-1-25 14:04:05 |显示全部楼层
现在的问题是COM DLL中的原函数function jia(a,b)
jia=a+b
end function
我跳转到了这里myjia,结果jia的值没变,存到了Myjia的内存上,只是跳转执行,没有修改函数返回结果,估计只用一句跳转是不行的,必须给他包装一个汇编代码,1加一个寄存器BB,2执行跳转的代码返回值存到BB,再把BB的值返回给function jia(),当然直接能读取function jia()返回值的寄存器就最强了,那就不需要用bb变量了。
Function Myjia(ByRef A As Long, ByRef B As Long, GoNext As Boolean) As Long
Myjia = A + B
A = A * A
GoNext = True '继续执行
End Function
回复

使用道具 举报

229

主题

20

听众

2万

积分

网络设计师

Rank: 7Rank: 7Rank: 7

擂点
0
人气
140
威望
213
注册时间
2010-9-12
精华
1
帖子
3428
发表于 2017-1-25 20:23:19 |显示全部楼层
可以参照论坛里的有个sunday算法的帖子
内联汇编
回复

使用道具 举报

21

主题

7

听众

7721

积分

系统分析员

Rank: 5Rank: 5Rank: 5

擂点
0
人气
67
威望
112
注册时间
2010-2-8
精华
0
帖子
757
发表于 2017-1-28 00:52:36 |显示全部楼层
正确的做法是先执行一遍原函数,再返回
回复

使用道具 举报

8

主题

0

听众

76

积分

初级程序员

Rank: 2Rank: 2

擂点
0
人气
0
威望
0
注册时间
2016-8-1
精华
0
帖子
23
发表于 2017-1-29 20:50:48 |显示全部楼层
本帖最后由 自动化软件开发 于 2017-1-29 21:02 编辑
404022 发表于 2017-1-28 00:52
正确的做法是先执行一遍原函数,再返回


嗯,主要是COM里的一些函数或过程是一些虚表,改了跳转地址,他就执行到我的一个函数上去了,而这个函数只是用来拦截原函数调用时相关的参数用的
比如HOOK COM DLL中的
FUNCTION JIA(A AS LONG ,B AS LONG) AS LONG
JIA=A+B
END FUNCTION
然后跳转到了我的EXE中的函数
在我的EXE中这个COM的名称是COM1
FUNCTION MYJIA(dll对象地址,A AS LONG ,B AS LONG,结果值 as long) AS LONG
取消HOOKCOM
结果值=COM1.jia(a,b)
MSGBOX A & "," & B

END FUNCTION
理论上是上面这个走法,
COM的函数HOOK,原来是2个参数,HOOK后会变成4个参数,前面是对象地址,后面是返回值的地址
我现在用的是另一个方法 结果值=执行汇编字节(COM函数JIA的地址,a,b)
执行汇编字节这个找人花了不少时间
要是有办法可以直接在FUNCTION MYJIA里面自动获取到相应的堆zhang,直接用汇编重新执行就省事了。

最强的做法呢,是把所有的HOOK全执行到一个通用过 程里面来,如果有需要时我自已再去取出里面几个参数,如果不需要就继续执行原函数。
  Dim WithEvents ExtObj As VBControlExtender
set ExtOb=com1
Private Sub ExtObj_ObjectEvent(Info As EventInfo)
Debug.Print Now & " 事件发生:" & Info.Name & "," & Info.EventParameters.Count
End Sub
差不多就是想实现这样的功能吧
但是这个COM1我是从内存中直接创建的DLL,用这种方法没法直接(set ExtOb=com1),所以就是在想办法实现“ExtObj_ObjectEvent”这样的通用事件拦载,方法函数调用拦截“
我现在在做的事情是,把一个OCX控件二进制资源直接在内存中生成一个控件,然后需要监控他的事件,
但是有的控件(自已用VB写的),可以加载成功控件但是显示不出来,需要按类名一一查找再SETPARENT,而第三方控件比如MSFLEXGRID,加载成功之后,看不到界面,也在进程中找不到类名,但是可以执行里面行列的增加,删除等动作。
怪事好多呀。

总的一个来说COM DLL已经实现了内存加载,带事件,COM OCX可以加载,但是好多显示不了界面,COM 标准DLL的这种内存加载用了好多年了。
有一个目标是想在内存中加载FLASH.OCX,然后显示一个内存中的SWF地址,都不保存到硬盘的,主要就是这个难度。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

文字版|手机版|VBGood

GMT+8, 2017-2-23 08:33

VB爱好者乐园(VBGood)
回顶部