LoadLibrary, SafeLoadLibrary。。单步执行,居然发现停留在这句不返回! ( 积分: 30 )

  • 主题发起人 主题发起人 linuxping
  • 开始时间 开始时间
L

linuxping

Unregistered / Unconfirmed
GUEST, unregistred user!
代码: HDLL := SafeLoadLibrary('E:/clam/TClamav.0.1.1/lib/'+ ClamDLL);
用HDLL := LoadLibrary('E:/clam/TClamav.0.1.1/lib/'+ ClamDLL); 也一样。。。
 
LoadLibrary的时候不要加路径,把路径加到环境变量中的Path下
 
下面是完整的代码:

unit libpclamav;

(*
As taken from clamav for windows package

Pascal DLL renamed to libpclamav.dll to avoid loading wrong dll version.
Pascal DLL compiled by Rene using minGW ** issues on bzip support **

Added support for dynamic loading


*)
{**************************************************************************}
{ Partial Delphi header for clamav.h }
{ Generated Date: 2004-10-09 }
{ Generated Time: 12:48:04 }
{ }
{**************************************************************************}

interface
uses
Windows,SysUtils;

type
PPChar=^PChar;

const
ClamDLL='cygclamav-2.dll';

CL_COUNT_PRECISION = 4096;
{+// return codes*/ }
CL_CLEAN = 0; {/* virus not found*/}
CL_VIRUS = 1; {/* virus found*/}
CL_EMAXREC = -100; {/* recursion level limit exceeded*/}
CL_EMAXSIZE = -101; {/* size limit exceeded*/}
CL_EMAXFILES = -102; {/* files limit exceeded*/}
CL_ERAR = -103; {/* rar handler error*/}
CL_EZIP = -104; {/* zip handler error*/}

CL_EGZIP= -105; { gzip handler error }
CL_EBZIP= -106; { bzip2 handler error }
CL_EOLE2= -107; { OLE2 handler error }
CL_EMSCOMP= -108; { MS Expand handler error }
CL_EMSCAB= -109; { MS CAB module error }
CL_EACCES= -110; { access denied }
CL_ENULLARG= -111; { null argument }
CL_ETMPFILE= -112; { tmpfile() failed }
CL_EFSYNC= -113; { fsync() failed }
CL_EMEM= -114; { memory allocation error }
CL_EOPEN= -115; { file open error }
CL_EMALFDB= -116; { malformed database }
CL_EPATSHORT= -117; { pattern too short }
CL_ETMPDIR= -118; { mkdir() failed }
CL_ECVD= -119; { not a CVD file (or broken) }
CL_ECVDEXTR= -120; { CVD extraction failure }
CL_EMD5= -121; { MD5 verification error }
CL_EDSIG= -122; { digital signature verification error }
CL_EIO= -123; { general I/O error }
CL_EFORMAT= -124; { bad format or broken file }
CL_ESUPPORT= -125; { not supported data format }
CL_ELOCKDB= -126; { can't lock DB directory }

CL_ENCINIT= -200;
CL_ENCIO= -202 ;

{/* db options */ }
CL_DB_NCORE= $1 ;
CL_DB_PHISHING= $2;
CL_DB_ACONLY= $4; {/* WARNING: only for developers */}
CL_DB_PHISHING_URLS= $8;

{/* recommended db settings */ }
CL_DB_STDOPT= CL_DB_PHISHING;

{/* scan options */ }
CL_SCAN_RAW= $0;
CL_SCAN_ARCHIVE= $1;
CL_SCAN_MAIL= $2;
CL_SCAN_OLE2= $4 ;
CL_SCAN_BLOCKENCRYPTED= $8;
CL_SCAN_HTML= $10;
CL_SCAN_PE= $20;
CL_SCAN_BLOCKBROKEN= $40 ;
CL_SCAN_MAILURL= $80 ;
CL_SCAN_BLOCKMAX= $100;
CL_SCAN_ALGORITHMIC= $200;
CL_SCAN_PHISHING_DOMAINLIST= $400;
CL_SCAN_PHISHING_BLOCKSSL= $800 ; {/* ssl mismatches, not ssl by itself*/ }
CL_SCAN_PHISHING_BLOCKCLOAK= $1000 ;
CL_SCAN_ELF= $2000 ;
CL_SCAN_PDF= $4000;

{/* recommended scan settings */ }
CL_SCAN_STDOPT= (CL_SCAN_ARCHIVE or CL_SCAN_MAIL or CL_SCAN_OLE2 or CL_SCAN_HTML or CL_SCAN_PE or CL_SCAN_ALGORITHMIC or CL_SCAN_ELF);

{/* aliases for backward compatibility */ }
CL_RAW= CL_SCAN_RAW;
CL_ARCHIVE =CL_SCAN_ARCHIVE;
CL_MAIL= CL_SCAN_MAIL;
CL_OLE2= CL_SCAN_OLE2 ;
CL_ENCRYPTED= CL_SCAN_BLOCKENCRYPTED;

type
PPcli_bm_patt=^Pcli_bm_patt;
Pcli_bm_patt = ^Tcli_bm_patt;
Tcli_bm_patt = record
pattern : PChar;
virname : PChar;
offset : PChar;
viralias : PChar;
length : Word ;
target : Word;
next : pcli_bm_patt;
end;
//struct cli_bm_patt {
// unsigned char *pattern;
// char *virname, *offset;
// const char *viralias;
// unsigned int length;
// unsigned short target;
// struct cli_bm_patt *next;
//}



Pcli_ac_patt = ^Tcli_ac_patt;
Tcli_ac_patt = record
pattern : PSmallInt;
length ,
mindist,
maxdist,
prefix_length : Word;
virname : PChar;
offset : PChar;
viralias : PChar;
sigid : Word;
parts : Word;
partno : Word;
alt : Word;
altn : PWord; //modified by linuxping
alt_pattern:Word; //modified by linuxping
typed : Word;
target : Word;
altc : PPChar; {unsigned char **altc;}
next : pcli_ac_patt;
end;

//struct cli_ac_patt {
// short int *pattern, *prefix;
// unsigned int length, mindist, maxdist, prefix_length;
// char *virname, *offset;
// const char *viralias;
// unsigned short int sigid, parts, partno, alt, *altn, alt_pattern;
// unsigned short type, target;
// unsigned char **altc;
// struct cli_ac_patt *next;
//}


PPcli_ac_node=^Pcli_ac_node;
Pcli_ac_node = ^Tcli_ac_node;
Tcli_ac_node = record
islast : Char;
list : pcli_ac_patt;
trans : array[0..255] of pcli_ac_node;
fail : pcli_ac_node;
end;
//struct cli_ac_node {
// unsigned char islast;
// struct cli_ac_patt *list;
// struct cli_ac_node *trans[256], *fail;
//};

PPcli_md5_node=^Pcli_md5_node;
Pcli_md5_node = ^Tcli_md5_node;
TCli_md5_node = record
virname : PChar;
viralias : PChar;
md5 : PChar;
size : Word ;
fp: Word;
next : pcli_md5_node;
end;
//struct cli_md5_node {
// char *virname, *viralias;
// unsigned char *md5;
// unsigned int size;
// unsigned short fp;
// struct cli_md5_node *next;
//};

Pcli_meta_node=^Tcli_meta_node;
Tcli_meta_node=record
csize, size, method:Integer;
crc32, fileno, encrypted, maxdepth:Word;
filename, virname:PChar;
next:Pcli_meta_node;
end;
//struct cli_meta_node {
// int csize, size, method;
// unsigned int crc32, fileno, encrypted, maxdepth;
// char *filename, *virname;
// struct cli_meta_node *next;
// }

PPcli_matcher=^Pcli_matcher;
Pcli_matcher=^Tcli_matcher;
Tcli_matcher=record
maxpatlen:Word;
ac_only: Word;

bm_shift:PInteger;
bm_suffix:PPcli_bm_patt;

ac_depth:Word;
ac_root:Pcli_ac_node;
ac_nodetable:PPcli_ac_node;
ac_partsigs, ac_nodes:Word;
end;
//struct cli_matcher {
// unsigned int maxpatlen; /* maximal length of pattern in db */
// unsigned short ac_only;
//
// /* Extended Boyer-Moore */
// int *bm_shift;
// struct cli_bm_patt **bm_suffix;
//
// /* Extended Aho-Corasick */
// unsigned int ac_depth;
// struct cli_ac_node *ac_root, **ac_nodetable;
// unsigned int ac_partsigs, ac_nodes;
//}

Pcl_engine=^Tcl_engine;
Tcl_engine=record
refcount:Word;
ncore,
sdb: word;
dboptions: Word;

{/* Roots table */}
root:PPcli_matcher;

{/* MD5 */}
md5_hlist:PPcli_md5_node;

{/* MD5 list for PE sections */}
md5_sect:Pcli_md5_node;

{/* Zip metadata */}
zip_mlist:pcli_meta_node;

{/* RAR metadata */}
rar_mlist:Pcli_meta_node;

{ /* NodalCore database handle */}
ncdb:Pointer;

{ /* Phishing .pdb and .wdb databases*/}
whitelist_matcher,domainlist_matcher,phishcheck,
{/* Dynamic configuration */}
dconf:Pointer;
end;

//struct cl_engine {
// unsigned int refcount; /* reference counter */
// unsigned short ncore;
// unsigned short sdb;
// unsigned int dboptions;
//
// /* Roots table */
// struct cli_matcher **root;
//
// /* MD5 */
// struct cli_md5_node **md5_hlist;
//
// /* MD5 list for PE sections */
// struct cli_md5_node *md5_sect;
//
// /* Zip metadata */
// struct cli_meta_node *zip_mlist;
//
// /* RAR metadata */
// struct cli_meta_node *rar_mlist;
//
// /* NodalCore database handle */
// void *ncdb;
//
// /* Phishing .pdb and .wdb databases*/
// void *whitelist_matcher;
// void *domainlist_matcher;
// void *phishcheck;
//
// /* Dynamic configuration */
// void *dconf;
// };


Pcl_limits = ^Tcl_limits;
Tcl_limits = record
maxreclevel: Word;
maxfiles: Word;

maxmailrec,
maxratio: Word;
archivememlim: Word;
maxfilesize: LongInt;
end;
//struct cl_limits {
// unsigned int maxreclevel; /* maximum recursion level for archives */
// unsigned int maxfiles; /* maximum number of files to be scanned
// * within a single archive
// */
// unsigned int maxmailrec; /* maximum recursion level for mail files */
// unsigned int maxratio; /* maximum compression ratio */
// unsigned short archivememlim; /* limit memory usage for some unpackers */
// unsigned long int maxfilesize; /* compressed files larger than this limit
// * will not be scanned
// */
//};

//struct stat {
// _dev_t st_dev;
// _ino_t st_ino;
// unsigned short st_mode;
// short st_nlink;
// short st_uid;
// short st_gid;
// _dev_t st_rdev;
// _off_t st_size;
// time_t st_atime;
// time_t st_mtime;
// time_t st_ctime;
// };


{ PStat=TStat;
TStat=record
_dev_t:

end; }

{
struct cl_stat {
char *dir;
unsigned int entries;
struct stat *stattab;
char **statdname;
}

{ Tcl_stat=record
dir:PChar;
entries:Cardinal;
stattab:Pstat
statdname:PPchar;
end; }

Pcl_cvd = ^Tcl_cvd;
Tcl_cvd = record
time: PChar;
version,
sigs,
fl:Word;
md5: PChar;
dsig: PChar;
builder: PChar;
stime: Word;
end;
//struct cl_cvd { /* field no. */
// char *time; /* 2 */
// unsigned int version; /* 3 */
// unsigned int sigs; /* 4 */
// unsigned int fl; /* 5 */
// char *md5; /* 6 */
// char *dsig; /* 7 */
// char *builder; /* 8 */
// unsigned int stime; /* 9 */
//};

// scan memory buffer
// TClam_scanbuff=function (const buffer: PChar;
// length: integer;
// const virname: PChar;
// root : Pointer): Integer ; cdecl;
//


//scan file
{extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned,
const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options);}
TClam_scanfile=function (const filename: PChar;
const virname: PChar;
var scanned: Cardinal;
var engine : Tcl_engine;
limits: pcl_limits;
options: Word ): Integer ; cdecl;

{extern int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, unsigned int options);}
TClam_load=function (const path:PChar; var engine: Pcl_engine;var signo:PWORD;options:Word ):Integer;cdecl;

{extern const char *cl_retdbdir(void);}
TClam_retdbdir=function :PChar;cdecl;

{extern struct cl_engine *cl_dup(struct cl_engine *engine);}

{/* CVD */
extern struct cl_cvd *cl_cvdhead(const char *file);
extern struct cl_cvd *cl_cvdparse(const char *head);
extern void cl_cvdfree(struct cl_cvd *cvd);
}


{
/* db dir stat functions */
extern int cl_statinidir(const char *dirname, struct cl_stat *dbstat);
extern int cl_statchkdir(const struct cl_stat *dbstat);
extern int cl_statfree(struct cl_stat *dbstat);
}

{
/* others */
extern void cl_settempdir(const char *dir, short leavetemps);
}


//scan file descriptor (open handle to file)
{extern int cl_scandesc(int desc, const char **virname, unsigned long int *scanned,
const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options);}
TClam_scandesc=function (desc : integer;
const virname: PChar;
var scanned: Cardinal;
var engine : Tcl_engine;
limits: pcl_limits;
options: Word): Integer ; cdecl;

// /* software versions */
// extern unsigned int cl_retflevel(void);
// extern const char *cl_retver(void);
TClam_retflevel=function : Word ; cdecl;
TClam_retver=function : PChar ; cdecl;


// /* enable debug messages */
// extern void cl_debug(void);
TClam_debug = procedure; cdecl;
{extern int cl_build(struct cl_engine *engine);}
TClam_build=function (var engine : Tcl_engine) : integer ; cdecl;
{extern void cl_free(struct cl_engine *engine);}
TClam_free=procedure (var engine : Tcl_engine) ; cdecl;

// extern const char *cl_retdbdir(void);}
// {
// int cl_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo) {
// return cli_loaddbdir(dirname, engine, signo, CL_DB_STDOPT);
// }
TClam_loaddbdir=function (const dirname: PChar; var cl_engine:Pcl_engine;
var signo: Pword{;var errcode : Integer}): Integer ; cdecl;

{
int cl_loaddb(const char *filename, struct cl_engine **engine, unsigned int *signo) {
return cli_load(filename, engine, signo, CL_DB_STDOPT);
}
TClam_loaddb=function (const filename: PChar; var cl_engine:Pcl_engine;
var signo:Pword{;var errcode: Integer}): Integer ; cdecl;

{ extern int cl_cvdverify(const char *file); }
TClam_cvdverify=function (const filename : PChar) : integer ; cdecl;

{ extern const char *cl_strerror(int clerror);}
TClam_strerror=function (clerror : integer) : PChar ; cdecl;



cl_node= Tcl_engine;
cl_perror= TClam_strerror;


var
//Clam_scanbuff : TClam_scanbuff;
Clam_scanfile : TClam_scanfile;
Clam_scandesc : TClam_scandesc;
Clam_retflevel : TClam_retflevel;
Clam_retver : TClam_retver;
Clam_strerror : TClam_strerror;
Clam_debug : TClam_debug;
Clam_build : TClam_build;
Clam_free : TClam_free;
Clam_loaddbdir : TClam_loaddbdir;
Clam_loaddb : TClam_loaddb;
Clam_cvdverify : TClam_cvdverify;

Clam_load:TClam_load;
Clam_retdbdir:TClam_retdbdir;

function LoadClamavDLL: Boolean;

implementation

var
LibLoaded: Boolean = False;
HDLL: THandle=0;

function LoadClamavDLL: Boolean;
var Loaded: Boolean;

function ProcAddress (Proc: String): Pointer;
begin
{$IFNDEF FPC}
Result := GetProcAddress (HDLL, PChar(Proc));
{$ELSE}
Result := GetProcedureAddress (HDLL, PChar(Proc)); //verify this call (it's not correct now).
{$ENDIF}
if not Assigned(Result) then
Loaded := False;
end;

begin
Result := LibLoaded;
if Result then
exit;
if HDLL = 0 then
begin
HDLL := SafeLoadLibrary(PAnsiChar(ClamDLL+#0));
if HDLL <> 0 then
begin
Loaded := True;
//Clam_scanbuff := ProcAddress ('clam_scanbuff');
Clam_scanfile := ProcAddress ('cl_scanfile');
Clam_scandesc := ProcAddress ('cl_scandesc');
Clam_retflevel := ProcAddress ('cl_retflevel');
Clam_retver := ProcAddress ('cl_retver');
Clam_strerror := ProcAddress ('cl_strerror');
Clam_debug := ProcAddress ('cl_debug');
Clam_build := ProcAddress ('cl_build');
Clam_free := ProcAddress ('cl_free');
Clam_loaddbdir := ProcAddress ('cl_loaddbdir');
Clam_loaddb := ProcAddress ('cl_loaddb');
Clam_cvdverify := ProcAddress ('cl_cvdverify');
Clam_load := ProcAddress ('cl_load');
Clam_retdbdir:= ProcAddress ('cl_retdbdir');
LibLoaded := Loaded;
Result := LibLoaded;
if not Result then
begin
FreeLibrary (HDLL);
HDLL := 0;
end;
end;
end;
end;

end.
 
dll在应用程序目录下..我不加路径也是这样...所以我加个路径...结果依然是这样~~
 
LoadLobirary 文档是这样写的(加个路径也行啊):

If the string specifies a path but the file does not exist in the specified directory, the function fails.

When no path is specified, the function searches for the file in the following sequence:

1. The directory from which the application loaded.
2. The current directory.
3. Windows 95: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

4. Windows NT: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
6. The directories that are listed in the PATH environment variable.
 
高手指点一下~~ 确实迷茫~~~

这是在Dll中LoadLibrary另外一个Dll,难道与这有关~~ 迷茫啊~~~
 
找到了 <windows高级编程>上这样说:

"注意必须记住,D L L使用D l l M a i n函数来对它们进行初始化。当你的D l l M a i n函数执行时,同一个地址空间中的其他D L L可能尚未执行它们的D l l M a i n函数。这意味着它们尚未初始化,因此你应该避免调用从其他D L L中输入的函数。此外,你应该避免从D l l M a i n内部调用L o a d L i b r a r y ( E x )和F r e e L i b r a r y函数,因为这些函数会形式一个依赖性循环。"
"Platform SDK文档说,你的D l l M a i n函数只应该进行一些简单的初始化,比如设置本地存储器(第2 1章介绍),创建内核对象和打开文件等。你还必须避免调用U s e r、S h e l l、O D B C、C O M、R P C和套接字函数(即调用这些函数的函数),因为它们的D L L也许尚未初始化,或者这些函数可能在内部调用L o a d L i b r a r y ( E x )函数,这同样会形成一个依赖性循环。

另外,如果创建全局性的或静态的C + +对象,那么应该注意可能存在同样的问题,因为在你调用D l l M a i n函数的同时,这些对象的构造函数和析构函数也会被调用。
"

那么我想在一个DLL中调用另一个DLL,该怎么做啊?
 
后退
顶部