Solved

dynamic array and variant record

Posted on 2011-09-16
10
365 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 30

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 30

Author Closing Comment

by:Marco Gasi
ID: 36554347
Thanks a lot for your help, epasquier. It works very fine :-)
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 30

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 30

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 30

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

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

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 my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video discusses moving either the default database or any database to a new volume.

705 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

19 Experts available now in Live!

Get 1:1 Help Now