Jump to content

API Hooking in AutoIt


monoceres
 Share

Recommended Posts

arf i don't express well sry, i know you just intercepts the call of the process to a dll.

What i want to do is to intercept explorer.exe calls to the shell32.dll, of the function SHFileOperationW.

I think i need an external hook dll made in C++, like for VB6.

-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
Link to comment
Share on other sites

  • Replies 60
  • Created
  • Last Reply

Top Posters In This Topic

arf i don't express well sry, i know you just intercepts the call of the process to a dll.

What i want to do is to intercept explorer.exe calls to the shell32.dll, of the function SHFileOperationW.

I think i need an external hook dll made in C++, like for VB6.

Yeah, that's what you need. Shouldn't be too hard with some C++ knowledge.

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

Is it possible to hook API as it is called by other programs?

Yes. But not in AutoIt. As I've said before, to hook something not in our process we need to inject the hook into the process we wanna hook, or replace the original dll which contains the functions we wanna hook with our own. Simply put, there are no clean way to achieve anything like this without a dll (and by no clean way I mean "I'm sure someone with too much time could write some buggy dirty hack that allows you to be notifyed of an api call").

Unfortunetly this is simply out or Autoits range, but it's really not a big problem since this is not AutoIt was designed for anyway.

Maybe in the future I or someone else will write a dl that can be injected and will provide an easy interface for you to communicate it. Until then your only alternative is to: a) Learn how to write it yourself, or :) wait until someone else do it.

I added a faq.

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

i'm studying a hook dll that purposes was for vb6, but i've to adapt it for autoit. I think it's possible but i've to work really hard on it, and as you said, i've not too much time ( unfortunately ).

-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
Link to comment
Share on other sites

i'm studying a hook dll that purposes was for vb6, but i've to adapt it for autoit. I think it's possible but i've to work really hard on it, and as you said, i've not too much time ( unfortunately ).

The too much time note was for those who attempt to do api hooking in other processes in native autoit code (no dll).

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

I have an example that shows how to call original GetProcAddress in the hook. So you aren't forced to restore the hook before a DLLCall with a funtion name and not a pointer: (You just have to provide the poiner to CallWindowProcA :)

$GetProcAddress=DllCallbackRegister("GetProcAddress","ptr","ptr;str")
$GetProcAddressPtr=DllCallbackGetPtr($GetProcAddress)


Global Const $_NEEDED_CallWindowProcA = _GetProcAddress(_WinAPI_GetModuleHandle("User32.dll"), "CallWindowProcA")

; We save this so we can restore it later
Global Const $ORIGINALGETPROCADDRESS = _GetProcAddress(_WinAPI_GetModuleHandle("Kernel32.dll"), "GetProcAddress")

; Get the pointer to LockWorkStation
$LockWorkStation=_GetProcAddress(_WinAPI_GetModuleHandle("user32.dll"),"LockWorkStation")

; Hook GetProcAddress
$hook = _AddHookApi("Kernel32.dll", "GetProcAddress", $GetProcAddressPtr)
; Use DllCall as usual, but use a pointer instead and remember String() so that the pointer doesn't get fucked up
MsgBox(0x40000, 'Hooked GetProcAddress', "Call with Pointer")
DllCall("kernel32.dll","int",String($LockWorkStation))
MsgBox(0x40000, 'Hooked GetProcAddress', "Call with String")
DllCall("user32.dll","int","LockWorkStation")

; Restore to normal mode
_ChangeHookApi($hook,$originalgetprocaddress)


Func GetProcAddress($ptr,$str)
;~     $string = DllStructCreate("char[255]", $str)
    
   ;; When we call _ChangeHookApi AutoIt requests these functions addresses,
   ;;    we need to provide them or we won't be able to change back
    
    If $str="CallWindowProcA" Then
        Return $_NEEDED_CallWindowProcA
    ElseIf Ptr($str) = 0 Then
        ConsoleWrite($str & @CRLF)
        Return _GetProcAddrCallByPtr($ORIGINALGETPROCADDRESS,$ptr,$str)
    Else
        Return Ptr($str)
    EndIf
    Return 0
EndFunc

; used code from http://www.activevb.de/tipps/vb6tipps/tipp0692.html
; by Prog@ndy
Func _GetProcAddrCallByPtr($PTR_GetProcAddr,$Hwnd,$Name)
    If $PTR_GetProcAddr = 0 Then Return SetError(-1,0,0)
    If $Hwnd = 0 Then Return SetError(-2,0,0)
    If $Name = "" Then Return SetError(-3,0,0)
    Local $Args = DllStructCreate("ptr;ptr"),$StringBuff=DllStructCreate("char[" & StringLen($Name)+1 & "]")
    DllStructSetData($Args,2,$Hwnd)
    DllStructSetData($Args,1,DllStructGetPtr($StringBuff))
    DllStructSetData($StringBuff,1,$Name)
    Local $asm = DllStructCreate("dword;dword;dword;dword;dword;dword;dword"); As Long
    Local $UBnd=2
        DllStructSetData($asm,1 , 0x8BEC8B55)
        DllStructSetData($asm,2 , 0x5D8B0C4D)
        DllStructSetData($asm,3 , 0x744B4310)
        DllStructSetData($asm,4 , 0x50018B08)
        DllStructSetData($asm,5 , 0xEB04C183)
        DllStructSetData($asm,6 , 0x855FFF5)
        DllStructSetData($asm,7 , 0x10C2C9)
    Local $ret = DllCall("user32.dll","ptr","CallWindowProcA","ptr",DllStructGetPtr($asm),"ptr",$PTR_GetProcAddr,"ptr",DllStructGetPtr($Args),"uint",$UBnd,"ptr",0)
    Return $ret[0]
EndFunc

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I would not call API hooking a missing feature.

I meant DllCall which supports function pointers as well as a function name. My first solution required code to be called before and after each call (since we don't wanna have a crippled dllcall), but with this new code we can simply have a function called "_PatchDllCall()" which we call at script startup and tada, dllcall has got a new feature.

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

I've never understood this, though. Why do you need to call a function by address?

You need it to call methods in some types of COM objects (I think objects who lack IDispatch interface,not sure though since COM objects really aren't my thing).

Like Direct3D for example: http://www.autoitscript.com/forum/index.ph...c=84532&hl=

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

I know about calling COM objects that don't have IDispatch. I did it years ago in a different way.

Direct3D? Yeah, because AutoIt is a suitable language for writing 3D applications. Other uses? Very very few. There's a reason it doesn't exist natively.

Link to comment
Share on other sites

I know about calling COM objects that don't have IDispatch. I did it years ago in a different way.

Mind sharing? :)

Direct3D? Yeah, because AutoIt is a suitable language for writing 3D applications. Other uses? Very very few. There's a reason it doesn't exist natively.

It's certainly not. I would rather chop off my hand than write a full 3d game in autoit and native Direct3D. However it's still a fun challenge, and for those who don't program in other languages it's a simple way to learn and understand how 3d programming works.

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

monoceres

Nice job!

Q: Is it possible that hook function in Game Process's .DLL?

[2008-12-04(Thu) 22:19:29.078] -161> SRC_LINE[05572] ycmMemGetModuleAddr( "Engine.dll" ) got BASE 0x00000000 , OFF. +00000000 , ADDR 0x00000000 , IsWaitingForServer

Edited by GoodMan
Link to comment
Share on other sites

monoceres

Nice job!

Q: Is it possible that hook function in Game Process's .DLL?

Thanks.

Since we cannot create dll's in AutoIt we can only hook stuff that is loaded in our address space, if you want to hook stuff in games and such you need to use a language that supports compilation of dll's (like C++). Just google "Api hooking" or check out the link to CodeProject in my first post.

Good luck.

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

Thanks.

Since we cannot create dll's in AutoIt we can only hook stuff that is loaded in our address space, if you want to hook stuff in games and such you need to use a language that supports compilation of dll's (like C++). Just google "Api hooking" or check out the link to CodeProject in my first post.

Good luck.

I like your beautiful works. :)

Thank your reply.

;===================================================================================================

=================

Func ycmMemGetModuleAddr( $sModName , $sFuncName )

;2008-11-26(Wed) 양창민 - Original source by monoceres at http://www.autoitscript.com/forum/index.ph...st&p=608951

Local $tText = DllStructCreate( "char Text[4096]" )

If @Error Then

SetError( 1 )

Return 0

EndIf

Local $aResult[2] = [ -1 , -1 ]

ycmMemGetPtr( $_DLL_PTR_Kernel32 , "Kernel32.dll" , @ScriptLineNumber )

If StringLen( $sModName ) >= 1 Then

DllStructSetData( $tText , "Text" , $sModName )

$aResult = DllCall( $_DLL_PTR_Kernel32 , "hwnd" , "GetModuleHandle" , "ptr" , DllStructGetPtr( $tText ) )

Else

$aResult = DllCall( $_DLL_PTR_Kernel32 , "hwnd" , "GetModuleHandle" , "ptr" , 0 )

EndIf

$tText = 0

Local $procAddr = DllCall( $_DLL_PTR_Kernel32 , "long" , "GetProcAddress" , "long" , $aResult[0] , "str" , $sFuncName )

ycmSetTextMain( ycmFixLine( @ScriptLineNumber ) & "ycmMemGetModuleAddr( " & ycmFixStrL( Chr( 34 ) & $sModName & Chr( 34 ) , 14 ) & " ) got BASE 0x" & Hex( $procAddr[1] , 8 ) & " , OFF. +" & Hex( ( $procAddr[0] - $procAddr[1] ) , 8 ) & " , ADDR 0x" & Hex( $procAddr[0] , 8 ) & " , " & $sFuncName )

;Local $strSet = DllStructCreate( "char[255]" , $sFuncName )

;Local $strGet = DllStructGetData( $strSet , 1 )

;$strSet = 0

Return $procAddr[0]

EndFunc

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...