Sign in to follow this  
Followers 0

ProcessCall.au3 UDF

23 posts in this topic

Posted (edited)

Hello.

I have been working on this UDF which implements the following features:

  • Call any function in any process, including your own - see DllCallEx.
  • Runtime linking features using GetRemoteModuleHandle and GetRemoteProcAddress.
The UDF has reached a state where i would like others input, maybe some on design and such.

Supports:

  • stdcall and fastcall
  • reference passing
  • address-of passing
  • static arrays when used with byte*, char* and wchar*
Current functions:

  • ProcCall
  • ProcCallbackRegister
  • ProcCallback
  • ProcCallbackFree
  • GetRemoteModuleHandle
  • GetRemoteModuleList
  • OpenProcess
  • GetRemoteProcAddress
  • DllCallEx
Idea

The goal of the UDF was mainly proof-of-concept, extended debugging abilities, learning by doing and enhanced inter process communication.

How does it work?

It evaluates the arguments and assembles a small thread, which pushes the arguments and returns. Really it just automates the process.

Syntax

All the function use DllCall() style. Read documentation.

Examples

A set of basic examples is included.

Notes

This is in an early alpha state, which means that if you want to use this you should have a good idea about how calling conventions work, understand the relation between types and values, and a basic understanding of pointers. If you don't, you'll most likely end up crashing either your or the target process. Only x86 is supported.

Be aware that no in-depth type checking is done, so it's assumed you know what you are doing ;)

To be implemented

  • ProcCall returning an array of parameters and return values like DllCall()
  • x64 Support
  • Better documentation
  • Bulletproof return code.
  • cdecl support.

Changelog

  • 07-08 '11

    • Fixed a bug with global deallocations associated with callbacks.
    • Callbacks, if return type is void, will not wait for the thread to return (parallel to Run() and RunWait()).
    • Added GetRemoteModuleList().
    • Rewrote GetRemoteModuleHandle.
    • Added an extra param in OpenProcess() and made it public.
    • Added more errors and better descriptions.. imo.
    • Optimized DllCallEx().
  • 22-06 '11

    • Fixed a bug when using fastcall convention that would crash the script.

Lmk what you guys think about this :huh2:

e: aaaand attaching the file lol.

ProcCall.zip

Edited by Shaggi
FaridAgl likes this

Share this post


Link to post
Share on other sites



Posted

This UDF should proove all AutoIt haters that C++ isn't only _real_ language. :huh2:

Share this post


Link to post
Share on other sites

Posted

This UDF should proove all AutoIt haters that C++ isn't only _real_ language. :huh2:

Perhaps ;)

New version with a small bug fix uploaded.

Share this post


Link to post
Share on other sites

Posted

Can this be used to call so called commands in external process?

If to be more specific, it's in Opera browser, it's supporting commands in his interface (from hotkeys or menu items/toolbar buttons), and i want to call these commands (functions?) from autoit script, is that possible?

Share this post


Link to post
Share on other sites

Posted (edited)

Hi, thanks for sharing.

I was only asking in the Help section last week on how to do such a thing while working with wnaspi32.dll.

LoadLibrary -> GetProcessAddress -> Call Process.

Once I got to the Call Process function in AutoIt I didn't have a clue where to start.

1 week later and you post a whole udf of what I wanted to know, I feel special :)

Look forward to poking through your code. ;)

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

Posted (edited)

@MrCreatoR yes possible all you need to do is find out address and parameters. Knowing little asm would help you but you might have to mess with olly dbg or ida or cheat engine to find out addresses you want to call.

For example If you know what is the address of function that sets volume for vlc media player you can make autoit script that sets it with out sending any keystokes/mouseclicks to it.

Edited by E1M1

Share this post


Link to post
Share on other sites

Posted

@MrCreatoR yes possible all you need to do is find out address and parameters. Knowing little asm would help you but you might have to mess with olly dbg or ida or cheat engine to find out addresses you want to call.

Thank you for replying.

But unfortunaly i don't know asm, and i have no idea how to get these addresses :)

Share this post


Link to post
Share on other sites

Posted

I could help you with addresses (I still dont know how to find out arguments count and types) but do you know what argument your function takes? or how many arguments. If you use wrong type or wrong number of args or wrong call (stdcall or fastcall) then your app will crash, which means you would have to spend day for experimenting with different calls.

Share this post


Link to post
Share on other sites

Posted

do you know what argument your function takes?

I am not sure that i know what functions are called, because it's user commands, used from menu, for example:

Item, "Visit autoitscript.com" = Go to page, "http://www.autoitscript.com"

here the Go to page is one command (there is many, i can provide the whole list that Opera supports), and the page address is the argument for this command.

I hoped that we could do something like that (changed example of DllCallEx):

#include "..\..\ProcessCall.au3"

;Example 2 - Calling a function from address
$Pointer = _GetProcAddress(_WinApi_GetModuleHandle("C:\Opera\Opera.dll"), "GoToPage")

;Now we call the command from its address in memory
$iRet = DllCallEx($Pointer, "int", "hwnd", 0, "char*", "http://autoitscript.com", "int", 0, "int", 0)
ConsoleWrite($iRet & @CRLF)

But it's crashed with memory access error message :).

Share this post


Link to post
Share on other sites

Posted (edited)

There are 2 methods to get address. See if _GetProcAddress is valid address. compare it's return value with what you get from cheat enginge or from olly dbg.

Method 1

you could try downloading http://www.heijnen1.demon.nl/CheatEngine61.exe Open opera by clicking on that computer icon on left top. Then click on memory view. Then in new window that pops up select View > Ennumerate DLL's and symbols. And you should have window that shows you all dlls attached to opera

Method 2

download http://www.ollydbg.de/odbg110.zip Run OLLYDBG.exe with admin rights. From filemenu click attach. From new window select opera.exe. click attach. After that you see window displays you asm. in this window press ALT + E. "This pops up Executable Modules" window. Right click on dll you are interested in. from menu choose View Names.

Also note that DllCallEx cals dll from your script but you want to call it from opera.exe so you need ProcCall instead.

Shaggi might know this better, but I haven't seen him around. Hopefully I can help too.

Edited by E1M1

Share this post


Link to post
Share on other sites

Posted (edited)

Can this be used to call so called commands in external process?

If to be more specific, it's in Opera browser, it's supporting commands in his interface (from hotkeys or menu items/toolbar buttons), and i want to call these commands (functions?) from autoit script, is that possible?

Indeed it is, but it would definately be better to send a message instead of calling the raw functions, many programs have critical code inside their window procedure. Look up _SendMessage or PostMessage.

Hi, thanks for sharing.

I was only asking in the Help section last week on how to do such a thing while working with wnaspi32.dll.

LoadLibrary -> GetProcessAddress -> Call Process.

Once I got to the Call Process function in AutoIt I didn't have a clue where to start.

1 week later and you post a whole udf of what I wanted to know, I feel special ;)

Look forward to poking through your code. :D

Cheers

Guess it's your lucky day :) Feel free to post if you have any questions.

I am not sure that i know what functions are called, because it's user commands, used from menu, for example:

Item, "Visit autoitscript.com" = Go to page, "http://www.autoitscript.com"

here the Go to page is one command (there is many, i can provide the whole list that Opera supports), and the page address is the argument for this command.

I hoped that we could do something like that (changed example of DllCallEx):

#include "..\..\ProcessCall.au3"

;Example 2 - Calling a function from address
$Pointer = _GetProcAddress(_WinApi_GetModuleHandle("C:\Opera\Opera.dll"), "GoToPage")

;Now we call the command from its address in memory
$iRet = DllCallEx($Pointer, "int", "hwnd", 0, "char*", "http://autoitscript.com", "int", 0, "int", 0)
ConsoleWrite($iRet & @CRLF)

But it's crashed with memory access error message ;).

Go with the sendmessage method instead. There are several faults in your script. Firstly, you need to use GetRemoteProcAddress, because _GetProcAddress and _GetModuleHandle only works in your own process. If a function called "GoToPage" exists (this is highly unlikely), you should get the address like this:

$Pointer = GetRemoteProcAddress("<insert processname here>","Opera.dll", "GoToPage")

Also, DllCallEx calls a machinecode address (contrary to DllCall) in your own process, so you need to use ProcCall instead.

Edited by Shaggi

Share this post


Link to post
Share on other sites

Posted (edited)

E1M1

Thank you, i have tried both methods, but there is no dll that includes any similar functions to opera commands.

Shaggi

it would definately be better to send a message instead of calling the raw functions, many programs have critical code inside their window procedure. Look up _SendMessage or PostMessage

But what messages i should use?

How do i know what message is related to specific command?

Go with the sendmessage method instead. There are several faults in your script. Firstly, you need to use GetRemoteProcAddress, because _GetProcAddress and _GetModuleHandle only works in your own process. If a function called "GoToPage" exists (this is highly unlikely), you should get the address like this:

$Pointer = GetRemoteProcAddress("<insert processname here>","Opera.dll", "GoToPage")

Also, DllCallEx calls a machinecode address (contrary to DllCall) in your own process, so you need to use ProcCall instead.

Yep, no such function, the $Pointer is 0.

Edited by MrCreatoR

Share this post


Link to post
Share on other sites

Posted (edited)

in cheatengine when you list dlls you see Opera.dll did you try click on that + sign to view functions inside this dll? are you sure it's Opera.dll you need? try think logically. Same functionality can have different func names and how do you know you need GoToPage? from opera.dll you might find similar funcc name for this action.

I never used opera so please don't frown on me. I just tried to give some hints.

... Just tested it with latest opera 11.5. there's no such function as GoToPage in opera.dll.

Edited by E1M1

Share this post


Link to post
Share on other sites

Posted (edited)

in cheatengine when you list dlls you see Opera.dll did you try click on that + sign to view functions inside this dll?

Yes ofcourse, i even checked the dll in Dll Explorer.

I think it's internal Opera functions, so the only chance to get it working is to wait untill opera make some sort of API for these commands.

Anyway, thank you both for trying to help me, i sure i will find use for this great UDF :).

Edited by MrCreatoR

Share this post


Link to post
Share on other sites

Posted

No problem. You can also lookup internal functions but this would require 3-4 days digging in tutorials and other day or 2 experimenting with opera. But firefox was automated with TCP/UDP functions (see udf) myabe opera can be automated same way. Or there might be even UDF for that. I haven't searched but you could do forum search.

Share this post


Link to post
Share on other sites

Posted (edited)

there might be even UDF for that

There is, wroten by... well, me :)

But it's only on "file system level", and this is the reason why i want to triger commands in Opera, i want to extend the library and bring it to different level.

Edited by MrCreatoR

Share this post


Link to post
Share on other sites

Posted

can't you just click and send keys? There was even UDF that allowed to do this minimized window.

Share this post


Link to post
Share on other sites

Posted

can't you just click and send keys?

First of all, i think that it's not correct way of doing things, and second of all, i want to automate things like open/close tabs, open preferences, change view, select text, open links etc.

Every user can change hotkeys in opera very easily, so sending keys is not an option.

Share this post


Link to post
Share on other sites

Posted

Nice, really nice.

Maybe '__thiscall' support aswell?

Share this post


Link to post
Share on other sites

Posted

Nice, really nice.

Maybe '__thiscall' support aswell?

I might do that, but you will have to pass the pointer to the object itself - the udf cannot know this :)

Share this post


Link to post
Share on other sites

Posted

New UDF uploaded with several fixes.

Share this post


Link to post
Share on other sites

Posted

Hi,

Dont work anymore?

See the error:

D:Arquivos de programasAutoIt3IncludeProcessCall.au3(72,35) : ERROR: $WRITE_DAC previously declared as a 'Const'.

Global Const $WRITE_DAC = 0x000400

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

D:Arquivos de programasAutoIt3IncludeProcessCall.au3(74,40) : ERROR: $READ_CONTROL previously declared as a 'Const'.

Global Const $READ_CONTROL = 0x00020000

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

-------------------------

Grtz!!!

Share this post


Link to post
Share on other sites

Posted

Just remove that 2 variables.

Waiting for cdecl support, it makes it great.

Share this post


Link to post
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
Sign in to follow this  
Followers 0