API-hooking question [SOLVED!] :)
API-hooking question [SOLVED!] :)
Hi, comrades.
Can anyone help me? My question is not for hack/crack or steal. I have a bit experience and therefore I created new theme here (in fact the profile topic already exists).
The problem is as follows:
I have third-party app, which requires that TZI = utc. But at the same time, other applications are running on the computer (requires that TZI is setted as local). And yes, local <> utc. Otherwise I didn't ask the question here.
Correction/clarification: the TZI setting is not so much important as the time value. The problem is that this one application is reading the time every second. Therefore, here you cannot do this without an API-function hook. I looked at the import table and saw GetLocalTime there (from kernel32.dll). This is what I need. I would be very grateful if someone shows an example of a dynamic library with GetLocalTime function hooking based on the Hook Engine Module API (by Peyman). The point is to respond to the application on every request with time value chosen by user. As if the OS did it. If the time can be changed dynamically (send parameter from the injector part), then it will be super.
Sorry, but my attempts were unsuccessful (not a working solution). For this reason, I don't publish it here.
If someone has the time and desire to help me with this, then I will be very happy. If not, thanks anyway for your attention.
Can anyone help me? My question is not for hack/crack or steal. I have a bit experience and therefore I created new theme here (in fact the profile topic already exists).
The problem is as follows:
I have third-party app, which requires that TZI = utc. But at the same time, other applications are running on the computer (requires that TZI is setted as local). And yes, local <> utc. Otherwise I didn't ask the question here.
Correction/clarification: the TZI setting is not so much important as the time value. The problem is that this one application is reading the time every second. Therefore, here you cannot do this without an API-function hook. I looked at the import table and saw GetLocalTime there (from kernel32.dll). This is what I need. I would be very grateful if someone shows an example of a dynamic library with GetLocalTime function hooking based on the Hook Engine Module API (by Peyman). The point is to respond to the application on every request with time value chosen by user. As if the OS did it. If the time can be changed dynamically (send parameter from the injector part), then it will be super.
Sorry, but my attempts were unsuccessful (not a working solution). For this reason, I don't publish it here.
If someone has the time and desire to help me with this, then I will be very happy. If not, thanks anyway for your attention.
Last edited by ZX80 on Mon Sep 21, 2020 11:46 am, edited 4 times in total.
Re: API-hooking question
This should get you started...
[/size]
Now you only need to rewrite the example to fit your needs
Code: Select all
XIncludeFile "API_HookEngine.pbi"
UseModule API_HookEngine
Global *GetLocalTime
Procedure GetLocalTime__(*lpSystemTime.SYSTEMTIME)
Protected func = UnHook(*GetLocalTime)
Protected retn = CallFunctionFast(func, *lpSystemTime)
*lpSystemTime\wYear = 2019
*lpSystemTime\wHour = 21
*GetLocalTime = Hook(func, @GetLocalTime__())
ProcedureReturn retn
EndProcedure
GetLocalTime_(@lpSystemTime.SYSTEMTIME)
Debug "" + lpSystemTime\wYear + "/" + lpSystemTime\wMonth + "/" + lpSystemTime\wDay + " (" + lpSystemTime\wDayOfWeek + ")"
Debug "" + lpSystemTime\wHour + ":" + lpSystemTime\wMinute + ":" + lpSystemTime\wSecond + ":" + lpSystemTime\wMilliseconds
Debug ""
*GetLocalTime = Hook(ProcAddress("kernel32.dll", "GetLocalTime"), @GetLocalTime__())
GetLocalTime_(@lpSystemTime.SYSTEMTIME)
Debug "" + lpSystemTime\wYear + "/" + lpSystemTime\wMonth + "/" + lpSystemTime\wDay + " (" + lpSystemTime\wDayOfWeek + ")"
Debug "" + lpSystemTime\wHour + ":" + lpSystemTime\wMinute + ":" + lpSystemTime\wSecond + ":" + lpSystemTime\wMilliseconds
UnHook(*GetLocalTime)
UnuseModule API_HookEngine
Now you only need to rewrite the example to fit your needs
Et cetera is my worst enemy
Re: API-hooking question
chi, thank you very much!
I will think about your code...
I am aware of the existence of such a utility. It's working well. But ... it is not completely suitable for my task, because it changes the time only once (at the start). I need to be able change the time dynamically, i.e. in already launched app (on the fly / immediately upon request). In order not to reload the application every time when you need to change the time. Also, your own application gives more options (for example, creating your own GUI).
Thanks again
I will think about your code...
I am aware of the existence of such a utility. It's working well. But ... it is not completely suitable for my task, because it changes the time only once (at the start). I need to be able change the time dynamically, i.e. in already launched app (on the fly / immediately upon request). In order not to reload the application every time when you need to change the time. Also, your own application gives more options (for example, creating your own GUI).
Thanks again
Re: API-hooking question
Now it works! Is it right?
[/size]
Today I once again looked at the code with my fresh eyes and deleted all unnecessary. This is final version.
In this case, no structure is required! I leave it for the future.
chi, thank you very much for the start point.
Code: Select all
IncludeFile "API_HookEngine.pbi"
UseModule API_HookEngine
EnableExplicit
Structure Params
diff.i
EndStructure
Global *GetLocalTime
Global difference
Procedure GetLocalTime__(*lpSystemTime.SYSTEMTIME)
Protected func = UnHook(*GetLocalTime)
Protected retn = CallFunctionFast(func, *lpSystemTime)
Protected SetTime.q = Date() + difference
*lpSystemTime\wDay = Day(SetTime)
*lpSystemTime\wMonth = Month(SetTime)
*lpSystemTime\wYear = Year(SetTime)
*lpSystemTime\wHour = Hour(SetTime)
*lpSystemTime\wMinute = Minute(SetTime)
*lpSystemTime\wSecond = Second(SetTime)
*GetLocalTime = Hook(func, @GetLocalTime__())
ProcedureReturn retn
EndProcedure
ProcedureDLL ChangeTime(*Parameters.Params)
difference = *Parameters\diff
EndProcedure
ProcedureDLL Start()
*GetLocalTime = Hook(ProcAddress("kernel32.dll", "GetLocalTime"), @GetLocalTime__())
EndProcedure
ProcedureDLL _End()
UnHook(*GetLocalTime)
UnuseModule API_HookEngine
EndProcedure
Today I once again looked at the code with my fresh eyes and deleted all unnecessary. This is final version.
In this case, no structure is required! I leave it for the future.
chi, thank you very much for the start point.
Last edited by ZX80 on Mon Sep 07, 2020 11:11 am, edited 3 times in total.
Re: API-hooking question
Comrades, one more question, please. How can I set the second hook? I also need to know when the third-party program will be closed to terminate my application correctly (at the same time). Of course, I could check the existence of a window by timer, but we already have one hook installed. I changed the start-procedure to this:
[/size]
I also added a DestroyWindow-procedure "DestroyWindow__(hWnd)", but it cannot catch the third-party application termination event. The DestroyWindow API has only one argument, the window handle.
Please tell me how to catch this event.
Code: Select all
...
Global *GetLocalTime
Global *DestroyWindow
...
ProcedureDLL Start()
*GetLocalTime = Hook(ProcAddress("kernel32.dll", "GetLocalTime"), @GetLocalTime__())
*DestroyWindow = Hook(ProcAddress("kernel32.dll", "DestroyWindow"), @DestroyWindow__())
EndProcedure
...
I also added a DestroyWindow-procedure "DestroyWindow__(hWnd)", but it cannot catch the third-party application termination event. The DestroyWindow API has only one argument, the window handle.
Please tell me how to catch this event.
Re: API-hooking question [NOT solved] :(
Seems about rightZX80 wrote:Now it works! Is it right?
If you're working with WinAPI you should always check the documentation on msdn (DestroyWindow) first! Scroll down to "Requirements" and you'll see that DestroyWindow is located in the User32.dll and not in the Kernel32.dll. So you probably want to change that in your Hook function call. But DestroyWindow might not even get called in your third-party application!!!ZX80 wrote:Comrades, one more question, please. How can I set the second hook? I also need to know when the third-party program will be closed to terminate my application correctly (at the same time). Of course, I could check the existence of a window by timer, but we already have one hook installed. I changed the start-procedure to this:
[/size]Code: Select all
... Global *GetLocalTime Global *DestroyWindow ... ProcedureDLL Start() *GetLocalTime = Hook(ProcAddress("kernel32.dll", "GetLocalTime"), @GetLocalTime__()) *DestroyWindow = Hook(ProcAddress("kernel32.dll", "DestroyWindow"), @DestroyWindow__()) EndProcedure ...
I also added a DestroyWindow-procedure "DestroyWindow__(hWnd)", but it cannot catch the third-party application termination event. The DestroyWindow API has only one argument, the window handle.
Please tell me how to catch this event.
Maybe DetachProcess() works better for you?!
Code: Select all
XIncludeFile "API_HookEngine.pbi"
UseModule API_HookEngine
EnableExplicit
Structure Params
diff.i
EndStructure
Global *GetLocalTime
Global difference
Procedure GetLocalTime__(*lpSystemTime.SYSTEMTIME)
Protected func = UnHook(*GetLocalTime)
Protected retn = CallFunctionFast(func, *lpSystemTime)
Protected SetTime.q = Date() + difference
*lpSystemTime\wDay = Day(SetTime)
*lpSystemTime\wMonth = Month(SetTime)
*lpSystemTime\wYear = Year(SetTime)
*lpSystemTime\wHour = Hour(SetTime)
*lpSystemTime\wMinute = Minute(SetTime)
*lpSystemTime\wSecond = Second(SetTime)
*GetLocalTime = Hook(func, @GetLocalTime__())
ProcedureReturn retn
EndProcedure
ProcedureDLL AttachProcess(Instance)
MessageRequester("AttachProcess()", "Dll attached")
EndProcedure
ProcedureDLL DetachProcess(Instance)
MessageRequester("DetachProcess()", "Dll detached")
EndProcedure
ProcedureDLL ChangeTime(*Parameters.Params)
difference = *Parameters\diff
EndProcedure
ProcedureDLL Start()
*GetLocalTime = Hook(ProcAddress("kernel32.dll", "GetLocalTime"), @GetLocalTime__())
MessageRequester("Start()", "*GetLocalTime = " + Str(*GetLocalTime))
EndProcedure
ProcedureDLL _End()
If UnHook(*GetLocalTime)
MessageRequester("_End()", "UnHooked")
EndIf
;UnuseModule API_HookEngine
EndProcedure
Et cetera is my worst enemy
Re: API-hooking question [NOT solved] :(
chi, thanks for your reply.
My bad. You are absolutely right!
No it is not. This API-function is exactly called (100%). Additionally, I have also seen CreateWindowExA. So DestroyWindow can be caught (sure).
Thanks for another variant! I know about these special/internal procedures, but it's not suitable. Yes, it works, but... with latency/delay. The third-party application has time to close before the message is displayed ("Dll detached"). Thus, there is no way to properly close the injector part. Since I am getting the following messages:
Is this dangerous or not?
I made the following small changes (for test):
Actually I wanted to set a hook to prevent premature closing of the third-party program (to prevent the third-party application from responding to close commands from the GUI such as menu, "x", etc). But without using DeleteMenu_(hsubmnu, item, #MF_BYPOSITION).
The algorithm is as follows: if terminate event detected then send message to injector (don't let the operating system process it). Then call ProcedureDLL _End(). Then correctly eject the dll: EjectDLL(PID, "", *func). Then send the command to close the third-party application: PostMessage_(hWnd,#WM_CLOSE,0,0).
So if possible, could you show the correct procedure for DestroyWindow, please. The point is that this function should not be processed by the system (catch and skip). Then I will close the third-party application myself (as I said above). This is the goal.
Thank in advance.
P.S.
So... we got the following code. Is it right?
[/size]
Looks like it works. But not in the case of a right click on the tab bar and choose "close window" menu item. The same goes for the task manager.
Sorry for my English. I think if you look at the code, it will be better than my words.
If you're working with WinAPI you should always check the documentation on msdn (DestroyWindow) first! Scroll down to "Requirements" and you'll see that DestroyWindow is located in the User32.dll and not in the Kernel32.dll.
My bad. You are absolutely right!
But DestroyWindow might not even get called in your third-party application!!!
No it is not. This API-function is exactly called (100%). Additionally, I have also seen CreateWindowExA. So DestroyWindow can be caught (sure).
Maybe DetachProcess() works better for you?!
Thanks for another variant! I know about these special/internal procedures, but it's not suitable. Yes, it works, but... with latency/delay. The third-party application has time to close before the message is displayed ("Dll detached"). Thus, there is no way to properly close the injector part. Since I am getting the following messages:
"Cannot Call _End Procedure"
"Error in Ejecting DLL from program"
Is this dangerous or not?
I made the following small changes (for test):
Code: Select all
Structure Params
diff.i
hWnd.i ;injector window handle
EndStructure
Global handle
...
ProcedureDLL DetachProcess(Instance)
PostMessage_(handle,#WM_CLOSE,0,0) ;for automatically close the injector
;MessageRequester("DetachProcess()", "Dll detached")
EndProcedure
ProcedureDLL ChangeTime(*Parameters.Params)
difference = *Parameters\diff
handle = *Parameters\hWnd
EndProcedure
The algorithm is as follows: if terminate event detected then send message to injector (don't let the operating system process it). Then call ProcedureDLL _End(). Then correctly eject the dll: EjectDLL(PID, "", *func). Then send the command to close the third-party application: PostMessage_(hWnd,#WM_CLOSE,0,0).
So if possible, could you show the correct procedure for DestroyWindow, please. The point is that this function should not be processed by the system (catch and skip). Then I will close the third-party application myself (as I said above). This is the goal.
Thank in advance.
P.S.
So... we got the following code. Is it right?
Code: Select all
IncludeFile "API_HookEngine.pbi"
UseModule API_HookEngine
EnableExplicit
Structure Params
diff.i
h.i
EndStructure
Global *GetLocalTime
Global *DestroyWindow
Global difference, handle
Procedure GetLocalTime__(*lpSystemTime.SYSTEMTIME)
Protected func = UnHook(*GetLocalTime)
Protected retn = CallFunctionFast(func, *lpSystemTime)
Protected SetTime.q = Date() + difference
*lpSystemTime\wDay = Day(SetTime)
*lpSystemTime\wMonth = Month(SetTime)
*lpSystemTime\wYear = Year(SetTime)
*lpSystemTime\wHour = Hour(SetTime)
*lpSystemTime\wMinute = Minute(SetTime)
*lpSystemTime\wSecond = Second(SetTime)
*GetLocalTime = Hook(func, @GetLocalTime__())
ProcedureReturn retn
EndProcedure
Procedure DestroyWindow__(hWnd)
Protected func = UnHook(*DestroyWindow)
Protected retn = CallFunctionFast(func, @hWnd)
PostMessage_(handle,#WM_CLOSE,0,0)
*DestroyWindow = Hook(func, @DestroyWindow__())
ProcedureReturn retn
EndProcedure
ProcedureDLL ChangeTime(*Parameters.Params)
difference = *Parameters\diff
handle = *Parameters\h
EndProcedure
ProcedureDLL Start()
*GetLocalTime = Hook(ProcAddress("kernel32.dll", "GetLocalTime"), @GetLocalTime__())
*DestroyWindow = Hook(ProcAddress("user32.dll", "DestroyWindow"), @DestroyWindow__())
EndProcedure
ProcedureDLL _End()
UnHook(*GetLocalTime)
UnHook(*DestroyWindow)
EndProcedure
Looks like it works. But not in the case of a right click on the tab bar and choose "close window" menu item. The same goes for the task manager.
Sorry for my English. I think if you look at the code, it will be better than my words.
Re: API-hooking question [NOT solved] :(
Hi to all.
Please tell me how to add a condition to the "DestroyWindow__" procedure? Processing or not. It is not always necessary to intercept this function (only for main window). А lot of dialog windows(other settings) wich also using "DestroyWindow" API = headache.
Thank in advance.
Please tell me how to add a condition to the "DestroyWindow__" procedure? Processing or not. It is not always necessary to intercept this function (only for main window). А lot of dialog windows(other settings) wich also using "DestroyWindow" API = headache.
Thank in advance.
Re: API-hooking question [NOT solved] :(
I didnt have the time to read all... but u could try hooking ExitProcess for cleanup.
Otherwise i suggest to hook WindowProc to catch window messages there.
Otherwise i suggest to hook WindowProc to catch window messages there.
Re: API-hooking question [NOT solved] :(
Mijikai, thank you! Use the "ExitProcess" is good point/hint. Will try...
Re: API-hooking question [NOT solved] :(
Instead of hooking, you could simply subclass the window. This way you can intercept WM_CLOSE/WM_DESTROY messages and redirect them at will.
Et cetera is my worst enemy
Re: API-hooking question [NOT solved] :(
Good time, chi. Thanks for your reply again.
I really don't understand why the DestroyWindow message comes up when I open the application preferences/settings. It is confusing. How can I separate all DestroyWindow-messages for target process? I thought to use something like this(immediately after hooked):
[/size]
to compare it with main window title (to decide whether to handle the hook or skip). But I think this is a bad idea. The new window will not appear until I make a decision. But when I write ProcedureReturn it will be too late. Vicious circle.
Also I saw this fresh topic. But mouse interception does not suit for me, since the main window can be closed in several ways (for example via the context menu or task bar). And I don't know in advance what will user choose. Netmaestro's code works well with notepad, but not with my third party app. Of course I changed the line
[/size]
in the DLL to my own. Why? I don't know. All apps is x86.
On your recommendation, I also looking for topic about subclasses. But so far unsuccessfully.
Finally I think I need to use ExitProcess(it's only one right way), but I don't understand how to make it work. If you have an example then share it, please.
At the moment I have only this:
[/size]
It looks working, but I don't know if it's correct or not. I also noticed that DestroyWindow is called before calling ExitProcess. But I don't understand how to use DestroyWindow. Namely, when to process the hook, and when to skip. To skip it, just write ProcedureReturn without a parameter. But how determine a condition? This is a big question.
P.S. Here I found some very interesting code (by Sparkie). I fixed it a bit and it worked, but not with all windows. Including the window of my third-party application is not processed.
I really don't understand why the DestroyWindow message comes up when I open the application preferences/settings. It is confusing. How can I separate all DestroyWindow-messages for target process? I thought to use something like this(immediately after hooked):
Code: Select all
GetWindowText_(GetForegroundWindow_(),title,255)
to compare it with main window title (to decide whether to handle the hook or skip). But I think this is a bad idea. The new window will not appear until I make a decision. But when I write ProcedureReturn it will be too late. Vicious circle.
Also I saw this fresh topic. But mouse interception does not suit for me, since the main window can be closed in several ways (for example via the context menu or task bar). And I don't know in advance what will user choose. Netmaestro's code works well with notepad, but not with my third party app. Of course I changed the line
Code: Select all
hwndTarget = FindWindow_ (0, "Testing123")
in the DLL to my own. Why? I don't know. All apps is x86.
On your recommendation, I also looking for topic about subclasses. But so far unsuccessfully.
Finally I think I need to use ExitProcess(it's only one right way), but I don't understand how to make it work. If you have an example then share it, please.
At the moment I have only this:
Code: Select all
#WM_MYEVENT = #WM_USER + 1
...
Procedure ExitProcess__(ExitCode)
UnHook(*GetLocalTime)
UnHook(*ExitProcess)
PostMessage_(handle, #WM_MYEVENT, 0, 0)
EndProcedure
It looks working, but I don't know if it's correct or not. I also noticed that DestroyWindow is called before calling ExitProcess. But I don't understand how to use DestroyWindow. Namely, when to process the hook, and when to skip. To skip it, just write ProcedureReturn without a parameter. But how determine a condition? This is a big question.
P.S. Here I found some very interesting code (by Sparkie). I fixed it a bit and it worked, but not with all windows. Including the window of my third-party application is not processed.
Re: API-hooking question [NOT solved] :(
Ok, let's try this one...
First download and run Process Explorer so you can get the Process ID (PID) of the program you want to inject your dll. Go to View/Select Columns.../Process Image/ and check "Image Type (64 vs 32-bit)". Now run your program of choice (e.g. Calculator) and find the PID and Image Type. Compile app.pb + dll.pb to app.exe and dll.dll (must be the same Image Type as your opened program!). Run app.exe, enter the PID and hit Inject... You should hear a Beep when injected correctly. If you opened up the Calculator, you should see a hooked MsgBox by clicking Help/About Calculator. Closing the app will unhook first and then close...
app.pb
[/size]
dll.pb
[/size]
Try first with the Calculator and, if it works like expected, try your 3rd party app. If your app doesn't work, the only way I could help you further is by letting me know the name of your 3rd party app...
First download and run Process Explorer so you can get the Process ID (PID) of the program you want to inject your dll. Go to View/Select Columns.../Process Image/ and check "Image Type (64 vs 32-bit)". Now run your program of choice (e.g. Calculator) and find the PID and Image Type. Compile app.pb + dll.pb to app.exe and dll.dll (must be the same Image Type as your opened program!). Run app.exe, enter the PID and hit Inject... You should hear a Beep when injected correctly. If you opened up the Calculator, you should see a hooked MsgBox by clicking Help/About Calculator. Closing the app will unhook first and then close...
app.pb
Code: Select all
XIncludeFile "API_HookEngine.pbi"
UseModule API_HookEngine
dll.s = GetCurrentDirectory() + "dll.dll"
OpenWindow(0, 0, 0, 130, 80, "Inject DLL", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StickyWindow(0, 1)
StringGadget(0, 10, 10, 110, 21, "")
ButtonGadget(1, 10, 40, 110, 30, "Inject")
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case 1
pid = Val(GetGadgetText(0))
If pid
InjectDll(pid, dll)
Break
EndIf
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow
dll.pb
Code: Select all
XIncludeFile "API_HookEngine.pbi"
UseModule API_HookEngine
Global OldWinProc
Global *ShellAboutW
Global *ShellAboutA
Procedure My_ShellAboutW(hWnd, *szApp, *szOtherStuff, hIcon)
MessageRequester("About", "Hooked Message.")
ProcedureReturn 0
EndProcedure
Procedure My_ShellAboutA(hWnd, *szApp, *szOtherStuff, hIcon)
MessageRequester("About", "Hooked Message.")
ProcedureReturn 0
EndProcedure
Procedure myWinProc(hWnd, uMsg, wParam, lParam)
Select uMsg
Case #WM_CLOSE
; If MessageRequester("Hello ZX80", "Do you want to close the program?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_No
; ProcedureReturn 0
; EndIf
If UnHook(*ShellAboutW) And UnHook(*ShellAboutA)
MessageRequester("Info", "All unhooked...")
EndIf
Case #WM_NCDESTROY
SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @OldWinProc)
EndSelect
ProcedureReturn CallWindowProc_(OldWinProc, hWnd, uMsg, wParam, lParam)
EndProcedure
Procedure EnumWindowsProc(hWnd, lParam)
GetWindowThreadProcessId_(hWnd, @lpProc)
If lpProc = PeekL(lParam)
PokeL(lParam, hWnd)
ProcedureReturn 0
EndIf
ProcedureReturn 1
EndProcedure
Procedure GetProcHwnd()
Protected pid = GetCurrentProcessId_()
ptr = pid
EnumWindows_(@EnumWindowsProc(), @ptr)
If ptr = pid
ProcedureReturn 0
EndIf
ProcedureReturn ptr
EndProcedure
ProcedureDLL AttachProcess(hInstance)
Beep_(800, 50)
hWnd = GetProcHwnd()
OldWinProc = SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @myWinProc())
*ShellAboutW = Hook(ProcAddress("Shell32.dll", "ShellAboutW"), @My_ShellAboutW())
*ShellAboutA = Hook(ProcAddress("Shell32.dll", "ShellAboutA"), @My_ShellAboutA())
EndProcedure
ProcedureDLL DetachProcess(hInstance)
Beep_(800, 50)
EndProcedure
Try first with the Calculator and, if it works like expected, try your 3rd party app. If your app doesn't work, the only way I could help you further is by letting me know the name of your 3rd party app...
Et cetera is my worst enemy
Re: API-hooking question [NOT solved] :(
Good time, chi
Thanks a lot for the hint. And sorry for too late reply. I was busy these days so couldn't answer earlier (other things, not programing). Also I needed a some time for test it. I'm so sorry.
Okay. You showed me exactly what I asked. But I really don't understand why you're dropping the injector. In my opinion, it should work all time. Because for correct completion, you need to call the EjectDLL procedure. I didn't see it in your code. This was the main goal of my question!
Thus, I did the following(for your example):
dll.pb
[/size]
What is 20005? I don't know. The code catched it. I looked for this value in all PB constants, but did not found it. Probably it's some internal message. Anyway, but it works now. Also I read about WM_NCDESTROY here.
Removed that + next line:
[/size]
Reason: third-party application to crash with it.
Finally, the injector now looks something like this:
app.pb
[/size]
I think this is more correct now.
Hope I was able to explain what I was looking for.
P.S. To find out the pid, I just need to open the standard Task Manager ("Processes" tab). Wink.
Anyway, thanks again to YOU!
Thanks a lot for the hint. And sorry for too late reply. I was busy these days so couldn't answer earlier (other things, not programing). Also I needed a some time for test it. I'm so sorry.
Okay. You showed me exactly what I asked. But I really don't understand why you're dropping the injector. In my opinion, it should work all time. Because for correct completion, you need to call the EjectDLL procedure. I didn't see it in your code. This was the main goal of my question!
Thus, I did the following(for your example):
dll.pb
Code: Select all
...
Global *OldWinProc
Global handle = FindWindow_(0, "Inject DLL")
#WM_MYEVENT = #WM_USER + 1
...
...
Procedure myWinProc(hWnd, uMsg, wParam, lParam)
Select uMsg
Case #WM_COMMAND ;4 context menu
If wParam = 20005
PostMessage_(handle, #WM_MYEVENT, 0, 0)
ProcedureReturn 0
EndIf
Case #WM_CLOSE ;4 taskbar
PostMessage_(handle, #WM_MYEVENT, 0, 0)
ProcedureReturn 0
EndSelect
ProcedureReturn CallWindowProc_(*OldWinProc, hWnd, uMsg, wParam, lParam)
EndProcedure
...
...
ProcedureDLL AttachProcess(hInstance)
Beep_(800, 50)
Protected hWnd = GetProcHwnd()
*OldWinProc = GetWindowLongPtr_(hWnd, #GWL_WNDPROC)
SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @myWinProc())
...
...
EndProcedure
ProcedureDLL _End()
UnHook(*...)
UnHook(*...)
EndProcedure
What is 20005? I don't know. The code catched it. I looked for this value in all PB constants, but did not found it. Probably it's some internal message. Anyway, but it works now. Also I read about WM_NCDESTROY here.
Removed that + next line:
Code: Select all
Case #WM_NCDESTROY
SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @OldWinProc)
Reason: third-party application to crash with it.
Finally, the injector now looks something like this:
app.pb
Code: Select all
...
#WM_MYEVENT = #WM_USER + 1
...
Define program = RunProgram(",,,
handle = OpenWindow(0, ...
pid = ProgramID(program)
...
Repeat
event = WaitWindowEvent()
Select event
Case #WM_MYEVENT
If *func
If CallRemoteFunction(pid, *func, "_End", #True)
Debug "_End Procedure Called"
If EjectDLL(pid, "", *func) ;This particular line was very important for me! Everything is done for this!
;If the UnHook procedure can be called from the dll directly, then you cannot do this with EjectDLL (I think so).
;This should be called from the injector.
Debug "DLL Ejected Sucessfuly"
*func = #Null
;Now I can safely close the third party application
PostMessage_(hWnd,#WM_CLOSE,0,0) ;In my case, this is enough and works well, but I know there are other variation/version.
;hWnd is a third-party program window handle that can be found via EnumWindows_
Break
Else
Debug "Error in Ejecting DLL from program"
EndIf
Else
Debug "Cannot Call _End Procedure"
EndIf
EndIf
Case #PB_Event_Gadget
Select EventGadget()
Case 1
;pid = Val(GetGadgetText(0))
If pid
*func = InjectDll(pid, dll)
;Break
EndIf
EndSelect
Case #PB_Event_CloseWindow
PostMessage_(handle, #WM_MYEVENT, 0, 0)
...
...
EndSelect
Break
I think this is more correct now.
Hope I was able to explain what I was looking for.
P.S. To find out the pid, I just need to open the standard Task Manager ("Processes" tab). Wink.
Anyway, thanks again to YOU!
Re: API-hooking question [SOLVED!] :)
No problem at all... Same hereZX80 wrote:Thanks a lot for the hint. And sorry for too late reply. I was busy these days so couldn't answer earlier (other things, not programing). Also I needed a some time for test it. I'm so sorry.
I dropped the ejector to show you that it's not needed. The dll gets automatically detached when the program exit (DetachProcess). The only reason (for me) to call eject would be, when you develop a dll and you don't want to close your main app every time you changed a line.ZX80 wrote:Okay. You showed me exactly what I asked. But I really don't understand why you're dropping the injector. In my opinion, it should work all time. Because for correct completion, you need to call the EjectDLL procedure. I didn't see it in your code. This was the main goal of my question!
is the same asZX80 wrote:Code: Select all
*OldWinProc = GetWindowLongPtr_(hWnd, #GWL_WNDPROC) SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @myWinProc())
Code: Select all
*OldWinProc = SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @myWinProc())
As long as your 3rd party app is not crashing on exit, it's fineZX80 wrote:I think this is more correct now.
Hope I was able to explain what I was looking for.
I never used the standard TM so I was not sure if it shows the PID somewhere...ZX80 wrote:P.S. To find out the pid, I just need to open the standard Task Manager ("Processes" tab). Wink.
Anyway, seems like you [SOLVED!] your problem...
Et cetera is my worst enemy