load and call DLL in another process

delphi package - easy access to kernel objects etc.

load and call DLL in another process

Postby Ahell » Sun Sep 18, 2011 10:59 am

Hello, Madshi! :wink:

My task is change window caption in Console application.

I think:
1. call this function from memory of another process, by using
Code: Select all
IProcess.ExecuteFunction
. But example of using this function in the help, misunderstood for me. Can you make very simple example for me, please? :blush:
2. load dll in memory of another process by using IProcess.LoadModule and them call same function by
Code: Select all
 IModule.GetProcAddress
. But a can't found example for this.

How I can complete this task? :crazy:
Ahell
 
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: load and call DLL in another process

Postby Ahell » Mon Sep 19, 2011 6:44 pm

Help me, please :wink:
Ahell
 
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: load and call DLL in another process

Postby madshi » Mon Sep 19, 2011 9:05 pm

For changing the window caption usually SendMessage(WM_SETTEXT) works just fine. Not sure if it also works for console windows, though.

Not sure what you want to know about IProcess.ExecuteFunction and IModule.GetProcAddress exactly?
madshi
Site Admin
 
Posts: 9431
Joined: Sun Mar 21, 2004 5:25 pm

Re: load and call DLL in another process

Postby Ahell » Mon Sep 19, 2011 10:40 pm

madshi wrote:For changing the window caption usually SendMessage(WM_SETTEXT) works just fine. Not sure if it also works for console windows, though.

Not sure what you want to know about IProcess.ExecuteFunction and IModule.GetProcAddress exactly?


Console windows do not have a message handler windows.
and SendMessage does not always work.
Determine the console application window so as impossible as they all have a class ConsoleWindowClass.

At the moment I'm using just such a scheme:
Sleep (SleepTime);
AttachConsole (Pinfo.dwProcessId);
AppInfo.WindowHande: = GetConsoleWindow;
ShowWindow (AppInfo.WindowHande, SW_HIDE);
FreeConsole;

And it works, but again not always.

So I came up with another option. Load a DLL into the address space of another process also control the process through this DLL.
Program TrayIt, exactly what works! DLL is the Windows message handler and react like a normal gui application.

The problem is that I don `t know how to call a function from the loaded DLL in the address space of another process, and pass it a parameter.

Or how to run my code in the address space of another process. Examples are described in the certificate are not entirely clear to me ...

Could you give some examples to meet the following of my code in the address space of another process? Or with a call to the DLL is loaded into the address space of another process ....
Ahell
 
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: load and call DLL in another process

Postby madshi » Tue Sep 20, 2011 7:30 am

The easiest solution would be to use madCodeHook. With InjectLibrary you can inject your dll into the other process. Then your dll could call CreateIpcQueue in the initialization section and your exe could then call SendIpcMessage to send a message to the dll. As a result your dll would call your IPC message callback function in which you could run some code and then return data to the exe.

Doing all of this with madKernel would be possible, too, but you'd need to do more work by yourself. E.g. you'd have to implement the whole inter process communication yourself. Btw, the "IProcess.ExecuteFunction" and "IProcess.LoadModule" functionality will need madDisAsm. If you don't have madExcept or madCodeHook installed, madKernel doesn't have access to madDisAsm. So you need to have madExcept or madCodeHook installed, otherwise IProcess.ExecuteFunction and IProcess.LoadModule will fail.
madshi
Site Admin
 
Posts: 9431
Joined: Sun Mar 21, 2004 5:25 pm

Re: load and call DLL in another process

Postby Ahell » Tue Sep 20, 2011 8:37 am

madshi wrote:The easiest solution would be to use madCodeHook. With InjectLibrary you can inject your dll into the other process. Then your dll could call CreateIpcQueue in the initialization section and your exe could then call SendIpcMessage to send a message to the dll. As a result your dll would call your IPC message callback function in which you could run some code and then return data to the exe.

Doing all of this with madKernel would be possible, too, but you'd need to do more work by yourself. E.g. you'd have to implement the whole inter process communication yourself. Btw, the "IProcess.ExecuteFunction" and "IProcess.LoadModule" functionality will need madDisAsm. If you don't have madExcept or madCodeHook installed, madKernel doesn't have access to madDisAsm. So you need to have madExcept or madCodeHook installed, otherwise IProcess.ExecuteFunction and IProcess.LoadModule will fail.


MadCollection(except MadCodeHook 3, becouse is are shareware product) are installed.

I have a DLL, with this code:
Code: Select all
library DLL;

type
    BOOL = LongBool;
    DWORD = LongWord;

function SetConsoleTitle(lpConsoleTitle: PChar): BOOL; stdcall; external 'kernel32.dll' name 'SetConsoleTitleA';
procedure FreeLibraryAndExitThread(hLibModule: HMODULE; dwExitCode: DWORD); stdcall; external 'kernel32.dll' name 'FreeLibraryAndExitThread';
function GetModuleHandle(lpModuleName: PChar): HMODULE; stdcall; external 'kernel32.dll' name 'GetModuleHandleA';

procedure SetWindowCaption(aNewCaption:PChar); stdcall;
begin
  SetConsoleTitle(aNewCaption);
  FreeLibraryAndExitThread(GetModuleHandle('myDLL.dll'), 0);
end;

exports
   SetWindowCaption;

begin
end.


Using madKernel.pas of madCallection. I want to load this DLL in another process, then call the function from the DLL "SetWindowCaption" and pass prametr type PChar in this function ..

How do I do?

I wrote the following code:

Code: Select all
procedure TForm1.Button1Click(Sender: TObject);
type
  TCallProc=procedure (aStr:PChar);
var
  dh:THandle;
  myProc:TCallProc;
begin
  with Process('Console.exe') do
  begin
    If IsStillRunning then
    begin
     @myProc:=LoadModule(ExtractFilePath(ParamStr(0))+'mydll.dll').GetProcAddress('SetWindowCaption');
     myProc('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); //raised exception class EAccesViolation at 0x0000000 to 0x00000000
    end;
  end;


But I can not understand why not get a pointer to a callback function IProcess ('Console.exe'). LodLibrary ('myDLL.dll'). GetProcAdderss ('SetWindowsCaption');

And there is an error of memory access to get a pointer (EAccesViolation)
Ahell
 
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: load and call DLL in another process

Postby madshi » Tue Sep 20, 2011 9:12 am

The dll is loaded in another process. The address you get by IModule.GetProcAddress is valid only in the other process, not in yours. So you can't simply call "myProc", because doing so would try to execute the dll's exported function in your own process. You need to execute the function in the other process, not in your own one.
madshi
Site Admin
 
Posts: 9431
Joined: Sun Mar 21, 2004 5:25 pm

Re: load and call DLL in another process

Postby Ahell » Tue Sep 20, 2011 4:56 pm

madshi wrote:The dll is loaded in another process. The address you get by IModule.GetProcAddress is valid only in the other process, not in yours. So you can't simply call "myProc", because doing so would try to execute the dll's exported function in your own process. You need to execute the function in the other process, not in your own one.


If I get a function pointer to dll, which is located in another process, and I can not just call in its process (I need to call in another process), I use IProcess.ExecuteFunction and the pointer to point to dll exported function in a foreign process?

Or as something else?
Ahell
 
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: load and call DLL in another process

Postby madshi » Tue Sep 20, 2011 6:03 pm

Yes, you could use IProcess.ExecuteFunction. Of course then your exported function must match the parameter and calling type required for IProcess.ExecuteFunction. Alternatively you could create some kind of inter process communication message queue in your dll and then send notifications to it by your exe. For that to work your hook dll would create a private thread in its DllMain function. The private thread could then e.g. create an invisible window and then go into an endless message loop (GetMessage, ...). Your exe could then search for that window (FindWindow) and send messages to it. In your hook dll's private thread's message loop you would get these messages and could then directly call the exported function. Actually you wouldn't even have to export it this way.
madshi
Site Admin
 
Posts: 9431
Joined: Sun Mar 21, 2004 5:25 pm

Re: load and call DLL in another process

Postby Ahell » Tue Sep 20, 2011 7:15 pm

Strange, but I can not really get a pointer to the procedure in the dll, which is in another process.

and if you do not check for nil, I write that "the paramter is given is not true."

can I do something wrong? attach the source ...

Please, help me.
Attachments
src.zip
this is my test project and test console application
(27.38 KiB) Downloaded 265 times
Ahell
 
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: load and call DLL in another process

Postby madshi » Tue Sep 20, 2011 8:05 pm

Ahell wrote:I can not really get a pointer to the procedure in the dll

I need more details than that. What do you get? A nil pointer or what?
madshi
Site Admin
 
Posts: 9431
Joined: Sun Mar 21, 2004 5:25 pm

Re: load and call DLL in another process

Postby Ahell » Tue Sep 20, 2011 8:32 pm

Yes,
In a variable myProc not a pointer to a callback function from the DLL in another process ..
See screenshot
Безымянный.JPG
Безымянный.JPG (88.7 KiB) Viewed 7597 times


if assigned(Pointer) then Pointer is not nil.
Ahell
 
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: load and call DLL in another process

Postby madshi » Tue Sep 20, 2011 8:44 pm

Please check "LoadModule(...).IsValid". Is the module valid?
madshi
Site Admin
 
Posts: 9431
Joined: Sun Mar 21, 2004 5:25 pm

Re: load and call DLL in another process

Postby Ahell » Tue Sep 20, 2011 8:51 pm

hm, something wrorng with me or with my code :o
i wrote this code, but my dll.dll does not loaded in process....
Code: Select all
procedure TForm1.Button1Click(Sender: TObject);
type
  TCallProc = procedure(aNewCaption: PChar);
var
  myProc: TCallProc;
  s: PChar;
  b: Boolean;
  i: Integer;
begin
  with Process('Console.exe') do
  begin
    if IsStillRunning then
    begin
      if FileExists(ExtractFilePath(ParamStr(0)) + 'dll.dll') then
      begin
      ShowMessage('DLL.dll are exists!');  //condition is satisfied
      end else
      ShowMessage('DLL.dll not found!');

      if not LoadModule(ExtractFilePath(ParamStr(0)) + 'dll.dll', false).IsValid then
      begin
       ShowMessage('LoadModule is not valid!');    //condition is satisfied
      end;

      for i := 0 to Modules.ItemCount - 1 do
      begin
        if Modules.Items[i].FileName = 'dll.dll' then
        begin
          @myProc := Modules.Items[i].GetProcAddress('SetWindowCaption');
          b := Assigned(myProc);
          if b then
          begin
            s := PChar(Edit1.text);
            ExecuteFunction(@myProc, 1000, @s, Length(s));
          end;
        end;
      end;
    end;
  end;
end;


The dll.dll are exists, but LoadModule not worked. What is wrong? :o
Ahell
 
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: load and call DLL in another process

Postby madshi » Wed Sep 21, 2011 7:19 am

You do have madExcept installed, correct?

Are you sure you have enough privileges to inject the dll into the target process? Try running your exe as admin.
madshi
Site Admin
 
Posts: 9431
Joined: Sun Mar 21, 2004 5:25 pm

Next

Return to madKernel

Who is online

Users browsing this forum: No registered users and 1 guest