weirddave

passing a pointer to a child process via command line

35 posts in this topic

If I created a struct of bytes in a parent process and passed the pointer and the number of bytes to a child process via command line arguments, would the child be able to read and/or write to the struct without BSOD?

something along the lines of:

$tSTRUCT1 = DllStructCreate( "byte [" & $size & "]" )
$mypointer = DllStructGetPtr( $tSTRUCT1 )
ShellExecute ( "Child.exe", "", $mypointer &" "& $size )

 

Share this post


Link to post
Share on other sites



Awesome! I think this will solve my remaining problems :)

Or at least until I find another one ;)

Share this post


Link to post
Share on other sites

I'm looking at the shared memory example and it's not entirely obvious to me what I need to do.
If my pointer is to a structure of 100 bytes, how do I read that into the child process local structure?

Is the pointer 'real'? If it is, then couldn't the child process just recreate the struct using the pointer it was given from the parent? Or does that cause a warp core breach?

 

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Hi,

some example....

Parent.au3

$gui = GUICreate("Parent", -1, -1, 0, 0)
$label = GUICtrlCreateLabel("", 20, 20, 200, 30)
GUISetState()

$struct_parent = DllStructCreate("dword;char[20]")
$ptr = DllStructGetPtr($struct_parent)

ShellExecute("child.exe", $ptr)


$x = 0

While $x < 1000 * Sleep(1000)
    $x = $x + 1
    $int = DllStructGetData($struct_parent, 1)
    $txt = DllStructGetData($struct_parent, 2)
    GUICtrlSetData($label, "received from child: " & $int & $txt)
WEnd

 

child.au3

#include <WinAPI.au3>


If $CmdLine[0] = 0 Then Exit
$ptr_parent = $CmdLine[1]                      ;pointer from parent

$gui = GUICreate("Child")
$label = GUICtrlCreateLabel("", 50, 80, 200, 30)
GUISetState()

$struct = DllStructCreate("dword;char[20]")
$ptr = DllStructGetPtr($struct)


$pid = ProcessExists("Parent.exe")
$ph = _WinAPI_OpenProcess(0xFFFF, False, $pid, True)

$bytes = 0
$x = 0
While $x < 1000 * Sleep(1000)
    $x = $x + 1
    DllStructSetData($struct, 1, $x)
    DllStructSetData($struct, 2, " AutoIt_" & $x)
    $writeprocess = _WinAPI_WriteProcessMemory($ph, $ptr_parent, $ptr, 24, $bytes)
    GUICtrlSetData($label, "send to parent: " & $bytes & " bytes" & @CRLF & DllStructGetData($struct, 1) & DllStructGetData($struct, 2))
WEnd

 

Compile both scripts, then start "Parent.exe", which will start the child-process. The child-process sends data into the parents memory / dllstruct

 

//EDIT

You could "send" the pointer from the parent via a control. Create an invisible label which contains the pointer, then get this pointer via ControlGetText() by the child. Using this technique you wont  need the "Memory/Dllstruct"-stuff ;)

Edited by AndyG

Share this post


Link to post
Share on other sites

#7 ·  Posted

That does look a lot simpler. I think I will also have to pass @AutoItPID from the parent as there may be 2 instances of Parent.exe running.

 

How would hiding the pointer in a label differ from passing it as a cmd line parameter? Would I not still need to get a handle to the memory from the parent pid?
I assume the need to open a handle is due to the pointer only being valid for the process that asked for the memory, the memory management plays tricks with the pointers?


Just for fun I did try reading the memory by creating a struct from the passed pointer, caused an access violation :D

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

47 minutes ago, weirddave said:

I think I will also have to pass @AutoItPID from the parent as there may be 2 instances of Parent.exe running.

To share memory with many scripts/programs there is a much simpler solution. I use a dll which only gives back a pointer to some memory inside the dll. 

sharedmem.zip

The memory in the dll can easily be customized depending on the needed size. Assembler is FASM. There is only one function, returning a pointer to the memory. EVERY program (no matter of the  language) can access this memory and "share" it!

Start the sharedmemdll.exe several times. Every instance runs its own timer. You can "stop" this timer by holding the border of the window. With the "Reset"-Button of any of the GUIs, you can reset ALL timers of ALL running sharedmemdll.exe simultaneously ! So no "pointer deployment/allocation" is needed any more....

Edited by AndyG

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

1 hour ago, weirddave said:

creating a struct from the passed pointer, caused an access violation

Writing in a process's address space requires higher access privileges than reading from one, so I would always take the reverse approach, i.e., let the process that needs the info read from the process that has the info (again, see my Pool environment).

You may also wish to adjust SEDEGBUG privileges beforehand, as done here.

Edited by RTFC

Share this post


Link to post
Share on other sites

#10 ·  Posted

2 minutes ago, RTFC said:

Writing in a process's address space requires higher access privileges than reading from one

The question is, WHY does someone need to write into an other process´s address space. In early DOS-times, TSR-programs were "state of the art" and used to to expand functionality of the operating system or some programs. 30 years ago I used self-modifying code very often because the lack of enough memory.

Today there is no need of self-modifying code nor to "patch" the operating system or programs. Apart from cheating games and programming malware...

And because of the strive of the modern OS to make everything much "safer", the access to certain processes becomes more and more difficult. Therefore my intention to use a DLL. Every process/program can use/share the memory provided by the DLL.

28 minutes ago, RTFC said:

You may also wish to adjust SEDEGBUG privileges beforehand, as done here.

...or use a debugger. I prefer IDA or Kernel Debugger. No "privileges" needed... ;)

Share this post


Link to post
Share on other sites

#11 ·  Posted

@AndyG: Hi, I'm a fan of your contriutions.:)

45 minutes ago, AndyG said:

WHY does someone need to write into an other process´s address space.

I was actually advocating the reverse strategy, of passive reading. I agree that no programme other than a debugger should be actively tampering with a process's private affairs.

 

46 minutes ago, AndyG said:

30 years ago I used self-modifying code very often

Me too!^_^

51 minutes ago, AndyG said:

Today there is no need of self-modifying code

That reminds me a bit of the sales guy at the PC shop that told his customers: "modern operating systems are so robust that the PCs don't need a reset button anymore;" NB this was in the late eighties.:D I still prefer higher-level languages that allow me to selfmodify, or else something like my CodeCrypter would not be possible. At the moment I'm finalising a programming environment that is itself written in a high-level language (the exe creates a process-specific VM at runtime); certainly not malicious, yet would be impossible without self-modifying code (user-defined calls/UDFs at runtime).

48 minutes ago, AndyG said:

my intention to use a DLL

Didn't mean to disparage your solution in any way.;) But I don'tthink adjusting SEDEBUG does inherently imply malicious intent.

Share this post


Link to post
Share on other sites

#12 ·  Posted

38 minutes ago, RTFC said:

Didn't mean to disparage your solution in any way.;) But I don'tthink adjusting SEDEBUG does inherently imply malicious intent.

Sorry if my expression was perceived "negative", that was not my intention! :thumbsup:

 

47 minutes ago, RTFC said:

That reminds me a bit of the sales guy at the PC shop that told his customers: "modern operating systems are so robust that the PCs don't need a reset button anymore;" NB this was in the late eighties.

...and not to mention that this guy placed a newer/faster/better PC into the store window one minute after you bought your new "darling" from him. And software development was easy those days...if the program was too slow, the programmer has advised you to buy a newer/better/faster machineB)

 

Btt!

2 hours ago, RTFC said:

Writing in a process's address space requires higher access privileges than reading from one, so I would always take the reverse approach, i.e., let the process that needs the info read from the process that has the info (again, see my Pool environment).

...the essence of this thread!:thumbsup:

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

19 hours ago, AndyG said:

.and not to mention that this guy placed a newer/faster/better PC into the store window one minute after you bought your new "darling" from him. And software development was easy those days...if the program was too slow, the programmer has advised you to buy a newer/better/faster machine

Oh no, now you've made me feel really ancient! :D No worries.;)

PS the worst thing was, this guy actually lived in my student dorm, so we had to suffer endless lectures about how the latest tech was going to make our low-level efforts to get stuff done totally obsolete within weeks. Fortunately the days of having to build your own desktop from separate components if you wanted to make sure all bits were high-end and actually worked together, are over.

Edited by RTFC

Share this post


Link to post
Share on other sites

#14 ·  Posted

I ran the exe and got the error in the attached pic.

Ideally I need 4 shared blocks of memory, 2 for data and handshaking in each direction (parent to child and child to parent).
I suspect the only way I'm going to get this to work is to pass the pointers, memory sizes and PID to the child process (9 cmd line arguments) and use the _WinAPI functions. This is going to get messy :D 

 

oops.png

Share this post


Link to post
Share on other sites

#15 ·  Posted

@weirddave, your system OS and bitness?

The DLL is 32 bit, and the compiled exe is 32 bit too...here you can find a 64bit-version.

Depending on "access rights" you could try to registrate the dll in your system via  Regsvr32.exe

 

5 hours ago, weirddave said:

Ideally I need 4 shared blocks of memory, 2 for data and handshaking in each direction (parent to child and child to parent).
I suspect the only way I'm going to get this to work is to pass the pointers, memory sizes and PID to the child process (9 cmd line arguments) and use the _WinAPI functions.

Because not to work with these "pass the pointer, memory sizes and PID" i work with the DLL...There is only ONE (Base)Pointer for all the involved programs, all the rest is playing with dllstruct(). All programs can read/write from/to this memory.

$struct=dllstructcreate("byte mem1[1000];byte mem2[1000];byte mem3[1000];byte mem4[1000];dword handshake1;dword handshake2",$POINTER_FROM_DLL)  is all you have to work with...

From then on, you read/write to the mem3 only via dllstruct(g/s)etdata($struct,"mem3",$data).

 

But if you want to play with the Parent/Child - Version, i would prefer the method to communicate with invisible controls. And about "messy"....all depends on your programming skills:D

Share this post


Link to post
Share on other sites

#16 ·  Posted

Ah, I'm on win7 and 10 64bit, Hopefully I won't run this on anything older :)

I'm not familiar with the hidden controls method (or any method really :) )

Looking at the asm:

_mem dd 1000 dup 0    ;10 Kb Speicher

Is this reserving 4000 bytes?

Does this get reserved when:

$dll = DllOpen("sharedmem.dll")

Do I pass the pointer from the parent or

DllCall($dll, "dword", "GetPointer")

from within both the parent and child process?

Is the reserved memory freed with DllClose()?

I couldn't find the 64bit version from your link (my German isn't good).

Sorry for all the questions, I'm just trying to fully understand what's happening :)

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

Oddly, the 32bit dll seems to work on 64bit win7 Enterprise at work :)


I downloaded FASM, managed to compile the dll, for some reason it's almost 2x the size of the one in the zip file. I also tried to create a 64bit version (I found the code :) ) but I failed to get autoit to run, it complains about $ptr[0] not being accessible. I tried the example autoit code from the same thread, same problem.

 

Edit:

Upon further investigation, autoit is failing to open sharedmem64.DLL :(
This is due to me not running the script as 64bit :D 

Edited by weirddave

Share this post


Link to post
Share on other sites

#18 ·  Posted

On 2.10.2016 at 0:49 PM, weirddave said:

_mem dd 1000 dup 0    ;10 Kb Speicher

oops, yes of course 1000x 4byte is 4000byte and not 10K :)

On 2.10.2016 at 0:49 PM, weirddave said:

Do I pass the pointer from the parent or

DllCall($dll, "dword", "GetPointer")

from within both the parent and child process?

Yes, that´s the trick, all programs get the same poiter from the DLL.

 

On 2.10.2016 at 0:49 PM, weirddave said:

Does this get reserved when:

$dll = DllOpen("sharedmem.dll")

The dll is loaded into Memory, the code inside the dll only reserves some memory. The only function inside the dll is to give back the pointer to the reserved memory.

8 hours ago, weirddave said:

 

Oddly, the 32bit dll seems to work on 64bit win7 Enterprise at work

 

I suspect trouble with access privileges at your computer at home....

 

9 hours ago, weirddave said:

but I failed to get autoit to run, it complains about $ptr[0] not being accessible.

errormanagement ftw :D

First of all you should check if the dll is loaded by DllOpen()! What errorcode is shown?

9 hours ago, weirddave said:

This is due to me not running the script as 64bit

In most cases there is no advantage of 64-Bit-Programs. In AutoIt i  can not imagine a reason for a  64-Bit-mode Script:huh2:

Share this post


Link to post
Share on other sites

#19 ·  Posted

You might take a look at the example of _WinAPI_CreateFileMapping.  You could use it to set up a coherent named buffer that can be viewed across many processes, eliminating the need to use (Read/Write)ProcessMemory. 

Share this post


Link to post
Share on other sites

#20 ·  Posted

AndyG, thanks for you answers, the example code didn't have any error management for that :D. What would make the DLL better (in my humble opinion) would be to have an 'Init (bytes)' function which actually allocates a piece of memory for sharing, that way you can ask for the amount you actually need (or make autoit create the asm and compile it I guess ;) )

 

Tekk, I have taken a look that, but it's more work than the sharedmemory.dll method for what I'm trying to do. I suspect it's faster too.

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