string - 如何在 Delphi EXE 中加密或隐藏字符串?

标签 string delphi obfuscation

我目前正在 Delphi 中开发一个应用程序,其中我必须隐藏(混淆)源代码中的字符串,例如 str := 'Example String'
为什么 ?因为如果我在文本编辑器中打开 EXE 并搜索 Example String 我会在第二个位置找到该字符串...

我尝试使用基本的十六进制转录,例如#$65#$78#$61#$6d#$70#$6c#$65,但它在编译时以清晰的形式重新转录。
我寻找加壳程序,但这不是最好的解决方案(PECompact 可以被检测为误报恶意软件,UPX 太容易去反 UPX,...)。我希望在我的内部代码中有一个想法...

有人会让我走上正确的道路。

最佳答案

一个非常简单的方法就是存储ROT13混淆后的字符串。方法。

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;

稍微复杂一点的方法是使用凯撒芯片或维吉尼亚芯片。

要获取在源代码中使用的混淆字符串,您可以使用像我自己的那样的不错的文本编辑器 Rejbrand Text EditorWolfram|Alpha .

更新

ROT13 非常容易破译,但它可能足以满足您的情况,具体取决于它的外观!至少识别二进制文件中的字符串将变得非常困难。获得琴弦需要付出一些真正的努力。 (毕竟,日常用户甚至不会在十六进制编辑器/文本编辑器中查看二进制文件!)凯撒密码是 ROT13 密码的非常简单的概括,并且也很容易破译。事实上,只有 25 个不同的“密码”。维吉尼亚密码要复杂得多,需要付出一些非常认真的努力才能破解(尤其,因为您不知道准确地知道字符串在二进制文件中的位置)。

作为示例,下面我给出了使用 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.

当然可以扩展密码以处理数字和特殊字符,包括空格。它也可以混合大写和小写字母。那么破译就会非常困难(尽管有可能)。如果密码是已知单词(可以在字典中找到),那么破译可能会容易得多。如果它不是一个单词,那就更安全了。

上面的文本使用了一个可以在足够大的字典中找到的单词进行了混淆。下面的文本使用无意义的字符串作为密码进行了混淆:

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.

最后,下面的文本以相同的方式进行混淆,但是 - 此外 - 所有空格和特殊字符都已从字符串中删除:

cishkclruervutzgnyarkgzjsaqgsrzvmmrzweolpcnvbkxrvdnqrlurhpmhfaxsuoqncxgzqegnqmngaryfbgozpcgrkgzrrybybmouyzbbkoucbnrnsxkmcbywpllxhkoobmzoydrfvrkhpvsavmzocwjflouboymlotjcnqrirgucdrftllladcwtmnkqehjpmnafoobyvkvdaancbzeokdnsotkkawvanjkryculluyaoklpnojfnqrlatypznpalzocjunuxzdbnzntpqulplekxhrshpttjqyculkkjyxhxgxdozruwlbtkyrsuumkgslbyunabbkryfupvnafobhuoyyvqjlzgzpomc

我挑战你破译这三个文本。如果有人能成功破译最后一个,我保证给这个人 100 SEK(100 瑞典克朗)!

但是,Warren P 是对的:如果您确实需要高安全性,即使专家也无法破译,那么您应该选择一些真正的> 加密。

更新

根据 Warren P 的要求,我使用以下代码来加密/解密 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;

关于string - 如何在 Delphi EXE 中加密或隐藏字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6800326/

相关文章:

android - JSON omdb解析

c# - 从字符串中获取随机的单词序列?

java - 字符串格式 : 2 => 02

c++ - 无法从使用 Cmake 创建的可执行文件中删除符号名称

node.js - 创建闭源 npm 包

java - 除了混淆之外还可以做些什么来保护 jar 文件?

java - Java String 类内部是如何工作的?

Delphi IDE 开始结束对指示器

Delphi从TObject继承Create

multithreading - 我可以在 `Inherited Create` 之前做一些初始化吗?