我使用BTMemoryModule将DLL注入进程。 主/父进程可以调用函数/过程,但另一种方式呢? dll可以从Main / Parent进程读取/获取var或调用函数吗?
感谢您的帮助。
编辑: DLL
library mydll; // DLL obviously...
uses windows;
procedure Test
begin
// I need a string/integer/pointer from ParentProcess
end
exports
Test;
begin
// I need a string/integer/pointer from ParentProcess. (if possible).
end.
程序:
program myprogram
uses
...
var
M : PBTMemoryModule;
begin
BTMemoryLoadLibary (pointer, pointerlength);
@myMaintest := BTMemoryGetProcAddress(M, 'Test');
...
end;
答案 0 :(得分:4)
首先,这似乎不是通常所谓的注射。这只是一个简单的模块加载,虽然来自内存而不是文件。
关于DLL如何从EXE导入函数,请以与从EXE导入DLL时完全相同的方式执行此操作。
exports
列出EXE导出的函数。GetModuleHandle(nil)
获取EXE的模块句柄。GetProcAddress
以导入函数。与更常见的EXE链接到DLL模式的唯一区别是您使用GetModuleHandle
而不是LoadLibrary
。那是因为EXE必须已经加载,所以你可以简单地询问它的模块句柄,而不是要求加载模块。
我会评论说以这种方式做事很不寻常。通常,EXE会调用DLL并传递DLL所需的任何信息。该信息可能包括允许DLL查询其主机EXE的回调函数,接口等。
答案 1 :(得分:2)
如果Child模块(您的DLL)知道父应用程序的数据结构和功能,则可以这样做。这些数据和功能必须在父方面提供。
答案 2 :(得分:0)
这是为了进一步扩展我的评论大卫的回答:
代码段:
library TheDLL;
...
var
OwnerAPP: HMODULE; // To be initialized by a call of the exported procedure Init from the EXE
...
type
TTestCallfromExe = procedure(f_Text: PAnsiChar); stdcall;
var
OwnerAPP: LongInt;
l_TestCallfromExe: TTestCallfromExe;
procedure Init(Owner: HMODULE);
begin
OwnerAPP := Owner;
end;
...
exports
Init, // This is it and the others exports follow
...
对 TestCallfromExe 的调用与通常调用任何Dll的导出函数/过程一样执行。只要 OwnerAPP 被正确初始化,就可以根据OP的要求在Dll的导出函数体内进行调用。
根据需要导出每个过程/函数(从DLL调用),当然你应该实现它们。
program TheEXE;
uses
...
MyExportImplementation; // Refence to implementatio unit
...
exports
TestCallfromExe, // This is it
...
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
示例实现细节:
unit MyExportImplementation;
interface
...
procedure TestCallfromExe(f_Text: PAnsiChar); stdcall;
implementation
...
procedure TestCallfromExe(f_Text: PAnsiChar); stdcall;
begin
MessageBoxA(0, f_Text, 'Exe Dialog Ansi (stdcall)', 0);
end;
...
end.
这是基于DemoDLL(来自BTMemory)的示例,例如在 TheEXE.dpr 项目的MainForm单元中实现:
procedure TForm1.BtnCAllClick(Sender: TObject);
var
l_Init: procedure(Owner: HMODULE);
begin
m_DllHandle := LoadLibrary('TheDLL.dll');
try
if m_DllHandle = 0 then
Abort;
@l_Init := GetProcAddress(m_DllHandle, 'Init'); // <<<
if @l_Init = nil then
Abort;
// Fetch the remainding exported function(s)/procedure(s) adresses
l_Init(HInstance); // <<< Hand EXE's HInstance over to the DLL
// Call exported function(s)/procedure(s) accordingly
except
Showmessage('An error occured while loading the dll');
end;
if m_DllHandle <> 0 then
FreeLibrary(m_DllHandle)
end;
我也使用BTMemory进行了测试,但它确实有效。