Solved

dynamic array and variant record

Posted on 2011-09-16
10
366 Views
Last Modified: 2012-05-12
Hi all. I'll try to explain my problem. In order to hide some sensitive string
in a my program, I use a tecnique I don't know hot to call it, so I describe it.

I declare a record this way:
Rec = record
      case Boolean of
        False: (s: array[0..51] of AnsiChar);
        True: (i: array[0..12] of Integer);
    end;

Open in new window


Obviously the arry's length depends on the string length. Then, supposing the
string is s:
 
procedure TForm2.btnCreateStringClick(Sender: TObject);
var
  r: Rec;
  s: AnsiString;
  I: Integer;
  code, value: string;
begin
  //da stringa a Cardinal
  FillChar(r.s, SizeOf(r.s), 0);
  s := 'IDontKnowHowToDoItButIHopeYouCanHelpMeEasilyAndSoon';
  Move(PAnsiChar(s)^, r.s, Length(s));
  for I := Low(r.i) to High(r.i) do
  begin
    value := IntToStr(not(r.i[I] shl 1));
    mmoString.Lines.Add('r.i['+ IntToStr(I) +'] := Cardinal(not ' + value + ') shr 1;');
  end;
end;

Open in new window


This way I can refer to the string using r.s and the cracker has to work a lot more
to break my code.

Since I have yet changed several times the string to mask this way (it is the
url for convalidation the software license), I thought to make a little utility
to allow me to simply tyoe the string and output the record values to use in my code.
For the above example this code is:

 
r.i[0] := Cardinal(not 521606959) shr 1;
r.i[1] := Cardinal(not 933339531) shr 1;
r.i[2] := Cardinal(not 790570805) shr 1;
r.i[3] := Cardinal(not 924924205) shr 1;
r.i[4] := Cardinal(not -1557060819) shr 1;
r.i[5] := Cardinal(not 296035637) shr 1;
r.i[6] := Cardinal(not 765672245) shr 1;
r.i[7] := Cardinal(not 758358295) shr 1;
r.i[8] := Cardinal(not -1592183513) shr 1;
r.i[9] := Cardinal(not 1027022613) shr 1;
r.i[10] := Cardinal(not -1592183529) shr 1;
r.i[11] := Cardinal(not 252786489) shr 1;
r.i[12] := Cardinal(not 924784035) shr 1;

Open in new window


The r.s is 'IDontKnowHowToDoItButIHopeYouCanHelpMeEasilyAndSoon'.

Only problem is that I wish only type a string, and click a button without the
need to change the record declaration every time.

I tried to make the two arrays dynamic but I received this error:

"Type 'dynamic array' needs finalization - not alloweed in variant record".

How can I solve this' Have you a workaround?

Thanks in advance for any try to help me
0
Comment
Question by:Marco Gasi
  • 5
  • 5
10 Comments
 
LVL 25

Accepted Solution

by:
epasquier earned 500 total points
ID: 36550468
first :
Move(PAnsiChar(s)^, r.s, Length(s));
=
Move(s[1], r.s, Length(s));

then, it can be simplified a bit
Type
 EncodedString=Array of Cardinal;

procedure EncodeString(Str:AnsiString;Var R:EncodedString);
Var
 i:integer;
begin
 SetLength(R,Length(Str));
 for i:=1 to Length(Str) do R[i-1]:=Not(Byte(Str[i]) SHL 1);
end;

procedure DecodeString(const R:EncodedString;Var Str:AnsiString);
Var
 i:integer;
begin
 SetLength(Str,Length(R));
 for i:=1 to Length(Str) do Str[i]:=AnsiChar((Not R[i-1]) SHR 1);
end;

procedure WriteDecodingCode(const StrVarName:String;const Enc:EncodedString);
Var
 EncConstArray:String;
 i:integer;
begin
 if Length(Enc)=0 Then Exit; // prevent errors
 mmoString.Lines.Add('DecodeString('+StrVarName+',[');
 EncConstArray:='';
 for i:=0 to Length(Enc)-1 do EncConstArray:=EncConstArray+IntToStr(Enc[i])+',';
 EncConstArray[Length(EncConstArray)]:=']'; // replace last ',' with ']'
 mmoString.Lines.Add(EncConstArray+');');
end;

Open in new window

0
 
LVL 25

Expert Comment

by:epasquier
ID: 36550493
so, in your encoding tool application :

Var
 Enc:EncodedString;
begin
 EncodeString(edtStringToEncode.Text, Enc );
 WriteDecodingCode( edtStringVarName.Text, Enc );
end;

and include DecodeString in your target application
0
 
LVL 31

Author Comment

by:Marco Gasi
ID: 36550527
Thanks for your answer, epasquier. I'll try it as soon as possible  - now I have to prepare my wedding anniversary and I can stay no more at the beloved computer ;-)

Only a thing. You simplified the Move statement but you didn't use it in your code: your code doesn't need it? Or I have to merge my code with yours?

'See' you later...
0
 
LVL 25

Expert Comment

by:epasquier
ID: 36550542
no need to merge anything, take just my code

I only started with a comment on Move because obviously you didn't knew how to perform it that way.

Good Wedding Anniversary !

A night of love one never forgets...
0
 
LVL 31

Author Closing Comment

by:Marco Gasi
ID: 36554347
Thanks a lot for your help, epasquier. It works very fine :-)
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 31

Author Comment

by:Marco Gasi
ID: 36554887
Hi, epasquier. Are you still monitoring this question? I have a little problem: I can't copy and past the output of your code because Delphi7 doesn't compile it. Suppose string is 'Pippo'; The output is

DecodeString(Pippo,[
4294967135,4294967085,4294967071,4294967071,4294967073]);

Thisis wrong, because DecodeString procedure requires the first parameter be and EncodedString and the second one an AnsiString. I tried to change this way

DecodeString([
4294967135,4294967085,4294967071,4294967071,4294967073], s);

But with this code I receive this error: 'Constants expression violates subrange bounds'

I tried several ways, with quotes, without brackets and so on  but I didn't succeed. Can youhelp me?
0
 
LVL 25

Expert Comment

by:epasquier
ID: 36555167
ok, my bad you cannot pass array of Cardinal like that. Only  'array of const' can be but it's more complex. Let's build a var EncConst of type EncodedString instead and pass it (first parameter, I made also an error here)

procedure WriteDecodingCode(const StrVarName:String;const Enc:EncodedString);
Var
 i:integer;
begin
 if Length(Enc)=0 Then Exit; // prevent errors
 mmoString.Lines.Add('SetLength(EncConst,'+IntToStr(Length(Enc))+');');
 for i:=0 to Length(Enc)-1 do 
  mmoString.Lines.Add(Format('EncConst[%d]=%d',[i,Enc[i]]));
 mmoString.Lines.Add('DecodeString(EncConst,'+StrVarName+');');
end;

Open in new window

0
 
LVL 31

Author Comment

by:Marco Gasi
ID: 36555581
Hi, epasquier. Thank you for trying to help me and I'm sorry to waste your time, but that doesn't work.

The result is

SetLength(EncConst,5);
EncConst[0]=-161
EncConst[1]=-211
EncConst[2]=-225
EncConst[3]=-225
EncConst[4]=-223
DecodeString(EncConst,pippo);

The problem is syntactical and I fixed that making this

SetLength(EncConst,5);
EncConst[0]:=-161;
EncConst[1]:=-211;
EncConst[2]:=-225;
EncConst[3]:=-225;
EncConst[4]:=-223;
DecodeString(EncConst,s);

where s is an empty string which will holds the decoded value (It's right this?). Unfortunately I still receive the same error message: 'Constants expression violates subrange bounds'

Thanks a lot.
0
 
LVL 25

Expert Comment

by:epasquier
ID: 36555731
Cardinal is unsigned int, so I guess the format function treats it as Integer. Just declare
Type
 EncodedString=Array of Integer;

Open in new window

0
 
LVL 31

Author Comment

by:Marco Gasi
ID: 36556090
Yeah, now it works fine! Thank you very mutch for your help. On to the next. :-)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi - replicating a form 8 65
How to call a form that is in a DLL  from an application? 13 65
find a node in VST 2 63
RESTRequest Parameter 4 12
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…
As a trusted technology advisor to your customers you are likely getting the daily question of, ‘should I put this in the cloud?’ As customer demands for cloud services increases, companies will see a shift from traditional buying patterns to new…

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now