Dll问题(100分)

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

landina

Unregistered / Unconfirmed
GUEST, unregistred user!
我在动态连接库中使用FreeMem(p)时,系统提示无效的指针操作,为什么?
 
source code?
 
以下是128位加密算法:

unit uSecurity;

interface

uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;


procedure code;
Procedure Assemble;
procedure Crypt(var ThisCle, Buffer: PChar; BufferLength: Integer);
Procedure Decrypt(var ThisCle, Buffer: PChar; BufferLength: Integer);
function EnCode(var Source,Key:String):String;stdcall;
function DeCode(var Source,Key:String):String;stdcall;


var
ax,bx,cx,dx,si,tmp,x1a2,res,i,inter,cfc,cfd,compte,j,k,l : Word;
x1a0 : array[0..7] of Word;
cle : array[0..15] of char;
cry: array[0..33000] of char;
newkey : string;

implementation

{ TSecurity }

procedure Assemble;
begin
x1a0[0]:= ( ord(cle[0])*256 ) + ord(cle[1]);
code;
inter:= res;

x1a0[1]:= x1a0[0] xor ( (ord(cle[2])*256) + ord(cle[3]) );
code;
inter:= inter xor res;

x1a0[2]:= x1a0[1] xor ( (ord(cle[4])*256) + ord(cle[5]) );
code;
inter:= inter xor res;

x1a0[3]:= x1a0[2] xor ( (ord(cle[6])*256) + ord(cle[7]) );
code;
inter:= inter xor res;

x1a0[4]:= x1a0[3] xor ( (ord(cle[8])*256) + ord(cle[9]) );
code;
inter:= inter xor res;

x1a0[5]:= x1a0[4] xor ( (ord(cle[10])*256) + ord(cle[11]) );
code;
inter:= inter xor res;

x1a0[6]:= x1a0[5] xor ( (ord(cle[12])*256) + ord(cle[13]) );
code;
inter:= inter xor res;

x1a0[7]:= x1a0[6] xor ( (ord(cle[14])*256) + ord(cle[15]) );
code;
inter:= inter xor res;

i:= 0;
end;

procedure code;
begin
dx:= x1a2+i;
ax:= x1a0;
cx:= $015a;
bx:= $4e35;
tmp:= ax;
ax:= si;
si:= tmp;
tmp:= ax;
ax:= dx;
dx:= tmp;
if (ax <> 0) then ax:= ax*bx;
tmp:= ax;
ax:= cx;
cx:= tmp;
if (ax <> 0) then
begin
ax:= ax*si;
cx:= ax+cx;
end;
tmp:= ax;
ax:= si;
si:= tmp;
ax:= ax*bx;
dx:= cx+dx;
ax:= ax+1;
x1a2:= dx;
x1a0:= ax;
res:= ax xor dx;
i:= i+1;
end;

procedure Crypt(var ThisCle, Buffer: PChar;
BufferLength: Integer);
var
Rep: Char;
c, d, e: Byte;
begin
// Some initializations
ZeroMemory(@Cry, SizeOf(Cry));
ZeroMemory(@Cle, SizeOf(Cle));
StrCopy(Cle, ThisCle);
si:=0;
x1a2:=0;
i:=0;

for j:=0 to BufferLength-1 do begin
c:= ord(Buffer[j]); { c = first byte to crypt}
Assemble;
cfc:= inter shr 8;
cfd:= inter and 255;
for compte:= 0 to 15 do
cle[compte]:= chr(ord(cle[compte]) xor c);
c:= c xor (cfc xor cfd);

d:= c shr 4; e:= c and 15;
Case d of
0 : rep:= 'a';
1 : rep:= 'b';
2 : rep:= 'c';
3 : rep:= 'd';
4 : rep:= 'e';
5 : rep:= 'f';
6 : rep:= 'g';
7 : rep:= 'h';
8 : rep:= 'i';
9 : rep:= 'j';
10: rep:= 'k';
11: rep:= 'l';
12: rep:= 'm';
13: rep:= 'n';
14: rep:= 'o';
15: rep:= 'p';
end;
cry[j*2]:=rep; // contains the first letter
// shorter: cry[j*2]:=Char($61+d); // "case" and "rep" no longer needed


Case e of
0 : rep:= 'a';
1 : rep:= 'b';
2 : rep:= 'c';
3 : rep:= 'd';
4 : rep:= 'e';
5 : rep:= 'f';
6 : rep:= 'g';
7 : rep:= 'h';
8 : rep:= 'i';
9 : rep:= 'j';
10: rep:= 'k';
11: rep:= 'l';
12: rep:= 'm';
13: rep:= 'n';
14: rep:= 'o';
15: rep:= 'p';
end;
cry[j*2+1]:=rep; // contains here the second letter
// shorter: cry[j*2+1]:=Char($61+e); // "case" and "rep" no longer needed
end;
end;

function DeCode(var Source, Key: String): String;
var
Buf : PChar;
Bufkey : Pchar;
keysize : Integer;
Size : Integer;
begin
Size := length(Source);
if (Size=0) then
begin
result := '';
exit;
end;
keysize := length(Key);
if (keysize=0) then
begin
messagedlg('请输入长度不能大于16个字符的加密字符串!',mtwarning,[mbOK],0);
result := '';
exit;
end;
GetMem(buf, Size+1);
Buf := pchar(Source+#0);
GetMem(Bufkey,keysize+1);
Bufkey := pchar(Key + #0);

if (keysize>16) Then
begin
showmessage('加密字符串的长度不能大于16个字符!');
FreeMem(Buf);
FreeMem(Bufkey);
result := '';
end
else
begin
decrypt(Bufkey, buf, Size);
// FreeMem(buf);
// FreeMem(Bufkey);
result := string(Cry);
end;
end;

procedure Decrypt(var ThisCle, Buffer: PChar;
BufferLength: Integer);
var
Rep: Char;
c, d, e: Byte;
begin
// Some initializations
ZeroMemory(@Cry, SizeOf(Cry));
ZeroMemory(@Cle, SizeOf(Cle));
StrCopy(Cle, ThisCle);
si:=0;
x1a2:=0;
i:=0;
j:=0;
l:=0;

while j<BufferLength-1 do begin
//(j:=0 to BufferLength-1 do begin

rep:= Buffer[j];
case rep of
'a' : d:= 0;
'b' : d:= 1;
'c' : d:= 2;
'd' : d:= 3;
'e' : d:= 4;
'f' : d:= 5;
'g' : d:= 6;
'h' : d:= 7;
'i' : d:= 8;
'j' : d:= 9;
'k' : d:= 10;
'l' : d:= 11;
'm' : d:= 12;
'n' : d:= 13;
'o' : d:= 14;
'p' : d:= 15;
end;

d:= d shl 4;
j:=j+1;

rep:= Buffer[j]; { rep = second letter }
Case rep of
'a' : e:= 0;
'b' : e:= 1;
'c' : e:= 2;
'd' : e:= 3;
'e' : e:= 4;
'f' : e:= 5;
'g' : e:= 6;
'h' : e:= 7;
'i' : e:= 8;
'j' : e:= 9;
'k' : e:= 10;
'l' : e:= 11;
'm' : e:= 12;
'n' : e:= 13;
'o' : e:= 14;
'p' : e:= 15;
end;
c:= d + e;
Assemble;
cfc:= inter shr 8;
cfd:= inter and 255;

c:= c xor (cfc xor cfd);

for compte:= 0 to 15 do
cle[compte]:= chr(ord(cle[compte]) xor c);

// Note : c contains the decrypted byte
cry[l]:=chr(c);
j:=j+1;
l:=l+1;
end;

end;
function EnCode(var Source, Key: String): String;
var
Buf : PChar;
Bufkey : Pchar;
keysize : Integer;
Size : Integer;
begin
Size := length(Source);
if (Size=0) then exit;
keysize := length(Key);
if (keysize=0) then
begin
messagedlg('请输入长度不能大于16个字符的加密字符串!',mtwarning,[mbOK],0);
result := '';
exit;
end;
GetMem(buf, Size+1);
buf := pchar(Source+#0);
GetMem(Bufkey,keysize+1);
Bufkey := pchar(Key + #0);

if (keysize>16) Then
begin
showmessage('加密字符串的长度不能大于16个字符!');
Dispose(Buf);
Dispose(Bufkey);
result := '';
end
else
begin
crypt(Bufkey, buf, Size);
// FreeMem(buf);
// FreeMem(Bufkey);
result := string(Cry);
end;
end;
exports
EnCode,
DeCode;
end.
 
以上加密、解密的结果都正确,只是// FreeMem(buf);时有错
 
给我一个信箱,我这里有个调用dll加密解密的例子。你看看这个例子吧!
 
你FreeMem的位置不对吧?
应该与GetMem对应的。
检查一下了。
 
error info?
 
发了!你看看吧!好像没那么复杂!
 
to:卷起千堆雪tyn
FreeMem的位置改变后,发生一样的错误!!!

to:taozhiyu
Application Error Message:Exception EInvalidPointer in module Security.dll at 00002740!
 
会不会是那个dll里面的问题哦!他是否附带例子?例子成功了?

我给你的有例子,可以用的!而且加密的范围很广!
 
有例子,运行正常,我只是想把他改成DLL
 
把你的那个东西发给我看看 taozhiyu@21cn.com
 
我用我发给你的这个写了一个的,好像没什么问题。
 
你那是严重错误,谁写的,那么没水平:
GetMem(buf, Size+1);
Buf := pchar(Source+#0);
GetMem(Bufkey,keysize+1);
Bufkey := pchar(Key + #0);
---------------------------------------
2个错误一样的,挑一个来说:
GetMem(buf, Size+1);
buf就分配了内存了,他现在的值指向的就是刚刚getmem得到的内存,也是后面要freemem的
可是接着:Buf := pchar(Source+#0); buf赋了别的值,指向了别的内存,后面就freemem错了地址
这里不应该是 := ,而是应该把Source的字符串拷贝到buf的内存才对的,或者如果你的
程序如果能正常使用,还保持 := ,那么根本不需要getmem,也就不需要freemem了
本来,按照严格的写法,Buf := pchar(Source+#0) 后面内存会出错的,Buf := pchar(Source)就不会,
为什么,和本题无关,不多说了
另外,用了getmem,那么用 StrCopy 拷贝罗
 
多人接受答案了。
 
后退
顶部