2

我在网上找到的 Delphi 7 字符串解码器函数(“解密”)有问题。它需要一个字符串和 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.
4

2 回答 2

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;

您也不应该string在导出的 DLL 函数中用作参数(或者实际上是返回值)。string它不是互操作的有效类型,因为它依赖于使用相同实现和相同内存管理器的接口两侧。Decrypt如果要导出接口,您需要找到一种不同的方式来定义接口。或者您可能根本不应该导出该函数。我不可能确定地知道。我的猜测是您实际上是在调用callfunction而不是Decrypt从调用代码中调用。无论如何,在当前状态下,您不能导出Decrypt.

还有一点要说明。当你问一个涉及模块接口的问题时,你应该总是展示接口的两面。在这里,您显示了 DLL,但没有显示调用 DLL 的代码。错误可能在那里。事实上,除了我指出的错误之外,那里可能还有一个错误。

于 2012-04-21T19:56:23.083 回答
0

如果字符串操作代码如 exe 中所示工作,但不是来自 DLL,请检查 DLL 是否具有 delphi 内存管理器作为 FIRST 使用项。

uses
  ShareMem

这隐含在 Dephi exe 中,但不在其 DLL 中。

这一直是 Delphi 6 DLL 和字符串最喜欢的问题,但不能说它是否仍然适用于 Delphi 7!

于 2012-04-21T20:02:55.637 回答