I am currently developing an application in Delphi, in which I have to hide (obfuscate) a string in source code like str := 'Example String'
.
Why ? Because if I open the EXE in text editor and search for Example String
I'll find the string in second...
I tried to use a basic HEX transcription like #$65#$78#$61#$6d#$70#$6c#$65
but it's re-transcribed in clear at compile time.
I looked for packers, but it's not the best solution (PECompact can be detected as a false positive malware, UPX is too easy to de-UPX, ...). I would prefer an idea in my internal code...
Someone would put me on the right way.
A very simple method is to store the strings obfuscated by the ROT13 method.
procedure ROT13(var Str: string);
const
OrdBigA = Ord('A');
OrdBigZ = Ord('Z');
OrdSmlA = Ord('a');
OrdSmlZ = Ord('z');
var
i, o: integer;
begin
for i := 1 to length(Str) do
begin
o := Ord(Str[i]);
if InRange(o, OrdBigA, OrdBigZ) then
Str[i] := Chr(OrdBigA + (o - OrdBigA + 13) mod 26)
else if InRange(o, OrdSmlA, OrdSmlZ) then
Str[i] := Chr(OrdSmlA + (o - OrdSmlA + 13) mod 26);
end;
end;
function ROT13fun(const Str: string): string;
begin
result := Str;
ROT13(result);
end;
const
ObfuscatedString = 'Guvf vf n frperg zrffntr.';
procedure TForm4.FormCreate(Sender: TObject);
begin
ShowMessage(ROT13fun(ObfuscatedString));
end;
Slightly more sophisticated would be to employ the Caesar chipher or the Vigenère chipher.
To obtain the obfuscated strings to use in the source code, you can use a decent text editor like my own Rejbrand Text Editor or Wolfram|Alpha.
Update
ROT13 is very easy to decipher, but it might be more than enough for your situation, depending on how it looks! At least it will become very hard to identify strings in the binary. It will take some real effort to obtain the strings. (After all, the every-day user don't even look at binaries in a hex editor/text editor!) The Caesar cipher is a very simple generalisation of the ROT13 cipher, and is also easily deciphered. Indeed, there are only 25 different 'passwords'. The Vigenère cipher is far trickier, and takes some really serious effort to crack (especially since you don't know precisely where in the binary the strings are).
As an example, below I give a string obfuscated using the Vigenère cihper:
Xlc tsrgcdk sj ‘vrivem’ mw cei sd kli acirivqhfriw cw qsbsir tfmjmgw, rrh biimrk hyi pygk gilhlvc mf ws, wk leq rpws pvgsqc fj agrvwtvcou mrrsiiwx we izcfp-hew cmji, rpxlmixl ml r piqg xigfbzgep zrrkyyuv. Mlrvih, hyi qmrvvr qctmixw vbtpmwkw ilsikc qclvgiq ks wsqy er soxirr klex hyi ilhzvi cbmmvslavrx mt xli Srvxl wj irboekivcr. Mr hymw qstxmsl, ai uwcp mljvwxmeoki xfs tlcqwtep zojmw mt xli seivkw tsrgcdk.
It would certainly be possible to extend the cipher to also take care of digits and special characters, including spaces. It could also be made to mix capitals and small letters. Then it would be terribly hard (although possible) to decipher. It is probably far easier to decipher if the password is a known word, which can be found in the dictionary. If it is not a word, it will be safer.
The text above is obfuscated using a word that you can find in a large-enough dictionary. The text below is obfuscated using a nonsense string as password:
Miwzvjfy m vjsy-tombox zguol ap ahqovz d uwk sbze w conz pe biusvth pagh h njsx. Io puvyeq, fl cjsx xic vmovdq zappzjvz, vnjnatl frcb vy dtmd vhxkt fto babtf davf. Uuxlhqb, khk aa dbn eumsuzq, auk saed vlpnbuuo ywlemz ue pnyl ttmxv. Pa ghof, fl cjsx kmbbzk atmd wv sfjtmxcl rtfysk cb yuta md jsy. Sqf nql njsx ly vs ilusrn o gok uxwupagupaz u.
And, finally, the text below is obfuscated the same way, but - in addition - all spaces and special characters have been removed from the string:
cishkclruervutzgnyarkgzjsaqgsrzvmmrzweolpcnvbkxrvdnqrlurhpmhfaxsuoqncxgzqegnqmngaryfbgozpcgrkgzrrybybmouyzbbkoucbnrnsxkmcbywpllxhkoobmzoydrfvrkhpvsavmzocwjflouboymlotjcnqrirgucdrftllladcwtmnkqehjpmnafoobyvkvdaancbzeokdnsotkkawvanjkryculluyaoklpnojfnqrlatypznpalzocjunuxzdbnzntpqulplekxhrshpttjqyculkkjyxhxgxdozruwlbtkyrsuumkgslbyunabbkryfupvnafobhuoyyvqjlzgzpomc
I challenge you to decipher these three texts. If anyone would succeed in deciphering the last one, I promise to give this person 100 SEK (100 Swedish kronor)!
But, still, Warren P is right: If you really require high security, that even the experts will not be able to decipher, then you should go for some real encryption.
Update
As requested by Warren P, I use the following code to encrypt/decrypt Vigenère:
const
OrdBigA = Ord('A');
OrdBigZ = Ord('Z');
OrdSmlA = Ord('a');
OrdSmlZ = Ord('z');
function imod(const x: integer; const y: integer): integer;
begin
if x >= 0 then
imod := x - floor(x/y) * y
else
imod := x + ceil(-x/y) * y;
end;
procedure Vigenère(var Str: string; const Key: string);
var
n, i, o: integer;
KeyChrs: TBytes;
begin
n := length(Key);
SetLength(KeyChrs, n);
for i := 1 to n do
if InRange(ord(Key[i]), OrdBigA, OrdBigZ) then
KeyChrs[i - 1] := Ord(Key[i]) - OrdBigA
else
raise Exception.Create('Invalid character in Vigenère key.');
for i := 1 to length(Str) do
begin
o := Ord(Str[i]);
if InRange(o, OrdBigA, OrdBigZ) then
Str[i] := Chr(OrdBigA + imod((o - OrdBigA + KeyChrs[(i-1) mod n]), 26))
else if InRange(o, OrdSmlA, OrdSmlZ) then
Str[i] := Chr(OrdSmlA + imod((o - OrdSmlA + KeyChrs[(i-1) mod n]), 26));
end;
end;
function Vigenèref(const Str: string; const Key: string): string;
begin
result := Str;
Vigenère(result, Key);
end;
procedure VigenèreD(var Str: string; const Key: string);
var
n, i, o: integer;
KeyChrs: TBytes;
begin
n := length(Key);
SetLength(KeyChrs, n);
for i := 1 to n do
if InRange(ord(Key[i]), OrdBigA, OrdBigZ) then
KeyChrs[i - 1] := Ord(Key[i]) - OrdBigA
else
raise Exception.Create('Invalid character in Vigenère key.');
for i := 1 to length(Str) do
begin
o := Ord(Str[i]);
if InRange(o, OrdBigA, OrdBigZ) then
Str[i] := Chr(OrdBigA + imod((o - OrdBigA - KeyChrs[(i-1) mod n]), 26))
else if InRange(o, OrdSmlA, OrdSmlZ) then
Str[i] := Chr(OrdSmlA + imod((o - OrdSmlA - KeyChrs[(i-1) mod n]), 26));
end;
end;
function VigenèreDf(const Str: string; const Key: string): string;
begin
result := Str;
VigenèreD(result, Key);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With