我遇到了在线发现的Delphi 7字符串解码器功能(“Decrypt”)的问题。它需要一个字符串和1到120之间的四个数值来解码它。将该函数放在可执行文件中并运行它可以很好地工作。但是,我想在DLL中运行它。我正在使用额外的函数从调用任务接收必要的值,并从那里调用解密函数。出于某种原因,我无法将手指放在上面,每次dll调用解密函数时,主机应用程序都会崩溃。在过去的几个小时里,我一直在尝试一切可以让它发挥作用,但没有成功。我是Delphi和Pascal的新手,所以我可能只是忽略了一些明显的东西。无论哪种方式,我都输了。任何帮助将不胜感激。
编辑:这是崩溃时弹出的Windows错误:
Fault Module Name: StackHash_0a9e
Fault Module Version: 0.0.0.0
Fault Module Timestamp: 00000000
Exception Code: c0000005
Exception Offset: 00000000
OS Version: 6.1.7600.2.0.0.256.1
Locale ID: 1031
Additional Information 1: 0a9e
Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
Additional Information 3: 0a9e
Additional Information 4: 0a9e372d3b4ad19135b953a78882e789
这是我使用的代码:
library decrypt_test_dll;
uses
SysUtils,
Classes,
Dialogs;
{$R *.res}
function callfunction(externalstring, value1, value2, value3, value4: PAnsiChar):integer; cdecl;
var
convkey1, convkey2, convkey3, convkey4 : string;
convstring, decodedstring : string;
Decrypt : function(Text : string; Key1, Key2, Key3, Key4 : Integer) : string;
begin
convkey1 := value1;
convkey2 := value2;
convkey3 := value3;
convkey4 := value4;
convstring := externalstring;
decodedstring := Decrypt(externalstring, strtoint(convkey1), strtoint(convkey2), strtoint(convkey3), strtoint(convkey4));
showmessage(decodedstring);
end;
function Decrypt(Text : string; Key1, Key2, Key3, Key4 : Integer) : string;
var
BufS, Hexa1, Hexa2 : string;
BufI, BufI2, Divzr, Sc, Sl, Num1, Num2, Num3, Num4, Res1, Res2, Res3, Res4 : Integer;
begin
showmessage('within decryption function');
Sl := Length(Text);
Sc := 0;
BufS := '';
if (Key1 in [1 .. 120]) and (Key2 in [1 .. 120]) and (Key3 in [1 .. 120]) and (Key4 in [1 .. 120]) then
begin
Divzr := Key1 * Key4;
BufI2 := Key3 * Key2;
Divzr := Divzr - BufI2;
if Divzr = 0 then
begin
Result := '';
Exit;
end;
end
else
begin
Result := '';
Exit;
end;
repeat
for BufI := 1 to 4 do
begin
Inc(Sc);
Hexa1 := IntToHex(Ord(Text[Sc]), 2);
Inc(Sc);
Hexa2 := IntToHex(Ord(Text[Sc]), 2);
if Hexa1 = 'FF' then
begin
Hexa1 := '00';
Hexa2 := '00';
end;
if Hexa1 = 'FE' then Hexa1 := '00';
if Hexa1 = 'FD' then
begin
Hexa1 := Hexa2;
Hexa2 := '00';
end;
case BufI of
1 : Res1 := StrToInt('$' + Hexa1 + Hexa2);
2 : Res2 := StrToInt('$' + Hexa1 + Hexa2);
3 : Res3 := StrToInt('$' + Hexa1 + Hexa2);
4 : Res4 := StrToInt('$' + Hexa1 + Hexa2);
end;
end;
BufI := Res1 * Key4;
BufI2 := Res2 * Key3;
Num1 := BufI - BufI2;
Num1 := Num1 div Divzr;
BufI := Res2 * Key1;
BufI2 := Res1 * Key2;
Num2 := BufI - BufI2;
Num2 := Num2 div Divzr;
BufI := Res3 * Key4;
BufI2 := Res4 * Key3;
Num3 := BufI - BufI2;
Num3 := Num3 div Divzr;
BufI := Res4 * Key1;
BufI2 := Res3 * Key2;
Num4 := BufI - BufI2;
Num4 := Num4 div Divzr;
BufS := BufS + Chr(Num1) + Chr(Num2) + Chr(Num3) + Chr(Num4);
until Sc >= Sl;
Result := BufS;
end;
exports
Decrypt index 1,
callfunction index 2;
begin
end.
答案 0 :(得分:5)
这段代码都错了:
function callfunction(externalstring, value1, value2, value3, value4: PAnsiChar):integer; cdecl;
var
convkey1, convkey2, convkey3, convkey4 : string;
convstring, decodedstring : string;
Decrypt : function(Text : string; Key1, Key2, Key3, Key4 : Integer) : string;
begin
convkey1 := value1;
convkey2 := value2;
convkey3 := value3;
convkey4 := value4;
convstring := externalstring;
decodedstring := Decrypt(externalstring, strtoint(convkey1), strtoint(convkey2), strtoint(convkey3), strtoint(convkey4));
showmessage(decodedstring);
end;
永远不会分配局部变量Decrypt
。因此,当您致电Decrypt
时,任何事情都可能发生。您需要将callfunction
移到设备底部,以便它显示在真实Decrypt
之后。您需要删除函数指针变量。
function callfunction(externalstring, value1, value2, value3, value4: PAnsiChar):integer; cdecl;
var
convkey1, convkey2, convkey3, convkey4 : string;
convstring, decodedstring : string;
begin
convkey1 := value1;
convkey2 := value2;
convkey3 := value3;
convkey4 := value4;
convstring := externalstring;
decodedstring := Decrypt(externalstring, strtoint(convkey1), strtoint(convkey2), strtoint(convkey3), strtoint(convkey4));
showmessage(decodedstring);
end;
您也不应在导出的DLL函数中使用string
作为参数(或实际上是返回值)。它不是interop的有效类型,因为它依赖于使用相同string
实现的接口的两侧以及相同的内存管理器。如果要导出它,则需要找到另一种定义Decrypt
接口的方法。或者您可能根本不应该导出该功能。我无法确切地知道。我的猜测是你实际上是在调用代码中调用callfunction
而不是Decrypt
。无论如何,在当前状态下,您不得导出Decrypt
。
要做的另一点。当您提出涉及模块界面的问题时,应始终显示界面的两侧。这里显示了DLL,但没有显示调用DLL的代码。错误可能存在。实际上,除了我指出的错误之外,还可能存在错误。
答案 1 :(得分:0)
如果字符串操作代码如exe中所示但不是来自DLL,则检查DLL是否具有delphi内存管理器,因为FIRST使用项目。
uses
ShareMem
这在Dephi exe中是隐含的,但不在其DLL中。
这总是Delphi 6 DLL和字符串最喜欢的问题,不能说它是否仍然适用于Delphi 7!