Posted: Mon Aug 28, 2006 3:30 pm
Hmm, not a bad idea... But I would use it for PureAV
. Lemme search for PureFan's posts, maybe i can find some info about it...

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)
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)
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
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...)
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")
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).
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