CakeOfChaos Posted January 7, 2012 Share Posted January 7, 2012 (edited) Hello, I like you to show a possibility to hook external functions in other processes. It's EXTREMELY buggy, but it works. I think it'll take a lot of time to find all the bugs, but some guys wanted to help me because I won't have much time soon. You have to modify the NomadMemory.au3 because it does not work in conjunction with the WinAPI.au3. There are 2 constants which get redeclared when including both scripts. You have to comment them out. Ok, I think the most of you think: How does it work? I will shortly try to explain it: AutoitFunction->DllCallbackRegister->DllCallbackgetPtr() With these functions you are able to load the address of your function. But how does we load it into the other process? The answer is quite simple: We do not load it. We are calling the function with CreateRemoteThread from the other Process First we have to call OpenProcess by Injecting Assembler Code into the process. Then we call this code and save the handle. After that we create a CodeCave. This is done by allocating space in the RAM and write there our code. Following we write in the beginning of the target a jump to our code. The injected code will look like this: PUSH 0 PUSH 0 PUSH ESP PUSH 620000 PUSH 0 PUSH 0 PUSH DWORD PTR DS:[3E0000] CALL kernel32.CreateRemoteThread PUSH EAX PUSH -1 PUSH EAX CALL kernel32.WaitForSingleObject CALL kernel32.CloseHandle MOV EDI,EDI PUSH EBP MOV EBP,ESP JMP USER32.75CAFEB3 You can (hopefully) see, that we are creating a Thread and waiting INFINITE until it ends. Then we are executing the overwritten Code and jump back to our functions. the parameter for the Thread is the ESP-Register. With this we can load and modify the parameters on the stack. Unfortunately Autoit often crashes when executing the thread or hanging around without doing something. Thats the secret of Hooking with Autoit in the include-file are also some functions for modifying strings in the RAM. Ok, here is the first Example for Hooking the MessageboxA-Function: #include "Hooking.au3" ;===================>Global Variables Global $hHook, $hProc Global $pString[2] = [0, 0] ;the first element holds the address and the second the length, so its easier to call the _DelString() Function Global $sProcessName = "HookingTest.exe" ;our target process ;===========> SetPrivilege("SeDebugPrivilege", 1) ;too trivial $lpMsgBoxA = _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("user32.dll"), "MessageBoxA") ;we are reading the address of MessageBoxA in the RAM $callback = DllCallbackRegister("myHookFunc", "none", "dword") ;we are registering the callback function If @error Then MsgBox(16, "ERROR", "Couldn't initialize Callback") Exit EndIf $ptr = DllCallbackGetPtr($callback) _VirtualProtect(Number($ptr), 94) ;we have to unprotect the Callbackfunction $hProc = _OpenProcess($sProcessName) ;we have to open the process $hHook = _SetHook(number($lpMsgBoxA), 5, Number($ptr), "int;int;int;int", $hProc) ;we are going to hook the MessageBoxA-Function Do Sleep(1000) until NOT ProcessExists($sProcessName) ;waiting Func myHookFunc($iParam) ;=>our HookFunction If $pString[0] <> 0 Then _DelString($pString[0], $pString[1], $hProc) ;free the old string _GetParameter($iParam, $hHook, $hProc) ;get the parameter from the stack $sText = _ReadString(DllStructgetdata($hHook[5], 3), $hProc) ;read the content of the messagebox $sText = "OWNED BY AUTOIT ;)" & @crlf & "originalText: " & $sText ;modify it $pString = _CreateNewString($sText, $hProc) ;create space for it and write it in the other process DllStructSetData($hHook[5], 3, $pString[0]) ;set new string as parameter _SetParameter($iParam, $hHook, $hProc) ;and write it ;) return ;works much better with return EndFunc When executing this function we load the parameters and create a new string. After this we replace the old string. I used this program for testing it (C++, minGW and Code::Blocks): #include <windows.h> int main() { while (1) { system("pause"); MessageBoxA(NULL, "the text", "the title", NULL); } return 0; } The Include-File is in the attachement. I wish you much fun when debugging these programs It's extremely buggy but this example should work properly (I am using Windows 7 Ultimate 64-Bit). PS: There are a lot of number-calls. I've used them because sometimes Autoit did not convert variables properly. mfg CakeOfChaos (alias @night@)Hooking.au3 Edited January 7, 2012 by CakeOfChaos Link to comment Share on other sites More sharing options...
wraithdu Posted January 7, 2012 Share Posted January 7, 2012 Code injection and hooking has been discussed a lot before, so what you're doing is not exactly new. Although no one has quite gone this route by have the remote process create a thread within AutoIt. As you've seen, AutoIt is not thread friendly. Why not use some other communication solution such as messages or named pipes (or event CreateProcess to invoke another instance of the AutoIt script) to have the remote process feed AutoIt the data you are looking for, and then AutoIt can properly execute functions without trying to multithread. Link to comment Share on other sites More sharing options...
CakeOfChaos Posted January 7, 2012 Author Share Posted January 7, 2012 Code injection and hooking has been discussed a lot before, so what you're doing is not exactly new.I'm sorry. I did not find anything with google.Although no one has quite gone this route by have the remote process create a thread within AutoIt. As you've seen, AutoIt is not thread friendly. Why not use some other communication solution such as messages or named pipes (or event CreateProcess to invoke another instance of the AutoIt script) to have the remote process feed AutoIt the data you are looking for, and then AutoIt can properly execute functions without trying to multithread.In the beginning I wanted to write a Dll which communicates with Winsocks. But I thought this would be too slow. But if I use C++ it wouldn't be only Autoit Well, I keep experimenting with Hooks... Link to comment Share on other sites More sharing options...
wraithdu Posted January 7, 2012 Share Posted January 7, 2012 Nothing to apologize for, google doesn't find everything. As I said, you're taking a different approach anyway.Here's a few links, one for my UDF and a project based on it. They are geared towards injecting compiled DLL code. But that code could be used to communicate back to a running AutoIt to conform to your framework. Link to comment Share on other sites More sharing options...
KaFu Posted January 7, 2012 Share Posted January 7, 2012 Maybe also take a look at Ascend4nt's excellent Process + Thread + DLL Functions UDFs. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
CakeOfChaos Posted January 8, 2012 Author Share Posted January 8, 2012 (edited) Thank you for the informations. I think this will help me a lot finding a better way to hook external functions. First I have to find a method without crashing Autoit too often and after that I must increase the speed of the hook... Hopefully you'll hear something new of me in the next monthes mfg Edited January 8, 2012 by CakeOfChaos Link to comment Share on other sites More sharing options...
hamburger Posted January 27, 2012 Share Posted January 27, 2012 Mh was trying it with WinSocks but it fails all params seems to be 0 :S expandcollapse popup#RequireAdmin #include "Hooking.au3" ;===================>Global Variables Global $hSendHook,$hRecvHook, $hProc Global $pString[2] = [0, 0] ;the first element holds the address and the second the length, so its easier to call the _DelString() Function Global $sProcessName = "test.exe" ;our target process ;===========> #cs int recv( __in SOCKET s, __out char *buf, __in int len, __in int flags ); int send( __in SOCKET s, __in const char *buf, __in int len, __in int flags ); #ce SetPrivilege("SeDebugPrivilege", 1) ;too trivial $recv = _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("WS2_32.dll"), "recv") ;we are reading the address of recv in the RAM $send = _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("WS2_32.dll"), "send") ;we are reading the address of send in the RAM ;MsgBox("","",$lpMsgBoxA) $recvcallback = DllCallbackRegister("_Recv", "int", "dword") ;we are registering the callback function $sendcallback = DllCallbackRegister("_Send", "int", "dword") ;we are registering the callback function If @error Then MsgBox(16, "ERROR", "Couldn't initialize Callback") Exit EndIf $recvptr = DllCallbackGetPtr($recvcallback) $sendptr = DllCallbackGetPtr($sendcallback) _VirtualProtect(Number($recvptr), 94) ;we have to unprotect the Callbackfunction _VirtualProtect(Number($sendptr), 94) ;we have to unprotect the Callbackfunction $hProc = _OpenProcess($sProcessName) ;we have to open the process $hRecvHook = _SetHook(number($recv), 5, Number($recvptr ), "int;str;int;int", $hProc) ;we are going to hook the recv-Function $hSendHook = _SetHook(number($send), 5, Number($sendptr), "int;str;int;int", $hProc) ;we are going to hook the send-Function Do Sleep(1000) until NOT ProcessExists($sProcessName) ;waiting Func _Send($iParam) ;MsgBox("","","1: "&Hex($iParam)) _GetParameter($iParam, $hSendHook, $hProc) MsgBox("","","Data: "&DllStructgetdata($hSendHook[5], 1)) Return 0 EndFunc Func _Recv($iParam) ;MsgBox("","","1: "&Hex($iParam)) _GetParameter($iParam, $hRecvHook, $hProc) ;MsgBox("","","Data: "&DllStructgetdata($hRecvHook[5], 1)) Return 0 EndFunc Link to comment Share on other sites More sharing options...
CakeOfChaos Posted January 28, 2012 Author Share Posted January 28, 2012 The first Parameter is possibly the return address. I am not sure, but after Debugging I think so. This is a working example: #include "Hooking.au3" ;===================>Global Variables Global $hHook, $hProc Global $pString[2] = [0, 0] ;the first element holds the address and the second the length, so its easier to call the _DelString() Function Global $sProcessName = "exploit_test.exe" ;our target process ;===========> SetPrivilege("SeDebugPrivilege", 1) ;too trivial $lpMsgBoxA = _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("Ws2_32.dll"), "send") ;we are reading the address of MessageBoxA in the RAM $callback = DllCallbackRegister("myHookFunc", "none", "dword") ;we are registering the callback function If @error Then MsgBox(16, "ERROR", "Couldn't initialize Callback") Exit EndIf $ptr = DllCallbackGetPtr($callback) _VirtualProtect(Number($ptr), 94) ;we have to unprotect the Callbackfunction $hProc = _OpenProcess($sProcessName) ;we have to open the process $hHook = _SetHook(number($lpMsgBoxA), 5, Number($ptr), "int;int;int;int", $hProc) ;we are going to hook the MessageBoxA-Function Do Sleep(1000) until NOT ProcessExists($sProcessName) ;waiting Func myHookFunc($iParam) ;=>our HookFunction If $pString[0] <> 0 Then _DelString($pString[0], $pString[1], $hProc) ;free the old string _GetParameter($iParam, $hHook, $hProc) ;get the parameter from the stack ConsoleWrite("================NEW PAKET WILL BE SENDED==========" & @crlf) For $i = 2 To 5 ConsoleWrite($i & ". Argument is " & Number(DllStructgetdata($hHook[5], $i)) & @crlf) next ;==============>String auslesen $myString = _ReadString(DllStructgetdata($hHook[5], 3), $hproc) Consolewrite("Gesendet wird: " & $myString &@crlf) ;===================> _SetParameter($iParam, $hHook, $hProc) ;and write it ;) return ;works much better with return EndFunc Link to comment Share on other sites More sharing options...
DAYANS Posted November 20, 2012 Share Posted November 20, 2012 The first Parameter is possibly the return address. I am not sure, but after Debugging I think so. This is a working example: #include "Hooking.au3" ;===================>Global Variables Global $hHook, $hProc Global $pString[2] = [0, 0] ;the first element holds the address and the second the length, so its easier to call the _DelString() Function Global $sProcessName = "exploit_test.exe" ;our target process ;===========> SetPrivilege("SeDebugPrivilege", 1) ;too trivial $lpMsgBoxA = _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("Ws2_32.dll"), "send") ;we are reading the address of MessageBoxA in the RAM $callback = DllCallbackRegister("myHookFunc", "none", "dword") ;we are registering the callback function If @error Then MsgBox(16, "ERROR", "Couldn't initialize Callback") Exit EndIf $ptr = DllCallbackGetPtr($callback) _VirtualProtect(Number($ptr), 94) ;we have to unprotect the Callbackfunction $hProc = _OpenProcess($sProcessName) ;we have to open the process $hHook = _SetHook(number($lpMsgBoxA), 5, Number($ptr), "int;int;int;int", $hProc) ;we are going to hook the MessageBoxA-Function Do Sleep(1000) until NOT ProcessExists($sProcessName) ;waiting Func myHookFunc($iParam) ;=>our HookFunction If $pString[0] <> 0 Then _DelString($pString[0], $pString[1], $hProc) ;free the old string _GetParameter($iParam, $hHook, $hProc) ;get the parameter from the stack ConsoleWrite("================NEW PAKET WILL BE SENDED==========" & @crlf) For $i = 2 To 5 ConsoleWrite($i & ". Argument is " & Number(DllStructgetdata($hHook[5], $i)) & @crlf) next ;==============>String auslesen $myString = _ReadString(DllStructgetdata($hHook[5], 3), $hproc) Consolewrite("Gesendet wird: " & $myString &@crlf) ;===================> _SetParameter($iParam, $hHook, $hProc) ;and write it ;) return ;works much better with return EndFunc Guys, I can intercept the send and recv, but how can I change them ("send" and "recv" packets) using as base this code. I know it is hard, but this takes a lot of code. Grtz!! Link to comment Share on other sites More sharing options...
DAYANS Posted November 20, 2012 Share Posted November 20, 2012 (edited) Edited post Wrong code, I'll post later. Cya! Edited November 21, 2012 by DAYANS Link to comment Share on other sites More sharing options...
danilomalzao Posted April 24, 2013 Share Posted April 24, 2013 (edited) great job! This udf worked perfectly. I do like to know if i can use this callback to do something in the autoit script, like update something. Edited April 25, 2013 by danilomalzao Link to comment Share on other sites More sharing options...
MadaraUchiha Posted December 14, 2013 Share Posted December 14, 2013 Hey, I am really interessted in this... But I don't understand what to modify in the NomadMemory.au3 ? If I compile the code above, I get an error: C:Program Files (x86)AutoIt3IncludeNomadMemory.au3 (231) : ==> Can not redeclare a constant.: Just as you said? But how should I fix that? ;O Link to comment Share on other sites More sharing options...
JohnOne Posted December 15, 2013 Share Posted December 15, 2013 There are 2 constants which get redeclared when including both scripts. You have to comment them out. I'm not sure this can be more clear. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
MadaraUchiha Posted December 15, 2013 Share Posted December 15, 2013 I'm not sure this can be more clear. I did that, but i get the error that the variables are now not declared: Link to comment Share on other sites More sharing options...
guinness Posted December 15, 2013 Share Posted December 15, 2013 Is it me or have you never understood the term "declare a variable"? UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
MadaraUchiha Posted December 15, 2013 Share Posted December 15, 2013 Is it me or have you never understood the term "declare a variable"? No, excuse me, but where should I just declare them in the NomadMemory or in the Hooking.au3? And should it be local or global? Link to comment Share on other sites More sharing options...
Developers Jos Posted December 15, 2013 Developers Share Posted December 15, 2013 (edited) No, excuse me, but where should I just declare them in the NomadMemory or in the Hooking.au3? And should it be local or global?The point is that you have no clue what you are doing and are trying to complete a marathon without having first learned to walk. So, please start learning some basics before asking al these questions. This question should be easy to answer by yourself after having spend a little time trying you understand what the script does. Jos Edited December 15, 2013 by Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
dromenox Posted September 7, 2014 Share Posted September 7, 2014 Someone solved the problem of closing? Biatu 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now