zoukankan      html  css  js  c++  java
  • Delphi中编写无输出函数名的DLL文件(有点意思)(400多篇博客)

    用 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 .

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aroc_lo/archive/2010/07/27/5769801.aspx

  • 相关阅读:
    Delphi 正则表达式之TPerlRegEx 类的属性与方法(3): Start、Stop
    Delphi 正则表达式之TPerlRegEx 类的属性与方法(2): 关于子表达式
    Delphi 正则表达式之TPerlRegEx 类的属性与方法(1): 查找
    Delphi 正则表达式语法(10): 选项
    Delphi 正则表达式语法(9): 临界匹配
    Delphi 正则表达式语法(8): 引用子表达式
    Delphi 正则表达式语法(7): 匹配转义字符
    看阿里P7讲MyBatis:从MyBatis的理解以及配置和实现全帮你搞懂
    公司新来的小姐姐不懂java中的static关键字,这样给她描述不香吗?
    2020阿里,字节跳动,JAVA岗(一线企业校招、社招)面试题合集
  • 原文地址:https://www.cnblogs.com/findumars/p/5345741.html
Copyright © 2011-2022 走看看