当先锋百科网

首页 1 2 3 4 5 6 7

Delphi中编写无输出函数名的DLL文件

用 Delphi 用长了,总是发现,有些和 MS 不同的地方。例如,MS 的公开库中,常常隐藏了许多重要函数,这些函数在系统中常常有起着非常巨大的作用。一旦知道如何调用,可以给自己的应用程序提供很强的功能和很大的灵活性。但,这些函数通常又没有函数名(即使用 ExeScope 查看 DLL 文件的导出表也看不出函数意义),仅仅只有一个序号来表示。有时候我又自己想,为什么我在写程序的时候不能学学 MS 隐藏一些自己不希望公开的函数呢?
 其实用 Delphi 写 DLL 的时候,使用简单的技巧就可以实现隐藏函数名的效果。让我们来看看下面这个 DLL 源码:
library  proDll;
  uses
  Windows;
  { $R *.res }
  procedure  ShowMessageA(hWnd: HWND);  stdcall ;
begin
  MessageBox(hWnd,  ' 您调用的是 ShowMessageA 函数 ' ,  ' DLL 函数信息 ' ,
    MB_ICONINFORMATION);
end ;
  procedure  ShowMessageB(hWnd: HWND);  stdcall ;
begin
  MessageBox(hWnd,  ' 您调用的是 ShowMessageB 函数 ' ,  ' DLL 函数信息 ' ,
    MB_ICONINFORMATION);
end ;
  exports
  ShowMessageA index  1  name  '' ,
  ShowMessageB index  2  name  '' ;
  begin
end .

 

注意看 exports 部分,用 index 关键字指定输出函数的序号,后面紧跟一个 name 关键字指明输出函数名称。关键就在这里,name 后面是一个空字符串,这样就给函数生成了一个空字符串名。实际效果既是隐藏了输出函数的名称。是不是很容易呢?
 那么我们怎样调用这样的输出函数呢?由于没有了函数名,我们调用起来会显得和以前不一样。其实也不用担心,调用同样非常简单。我下面就静态调用和动态调用制作了两个工程,源码如下:
 静态调用例子:
unit  Unit1;
  interface
  uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
  type
  TForm1  =   class (TForm)
    Button1: TButton;
    Button2: TButton;
     procedure  Button1Click(Sender: TObject);
     procedure  Button2Click(Sender: TObject);
   private
     {  Private declarations  }
   public
     {  Public declarations  }
   end ;
  var
  Form1: TForm1;
  implementation
  { $R *.dfm }
  procedure  ShowMessageA(hWnd: HWND);  stdcall ;  external   ' proDll.dll '  index  1 ;
procedure  ShowMessageB(hWnd: HWND);  stdcall ;  external   ' proDll.dll '  index  2 ;
  procedure  TForm1.Button1Click(Sender: TObject);
begin
  ShowMessageA(Handle);
end ;
  procedure  TForm1.Button2Click(Sender: TObject);
begin
  ShowMessageB(Handle);
end ;
  end .

 

动态调用的例子:
unit  Unit2;
  interface
  uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
  type
  TForm2  =   class (TForm)
    Button1: TButton;
    Button2: TButton;
     procedure  Button1Click(Sender: TObject);
     procedure  Button2Click(Sender: TObject);
   private
     {  Private declarations  }
   public
     {  Public declarations  }
   end ;
  var
  Form2: TForm2;
  implementation
  { $R *.dfm }
  type
  TDllShowMessageFunc  =   procedure  (hWnd: HWND);  stdcall ;
  var
  hDllHandle: THandle;
  ShowMessageA, ShowMessageB: TDllShowMessageFunc;
  procedure  LoadFuncDll;
begin
   if  hDllHandle  =   0   then
   begin
    hDllHandle : =  LoadLibrary( ' proDll.dll ' );
     if  hDllHandle  =   0   then
       raise  Exception.Create( ' proDll.dll 加载失败 ' );
     try
       {
      lpProcName: the second argument of function GetProcAddress
        Points to a null-terminated string containing the function name,
        or specifies the function's ordinal value. If this parameter is
        an ordinal value, it must be in the low-order word; the high-order
        word must be zero.
       }
      @ShowMessageA : =  GetProcAddress(hDllHandle, Pointer(HiWord( 0 )  or  LoWord( 1 )));
       if  @ShowMessageA  =   nil   then
         raise  Exception.Create( ' proDll.dll 中没有输出 ShowMessageA 函数 ' );
      @ShowMessageB : =  GetProcAddress(hDllHandle, Pointer(HiWord( 0 )  or  LoWord( 2 )));
       if  @ShowMessageB  =   nil   then
         raise  Exception.Create( ' proDll.dll 中没有输出 ShowMessageB 函数 ' );
     except
      FreeLibrary(hDllHandle);
      hDllHandle : =   0 ;
       raise ;
     end ;
   end ;
end ;
  procedure  FreeFuncDll;
begin
   if  hDllHandle  <>   0   then
   begin
    FreeLibrary(hDllHandle);
    hDllHandle : =   0 ;
    @ShowMessageA : =   nil ;
    @ShowMessageB : =   nil ;
   end ;
end ;
  procedure  TForm2.Button1Click(Sender: TObject);
begin
   if  @ShowMessageA  =   nil   then  LoadFuncDll;
  ShowMessageA(Handle);
end ;
  procedure  TForm2.Button2Click(Sender: TObject);
begin
   if  @ShowMessageB  =   nil   then  LoadFuncDll;
  ShowMessageB(Handle);
end ;
  initialization
   //   do  nothing
finalization
  FreeFuncDll;
end .

 




转载于:https://www.cnblogs.com/rogee/archive/2010/09/15/1827283.html