-
Re: Check if Application is Running Without Timer
OK, that won't work for us.
When you created the dll, did you have to create an Entry point function called dllMain?
If so, the first parameter is our hInstance. It must be stored in a module-level variable from dllMain and can than be accessed from our set hook procedure.
-
Re: Check if Application is Running Without Timer
*slaps head* I forgot all about DLLMain() :blush:
I'll do that now.
-
Re: Check if Application is Running Without Timer
OK. Now it works. But it returns zero. :confused:
Here is the code from the DLL (minus declares etc.)
VB Code:
Private hInstance As Long
Private hHook As Long
Public IsHooked As Boolean
'
Public Function DLLMain( _
hInstDLL As Long, _
fdwReason As Long, _
lpvReserved As Long _
) As Long
hInstance = hInstDLL
DLLMain = 1
End Function
'
Public Function SetShellHook() As Long
If (Not IsHooked) Then
'the following line installs a system-wide hook
hHook = SetWindowsHookExA(WH_SHELL, AddressOf ShellProc, hInstance, 0)
IsHooked = True
End If
SetShellHook = hHook
End Function
'
Public Function RemoveShellHook() As Long
RemoveShellHook = UnhookWindowsHookEx(hHook)
IsHooked = False
End Function
'
Public Function ShellProc(ByVal uCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
ShellProc = CallNextHookEx(hHook, uCode, wParam, lParam)
End Function
And the EXE:
VB Code:
Private Declare Function SetShellHook _
Lib "C:\Yudster\Development\Visual Basic 6\My Code Tests\WH_SHELL hook\ShellHook.dll" ( _
_
) As Long
Private Declare Function RemoveShellHook _
Lib "C:\Yudster\Development\Visual Basic 6\My Code Tests\WH_SHELL hook\ShellHook.dll" ( _
) As Long
'
Private Sub cmdHook_Click()
MsgBox "Result: " & SetShellHook()
End Sub
Private Sub cmdUnhook_Click()
MsgBox "Result: " & RemoveShellHook
End Sub
and for what its worth, the exports:
Code:
LIBRARY VB6ShellHook
EXPORTS
DLLMain @1
SetShellHook @2
RemoveShellHook @3
-
Re: Check if Application is Running Without Timer
Make a call to GetLAstError to see what the error was.
-
Re: Check if Application is Running Without Timer
I got 0 from both GetLastError and Err.LastDLLError.
-
Re: Check if Application is Running Without Timer
My mistake. I had it set up wrong. Here is the modified version
VB Code:
Public Function SetShellHook() As Long
If (Not IsHooked) Then
'the following line installs a system-wide hook
hHook = SetWindowsHookExA(WH_SHELL, AddressOf ShellProc, hInstance, 0)
If (hHook = 0) Then
SetShellHook = Err.LastDLLError
Else
SetShellHook = hHook
IsHooked = True
End If
Else
SetShellHook = -1
End If
End Function
Now it returns 1428. If I remove the line with Err.LastDLLError in it then it returns zero. So obviously 1428 is the error code, which corresponds to:
"Cannot set nonlocal hook without a module handle."
Therefore the DLLMain() function is not working properly.
-
Re: Check if Application is Running Without Timer
see what hInstance is returning.
-
Re: Check if Application is Running Without Timer
Zero. evidently that what is triggering that particular error. Maybe DLLMain is set up wrong.
-
Re: Check if Application is Running Without Timer
im not sure what u mean...but take a look at the virus scanners source code.
-
Re: Check if Application is Running Without Timer
Quote:
Originally Posted by NiceSpammer
im not sure what u mean...but take a look at the virus scanners source code.
What are you talking about?
-
Re: Check if Application is Running Without Timer
I don't think the dllMain function is even being called.
I went ahead and compiled the demo program and all the functions worked, but then I tried to access values in the dllMain routine and always got 0.
A couple errors I notice in the coding were.
dllmain function should return integer since that is bool in C
parameters should be passed in byval
VB Code:
Public Function DllMain(ByVal hInst As Long, ByVal fdwReason As Long, _
ByVal lpvReserved As Long) As Integer
hInstance = hInst
Select Case fdwReason
Case DLL_PROCESS_DETACH
' No per-process cleanup needed
Case DLL_PROCESS_ATTACH
DllMain = 1
Case DLL_THREAD_ATTACH
' No per-thread initialization needed
Case DLL_THREAD_DETACH
' No per-thread cleanup needed
End Select
End Function
regardless, it still doesn't work :(
Another thing is that you don't have to export hte Maindll function
Idea:
Try passing App.hInstance to the dll as a parameter to the set hook function.
-
Re: Check if Application is Running Without Timer
After reading a bit more, I've decided that the DllMain function is probably not going to work in VB.
When you create a dll from C, the default entrypoint is the _DllMainCRTStartup function. This function initializes the C runtime libraries and then calls the DllMain function.
I noticed that the linker parameters for the VB dll included an entry /ENTRY:__vbaS, which means that this is the VB version of _DllMainCRTStartup. Unfortunately, it probably does not make a call to any DllMain that may exist. Even if it did, our DllMain function was probably renamed when it was compiled in the object code.
I think that the best bet is to pass the instance handle to the sethook function and see if that works.
-
Re: Check if Application is Running Without Timer
Quote:
Originally Posted by moeur
When you create a dll from C, the default entrypoint is the _DllMainCRTStartup function. This function initializes the C runtime libraries and then calls the DllMain function.
I noticed that the linker parameters for the VB dll included an entry /ENTRY:__vbaS, which means that this is the VB version of _DllMainCRTStartup. Unfortunately, it probably does not make a call to any DllMain that may exist. Even if it did, our DllMain function was probably renamed when it was compiled in the object code.
You were almost there moeur, but u gave up at the last moment.. Whereas i continued researching and found the click!
Did u ever doubted to change this param just to see what could happen?
One More Trick is to create your project as Standard EXE and File -> Make 'MyDLL.dll'
I am not joking lol... but its not over yet.. You need your customized DLL to check all these... The LINKER will prompt you if u have a .DEF under your project dir, whether it shd modify the parameters and send or just compile it as usual (giving you both the options).
If you choose Yes (the first option) 3 modifications occur in the parameters:
· Number 1: Change the /ENTRY switch to point to DLLMain
VB Code:
CmdLine = Replace(CmdLine, "/ENTRY:__vbaS", "/ENTRY:DLLMain")
· Number 2: Change the Base Address to 0x10000000 using the /BASE switch
VB Code:
CmdLine = Replace(CmdLine, "/BASE:0x400000", "/BASE:0x10000000")
Here is final fantasy:
· Number 3: Specify that we need a DLL file and not an EXE and also include the /DEF switched with the corresponding .DEF file
VB Code:
CmdLine = CmdLine & " /DLL /DEF:""" & sDEFfile & """"
I am so excited that it works now.. And finally a breakthrough in the world of programming that we Visual Basic programmers can too create a pure Win32DLL
HTH
Neo
-
Re: Check if Application is Running Without Timer
Yes there were a fair few mistakes and things left out of the article. Seeing as the linker is the same as the VC++ one that is why you can change the entry point, export definitions etc. manually. (Also the ByVals etc. were wrong in the article. however moeur you should be clear that a bool is a VB Long, whereas a BOOL on the other hand is an Integer.)
Quote:
Originally Posted by CodeBlock
One More Trick is to create your project as Standard EXE and File -> Make 'MyDLL.dll'
Now that is a good idea! I never thought of that. That way you eliminate the need for a redundant class module.
However I have to ask what exactly is the point of changing the base address?
-
Re: Check if Application is Running Without Timer
I'm not sure this is going to get us anywhere.
If you change the entry point, then how are the runtime libraies going to be initialized? You may get into the DllMain, but not be able to call any VB functions.
-
Re: Check if Application is Running Without Timer
A basic Win32DLL code with just one EXPORT method GethInstance
VB Code:
Public hInstance As Long ' One of the useful infos we get from DllEntry point
Public Const DLL_PROCESS_DETACH = 0
Public Const DLL_PROCESS_ATTACH = 1
Public Const DLL_THREAD_ATTACH = 2
Public Const DLL_THREAD_DETACH = 3
Public Function DLLMain(ByVal hInst As Long, ByVal fdwReason As Long, lpvReserved As Long) As Long
Select Case fdwReason
Case DLL_PROCESS_DETACH
' No per-process cleanup needed
Case DLL_PROCESS_ATTACH
' No per-process initialization needed
Case DLL_THREAD_ATTACH
' No per-thread initialization needed
Case DLL_THREAD_DETACH
' No per-thread cleanup needed
End Select
hInstance = hInst ' This is the App.Instance Call
DLLMain = 1 ' Return 1 on success
End Function
Sub Main()
'This is a dummy, so the IDE doesn't complain that
'there is no Sub Main.
End Sub
Public Function GethInstance() As Long
GethInstance = hInstance ' This is a pointer to
End Function
Now Create a Standard Exe Project
VB Code:
Private Declare Function GethInstance Lib "MyDLL.dll" () As Long
Private Sub Form_Load()
MsgBox GethInstance()
End Sub
-
Re: Check if Application is Running Without Timer
Quote:
Originally Posted by moeur
I'm not sure this is going to get us anywhere.
If you change the entry point, then how are the runtime libraies going to be initialized? You may get into the DllMain, but not be able to call any VB functions.
No runtime libraries are initialised anyway. Remember thats why we couldnt use MsgBox or App.hInstance in the first place ;)
-
Re: Check if Application is Running Without Timer
CodeBlock,
See what sort of functionality you have in the dll.
try running a few functions like Hex() and Sin() and even some string functions.
Then the next test is to see if it works in another process. That brings us back to the hook program.
-
Re: Check if Application is Running Without Timer
Quote:
Originally Posted by penagate
However I have to ask what exactly is the point of changing the base address?
EXEs have a Base Address specification of 0x400000
and DLLs 0x10000000
I learned this by comparing two linking: one an EXE and the other a DLL ... so it is basically implementing the 3rd point.. without point 2, nothing works.
Quote:
Originally Posted by moeur
If you change the entry point, then how are the runtime libraies going to be initialized? You may get into the DllMain, but not be able to call any VB functions.
VB Code:
Public Function DLLMain(ByVal hInst As Long, ByVal fdwReason As Long, lpvReserved As Long) As Long
Select Case fdwReason
Case DLL_PROCESS_DETACH
' No per-process cleanup needed
Case DLL_PROCESS_ATTACH
' No per-process initialization needed
' MessageBox 0, "Hi from DLL " & hInst, "Hi", 1
MsgBox "This is a VB Function", vbCritical
Case DLL_THREAD_ATTACH
' No per-thread initialization needed
Case DLL_THREAD_DETACH
' No per-thread cleanup needed
End Select
hInstance = hInst ' This is the App.Instance Parameter
DLLMain = 1 ' Return 1 on success
End Function
The above code works fine when run under a VB App... thats all we wanted.
See, You are not simply changing the entry point DLLMain, we dont have a direct access anywhere and to anything!!! We are asking only the linker to do them all. It might be the linking process which does all these hiding things from us.
-
Re: Check if Application is Running Without Timer
I'm going to be n00bish and ask how the runtime library is referenced. Seeing as it is part of the linking process. I looked at the command line arguments for the linker log and there was no mention of msvbm60.dll, So presumably it is part of the .obj file. I am going to try and copy the .obj file out at compile time and disassemble it to have a look. maybe if it is in there then we can add it in so it gets linked with the DLL.
-
Re: Check if Application is Running Without Timer
The original entry point is defined as /ENTRY:__vbaS where __vbaS is a routine that initializes the runtime libraries.
Quote:
The above code works fine when run under a VB App... thats all we wanted.
Well we want more. We want the dll to be able to run in a process that is seperate from the VB program.
The dll will attach itself to all running windows that receive any WH_SHELL messages. Most of these will not be VB programs.
-
Re: Check if Application is Running Without Timer
OK, LOL,
Even i am confused now..
Quote:
The original entry point is defined as /ENTRY:__vbaS where __vbaS is a routine that initializes the runtime libraries
The above point is right... But what if a predefined routine Microsoft made in the name of "DLLMain" hehe.. sounds kinky :p
I will be back with more TESTs. Also i am not sure how i could call in VC++ I have almost no knowledge of VC++ ... so i just need a code from moeur or someone to call an API... that might give solution to our questions
-
Re: Check if Application is Running Without Timer
VB Code:
Public hInstance As Long ' One of the useful infos we get from DllEntry point
Public ret As Long
Public Const DLL_PROCESS_DETACH = 0
Public Const DLL_PROCESS_ATTACH = 1
Public Const DLL_THREAD_ATTACH = 2
Public Const DLL_THREAD_DETACH = 3
Public Function DLLMain(ByVal hInst As Long, ByVal fdwReason As Long, lpvReserved As Long) As Long
Select Case fdwReason
Case DLL_PROCESS_DETACH
' No per-process cleanup needed
Case DLL_PROCESS_ATTACH
' No per-process initialization needed
'MessageBox 0, "Hi from DLL " & hInst, "Hi", 1
'MsgBox "This is a VB Function", vbCritical
Call Some_VB_Tests()
Case DLL_THREAD_ATTACH
' No per-thread initialization needed
Case DLL_THREAD_DETACH
' No per-thread cleanup needed
End Select
hInstance = hInst ' This is the App.Instance Parameter
DLLMain = 1 ' Return 1 on success
End Function
Public Function GetRetValue() As Long
GetRetValue = ret
End Function
Private Function Some_VB_Tests()
On Error GoTo ErrH
' returns how many test VB has passed
''' Test 1
' Exit Function
Do
ret = ret + 1
Loop While MsgBox("MsgBox Test Passed", vbRetryCancel) = vbRetry
''' Test 2
Do
ret = ret + 1
Call Shell("notepad", vbMaximizedFocus)
Loop While MsgBox("Shell Test", vbRetryCancel) = vbRetry
Do
ret = ret + 1
Call AppActivate("Untitled - Notepad", True)
Loop While MsgBox("AppActivate", vbRetryCancel) = vbRetry
Do
ret = ret + 1
Call AppActivate("Untitled - Notepad", True)
Call SendKeys("SENDKEYS PASSED~~~ REMEMBER SENDKEYS IS A NATIVE VB FUNCTION", True)
Loop While MsgBox("AppActivate + SendKeys", vbRetryCancel) = vbRetry
Dim arr() As String, i As Integer
Do
ret = ret + 1
ReDim Preserve arr(i) As String
arr(i) = "Val" & i
i = i + 1
Loop While MsgBox("Runtime Array assignment Test! Arr Count: " & UBound(arr), vbRetryCancel) = vbRetry
Dim Source As String
Source = "This is a test string where all spaces will be removed one by one"
Do
ret = ret + 1
Source = Replace$(Source, " ", "", , 1)
Loop While MsgBox("Replaced String: " & Source, vbRetryCancel) = vbRetry
Exit Function
ErrH:
MsgBox Err.Number & vbCrLf & Err.Description
Err.Clear
End Function
So now the result is: All Tests have passed.
But whenever an error occurs, the library unloads
So i have used even error handling in the test.. it worked too.. It was able to show what the error number and description were..
{EDITED}: Included Replace test
-
Re: Check if Application is Running Without Timer
It's probably better to no run too much code out of the dllMain since all the initialization could not be complete.
I'll try to implement the changes you've made to the linker, test it on a simple program, then see if it works when I try to hook Notepad or something.
-
Re: Check if Application is Running Without Timer
CodeBlock
Can you post the code for your link.exe
After adding the changes mine is not working
Nevermind:
-
Re: Check if Application is Running Without Timer
Found the bug in my code "DLLMain" <> "DllMain"
Now time to test with an out of process hook application.
-
Re: Check if Application is Running Without Timer
-
Re: Check if Application is Running Without Timer
Quote:
Originally Posted by moeur
CodeBlock
Can you post the code for your link.exe
Sorry, for the delay, we got to adjust with our Global Zone Timings
And before that.. please gimme a source in VC++ for me to test my VB DLL ... As in an equivalent code in VC++ for this:
VB Code:
Private Declare Function SampleFunction Lib "MyVBW32DLL.dll" () As Long
Private Sub Form_Load ()
Dim retVal As Long
retVal = SampleFunction()
End Sub
OK, This is the Linker source:
VB Code:
Option Explicit
Private Const LINK_FILE = "LINKER.EXE"
Dim FSO As FileSystemObject
Private Sub cmdCancel_Click()
Open App.Path & "\LinkerLog.txt" For Append As #1
Print #1, Now & ": ============================================"
Print #1, Now & ": Command Line Options: "; Command$
Print #1, Now & ": ============================================"
Print #1, vbCrLf & vbCrLf
Close #1
ShellWait App.Path & "\" & LINK_FILE & ".exe " & Command$
Unload Me
End Sub
Private Sub CmdOk_Click()
Dim CmdLine As String
CmdLine = Command$
CmdLine = Replace(CmdLine, "/ENTRY:__vbaS", "/ENTRY:DLLMain") ' BookMark #1
CmdLine = Replace(CmdLine, "/BASE:0x400000", "/BASE:0x10000000")
CmdLine = CmdLine & " /DLL /DEF:" & """" & txtCompiler.Text & """"
If Len(Dir(txtCompiler.Text, vbNormal)) <= 0 Then
MsgBox "No such DEF file.. please verify again!"
Exit Sub
End If
LINK CmdLine
End Sub
Private Sub Form_Load()
Dim intPos As Integer
Dim strPath As String
Dim fld As Folder
Dim fil As File
Set FSO = New FileSystemObject
' Determine if .DEF file exists
'
' Extract path from first .obj argument
intPos = InStr(1, Command$, ".OBJ", vbTextCompare)
strPath = Mid$(Command$, 2, intPos + 2)
intPos = InStrRev(strPath, "\")
strPath = Trim$(Left$(strPath, intPos - 1))
strPath = Replace$(strPath, """", "")
Debug.Print strPath
' MsgBox "Path=" & strPath
' Open folder
Set fld = FSO.GetFolder(strPath)
' MsgBox fld.Path
' Get files in folder
For Each fil In fld.Files
' MsgBox fil
If UCase$(FSO.GetExtensionName(fil)) = "DEF" Then
txtCompiler.Text = fil
Exit For
End If
Next
If txtCompiler.Text = vbNullString Then
LINK ' Default
Else
If MsgBox("Click Yes to apply DLL options over a Standard EXE Project," & vbCrLf & "otherwise click No to let VB handle the usual way.", vbYesNo) = vbNo Then
LINK ' Default
End If
End If
End Sub
Sub LINK(Optional CmdLine As String = vbNullString)
If CmdLine = vbNullString Then CmdLine = Command$
If CmdLine = vbNullString Then
Unload Me
Exit Sub
End If
Open App.Path & "\LinkerLog.txt" For Append As #1
Print #1, Now & ": ============================================"
Print #1, Now & ": Command Line Options: "; Command$
If CmdLine <> Command$ Then
Print #1, Now & ": Command Line Options: "; CmdLine ' Write only if there was a change
End If
Print #1, Now & ": ============================================"
Print #1, vbCrLf & vbCrLf
Close #1
ShellWait App.Path & "\" & LINK_FILE & " " & CmdLine ' i.e.: My SuperShell function
Unload Me
End Sub
Post on any doubts or errors, i am available! :)
HTH
Neo
EDIT: Had to edit coz 'BookMark #1' line shows a http://www.vbforums.com/images/icons/icon10.gif emoticon where it has the line of code /ENTRY:DLLMain
-
1 Attachment(s)
Re: Check if Application is Running Without Timer
About questions on this line:
VB Code:
CmdLine = Replace(CmdLine, "/BASE:0x400000", "/BASE:0x10000000")
I have told you that the base address specification of an EXE is 0x400000 which means Windows will first try to start mapping that EXE at the address 0x400000. If there is any other program already mapped at that address Windows will then allocate the next free address say: 0x470216 taking in count all the running programs at various memory addresses.
But DLLs have a different Base Address. Commonly, it is 0x10000000
To test this open a new ActiveX DLL project in VB. Goto Project->Properties and see Compile where the DLL Base Address will be showing: &H11000000
Hmm, now somebody might ask why is it 0x10000000 and not 0x11000000
This is the issue with ActiveX DLLs. http://www.kbalertz.com/kb_138062.aspx <-- This might feed some knowledge on what i am talking about.
If you want to know what is the difference between a regultar DLL and an ActiveX DLL, u must have known COM. But, i cannot explain COM, because it is a BIG BIG issue by itself and to learn about.
Question #1: Now, what is the real reason, that we should create our Win32DLL via a Standard EXE.. What is the need and y not through an ActiveX DLL project?
Answer:
Create an empty ActiveX DLL -> just open a new ActiveX DLL Project and Make 'Project1.DLL' Start->Programs->Microsoft Visual Studio 6.0->Microsoft Visual Studio 6.0 Tools->Depends
Open the File you just created and you will see that even if u haven't written any code or function there are two functions already in the DLL namely DLLRegisterServer and DLLUnRegisterServer
How did these two appear? Because you have created an ActiveX DLL Visual Basic automatically includes & compiles these two functions.. This is part of the compilation process. VB compiler adds this information in the .OBJ file which corresponds to the StartUp Object specified by the Project. This is the reason why we are creating the DLL via the Standard EXE and changing the switch while LINKing.
_________
We will move on to the first point now and see how that works (If you have not seen all my 3 points go here):
I have now come to the point that the above parameter does not tell the VB Linker to include VB Runtimes.. Then Whats the use of the above one?
To know the answer, read on.
This is an extract from the MSDN documentation for VC++ Linker options.. I know that we are not dealing with VC++ LINKer options but this is just basically how every linker works.
Code:
mainCRTStartup (or wmainCRTStartup) An application using /SUBSYSTEM:CONSOLE; calls main (or wmain)
WinMainCRTStartup (or wWinMainCRTStartup) An application using /SUBSYSTEM:WINDOWS; calls WinMain (or wWinMain), which must be defined with __stdcall
_DllMainCRTStartup A DLL; calls DllMain, which must be defined with __stdcall, if it exists
If the /DLL or /SUBSYSTEM option is not specified, the linker selects a
subsystem and entry point depending on whether main or WinMain is defined.
The functions main, WinMain, and DllMain are the three forms of the
user-defined entry point.
When creating a managed image, the function specified with /ENTRY must
have a signature of (LPVOID var1, DWORD var2, LPVOID var3).
You can find the page here
A linker's main aim is to collect all the .OBJ files and the specified .LIB files along with the language's RUNTIME files. No matter what VB LINK.exe does exactly the same and it includes the MSVBVM60.DLL Runtime DLL (You will see the proof soon)
The /ENTRY option has __vbaS value. This is nothing but a function inside one of those OBJ files.. The VB Compiler decides which OBJ by looking at the Startup Object specified in your project. If it is a form: frmMain then the __vbaS function has code to create the form object and show it eventually! (Have you ever wondered how your default form was loaded and shown?)
Quote:
Originally Posted by penagate
I'm going to be n00bish and ask how the runtime library is referenced. Seeing as it is part of the linking process. I looked at the command line arguments for the linker log and there was no mention of msvbm60.dll, So presumably it is part of the .obj file. I am going to try and copy the .obj file out at compile time and disassemble it to have a look. maybe if it is in there then we can add it in so it gets linked with the DLL.
It is not the part of the .OBJ file but it is the linking process like i said there.. You may also doubt on the highlighted part below.. This LIB file is LINKED with any VB project. No Matter it is a Standard EXE or an ActiveX DLL
Code:
7/19/2005 2:19:57 PM: Command Line Options: "E:\Dev\Programming
Languages\VB6\Fast TryOuts\VBWin32DLL Hook\stdcall.OBJ"
"E:\Dev\Programming Languages\VB6\Fast TryOuts\VBWin32DLL
Hook\test2.OBJ" "E:\Program Files\Microsoft Visual
Studio\VB98\VBAEXE6.LIB" /ENTRY:DLLMain /OUT:"E:\Dev\Programming
Languages\VB6\Fast TryOuts\VBWin32DLL Hook\test2.dll" /BASE:0x10000000
/SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /INCREMENTAL:NO /OPT:REF
/MERGE:.rdata=.text /IGNORE:40 /DLL /DEF:"E:\Dev\Programming
Languages\VB6\Fast TryOuts\VBWin32DLL Hook\StandardDLL.def"
To know the proof: I have attached my WIN32DLL done in VB 'test2.dll'. Open that DLL file through Depends, you will see MSVBVM60.DLL in the dependency tree.
Atlast, this means that we can include our Win32DLL in any project, such as VC++ or our own VB Project (obvious)
Questions are welcome!
-
Re: Check if Application is Running Without Timer
Quote:
Originally Posted by CodeBlock
It is not the part of the .OBJ file but it is the linking process like i said there.. You may also doubt on the highlighted part below.. This LIB file is LINKED with any VB project. No Matter it is a Standard EXE or an ActiveX DLL
Code:
7/19/2005 2:19:57 PM: Command Line Options: "E:\Dev\Programming
Languages\VB6\Fast TryOuts\VBWin32DLL Hook\stdcall.OBJ"
"E:\Dev\Programming Languages\VB6\Fast TryOuts\VBWin32DLL
Hook\test2.OBJ" "E:\Program Files\Microsoft Visual
Studio\VB98\VBAEXE6.LIB" /ENTRY:DLLMain /OUT:"E:\Dev\Programming
Languages\VB6\Fast TryOuts\VBWin32DLL Hook\test2.dll" /BASE:0x10000000
/SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /INCREMENTAL:NO /OPT:REF
/MERGE:.rdata=.text /IGNORE:40 /DLL /DEF:"E:\Dev\Programming
Languages\VB6\Fast TryOuts\VBWin32DLL Hook\StandardDLL.def"
Yep I found that also. I'm also interested in the fact that it becomes possible to create VB apps without using the runtime (To a degree). Would be good for things such as installers. Also if we wrote a lot of our own replacements for the functions in the runtime lib.
Did you try the shell hook and did it work?
-
Re: Check if Application is Running Without Timer
I tried it on a hook. I tried to hook Notepad but it causes Notepad to crash when the dll gets attached.
So, it appears that there is something wrong with the dll since I have no problem if the dll is written in C.
-
Re: Check if Application is Running Without Timer
Quote:
Originally Posted by moeur
I tried it on a hook. I tried to hook Notepad but it causes Notepad to crash when the dll gets attached.
So, it appears that there is something wrong with the dll since I have no problem if the dll is written in C.
1. Did you use my Linker Code? Coz i rewrote the whole code!
2. Whats your DLLMain Syntax? Did it look like this?
VB Code:
Public Function DLLMain([HL]hInst As Long, ByVal fdwReason As Long, lpvReserved As Long[/HL]) As Long
Select Case fdwReason
Case DLL_PROCESS_DETACH
' No per-process cleanup needed
Case DLL_PROCESS_ATTACH
' No per-process initialization needed
Case DLL_THREAD_ATTACH
' No per-thread initialization needed
Case DLL_THREAD_DETACH
' No per-thread cleanup needed
End Select
hInstance = hInst ' This is the App.Instance Parameter
DLLMain = 1 ' Return 1 on success
End Function
Check the highlighted signature, as specified in the MSDN documentation:
Code:
When creating a managed image, the function specified with /ENTRY must
have a signature of (LPVOID var1, DWORD var2, LPVOID var3).
3. Can u show your DLL code AND the Injector code?
HTH
Neo
-
Re: Check if Application is Running Without Timer
lpvReserved should be ByVal. Not that it matters since it is unused.
-
Re: Check if Application is Running Without Timer
I'm getting the code ready for upload now. Just removing any evidence of potentially embarassing past stupid mistakes :)
I use my own linker whick I modified. While playing around I noticed that if the linker runs into an error it exits with no messages. To see the linker messages, you can use the one that comes with C++. Here are the linker options I get.
Code:
Command line arguments after modification:
"C:\Documents and Settings\All Users\Documents\VBwin32DLL\dllHook\dllHook.OBJ" "C:\Documents and Settings\All Users\Documents\VBwin32DLL\dllHook\dllHook1.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\VBAEXE6.LIB" /ENTRY:DllMain /OUT:"C:\Documents and Settings\All Users\Documents\VBwin32DLL\dllHook\dllHook.dll" /BASE:0x10000000 /SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /DEF:"C:\Documents and Settings\All Users\Documents\VBwin32DLL\dllHook\dllHook.def" /DLL /INCREMENTAL:NO /OPT:REF /MERGE:.rdata=.text /IGNORE:4078
The DllMain syntax is
VB Code:
Public Function DllMain(ByVal hInst As Long, ByVal fdwReason As Long, _
ByVal lpvReserved As Long) As Long
All should be passed by value not by reference I do know this much since I write C dlls. The return type BOOL penagate points out should be Long, but I couldn't confirm that so I tried both.
I'll upload the code in a couple of minutes
-
1 Attachment(s)
Re: Check if Application is Running Without Timer
OK, here it is:
The linker, dll and VB test program
The test program call a routine in the dll to try to hook notepad.
It subclasses itself to receive return messages from Notepad.
Right now I've commented out the code inside the Notepad's hook routine to see if I could stop Notepad from crashing
No luck so far.
-
Re: Check if Application is Running Without Timer
I'll explain my last couple of posts a bit more, since we all seem to be doing it :)
BOOL along with a plethora of others is defined in windef.h.
an int in C++ is a 32-bit word which is a VB Long.
However a bool is 1 byte long (as of VC++ 5 anyway) so in VB it would be a Byte.
Since lpvReserved is typed LPVOID this indicates it is a long pointer to an untyped memory space. VB doesn't have these (although I recently discovered you can do some obscene memory tricks using strings as pointers) so we need to pull the pointer value from the stack directly by using ByVal. Of course this is immaterial since being reserved it is never touched anyway.
-
Re: Check if Application is Running Without Timer
Same goes for hInst which we do want to use.
-
Re: Check if Application is Running Without Timer
If hInst was typed LPVOID it would be a pointer, which it isn't, it is a straight value.
The correct prototype is
Code:
BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
HINSTANCE is a long handle type.
-
Re: Check if Application is Running Without Timer
In either case it needs to be defined as ByVal in VB.
-
Re: Check if Application is Running Without Timer
Quote:
Originally Posted by penagate
If hInst was typed LPVOID it would be a pointer, which it isn't, it is a straight value.
The correct prototype is
Code:
BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
HINSTANCE is a long handle type.
Ahh, Man! Everyone knows that if u need to extract the pointer u need to change your declaration as .. , ByVal lpvReserved As Long)
But the point is we just need the hInstDLL which can be declared directly as (hInst As Long,...
Why, declare as ByVal hInst and CopyMemory.. lol.. i just pointed out that to see whether moeur's had done it by mistake...
Quote:
So, it appears that there is something wrong with the dll since I have no problem if the dll is written in C
Why do u always blame the DLL, lol :p
When i Ran your EXE code i had a break point right at the cmdHook_Click and stepped over.. I found out that VB was trying to show some error message highlight as below:
VB Code:
strData = [HL=#3333FF]Space[/HL](dataStruct.cbData, 0)
The error obviously cannot be seen since you have subclassed your code.
Dont know the reason why the error was there.. Working on that now