
API hooking
Nope, it's too hard... Yes, i tried with VC++ express + Windows SDK + Windows DDK, but it takes to much space and it's very hard to build something good. So the better option is to use this code and patch all running processes... I don't see an alternative here unless a very experienced C coder will help us make a good driver. And that's hard. We'd better stick with this code until we find something better.
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
May this will help. I found it but i am not able to use it.
http://www.codeproject.com/system/kernelspying.asp
http://www.codeproject.com/system/api_spying_hack.asp
I am also not abel to use your good work for my purpose :
Where is my failure ?
Is OpenFileRequester not a part of my app-process ?
http://www.codeproject.com/system/kernelspying.asp
http://www.codeproject.com/system/api_spying_hack.asp
I am also not abel to use your good work for my purpose :
Code: Select all
;Translated from C to Pure by Siegfried Rings, 2006
;API Hooking example for PureBasic 4
;(c) Sigfried Rings and Inf0Byt3
;Version 0.1
;>------------------------------------------------------------
;License: Freeware but with some limits: By using this library you agree
;NOT use it for creating malware, viruses, spyware, worms or rootkits
;or any program of this kind. If you do this I will find you, I'll kick your sorry ass,
;and cut your arms off so you can't code such crap in the future ;)
;Now get back to coding!
#module = "kernel32"
#proc = "FindNextFileA"
; ############################################################################
; you should have a file with the extension ".wf" in c:\ to see any difference
; ############################################################################
Procedure SearchDisk(path.s)
Count = 0
url.s = path + "*"
Static searchData.WIN32_FIND_DATA
hFind = FindFirstFile_(url.s,@searchData)
If hFind <> #INVALID_HANDLE_VALUE
Repeat
Count+1
Until FindNextFile_(hFind, @searchData)= #False
FindClose_(handle)
EndIf
Debug Count
EndProcedure
Procedure Test ()
StandardFile$ = "C:\"
Pattern$ = "Text (*.txt)|*.txt;*.bat|*.pb|Alle Dateien (*.*)|*.*"
Pattern = 2
File$ = OpenFileRequester("Bitte Datei auswählen", StandardFile$, Pattern$, Pattern)
EndProcedure
Global Dim Backup.b(5)
Procedure.l MyHook ( FindFileHandle.l, *FindFileData.WIN32_FIND_DATA)
SetLastError_(#ERROR_NO_MORE_FILES)
ProcedureReturn 0
EndProcedure
Procedure.l Hook(Libname.s,FuncName.s,NewFunctionAddress)
dwAddr =GetProcAddress_(GetModuleHandle_(LibName), FuncName)
OriginalAdress=dwAddr
Result=ReadProcessMemory_(GetCurrentProcess_(), dwAddr, @Backup(0), 6, @readbytes) ;save old Bytes
Dim a.b(6)
a(0)=$e9
a(5)=$C3
dwCalc = NewFunctionAddress - dwAddr - 5; //((to)-(from)-5)
CopyMemory(@dwCalc,@a(1),4)
Result = WriteProcessMemory_(GetCurrentProcess_(), dwAddr, @a(0), 6, @written);
Debug "Result : "+Str(Result)
EndProcedure
Procedure UnHook(Libname.s,FuncName.s)
dwAddr = GetProcAddress_(GetModuleHandle_(LibName), FuncName)
Result= WriteProcessMemory_(GetCurrentProcess_(), dwAddr, @Backup(0), 6, @written);
EndProcedure
Test ()
SearchDisk("C:\")
Hook(#module, #proc, @MyHook());
Test ()
SearchDisk("C:\")
UnHook(#module, #proc)
Is OpenFileRequester not a part of my app-process ?
Please pardon my English, my native tongue is German.
the problem on this hook is that you need to hook and un hook the function everytime you need to use the original procedure
ex.
as a FIX
But this is not efficient since everytime the program uses the function you need to hook/unhook read/write memory
As a solution I found this asm code but I dont know how to translate it to PB
what does it do is that it hooks the function and then returns the relocated address of the original function
so you can do 1 time hook and just pass the parameters to the original function
so you will just do
Can anyone do help translate this wonderful piece of code?
thx
ex.
Code: Select all
procedure myfunction(a,b,c,d)
procedurereturn thisfunction(a,b,c,d)
;THIS RUNS ON AN INFINITE LOOP
;since calling thisfunction would jmp again to myfunction then to thisfunction...
endprocedure
HookFunction(thisfunction, myfunction)
Code: Select all
procedure myfunction(a,b,c,d)
UnHookFunction(thisfunction, myfunction) ;unhook first so that we can use thisfunction() without looping back
result = thisfunction(a,b,c,d)
HookFunction(thisfunction, myfunction)
procedurereturn result
endprocedure
HookFunction(thisfunction, myfunction)
As a solution I found this asm code but I dont know how to translate it to PB
what does it do is that it hooks the function and then returns the relocated address of the original function
so you can do 1 time hook and just pass the parameters to the original function
so you will just do
Code: Select all
myoriginalfunction =0
procedure myfunction(a,b,c,d)
procedurereturn CallFunctionFast(myoriginalfunction, a,b,c,d)
endprocedure
myoriginalfunction = HookFunction(thisfunction, myfunction)
Code: Select all
; ProcInstallHook proc uses ebx edi esi hookProc:DWORD, targetProc:DWORD, patchLen:DWORD
;
; mov esi, patchLen
; mov edi, targetProc
;
; mov eax, esi
; add eax, 5
; invoke Alloc, eax
; mov ebx, eax
;
; ; copy the to-be-emulated bytes from targetProc to detour's beginning
; invoke MemCopy, edi, eax, esi
;
; ; make the target writable
; invoke VirtualProtect, edi, 5, PAGE_EXECUTE_READWRITE, ADDR targetProc
;
; ; replace the bytes with a jmp to the hook
; mov eax, hookProc
; sub eax, edi
; sub eax, 5
; mov BYTE PTR [edi], 0E9h
; mov [edi + 1], eax
;
; ; set protections back to old ones to avoid complications
; invoke VirtualProtect, edi, 5, targetProc, ADDR targetProc
;
; ; put a jmp to the targetProc at the end of detour
; sub edi, ebx
; add esi, ebx
; sub edi, 5
; mov BYTE PTR [esi], 0E9h
; mov [esi + 1], edi
;
; Return ebx
;
; ProcInstallHook endp
thx
Can you hook a process running under different credentials? or, if your process is not running as an administrator can you hook a process that is? (I would hope not I guess...)
Paul Dwyer
“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
- DoubleDutch
- Addict
- Posts: 3220
- Joined: Thu Aug 07, 2003 7:01 pm
- Location: United Kingdom
- Contact:
If you create the system hooking code in a DLL, then call the hooking "start" from your user app it will hook system system wide.
(If no anti-virus code stops you).
(If no anti-virus code stops you).
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
https://reportcomplete.com <- School end of term reports system
I believe you can so long as you have equal or higher credentials than that process. I know this is very restrictive on Vista. I don't know how loose these rules are on other Windows operating systems.pdwyer wrote:Can you hook a process running under different credentials? or, if your process is not running as an administrator can you hook a process that is? (I would hope not I guess...)
-
- Enthusiast
- Posts: 480
- Joined: Thu Jul 27, 2006 4:06 am
I tried to port it but I messed up, I think at the last portions where I got "register loss" since I'm not very good with assembly
I assumed the size it requires is of the new function (else I don't know how to get the original function's size...!)
But it never beeps in my example, and if you swap the procedure pointers it does beep but in an endless loop (no detouring at all).
Perhaps someone could spot my mistake (I assume its on the bottom part of the code). I understand the idea behind this, I don't understand the "how" exactly.
Code: Select all
Procedure.l ProcInstallHook (hookProc.l, targetProc.l, patchLen.l) ; detouring hook.
Memory = AllocateMemory(patchLen+5)
; copy the to-be-emulated bytes from targetProc to detour's beginning
CopyMemory(targetProc, Memory, patchLen)
; make the target writable
VirtualProtect_(targetProc, 5, #PAGE_EXECUTE_READWRITE, @protection)
; replace the bytes with a jmp to the hook
PokeB(targetProc, $0E9)
PokeL(targetProc + SizeOf(BYTE), ((hookProc - targetProc) - 5) )
; set protections back to old ones to avoid complications
VirtualProtect_( targetProc, 5, protection, @protection )
targetProc - Memory
patchLen + Memory
targetProc - 5
; put a jmp to the targetProc at the end of detour
PokeB(Memory, $0E9)
PokeL(Memory + SizeOf(BYTE), targetProc)
ProcedureReturn Memory
EndProcedure ; ProcInstallHook
Global myoriginalfunction = 0
Procedure myfunction(hWnd, Title$, Text$, Flags=#Null)
a:
Beep_(1000,100) : Debug "BEEP!"
ProcedureReturn CallFunctionFast(myoriginalfunction, hWnd, Title$, Text$, Flags)
b:
EndProcedure
Declare MessageBox(hWnd, Title$, Text$, Flags=#Null )
Import "user32.lib"
MessageBox(hWnd, Title$, Text$, Flags=#Null ) As "_MessageBoxA"
EndImport
myoriginalfunction = ProcInstallHook( @MessageBox(), @myfunction(), ?b-?a)
MessageBox(0, "world", "hello")
;myfunction(0,"world", "hello")
But it never beeps in my example, and if you swap the procedure pointers it does beep but in an endless loop (no detouring at all).
Perhaps someone could spot my mistake (I assume its on the bottom part of the code). I understand the idea behind this, I don't understand the "how" exactly.


- Joakim Christiansen
- Addict
- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
I'm not sure if I understand what you mean, but I had no luck using a dll here. Can you maybe show some example?DoubleDutch wrote:If you create the system hooking code in a DLL, then call the hooking "start" from your user app it will hook system system wide.
(If no anti-virus code stops you).
I like logic, hence I dislike humans but love computers.
Re: API hooking
newbie wrote:Interesting piece of code, thanks for sharing
But I do not understand at all this snippet :
What are these values ? Where do they come from ?Code: Select all
Dim a.b(6) a(0)=$e9 a(5)=$C3
Basically you backup the current real API address, and then you overwrite it with your custom procedure address, I don't see the need of these values.
Code: Select all
Dim a.b(6)
a(0)=$e9 ;JMP
a(5)=$C3 ;RET