博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Delphi中编写无输出函数名的DLL文件
阅读量:7060 次
发布时间:2019-06-28

本文共 3561 字,大约阅读时间需要 11 分钟。

用 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

你可能感兴趣的文章
WebService基础介绍
查看>>
jdbc的使用
查看>>
云计算概念--公有云和私有云介绍
查看>>
托管代码
查看>>
Glusterfs hacker guide(三)
查看>>
谈epoll与高性能
查看>>
验证下载文件
查看>>
python输出%
查看>>
Json字符串转换为java对象的各种实现方法【json_lib框架、Gson、org.json】
查看>>
Cesium官方教程8-- 几何体和外观效果
查看>>
《×××颂》突破了千年国画技艺的难点
查看>>
Oracle 等待事件之 db file sequential read
查看>>
LoadRunner启动自带例子Web Tours报错
查看>>
致血气方刚的产品经理:如何不被程序员嫌弃
查看>>
导出文件名带时间信息的dmp文件
查看>>
zencart简单设置分类链接不同css样式
查看>>
4、移植三星官方内核
查看>>
jsp页面中jstl标签详解[转]
查看>>
linux下配置jdk+tomcat
查看>>
codeforce div 377
查看>>