It is currently Tue May 26, 2020 12:33 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Hot Patching hook (32bits)
PostPosted: Thu Sep 01, 2011 8:37 pm 
Offline
Enthusiast
Enthusiast

Joined: Sat Jul 09, 2011 7:57 am
Posts: 276
Since Windows XP, Most of the windows APIs are compiled with the hotpatch command who make inline hook more proper (no more trampolines).

Code:
; hot patching hook
; xorc1zt

Procedure HotPatchHook(TargetFuncAddress.l, ProxyFuncAddress.l)
  ;E9 XX XX XX XX EB F9
  Protection.w
  JumpOffset.l = ( ProxyFuncAddress - ( TargetFuncAddress-5 ) )-5
  VirtualProtect_(TargetFuncAddress-5, 7, #PAGE_EXECUTE_READWRITE, @Protection)
  PokeA( TargetFuncAddress-5, $E9 ) ;Far Jump
  PokeL( TargetFuncAddress-4, JumpOffset )
  PokeA( TargetFuncAddress,   $EB ) ;Short Jump
  PokeA( TargetFuncAddress+1, $F9 ) ; -5
  VirtualProtect_(TargetFuncAddress-5, 7, Protection, @Protection )
EndProcedure

Procedure RemoveHook(TargetFuncAddress.l)
  ;90 90 90 90 90 8B FF
  Protection.w
  VirtualProtect_(TargetFuncAddress-5, 7, #PAGE_EXECUTE_READWRITE, @Protection)
  PokeA( TargetFuncAddress-5, $90 )
  PokeA( TargetFuncAddress-4, $90 )
  PokeA( TargetFuncAddress-3, $90 )
  PokeA( TargetFuncAddress-2, $90 )
  PokeA( TargetFuncAddress-1, $90 )
  PokeA( TargetFuncAddress,   $8B )
  PokeA( TargetFuncAddress+1, $FF )
  VirtualProtect_(TargetFuncAddress-5, 7, Protection, @Protection )
EndProcedure


Example: hooking MessageBoxA
Code:
Prototype.l ProtoMessageBox(Window.l, Body$, Title$, Flags.l = 0)
Global CocoaMessageBox.ProtoMessageBox

Procedure MsgBoxProxy(Window.l, Body$, Title$, Flags.l = 0)
  Debug "MessageBoxA: "+Str(Window)+", "+Body$+", "+Title$+", "+Str(Flags)
  CocoaMessageBox(Window, Body$, Title$, Flags)
EndProcedure

OpenLibrary(0, "User32.dll")
address.l = GetFunction(0, "MessageBoxA")
CocoaMessageBox = address+2
HotPatchHook(address,@MsgBoxProxy())
CallFunction(0,"MessageBoxA", 0, @"Body", @"Title", 0)
CallFunction(0,"MessageBoxA", 0, @"aaaa", @"bbbb", 0)
CallFunction(0,"MessageBoxA", 0, @"1111", @"2222", 0)
RemoveHook(address)
CallFunction(0,"MessageBoxA", 0, @"cccc", @"dddd", 0)


edit : use this to check if a function is hot patchable or not

Code:
Procedure.b IsHotPatchable(TargetFuncAddress.l)
  op.q = PeekQ(TargetFuncAddress-5)
  If FindString(Hex(op), "FF8B9090909090", 3)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Thu Sep 01, 2011 9:24 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Aug 31, 2005 11:09 pm
Posts: 3698
Location: Italy
Weird in a nice way thanks !

So this can be useful to replace all the calls to a specific Windows api with your code ?

Didn't know about this thing. :)

I suppose this works only for the patching process, right ?

_________________
[ My little PureBasic review ]


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Thu Sep 01, 2011 10:55 pm 
Offline
Enthusiast
Enthusiast

Joined: Sat Jul 09, 2011 7:57 am
Posts: 276
luis wrote:
I suppose this works only for the patching process, right ?


Yes, system wide hook must be done at kernel level with a driver


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Fri Sep 02, 2011 11:42 am 
Offline
Addict
Addict

Joined: Sat Dec 31, 2005 5:24 pm
Posts: 2970
Location: Where ya would never look.....
It is nice in a weird sort of way, but I don't know about a replacement for a call to the API. I mean, if you still need to declair a prototype of some sort and still call the API then why not just call the API in the first place instead of adding additional code that in the end does the same thing?

But... it is interesting. Thanks for the tip. :)

_________________
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Fri Sep 02, 2011 4:26 pm 
Offline
Enthusiast
Enthusiast

Joined: Sat Jul 09, 2011 7:57 am
Posts: 276
with api hooking you can do what you want into every process where you inject your code.

example with ShellAboutW (many apps use this function for the about box)

Code:
; Proxy DLL
; xorc1zt

Prototype.l ProtoShellAbout(hWnd.l, szApp.s, szOtherStuff.s, hIcon.l)
Global oShellAbout.ProtoShellAbout
Global ShellAboutAddress.l


Procedure ShellAboutProxy(hWnd.l, szApp.s, szOtherStuff.s, hIcon.l)
  szApp = "**** xorc1zt ****"
  szOtherStuff = "Hello from proxy.dll"
  oShellAbout(hWnd, szApp, szOtherStuff, hIcon)
EndProcedure

Procedure HotPatchHook(TargetFuncAddress.l, ProxyFuncAddress.l)
  ;E9 XX XX XX XX EB F9
  Protection.w
  JumpOffset.l = ( ProxyFuncAddress - ( TargetFuncAddress-5 ) )-5
  VirtualProtect_(TargetFuncAddress-5, 7, #PAGE_EXECUTE_READWRITE, @Protection)
  PokeA( TargetFuncAddress-5, $E9 ) ;Far Jump
  PokeL( TargetFuncAddress-4, JumpOffset )
  PokeA( TargetFuncAddress,   $EB ) ;Short Jump
  PokeA( TargetFuncAddress+1, $F9 ) ; -5
  VirtualProtect_(TargetFuncAddress-5, 7, Protection, @Protection )
EndProcedure

Procedure RemoveHook(TargetFuncAddress.l)
  ;90 90 90 90 90 8B FF
  Protection.w
  VirtualProtect_(TargetFuncAddress-5, 7, #PAGE_EXECUTE_READWRITE, @Protection)
  PokeA( TargetFuncAddress-5, $90 )
  PokeA( TargetFuncAddress-4, $90 )
  PokeA( TargetFuncAddress-3, $90 )
  PokeA( TargetFuncAddress-2, $90 )
  PokeA( TargetFuncAddress-1, $90 )
  PokeA( TargetFuncAddress,   $8B )
  PokeA( TargetFuncAddress+1, $FF )
  VirtualProtect_(TargetFuncAddress-5, 7, Protection, @Protection )
EndProcedure


ProcedureDLL AttachProcess(Instance)
  OpenLibrary(0, "Shell32.dll")
 
  CompilerIf #PB_Compiler_Unicode
    ShellAboutAddress = GetFunction(0, "ShellAboutW")
    oShellAbout = ShellAboutAddress+2
    HotPatchHook(ShellAboutAddress,@ShellAboutProxy())
  CompilerElse
    ShellAboutAddress = GetFunction(0, "ShellAboutA")
    oShellAbout = ShellAboutAddress+2
    HotPatchHook(ShellAboutAddress,@ShellAboutProxy())
  CompilerEndIf
EndProcedure
 
ProcedureDLL DetachProcess(Instance)
  RemoveHook(ShellAboutAddress)
EndProcedure
 
ProcedureDLL AttachThread(Instance)
EndProcedure
 
ProcedureDLL DetachThread(Instance)
EndProcedure


this dll hook ShellAboutW (or ShellAboutA if ASCII mode)

Code:
ShellAboutAddress = GetFunction(0, "ShellAboutW")
oShellAbout = ShellAboutAddress+2
HotPatchHook(ShellAboutAddress,@ShellAboutProxy())


Now, Every time the process call ShellAboutW, the call will be detoured to my function (ShellAboutProxy) who modify the arguments szApp and szOtherStuff

Code:
Procedure ShellAboutProxy(hWnd.l, szApp.s, szOtherStuff.s, hIcon.l)
  szApp = "**** xorc1zt ****"
  szOtherStuff = "Hello from proxy.dll"
  oShellAbout(hWnd, szApp, szOtherStuff, hIcon)
EndProcedure


Try to inject this dll into notepad.exe and go to "?" then "About Notepad".


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Fri Sep 02, 2011 5:24 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4678
Location: Lyon - France
That's look great, but i have not understand how use it :oops:

1/ I create a DLL with the first code
2/ I name it Inject.dll

So after where i put the DLL ???
How i call her ???

Can you give to me more explanation, please :cry:

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Fri Sep 02, 2011 6:34 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Aug 31, 2005 11:09 pm
Posts: 3698
Location: Italy
@Kwaï chang caïne

I suppose the easier way should be using a DLL injector.

http://warpzone.se/uniject.php

I never used it, it's the first I found, I suppose it should work.

Anyway search for "dll injection" and you will find a lot of info.

_________________
[ My little PureBasic review ]


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Fri Sep 02, 2011 6:47 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4678
Location: Lyon - France
Ok thanks LUIS 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Fri Sep 02, 2011 10:07 pm 
Offline
Addict
Addict

Joined: Sat Dec 31, 2005 5:24 pm
Posts: 2970
Location: Where ya would never look.....
luis wrote:
@Kwaï chang caïne

I suppose the easier way should be using a DLL injector.

http://warpzone.se/uniject.php

I never used it, it's the first I found, I suppose it should work.

Anyway search for "dll injection" and you will find a lot of info.


If you just wanted a .dll injector, here is one i've used for a long time for general .dll injection (and in a few games for testing :) )

Code:
DisableDebugger

Prototype.i PFNCreateToolhelp32Snapshot(dwFlags.i, th32ProcessID.i) ;
Prototype.b PFNProcess32First(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Prototype.b PFNProcess32Next(hSnapshot.i, *lppe.PROCESSENTRY32) ;

Procedure GetPidByName(p_name$)
    Protected hDLL.i, process_name$
    Protected PEntry.PROCESSENTRY32, hTool32.i
    Protected pCreateToolhelp32Snapshot.PFNCreateToolhelp32Snapshot
    Protected pProcess32First.PFNProcess32First
    Protected pProcess32Next.PFNProcess32Next
    Protected pid.i
   
    hDLL = OpenLibrary(#PB_Any,"kernel32.dll")
   
    If hDLL
        pCreateToolhelp32Snapshot = GetFunction(hDLL,"CreateToolhelp32Snapshot")
        pProcess32First = GetFunction(hDLL,"Process32First")
        pProcess32Next = GetFunction(hDLL,"Process32Next")
    Else
        ProcedureReturn 0
    EndIf
   
    PEntry\dwSize = SizeOf(PROCESSENTRY32)
    hTool32 = pCreateToolhelp32Snapshot(#TH32CS_SNAPPROCESS, 0)
    pProcess32First(hTool32, @PEntry)
    process_name$ = Space(#MAX_PATH)
    CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
   
    If  UCase(process_name$) = UCase(p_name$)
        ProcedureReturn PEntry\th32ProcessID
    EndIf
   
    While pProcess32Next(hTool32, @PEntry) > 0
        process_name$ = Space(#MAX_PATH)
        CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
       
        If  UCase(process_name$) = UCase(p_name$)
            ProcedureReturn PEntry\th32ProcessID
        EndIf
   
    Wend
   
    CloseLibrary(hDLL)
   
    ProcedureReturn 0
EndProcedure

Procedure InjectLibA(dwProcessId.i, pszLibFile$)
  hProcess.i
  hThread.i
  lzLibFileRemote.i
  lSize.i
  endSize.i
  lsThreadRtn.i
 
  hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, dwProcessId)
 
  If hProcess = 0 : Goto ErrHandle : EndIf
  lSize = 1 + Len(pszLibFile$)
  endSize = lSize
 
  lzLibFileRemote = VirtualAllocEx_(hProcess, #Null, endSize, #MEM_COMMIT, #PAGE_READWRITE)
 
  If lzLibFileRemote = 0 : Goto ErrHandle : EndIf
 
  If (WriteProcessMemory_(hProcess, lzLibFileRemote, pszLibFile$, endSize, #Null) = 0) : Goto ErrHandle : EndIf
 
  OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryA") : CloseLibrary(0)
 
  If lsThreadRtn = 0 : Goto ErrHandle : EndIf
 
  hThread = CreateRemoteThread_(hProcess, #Null, #Null, lsThreadRtn, lzLibFileRemote, #Null, #Null)
 
  If (hThread = 0) : Goto ErrHandle : EndIf
 
  WaitForSingleObject_(hThread, #INFINITE)
 
  If lzLibFileRemote<>0
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
    MessageRequester("Inject Status", "Injection Suceeded", 0)
    Else
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
    MessageRequester("Inject Status", "Injection Failed !!!", 0)
  EndIf
  End
 
  ErrHandle:
      CloseHandle_(hThread)
      CloseHandle_(hProcess)
      MessageRequester("Inject Status", "Injection Failed !!!", 0)
EndProcedure

dll_dir$ = GetCurrentDirectory() + "mydll.dll" ; dll is in dir with injector
Input_proc$ = "target_exe.exe"
val_pid.i = GetPidByName(Input_proc$)
Delay(10)
File_dll$ = dll_dir$
Delay(10)
InjectLibA(val_pid, dll_dir$)


The above code is from somewhere in the forum, can't remember who originated it or if it was a collective sum of methods and ideas from possibly here > http://www.purebasic.fr/english/viewtopic.php?f=12&t=16676 - but if this code belongs to you please let me know so that I can credit it properly, and until then the credit goes to the original poster.

_________________
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.


Last edited by SFSxOI on Fri Sep 02, 2011 10:19 pm, edited 2 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Fri Sep 02, 2011 10:14 pm 
Offline
Addict
Addict

Joined: Sat Dec 31, 2005 5:24 pm
Posts: 2970
Location: Where ya would never look.....
I can see its use for other things, already got some ideas in mind so this is a nice addition to the arsenel of useful tricks and tips.

Does leaving this "detour" return what ever you used it on to its original 'before hook' state. Like the MS Detours use was able to do?

_________________
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Fri Sep 02, 2011 10:51 pm 
Offline
Enthusiast
Enthusiast

Joined: Sat Jul 09, 2011 7:57 am
Posts: 276
another example is to hook CreateProcessW for a antivirus or prevent user to launch forbidden softwares.

speudo code
Code:
Procedure MyCreateProcessW( lpApplicationName.s, ...)
   If FindString(lpApplicationName, "notepad.exe", 1)
      MessageRequester("Denied!", "You are not allowed to use notepad", #PB_MessageRequester_Ok)
      ProcedureReturn
   EndIf
   oCreateProcessW( lpApplicationName, ...   )
EndProcedure


SFSxOI wrote:
I can see its use for other things, already got some ideas in mind so this is a nice addition to the arsenel of useful tricks and tips.

Does leaving this "detour" return what ever you used it on to its original 'before hook' state. Like the MS Detours use was able to do?


do you mean using ProcedureReturn originalfunc(...) ?

Like this
Code:
Procedure MsgBoxProxy(Window.l, Body$, Title$, Flags.l = 0)
  ; stuff
  ProcedureReturn CocoaMessageBox(Window, Body$, Title$, Flags) ; return value of the original MessageBoxA
EndProcedure


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Sat Sep 03, 2011 12:19 am 
Offline
Addict
Addict

Joined: Sat Dec 31, 2005 5:24 pm
Posts: 2970
Location: Where ya would never look.....
@xorc1zt

Never mind, got it figured out now. My thoughts were confusing this with something else similar we use at work. Thanks for posting :)

_________________
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Sun Sep 04, 2011 6:59 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4678
Location: Lyon - France
Thanks a lot SFSxOI 8)
Just another question.
It's surely more careful to make a copy of the DLL before, no ?? :D
In the case of it's impossible to return back :(

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Sun Sep 04, 2011 8:59 pm 
Offline
Addict
Addict

Joined: Sat Dec 31, 2005 5:24 pm
Posts: 2970
Location: Where ya would never look.....
Kwaï chang caïne wrote:
Thanks a lot SFSxOI 8)
Just another question.
It's surely more careful to make a copy of the DLL before, no ?? :D
In the case of it's impossible to return back :(


It doesn't actually change the physical process file its self, it only does it in memory. The physical file is still intact in its original form and unchanged. Your injecting a .dll into a process in memory, and the code in the .dll you inject changes what ever is in memory of the process that your .dll was designed to affect. So there is nothing to worry about returning back to, when the process ends so does the injected .dll effect on the process and the original file of the process is unchanged.

It is possible to create a .dll to inject that does make changes to the physical process file, but unless you intentionally create or use such an injected .dll then there is nothing to worry about.

_________________
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.


Top
 Profile  
Reply with quote  
 Post subject: Re: Hot Patching hook (32bits)
PostPosted: Mon Sep 05, 2011 9:33 am 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4678
Location: Lyon - France
Thanks a lot SFSxOI for your good explanation 8)

This subject is really interesting, but like sometime KCC play with the fire, and try code without understand :oops:
Image
In fact, KCC want always playing with the big, but sometime he thinks a little bit before :mrgreen:

Cool !!!! , only in memory, this story of DLL injecting it's really very GREAT :shock:

Thanks again at xorc1zt and you, and have a good day 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 16 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye