Jump to content

API Hooking in AutoIt


monoceres
 Share

Recommended Posts

Well I've been into the PE format again, and this time I made a function that modifies the Import Address Table (IAT), I won't go exactly into what it is (since there are tons about it on the Internet), but simply it's a table of all the function addresses that windows looks up when it calls functions in DLL files (loaded in your address space that is). What my function does is changing the address of a specified function into a function of your own.

So what's the use of this? Well here's some things I have come up with while working on it:

Source with sample code:

apihook.au3

(Previous downloads: 140)

If anyone want a working C++ function that can be used in a dll (so the code can be injected) just send me a pm and I'll send it to you (not building a dll for you though).

FAQ

Q: How do I hook what other processes do?

A: It's not possible in AutoIt. it's possible in a language like C++ though. Here's a quick guide what to do:

  • Learn C++
  • Learn C++ properly
  • Write a dll that hooks api calls & is able to be controlled through some kind of inter-process communication (tcp, mutex, pipes, COM etc.)
  • Inject the code into the process you wanna hook (this can be done with a autoit script, check the forums)
  • Control the dll through the interface you built into the dll in step 3.

Read more about API hooking:

http://www.codeproject.com/KB/system/hooksys.aspx

Edited by monoceres

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

Link to comment
Share on other sites

  • Replies 60
  • Created
  • Last Reply

Top Posters In This Topic

VERY NICE! I've been looking for this for a long time. Is there a list of things we can hook?

And can you please PM me that code?

---

Found a list for kernel32.dll:

http://www.astercity.net/~azakrze3/html/wi...i_functios.html

Edited by Firestorm

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Link to comment
Share on other sites

VERY NICE! I've been looking for this for a long time. Is there a list of things we can hook?

And can you please PM me that code?

You can hook everything that is exported by dlls (most of the windows api).

PM Sent.

Edit: Take a look at my export viewer to see what functions different dlls export.

Edited by monoceres

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

Link to comment
Share on other sites

Thank you.

Why doesn't this portion of the code work?

$MyTest = DllCallbackRegister("MyTest", "none", "dword")
$MyTestAddress = DllCallbackGetPtr($MyTest)

;; Set the hook
$oldproc=_HookApi("Shell32.dll","ShellExecute",$MyTestAddress)

ShellExecute("notepad.exe")

;; Restore the hook
$oldproc=_HookApi("Shell32.dll","ShellExecute",$oldproc)

DllCallbackFree($MyTest)


Func MyTest($var)
    MsgBox(0, "Hook", "Hook Worked...")
EndFunc ;==>MyTest
Edited by Firestorm

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Link to comment
Share on other sites

Thank you.

Why doesn't this portion of the code work?

$MyTest = DllCallbackRegister("MyTest", "none", "dword")
 $MyTestAddress = DllCallbackGetPtr($MyTest)
 
;; Set the hook
 $oldproc=_HookApi("Shell32.dll","ShellExecute",$MyTestAddress)
 
 ShellExecute("notepad.exe")
 
;; Restore the hook
 $oldproc=_HookApi("Shell32.dll","ShellExecute",$oldproc)
 
 DllCallbackFree($MyTest)
 
 
 Func MyTest($var)
     MsgBox(0, "Hook", "Hook Worked...")
 EndFunc;==>MyTest

Since when did ShellExecute take one parameter of the type dword? :)

Remember, it's not the AutoIt function you're hooking. It's the underlying windows api function:

http://msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx

So you will have to fix that DllCallbackRegister :)

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

Link to comment
Share on other sites

Oh I see. Thanks.

EDIT:

Okay. Not sure what to do from here. I'm kind of new to DLL's. I've never really had to use them before.

;~ _DebugSetup()
;~ _DebugOut("1")

$MyTest = DllCallbackRegister("MyTest", "none", "hwnd;STR;STR;STR;STR;INT")
;~ _DebugOut("2")

$MyTestAddress = DllCallbackGetPtr($MyTest)
;~ _DebugOut("3")

;; Set the hook
$oldproc = _HookApi("Shell32.dll", "ShellExecute", $MyTestAddress)
;~ _DebugOut("4")

ShellExecute("notepad.exe")
;~ _DebugOut("5")

;; Restore the hook
$oldproc = _HookApi("Shell32.dll", "ShellExecute", $oldproc)
;~ _DebugOut("6")

DllCallbackFree($MyTest)
;~ _DebugOut("7")

Func MyTest($var)
    MsgBox(0, "Hook", "Hook Worked...")
EndFunc ;==>MyTest

Does not return anything.

Edited by Firestorm

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Link to comment
Share on other sites

Here's how to hook autoit's shellexecute function:

$MyTest = DllCallbackRegister("MyTest", "int", "ptr")
$MyTestAddress = DllCallbackGetPtr($MyTest)


;; Set the hook
_AddHookApi("Shell32.dll","ShellExecuteExW",$MyTestAddress)


ShellExecute(FileOpenDialog("All files","","All files (*.*)"))


DllCallbackFree($MyTest)


Func MyTest($ptr)
    $SHELLEXECUTEINFO=DllStructCreate("dword;ulong;hwnd;ptr;ptr;ptr;ptr;int;ptr;ptr;ptr;ptr;dword;ptr;ptr;",$ptr)
    $wstring=DllStructCreate("wchar[255]",DllStructGetData($SHELLEXECUTEINFO,5))
    MsgBox(0, "Shellexecute hook", "AutoIt tried to shellexecute: "&DllStructGetData($wstring,1)&@CRLF&"However we put a stop to that, didn't we?")
    Return 0
EndFunc;==>MySleep

Edit: I just noticed that restoring the hook doesn't work. I'm working on it :)

Edited by monoceres

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

Link to comment
Share on other sites

Here's how to hook autoit's shellexecute function:

$MyTest = DllCallbackRegister("MyTest", "int", "ptr")
$MyTestAddress = DllCallbackGetPtr($MyTest)


;; Set the hook
$oldproc=_HookApi("Shell32.dll","ShellExecuteExW",$MyTestAddress)


ShellExecute(FileOpenDialog("All files","","All files (*.*)"))

;; Restore the hook
$oldproc=_HookApi("Shell32.dll","ShellExecuteExW",$oldproc)

DllCallbackFree($MyTest)


Func MyTest($ptr)
    $SHELLEXECUTEINFO=DllStructCreate("dword;ulong;hwnd;ptr;ptr;ptr;ptr;int;ptr;ptr;ptr;ptr;dword;ptr;ptr;",$ptr)
    $wstring=DllStructCreate("wchar[255]",DllStructGetData($SHELLEXECUTEINFO,5))
    MsgBox(0, "Shellexecute hook", "AutoIt tried to shellexecute: "&DllStructGetData($wstring,1)&@CRLF&"However we put a stop to that, didn't we?")
    Return 0
EndFunc;==>MySleep

Edit: I just noticed that restoring the hook doesn't work. I'm working on it :)

Thanks. That worked quite well.

I hate to hijack your thread, but how did you get "dword;ulong;hwnd;ptr;ptr;ptr;ptr;int;ptr;ptr;ptr;ptr;dword;ptr;ptr;"?

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Link to comment
Share on other sites

Thanks. That worked quite well.

I hate to hijack your thread, but how did you get "dword;ulong;hwnd;ptr;ptr;ptr;ptr;int;ptr;ptr;ptr;ptr;dword;ptr;ptr;"?

Well since I'm hooking ShellExecuteEx the only param is a ptr to a SHELLEXECUTEINFO structure, the string I used is just the list of the types in the struct. The names are unnecessary.

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

Link to comment
Share on other sites

Very cool! Can you post an example of calling a function by pointer? I ask because there's some COM things that we just get pointers to functions in an interface. ProgAndy found a way to call those functions using the MemoryDLL funcs, but there may be issues with DEP.

I'd be interested to see your solution accomplish the same thing.

Link to comment
Share on other sites

Very cool! Can you post an example of calling a function by pointer? I ask because there's some COM things that we just get pointers to functions in an interface. ProgAndy found a way to call those functions using the MemoryDLL funcs, but there may be issues with DEP.

I'd be interested to see your solution accomplish the same thing.

More simple than you might think! Since AutoIt relies on GetProcAddress for getting the pointer to the function we can simply just hook it and provide it with a pointer of our choice.

There are some things to think about though, when we want to change the hook back we need to have a working GetProcAddress for VirtualQuery & VirtualProtect, but that's easy because we save the pointer to those function in advance and pass them to autoit when it requires them.

Here's a working sample. As you can see DllCall() works as usual but it takes a pointer instead of a function name :)

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


; we must have these for later
$virtualquery=_GetProcAddress(_WinAPI_GetModuleHandle("Kernel32.dll"), "VirtualQuery")
$virtualprotect=_GetProcAddress(_WinAPI_GetModuleHandle("Kernel32.dll"), "VirtualProtect")


; We save this so we can restore it later
$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
DllCall("kernel32.dll","int",String($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 DllStructGetData($string,1)="VirtualProtect" Then
        Return $virtualprotect
    Elseif DllStructGetData($string,1)="VirtualQuery" Then
        Return $virtualquery
    Else
        Return DllStructGetData($string,1)
    EndIf
    Return 0
EndFunc

:)

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

Link to comment
Share on other sites

wow API Hook !! excellent. Can we hook a call to a dll ( i mean like supercopier that hook shell32.dll to intercepts file copies message ) ?

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

This could be used to hook the registry/file system access, where you could make a none portable application portable? amirite?

Very useful, mind sending me that c example?

If properly injected it could quite easily be done. Just hook all calls to RegWrite, CreateFile, etc and find a way to communicate with your injected code (pipes,tcp,mutex, etc).

Oh, and I'll send you a pm :)

That is so very very cool :) Excellent example.

Yeah, it's pretty cool. These function allows you to twist, extend and expose autoit like never before.

wow API Hook !! excellent. Can we hook a call to a dll ( i mean like supercopier that hook shell32.dll to intercepts file copies message ) ?

Ehm, this already hook calls to dlls (it's actually all it does o:) ), but only calls from our address space. If you want more, then C/C++ (or any other language capable of dlls) is the only way to go.

Edited by monoceres

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

Link to comment
Share on other sites

arf i've not well formed my sentence.

Ok so if i need to access external process i need a dll between autoit and the dll i want to hhok ( if i understand well )

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

arf i've not well formed my sentence.

Ok so if i need to access external process i need a dll between autoit and the dll i want to hhok ( if i understand well )

You don't hook the dll directly. You hook the process who call functions in it. Basicly what this function do is to fool the process it resides in to believe that one of your custom made functions ia in fact a windows api function (like Sleep). Remember we're not doing anything with the actual dlls! Just screwing with the process that loads them.

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

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