在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
其实用 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.
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论