Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Having problem with Dll in debugger in 10.2


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 1 - Last Post: Oct 12, 2017 5:50 PM Last Post By: Remy Lebeau (Te...
Donald Bossen

Posts: 81
Registered: 2/3/02
Having problem with Dll in debugger in 10.2  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 12, 2017 3:11 PM
Here is all my code.
Calling Program
unit Main;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Math, Vcl.StdCtrls, Vcl.Mask,
RzEdit, RzButton, StStrL;

type
TFrmMain = class(TForm)
BtnDeCrypt: TRzBitBtn;
FldText: TRzEdit;
BtnEnCrypt: TRzBitBtn;
procedure BtnDeCryptClick(Sender: TObject);
procedure BtnEnCryptClick(Sender: TObject);
private
{ Private declarations }
function cSetEncodeText(Value,sbKey : String) : AnsiString;
function cGetDecodedText(value : AnsiString; sbKey: String) : String;
Function EncodePrice(Price : Currency) : AnsiString;
function DecodePrice(ClipperText : AnsiString) : Currency;
public
{ Public declarations }
end;

var
FrmMain: TFrmMain;

implementation

{$R *.dfm}

uses IcDc10Functions;

Function TFrmMain.EncodePrice(Price : Currency) : AnsiString;
var
value : String;
begin
Value := FloatToStr(Price);
result := cSetEncodeText(Value,'yawara')
end;

function TFrmMain.DecodePrice(ClipperText : AnsiString) : Currency;
var
Value : String;
begin
value := cGetDecodedText(ClipperText,'yawara');
if isStrNumericL(Value,'0123456789.') then
result := StrToFloat(Value)
else
result := 0.00;
end;

function TFrmMain.cSetEncodeText(Value,sbKey : String) : AnsiString;
var
CipherText : AnsiString;
Len,ilen : Integer;
begin
Len := 50;// 4 * Length(Value);
CipherText := '';
if Len > 0 then
begin
SetLength(CipherText,Len);
result := GetEncodedText10(PChar(Value),PChar(sbKey));
// GetEncodedText10 : function(aPlainText, sbKey : PChar): PAnsiChar; stdcall;
if Len = -1 then
raise Exception.CreateFmt('Unable to encode Key: %s\%s',[Value,sbKey]);
end;
iLen := Length(CipherText);

result := copy(CipherText,1,len);
if value <> '0' then
len := len;
end;

function TFrmMain.cGetDecodedText(value : AnsiString; sbKey: String) : String;
var
Len : Integer;
begin
result := '';
len := 50;
// Len := GetDecodedText10(PAnsiChar(Value),PChar(sbKey),nil,0);
// if Len = -1 then
// raise Exception.CreateFmt('Unable to decode Key: %s\%s',[SubKey,Key]);
if Len > 0 then
begin
SetLength(Result,Len);
// Len := GetDecodedText10(PAnsiChar(Value),PChar(sbKey),PChar(result),Len);
// if Len = -1 then
// raise Exception.CreateFmt('Unable to decode Key: %s\%s',[SubKey,Key]);
end;
end;

procedure TFrmMain.BtnDeCryptClick(Sender: TObject);
var
Value : String;
begin
FldText.Text := FloatToStr(DecodePrice(FldText.Text));
end;

procedure TFrmMain.BtnEnCryptClick(Sender: TObject);
begin
FldText.Text := EncodePrice(StrToFloat(FldText.Text));
end;

end.

IcDc10 Form

unit IcDc10Functions;

interface

var
GetDecodedText10 : function(aCipherText: PAnsiChar; sbKey: PChar): PChar; stdcall;
GetEncodedText10 : function(aPlainText, sbKey : PChar): PAnsiChar; stdcall;
FreeText10 : procedure(aValue: Pointer); stdcall;

implementation

uses
SysUtils, Windows;

var
DllHandleIcDc : THandle = 0;

procedure CheckDllHandle;
begin
if DllHandleIcDc = 0 then
begin
DllHandleIcDc := SafeLoadLibrary('IcDc.dll');
if DllHandleIcDc = 0 then
raise Exception.Create('Unable to Load IdDc.dll')
end;
end;

function FixupStub(const aName : String) : Pointer;
begin
CheckDllHandle;
Result := GetProcAddress(DllHandleIcDc, PChar(aName));
if Result = nil then
raise Exception.CreateFmt('Unable to Access %s', [aName]);
end;

function Stub_GetDecodedText(aCipherText: PAnsiChar; sbKey: PChar): PChar;
stdcall;
begin
@GetDecodedText10 := FixupStub('GetDecodedText');
Result := GetDecodedText10(aCipherText, sbKey);
end;

function Stub_GetEncodedText(aPlainText, sbKey : PChar): PAnsiChar; stdcall;
begin
@GetEncodedText10 := FixupStub('GetEncodedText');
Result := GetEncodedText10(aPlainText, sbKey);
end;

End.

IcDc10 Dll Code.

unit Main;

interface

function GetDecodedText10(aCipherText: PAnsiChar; sbKey: PChar): PChar; stdcall;
function GetEncodedText10(aPlainText, sbKey : PChar): PAnsiChar; stdcall;
procedure FreeText10(aValue: Pointer); stdcall;

implementation

uses
uTPLb_Codec, uTPLb_BaseNonVisualComponent, uTPLb_CryptographicLibrary, System.SysUtils;

function GetDecodedText10(aCipherText: PAnsiChar; sbKey : PChar): PChar; stdcall;
var
Codec : TCodec;
cLibrary : TCryptographicLibrary;
PlainText : String;
Size: Integer;
begin
try
Codec := TCodec.Create(nil);
try
cLibrary := TCryptographicLibrary.Create(nil);
try
Codec.CryptoLibrary := cLibrary;
Codec.ChainModeId := 'native.CFB';
Codec.StreamCipherId := 'native.StreamToBlock';
Codec.BlockCipherId := 'native.Blowfish';
Codec.Reset;
Codec.Password := sbkey;
codec.decryptString(PlainText,aCipherText,TEncoding.ASCII);
finally
cLibrary.Free;
end;
finally
Codec.Free;
end;
Size := (Length(PlainText) + 1) * SizeOf(Char);
GetMem(Result, Size);
Move(PChar(PlainText)^, Result^, Size);
except
Result := nil;
end;
end;

function GetEncodedText10(aPlainText, sbKey : PChar): PAnsiChar; stdcall;
var
Codec : TCodec;
cLibrary : TCryptographicLibrary;
CipherText : String;
Size: Integer;
begin
try
Codec := TCodec.Create(nil);
try
cLibrary := TCryptographicLibrary.Create(nil);
try
Codec.CryptoLibrary := cLibrary;
Codec.ChainModeId := 'native.CFB';
Codec.StreamCipherId := 'native.StreamToBlock';
Codec.BlockCipherId := 'native.Blowfish';
Codec.Reset;
Codec.Password := sbkey;
codec.EncryptString(string(aPlainText),CipherText,TEncoding.ASCII);
finally
cLibrary.Free;
end;
finally
Codec.Free;
end;
Size := (Length(CipherText) + 1) * SizeOf(AnsiChar);
GetMem(Result, Size);
Move(PAnsiChar(CipherText)^, Result^, Size);
except
Result := nil;
end;
end;

procedure FreeText10(aValue: Pointer); stdcall;
begin
try
FreeMem(AValue);
except
end;
end;

end.

I Enter in the FldText.Text := 9.99 and press the BtnEnCrypt Button and have a break point set in Dll Code in function GetEncodedText10 at line Codec.CryptoLibrary := cLibrary; It runs to this point I press F8 The Following error "Project TestCrypt raised exception class $C0000005 with message 'access violation at 0x00000000: read of address 0x00000000'" I have tried to add to watches cLibrary and Codec and I get Values of E2451 Undefined symbol 'cLibrary and Codec'. Something is corrupting Memory Local values sbKey = {L"yaw"} and Value = {L"9."}.
Thanks in Advance
Donald S. Bossen

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Having problem with Dll in debugger in 10.2  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 12, 2017 5:50 PM   in response to: Donald Bossen in response to: Donald Bossen
Donald Bossen wrote:

result := GetEncodedText10(PChar(Value),PChar(sbKey));

You are not freeing the output string. Also, in the DLL, even though
GetEncodedText10() returns a PAnsiChar, it is encrypting the data into
a UnicodeString and not converting it to an AnsiString before copying
it to the output.

Len := GetDecodedText10(PAnsiChar(Value),PChar(sbKey),nil,0);

Your cGetDecodedText() method expects GetDecodedText10() to return an
Integer, but it really returns a PWideChar pointer instead, which needs
to be freed when done using it.

FldText.Text := FloatToStr(DecodePrice(FldText.Text));

Why are you converting a String from the UI to an Extended, then to a
Currency, then to an Extended, just to convert it back to a String to
display in the UI? That is a lot of wasted overhead, not to mention is
subject to locale interpretation.

FldText.Text := EncodePrice(StrToFloat(FldText.Text));

Why are you converting a String from the UI to an Extended, then to a
Currency, just to convert it back to a String to then pass to the DLL?
That is also a lot of wasted overhead, and subject to locale
interpretation.

I Enter in the FldText.Text := 9.99 and press the BtnEnCrypt Button
and have a break point set in Dll Code in function GetEncodedText10
at line Codec.CryptoLibrary := cLibrary; It runs to this point I
press F8 The Following error "Project TestCrypt raised exception
class $C0000005 with message 'access violation at 0x00000000: read of
address 0x00000000'"

In your IcDc10Functions unit, you are not initializing your 3 function
pointers to point at your stub functions, so the pointers get
initialized to nil instead. So, you end up crashing when trying to
call the DLL functions through nil pointers, which is exactly what the
AV error message is telling you (the address of the code being executed
is 0X00000000).

With that said, try something more like this instead:

unit Main;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Math, Vcl.StdCtrls, Vcl.Mask,
  RzEdit, RzButton, StStrL;
 
type
  TFrmMain = class(TForm)
    BtnDeCrypt: TRzBitBtn;
    FldText: TRzEdit;
    BtnEnCrypt: TRzBitBtn;
    procedure BtnDeCryptClick(Sender: TObject);
    procedure BtnEnCryptClick(Sender: TObject);
  private
    { Private declarations }
    function cSetEncodeText(const Value, sbKey : String): AnsiString;
    function cGetDecodedText(const Value: AnsiString; const sbKey:
String): String;
    Function EncodePrice(Price: Currency): AnsiString;
    function DecodePrice(const ClipperText: AnsiString): Currency;
  public
    { Public declarations }
  end;
 
var
  FrmMain: TFrmMain;
 
implementation
 
{$R *.dfm}
 
uses
  IcDc10Functions;
 
function TFrmMain.EncodePrice(Price: Currency): AnsiString;
begin
  Result := cSetEncodeText(CurrToStr(Price), 'yawara');
end;
 
function TFrmMain.DecodePrice(const ClipperText: AnsiString): Currency;
var
  Value: String;
begin
   Value := cGetDecodedText(ClipperText, 'yawara');
   if isStrNumericL(Value, '0123456789.') then
     Result := StrToCurr(Value)
   else
     Result := 0.00;
end;
 
function TFrmMain.cSetEncodeText(const Value, sbKey: String):
AnsiString;
var
  CipherText: PAnsiChar;
begin
  CipherText := GetEncodedText10(PChar(Value), PChar(sbKey));
  if CipherText = nil then
    raise Exception.CreateFmt('Unable to encode Key: %s\%s', [Value,
sbKey]);
  try
    Result := CipherText;
  finally
    FreeText10(CipherText);
  end;
end;
 
function TFrmMain.cGetDecodedText(const Value: AnsiString; const sbKey:
String): String;
var
  PlainText: PChar;
begin
  PlainText := GetDecodedText10(PAnsiChar(Value), PChar(sbKey));
  if PlainText = nil then
    raise Exception.CreateFmt('Unable to decode Key: %s\%s', [Value,
sbKey]);
  try
    Result := PlainText;
  finally
    FreeText10(PlainText);
  end;
end;
 
procedure TFrmMain.BtnDeCryptClick(Sender: TObject);
begin
  FldText.Text := CurrToStr(DecodePrice(FldText.Text));
end;
 
procedure TFrmMain.BtnEnCryptClick(Sender: TObject);
begin
  FldText.Text := EncodePrice(StrToCurr(FldText.Text));
end;
 
end.


unit IcDc10Functions;
 
interface
 
var
  GetDecodedText10 : function(aCipherText: PAnsiChar; sbKey: PChar):
PChar; stdcall;
  GetEncodedText10 : function(aPlainText, sbKey: PChar): PAnsiChar;
stdcall;
  FreeText10       : procedure(aValue: Pointer); stdcall;
 
implementation
 
uses
  SysUtils, Windows;
 
var
  DllHandleIcDc : THandle = 0;
 
procedure CheckDllHandle;
begin
  if DllHandleIcDc = 0 then
  begin
    DllHandleIcDc := SafeLoadLibrary('IcDc.dll');
    if DllHandleIcDc = 0 then
      raise Exception.Create('Unable to Load IdDc.dll')
  end;
end;
 
function FixupStub(const aName: String): Pointer;
begin
  CheckDllHandle;
  Result := GetProcAddress(DllHandleIcDc, PChar(aName));
  if Result = nil then
    raise Exception.CreateFmt('Unable to Access %s', [aName]);
end;
 
function Stub_GetDecodedText(aCipherText: PAnsiChar; sbKey: PChar):
PChar;
stdcall;
begin
  @GetDecodedText10 := FixupStub('GetDecodedText');
  Result := GetDecodedText10(aCipherText, sbKey);
end;
 
function Stub_GetEncodedText(aPlainText, sbKey: PChar): PAnsiChar;
stdcall;
begin
  @GetEncodedText10 := FixupStub('GetEncodedText');
  Result := GetEncodedText10(aPlainText, sbKey);
end;
 
function Stub_FreeText10(aValue: Pointer); stdcall;
begin
  @FreeText10 := FixupStub('FreeText');
  Result := FreeText10(aValue);
end;
 
initialization
  GetDecodedText10 := Stub_GetDecodedText10;
  GetEncodedText10 := Stub_GetEncodedText10;
  FreeText10       := Stub_FreeText10;
 
finalization
  if DllHandleIcDc <> 0 then FreeLibrary(DllHandleIcDc);
 
End.


unit Main;
 
interface
 
function GetDecodedText10(aCipherText: PAnsiChar; sbKey: PChar): PChar;
stdcall;
function GetEncodedText10(aPlainText, sbKey : PChar): PAnsiChar;
stdcall;
procedure FreeText10(aValue: Pointer); stdcall;
 
implementation
 
uses
  uTPLb_Codec, uTPLb_BaseNonVisualComponent,
uTPLb_CryptographicLibrary, System.SysUtils;
 
function GetDecodedText10(aCipherText: PAnsiChar; sbKey: PChar): PChar;
stdcall;
var
  Codec : TCodec;
  cLibrary : TCryptographicLibrary;
  PlainText : String;
  Size: Integer;
begin
  try
    Codec := TCodec.Create(nil);
    try
      cLibrary := TCryptographicLibrary.Create(nil);
      try
        Codec.CryptoLibrary := cLibrary;
        Codec.ChainModeId  := 'native.CFB';
        Codec.StreamCipherId := 'native.StreamToBlock';
        Codec.BlockCipherId := 'native.Blowfish';
        Codec.Reset;
        Codec.Password := sbkey;
        codec.decryptString(PlainText, string(AnsiString(aCipherText)),
TEncoding.UTF8);
      finally
        cLibrary.Free;
      end;
    finally
      Codec.Free;
    end;
    Size := (Length(PlainText) + 1) * SizeOf(Char);
    GetMem(Result, Size);
    Move(PChar(PlainText)^, Result^, Size);
  except
    Result := nil;
  end;
end;
 
function GetEncodedText10(aPlainText, sbKey: PChar): PAnsiChar; stdcall;
var
  Codec : TCodec;
  cLibrary : TCryptographicLibrary;
  CipherText : String;
  aCipherText : AnsiString;
  Size: Integer;
begin
  try
    Codec := TCodec.Create(nil);
    try
      cLibrary := TCryptographicLibrary.Create(nil);
      try
        Codec.CryptoLibrary := cLibrary;
        Codec.ChainModeId  := 'native.CFB';
        Codec.StreamCipherId := 'native.StreamToBlock';
        Codec.BlockCipherId := 'native.Blowfish';
        Codec.Reset;
        Codec.Password := sbkey;
        codec.EncryptString(string(aPlainText), CipherText,
TEncoding.UTF8);
      finally
        cLibrary.Free;
      end;
    finally
      Codec.Free;
    end;
    aCipherText := AnsiString(CipherText);
    Size := (Length(aCipherText) + 1) * SizeOf(AnsiChar);
    GetMem(Result, Size);
    Move(PAnsiChar(aCipherText)^, Result^, Size);
  except
    Result := nil;
  end;
end;
 
procedure FreeText10(aValue: Pointer); stdcall;
begin
  try
    FreeMem(AValue);
  except
  end;
end;
 
end.

--
Remy Lebeau (TeamB)

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02