Page 2 of 2

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

Posted: Tue Aug 29, 2006 10:17 am
by newbie
Great info Rings ;)

About the driver, you will need to do it in C++ with the MS SDK I guess, and hook native API. Far less easy than PB :?

Posted: Tue Aug 29, 2006 11:54 am
by Inf0Byt3
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.

Posted: Tue Oct 10, 2006 7:10 pm
by uweb
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 :

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)
Where is my failure ?
Is OpenFileRequester not a part of my app-process ?

Posted: Fri Jun 06, 2008 11:01 am
by sazuker
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.

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)
as a FIX

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

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 
Can anyone do help translate this wonderful piece of code?
thx

Posted: Fri Jun 06, 2008 1:17 pm
by rsts
They prefer if you post a request one time in one forum.

cheers

Posted: Sat Jun 07, 2008 9:12 am
by pdwyer
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...)

Posted: Sat Jun 07, 2008 9:38 am
by DoubleDutch
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).

Posted: Sat Jun 07, 2008 6:27 pm
by Mistrel
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...)
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.

Posted: Wed Jun 11, 2008 2:06 am
by superadnim
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



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

Posted: Tue Jun 17, 2008 6:28 pm
by Joakim Christiansen
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'm not sure if I understand what you mean, but I had no luck using a dll here. Can you maybe show some example?

Re: API hooking

Posted: Sat May 25, 2013 7:46 am
by Blankname
newbie wrote:Interesting piece of code, thanks for sharing ;)
But I do not understand at all this snippet :

Code: Select all

Dim a.b(6)
a(0)=$e9
a(5)=$C3
What are these values ? Where do they come from ?
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
It backs up existing API bytes, and makes the function jump to your own procedure. From there you can do whatever you want with the information that is sent in the API call. When its done, it just writes the original bytes back to restore the original function.