动态连接库的动态调用问题(50分)

Z

ZQFILE

Unregistered / Unconfirmed
GUEST, unregistred user!
要求:我通过OpenDialog1任意选择一个动态连接库文件,可以找出该动态连接库中的
函数或过程名(这里已经完成),然后我想直接调用动态连接库中的函数和过程
问如何实现。

是否可以这样做?
 
要知道它的原型!!
首先声明这一原型
 
我的要求就是,动态的调用动态连接库,在动态的使用其中的函数和过程
不要声明他的原型,如果要那样我就不提这个问题了
 
在不知道函数的参数类型和数量的情况下, 这是不可能的..如果已知函数参数的情况
不声明原型也可以通过一些技巧来实现...
 
To tseug
假设现在知道函数和过程的参数,那如何实现
 
大概就是这样....手头有活, 没有详细写

procedure Hello(const Msg: String); stdcall;
begin
ShowMessage(Msg);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
S : String;
P : Pointer;
begin
S := 'Hello, World';
P := @Hello;
asm
push S
call P
end;
end;

end.
 
to :tseug
谢谢你的回答,但我对汇编知道的不多,
真诚希望你能帮我完成这个功能

如果分不够,我在加
 
关注这个问题的解决方法,与我想解决的想法一样/
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1441448
不过,没有理想的解决方法
 
既然你已经
任意选择一个动态连接库文件,可以找出该动态连接库中的
函数或过程名(这里已经完成)就可以这样
var
FDll_HWnd: HWnd;
HPIOpen: function(FileName: LPSTR): PVoid; stdcall;
begin
FDll_HWnd := LoadLibrary('HPIUtil.dll');
HPIOpen := GetProcAddress(FDll_HWnd, 'HPIOpen');
if Assigned(HPIOpen) then
Fhpi := HPIOpen(pchar(FFileName));
FreeLibrary(FDll_HWnd);
end;
请问你是用什么方法知道任意动态连接库中的函数或过程名,我也想知道,请指教。
 
楼上的办法只适合固定格式的函数调用, 如果不知道参数的个数就不适合了. 由于
Delphi不支持类似C中的printf这种声命方法(当然, 可以调用), 所以需要有一些
特殊的处理.
 
TO YOKI2003
USES
DLLTOOLS;
.......
procedure TForm1.Button1Click(Sender: TObject);
begin
if opendialog.execute then begin
Memo1.Clear ;
ListDLLExports(opendialog.filename, listexport );
end;
end;

function TForm1.ListExport( const name: String; ordinal: Integer; address:pointer ): Boolean;
begin
Result := true;
Memo1.Lines.Add('Name:'+Name+' Address:' +Format('%p',[address] )+' Ordinal:'+format('%d',[ordinal] ))
end;

unit dlltools;


interface


Uses Windows, Classes, Sysutils, imagehlp ;


type

TDLLExportCallback = function (const name: String; ordinal: Integer;

address: Pointer): Boolean of Object;

{ Note: address is a RVA here, not a usable virtual address! }

DLLToolsError = Class( Exception );


Procedure ListDLLExports( const filename: String; callback:

TDLLExportCallback );

Procedure DumpExportDirectory( Const ExportDirectory: TImageExportDirectory;

lines: TStrings; const Image: LoadedImage );

Function RVAToPchar( rva: DWORD; const Image: LoadedImage ): PChar;

Function RVAToPointer( rva: DWORD; const Image: LoadedImage ): Pointer;


implementation


resourcestring

eDLLNotFound =

'ListDLLExports: DLL %s does not exist!';


{+----------------------------------------------------------------------

| Procedure EnumExports

|

| Parameters :

| ExportDirectory: IMAGE_EXPORT_DIRECTORY record to enumerate

| image : LOADED_IMAGE record for the DLL the export directory belongs

| to.

| callback : callback function to hand the found exports to, must not be

Nil

| Description:

| The export directory of a PE image contains three RVAs that point at

tables

| which describe the exported functions. The first is an array of RVAs

that

| refer to the exported function names, these we translate to PChars to

| get the exported name. The second array is an array of Word that

contains

| the export ordinal for the matching entry in the names array. The

ordinal

| is biased, that is we have to add the ExportDirectory.Base value to it

to

| get the actual export ordinal. The biased ordinal serves as index for

the

| third array, which is an array of RVAs that give the position of the

| function code in the image. We don't translate these RVAs since the DLL

| is not relocated since we load it via MapAndLoad. The function array is

| usually much larger than the names array, since the ordinals for the

| exported functions do not have to be in sequence, there can be (and

| frequently are) gaps in the sequence, for which the matching entries in

the

| function RVA array are garbage.

| Error Conditions: none

| Created: 9.1.2000 by P. Below

+----------------------------------------------------------------------}

Procedure EnumExports( const ExportDirectory : TImageExportDirectory ;

const image : LoadedImage ;

callback : TDLLExportCallback ) ;

Type

TDWordArray = Array [0..$FFFFF] of DWORD;

Var

i: Cardinal;

pNameRVAs, pFunctionRVas: ^TDWordArray;

pOrdinals: ^TWordArray;

name: String;

address: Pointer;

ordinal: Word;

Begin { EnumExports }

pNameRVAs :=

RVAToPointer( DWORD(ExportDirectory.AddressOfNames), image );

pFunctionRVAs :=

RVAToPointer( DWORD(ExportDirectory.AddressOfFunctions), image );

pOrdinals :=

RVAToPointer( DWORD(ExportDirectory.AddressOfNameOrdinals), image );

For i:= 0 to Pred( ExportDirectory.NumberOfNames ) Do Begin

name := RVAToPChar( pNameRVAs^, image );

ordinal := pOrdinals^;

address := Pointer( pFunctionRVAs^[ ordinal ] );

If not callback( name, ordinal+ExportDirectory.Base, address ) Then

Exit;

End; { For }

End; { EnumExports }


{+----------------------------------------------------------------------

| Procedure ListDLLExports

|

| Parameters :

| filename : full pathname of DLL to examine

| callback : callback to hand the found exports to, must not be Nil

| Description:

| Loads the passed DLL using the LoadImage function, finds the exported

| names table and reads it. Each found entry is handed to the callback

| for further processing, until no more entries remain or the callback

| returns false. Note that the address passed to the callback for a

exported

| function is an RVA, so not identical to the address the function would

| have in a properly loaded and relocated DLL!

| Error Conditions:

| Exceptions are raised if

| - the passed DLL does not exist or could not be loaded

| - no callback was passed (only if assertions are on)

| - an API function failed

| Created: 9.1.2000 by P. Below

+----------------------------------------------------------------------}

Procedure ListDLLExports( const filename : String ; callback :

TDLLExportCallback ) ;

Var

imageinfo: LoadedImage;

pExportDirectory: PImageExportDirectory;

dirsize: Cardinal;

Begin { ListDLLExports }

Assert( Assigned( callback ));

If not FileExists( filename ) Then

raise DLLToolsError.CreateFmt( eDLLnotFound, [filename] );


If MapAndLoad( PChar( filename ), nil, @imageinfo, true, true ) Then

try

pExportDirectory :=

ImageDirectoryEntryToData(

imageinfo.MappedAddress, false,

IMAGE_DIRECTORY_ENTRY_EXPORT, dirsize );


If pExportDirectory = Nil Then

RaiseLastWin32Error

Else

EnumExports( pExportDirectory^, imageinfo, callback );

finally

UnMapAndLoad( @imageinfo );

end

Else

RaiseLastWin32Error;

End; { ListDLLExports }


{+----------------------------------------------------------------------

| Procedure DumpExportDirectory

|

| Parameters :

| ExportDirectory: a IMAGE_EXPORT_DIRECTORY record

| lines : a TStrings descendend to put the info into, must not be Nil

| Description:

| Dumps the fields of the passed structure to the passed strings

descendent

| as strings.

| Error Conditions:

| will raise an exception if lines is Nil and assertions are enabled.

| Created: 9.1.2000 by P. Below

+----------------------------------------------------------------------}

Procedure DumpExportDirectory( Const ExportDirectory : TImageExportDirectory;

lines : TStrings; const Image: LoadedImage ) ;

Begin { DumpExportDirectory }

Assert( Assigned( lines ));


lines.add( 'Dump of IMAGE_EXPORT_DIRECTORY' );

lines.add( format('Characteristics: %d',

[ExportDirectory.Characteristics]));

lines.add( format('TimeDateStamp: %d',

[ExportDirectory.TimeDateStamp]));

lines.add( format('Version: %d.%d',

[ExportDirectory.MajorVersion,

ExportDirectory.MinorVersion]));

lines.add( format('Name (RVA): %x',

[ExportDirectory.Name]));

lines.add( format('Name (translated): %s',

[RVAToPchar( ExportDirectory.name, Image )]));

lines.add( format('Base: %d',

[ExportDirectory.Base]));

lines.add( format('NumberOfFunctions: %d',

[ExportDirectory.NumberOfFunctions]));

lines.add( format('NumberOfNames: %d',

[ExportDirectory.NumberOfNames]));

lines.add( format('AddressOfFunctions (RVA): %p',

[Pointer(ExportDirectory.AddressOfFunctions)]));

lines.add( format('AddressOfNames (RVA): %p',

[Pointer(ExportDirectory.AddressOfNames)]));

lines.add( format('AddressOfNameOrdinals (RVA): %p',

[Pointer(ExportDirectory.AddressOfNameOrdinals)]));

End; { DumpExportDirectory }


{+----------------------------------------------------------------------

| Function RVAToPointer

|

| Parameters :

| rva : a relative virtual address to translate

| Image : LOADED_IMAGE structure for the image the RVA relates to

| Returns : translated address

| Description:

| Uses the ImageRVAToVA function to translate the RVA to a virtual

| address.

| Error Conditions:

| Will raise an exception if the translation failed

| Created: 9.1.2000 by P. Below

+----------------------------------------------------------------------}

Function RVAToPointer( rva : DWORD ; const Image : LoadedImage ) : Pointer;

var

pDummy: PImageSectionHeader;

Begin { RVAToPchar }

pDummy := nil;

Result :=

ImageRvaToVa( Image.FileHeader, Image.MappedAddress, rva,

pDummy );

If Result = Nil Then

RaiseLastWin32Error;

End; { RVAToPointer }


{+----------------------------------------------------------------------

| Function RVAToPchar

|

| Parameters :

| rva : a relative virtual address to translate

| Image : LOADED_IMAGE structure for the image the RVA relates to

| Returns : translated address

| Description:

| Uses the RVAToPointer function to translate the RVA to a virtual

| address. Note that we do not check that the address does indeed point

| to a zero-terminated string!

| Error Conditions:

| Will raise an exception if the translation failed

| Created: 9.1.2000 by P. Below

+----------------------------------------------------------------------}

Function RVAToPchar( rva : DWORD ; const Image : LoadedImage ) : PChar ;

Begin { RVAToPchar }

Result := RVAToPointer( rva, image );

End; { RVAToPchar }


end.

 
建议做成一个组件,那会有N多DD感谢你啊,DLLTOOLS是D自带的吗?
 
多人接受答案了。
 
顶部