Jump to content

Callback - no external library (dll) required


piccaso
 Share

Recommended Posts

_DllCallBack() creates a stub in executable memory on local heap which forwards a stack pointer to AutoIt's message queue

where it gets caught by a handler function.

Sound's pretty tricky but i did my best to make it easy to use:

#include "DllCallBack.au3"

; Create Stub
$hStub_EnumWindows = _DllCallBack ("_EnumWindowsProc", _ ; Name of the function
                                   "hwnd;ptr")           ; DllStruct like parameter definition
                                                         ; Only 32 and 64bit datatypes supported

; Call EnumWindows
DllCall("user32.dll", "int", "EnumWindows", "ptr", $hStub_EnumWindows, "long", 0)

; Callback Procedure
Func _EnumWindowsProc($hWnd, $lParam)
    $hWnd = HWnd($hWnd)
    ConsoleWrite($hWnd & " -> " & WinGetTitle($hWnd) & @CRLF)
    Return 1
EndFunc   ;==>_EnumWindowsProc

; Free Stub
_DllCallBack_Free ($hStub_EnumWindows)

More examples in the archive:

  • EnumChildWindows
  • EnumWindowStations
  • SetWindowsHookEx (Mouse hook)
  • CopyFileEx - Progress indicator for copying files. (NT4+)
  • Richedit - EM_STREAMOUT & EM_STREAMIN
  • LibCurl - Runtime dll not included, get it here
  • Subclassing - Subclassing an edit box
  • SetTimer - Multiple timers without Adlib
  • An example dll - How to do callbacks from your own dll's in c and freebasic
Remarks:

Return type cannot be set, its always a 32bit integer (signed or unsigned, AutoIt converts it).

There is no stack corruption check like in DllCall so if you make a mistake in the parameter definition your application just crashes.

Only 64 functions can be registered simultaneously (this number can be increased by editing the source).

The windows message 0x7FFF (WM_USER + 0x7BFF) should not be used to avoid conflicts (can be changed too).

Since its based on GuiRegisterMsg() this warning applies here too:

Warning: blocking of running user functions which executes window messages with commands such as "Msgbox()" can lead to unexpected behaviour, the return to the system should be as fast as possible !!!

au3_callback_v6.5.zip

This udf should work on every os Autoit runs on.

Tested on Win98, WinXP, Vista and Wine 0.9.x.

(Thanks to Zedna & jfisher)

Edited by piccaso
CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

  • Replies 80
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

This is awesome, very good for copy with progress :)

My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop.
Link to comment
Share on other sites

i like this very much maybe we can now update the "create com object without the need of dlls" thread :)

i imagine a world where autoit can register events globally and recieve them with more then one process,

these child processes are able to register events to and allow the main thread to be updated when they are ready with their calculation...

something like this:

1. main program is started

2. it creates with the help of vbs a com object that handeles all sub programms

3. when a function is called the vbs com object created the subt program

4. the subprogramm is listening for calculations

5. the main program gets a successful created sub program handle

6. it sends the part to calculate to the sub program

7. the sub program recieves the event though the CALLBACK

8. it calculates, while the main program is in idle/GUI mode.

9. it fires the done event with the result.

10. the main program recieves the sub event reads the result into memory

11. kills the sub program

12. returns to idle mode.

ey voila ... again >>> REAL: multithreading is born.

Edited by JRSmile
$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")
For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)
Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI"
Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;
MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
Link to comment
Share on other sites

I'm not really sure what your trying to do JRSmile but you should rather look into this 'CoProc' library i did (see sig.).

As for 'real multithreading':

The stub is thread save so it can be called by multiple threads but the messages are buffered in the message queue and autoit

processes them one after another.

Edited by piccaso
CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

thanks for notifying picasso,

i will try to figure out how to handle your udf.

but callback would be better for external dlls.

$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")
For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)
Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI"
Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;
MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
Link to comment
Share on other sites

  • 2 weeks later...

I've been unable to get it to work for setting a mousehook in an external process, does it only work for au3 processes? If not could someone give an example of how to mousehook an external process?

FYI, I know about Larry's dll, I just wanted to see if this could do it also.

Link to comment
Share on other sites

I've been unable to get it to work for setting a mousehook in an external process...

You can only hook the current processes threads, you need a dll for other processes.

So, now is it possible to use Libcurl with autoit ?

I didn't realise this until i played around with it recently but it was possible all the time, only some features (progress, download to memory) where not.

There will be a libcurl example in the next update, but i rewrote the asm stub from scratch and i'm not finished testing jet...

CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

Have just noticed this topic.

Very nice work! Thank you!

int (*_cb)(char*) = pcb;

So this creates a symbol "_cb" which represents a function which takes an array of chars (pointer to char) and returns an int... pcb is the function pointer which is received by cdecl_test()... correct me if I'm wrong.

Nice assembly, thanks again! :)

Edit: by 'symbol "_cb"' I mean pointer to function which accepts char* and returns int

Edited by zatorg
Link to comment
Share on other sites

You can only hook the current processes threads, you need a dll for other processes. I didn't realise this until i played around with it recently but it was possible all the time, only some features (progress, download to memory) where not.

There will be a libcurl example in the next update, but i rewrote the asm stub from scratch and i'm not finished testing jet...

Another use of your great CallBack UDF is subclassing.

I saw here very nice subclassing example in VB to set image as background of ListBox (but it's in Czech language).

Here is core/princip of example:

Public oldWindowProc as Long

Public gBGBrush As Long

Public Declare Function CreatePatternBrush Lib "gdi32" (ByVal hBitmap As Long) As Long

Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Declare Function SetBkMode Lib "gdi32" (ByVal hdc As Long, ByVal nBkMode As Long) As Long

Private Const WM_CTLCOLORLISTBOX = &H134

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( ByVal lpPrevWndFunc As Long, _

  ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Sub Form_Load()

  Image1.Visible = False

  gBGBrush = CreatePatternBrush(Image1.Picture.Handle)

  oldWindowProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf NewWindowProc)

End Sub

Private Sub Form_Unload(Cancel As Integer)

  SetWindowLong Me.hWnd, GWL_WNDPROC, oldWindowProc

  DeleteObject gBGBrush

End Sub

Public Function NewWindowProc(ByVal hWnd As Long, _

  ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

  'Debug.Print "&H" & Hex(uMsg), wParam, lParam

  If uMsg = WM_CTLCOLORLISTBOX And gBGBrush <> 0 Then

    SetBkMode wParam, 1 'Print text as transparent

    NewWindowProc = gBGBrush

  Else

    NewWindowProc = CallWindowProc(oldWindowProc, hWnd, uMsg, wParam, lParam)

  End If

End Function

I want to make some similar very simple example in AU3 to show CallBack & subclassing big power

but I don't know when it will be done if ever.

So idea for you (skilled man) to make it more quickly then me if you wish :)

EDIT: aded some missing declarations in VB code example

Edited by Zedna
Link to comment
Share on other sites

Have just noticed this topic.

Very nice work! Thank you!

int (*_cb)(char*) = pcb;

So this creates a symbol "_cb" which represents a function which takes an array of chars (pointer to char) and returns an int... pcb is the function pointer which is received by cdecl_test()... correct me if I'm wrong.

Nice assembly, thanks again! :)

Edit: by 'symbol "_cb"' I mean pointer to function which accepts char* and returns int

Correct ;)

I didnt do the assembly, just copy and paste from that dll in Feature request's forum.

But the next version will contain a 'all self written' asm stub ;)

So theoretically one can create a userland rootkit using AutoIt3!

no its not that easy ;)

You can easily hook api's of the current process but hooking them global is a different story...

Another use of your great CallBack UDF is subclassing.

Is it possible to subclass a window form a foreign process without code injection?

I'm sure its possible to subclass windows from the current process and i can add an example if you like, but i'm also pretty sure that it wont work with other processes...

CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

Is it possible to subclass a window form a foreign process without code injection?

I'm sure its possible to subclass windows from the current process and i can add an example if you like, but i'm also pretty sure that it wont work with other processes...

I was talking about current process. I don't know much about possibility use that also for another process.

If you can make some subclass simple example please (for current process). Thanks.

Link to comment
Share on other sites

Subclassing gave me something to chew on :)

It looks like the os doesn't like it if CallWindowProc is called from a callback function, probably because of the detour...

anyway i found a workaround and wrote an example on how to use it but it does not follow ms's documented ways.

instead of calling CallWindowProc it jumps directly to the WindowsProc, but if this is an issue for someone on some os i'll correct it.

The whole assembly and the way it is created is rewritten, fixed some flaws and maybe added new ones...

So all you assembler speaking creatures please have a close look and tell me if you see something wierd

edit: Assembly listings removed, look inside the zip.

Happy Callbacking ;)

Edited by piccaso
CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

Ok i played around a bit with Subclassing and there happened a lot of strange things so i decided to go the documented way and call CallWindowProc from within the asm stub.

Its pretty tricky copying parameters from the stack while pushing it on the stack without having a compiler doing calculations...

But after some trail and error it works fine and all those strange things are gone too :)

And since v6.3 unicode api's are used (if @unicode is true) where available.

CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

  • Recently Browsing   0 members

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