-
May 29th, 2018, 01:27 PM
#1
[RESOLVED] Call By Address
Okay, I think I've done this before, but I can't find it.
Let's say I've got the following function (and I can't change it):
Code:
Public Function SomeProc(ByVal SomeLong As Long) As Long
'
' Do Stuff.
'
End Function
And now, I'm down in a procedure and all I've got is that function's address (via AddressOf).
Also, and this is important, I just want to do this in the IDE.
How can I call that function (again, no changes to arguments) when all I've got is its address?
Thanks,
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
May 29th, 2018, 01:34 PM
#2
Re: Call By Address
From memory, CallWindowProc should do the job. Lemme just check...
EDIT:
Can't find the code I thought I had, but it was something I played around with relating to this:
http://www.vbforums.com/showthread.p...own-callbacks)
Last edited by ColinE66; May 29th, 2018 at 01:39 PM.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 29th, 2018, 01:47 PM
#3
Last edited by dz32; Apr 26th, 2019 at 11:18 AM.
-
May 29th, 2018, 01:55 PM
#4
Re: Call By Address
Yup, DispCallFunc is the standard (for VBA too). You can use it to call any Calling Convention, like C Dlls etc.
LaVolpe,Schmidt,Trick and I have examples floating around.
Some people also use Assembly thunks. I think Trick or Bonnie and Wqweto have examples of that somewhere. The thunks are very simple and low overhead (fast)
I think Hacker posted a cool method on a russian VB site where you can patch up an API Declare, to point to your function too.
Last edited by DEXWERX; May 29th, 2018 at 02:07 PM.
-
May 29th, 2018, 02:00 PM
#5
Re: Call By Address
Yeah, I knew that CallWindowProc could do something similar. However, to use that, you must have your procedure set up as:
Code:
Public Sub Proc1(ByVal arg1 As Long, ByVal arg2 As Long, ByVal arg3 As Long, ByVal arg4 As Long)
'
End Sub
' ********* or **********
Public Function Proc2(ByVal arg1 As Long, ByVal arg2 As Long, ByVal arg3 As Long, ByVal arg4 As Long) As Long
'
End Function
And I'd rather not change how my procedure is declared. And yeah, I'm looking at FireHacker's stuff, but it's complicated. I need to figure out how to use DispCallFunc I suppose. Maybe LaVolpe will weigh in and give me some pointers.
Thanks,
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
May 29th, 2018, 02:05 PM
#6
Re: Call By Address
http://www.vbforums.com/showthread.p...ons-by-pointer
Code:
Sub Main()
PatchFunc AddressOf SomeProc_Proto
' // Call by pointer
SomeProc_Proto AddressOf SomeProc, 1234
End Sub
Public Function SomeProc_Proto(ByVal pAddr As Long, ByVal SomeLong As Long) As Long
End Function
Public Function SomeProc(ByVal SomeLong As Long) As Long
'
' Do Stuff.
'
MsgBox "By pointer " & SomeLong
End Function
With DispCallFunc:
Code:
Option Explicit
Private Declare Function DispCallFunc Lib "oleaut32.dll" ( _
ByVal pvInstance As Long, _
ByVal FuncAddr As Long, _
ByVal CallConvention As Integer, _
ByVal rtnType As VbVarType, _
ByVal FuncArgsCnt As Long, _
ByRef FuncArgTypes As Any, _
ByRef FuncArgVarAddresses As Any, _
ByRef FuncResult As Any) As Long
Sub Main()
StdCall AddressOf SomeProc, vbLong, 1234&
End Sub
Public Function SomeProc(ByVal SomeLong As Long) As Long
'
' Do Stuff.
'
MsgBox "By pointer " & SomeLong
End Function
Public Function StdCall(ByVal pAddr As Long, ByVal retType As VbVarType, ParamArray params()) As Variant
Dim types() As Integer
Dim list() As Long
Dim param() As Variant
Dim pIndex As Long
Dim ptrList As Long
Dim ptrTypes As Long
Dim resultCall As Long
Const CC_STDCALL As Long = 4
If LBound(params) <= UBound(params) Then
ReDim list(LBound(params) To UBound(params))
ReDim types(LBound(params) To UBound(params))
ReDim param(LBound(params) To UBound(params))
For pIndex = LBound(params) To UBound(params)
param(pIndex) = params(pIndex)
list(pIndex) = VarPtr(param(pIndex))
types(pIndex) = VarType(types(pIndex))
Next
ptrList = VarPtr(list(LBound(list)))
ptrTypes = VarPtr(types(LBound(types)))
End If
resultCall = DispCallFunc(ByVal 0&, _
pAddr, _
CC_STDCALL, _
retType, _
UBound(params) - LBound(params) + 1, _
ByVal ptrTypes, _
ByVal ptrList, _
StdCall)
If resultCall Then Err.Raise 5: Exit Function
End Function
With single param you can make it more shorter (from Multithreading code):
Code:
DispCallFunc(ByVal 0&, lpStartAddress, CC_STDCALL, vbEmpty, 1, vbLong, VarPtr(CVar(lpParameter)), CVar(0))
Last edited by The trick; May 29th, 2018 at 02:22 PM.
-
May 29th, 2018, 02:39 PM
#7
Re: Call By Address
@Trick: Thank you! That's absolutely perfect.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
May 29th, 2018, 05:16 PM
#8
Re: [RESOLVED] Call By Address
I shrinked Trick's trampoline factory a bit here with a single Currency var:
thinBasic Code:
Public Sub RtccPatchProto(ByVal pfn As Long) '--- Helper by The trick
Dim bInIDE As Boolean
Debug.Assert pvSetTrue(bInIDE)
If bInIDE Then
Call CopyMemory(pfn, ByVal UnsignedAdd(pfn, &H16), 4)
Else
Call VirtualProtect(pfn, 8, PAGE_EXECUTE_READWRITE, 0)
End If
' 0: 58 pop eax
' 1: 59 pop ecx
' 2: 50 push eax
' 3: ff e1 jmp ecx
' 5: 90 nop
' 6: 90 nop
' 7: 90 nop
Call CopyMemory(ByVal pfn, -802975883527609.7192@, 8)
End Sub
... and the proto routines can be self-patching like this:
thinBasic Code:
Public Function CallMul(ByVal pfn As Long, ByVal lFirst As Long, ByVal lSecond As Long) As Long
'--- on first call will self-patch to call `pfn` with args `lFirst` and `lSecond` directly
RtccPatchProto AddressOf Module1.CallMul
CallMul = CallMul(pfn, lFirst, lSecond)
End Function
... to reduce initialization ceremony.
cheers,
</wqw>
-
May 30th, 2018, 06:42 AM
#9
Re: [RESOLVED] Call By Address
@wqweto nice. That's a lot like Curland's approach with the code in a single currency; even the assembly is similar Although Curland has a way of over complicating everything, by involving typelibs and interfaces, and patching vtables...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|