从Inno Setup拆卸字符串[代码]

埃齐奥

当我编译一个Inno Setup项目时,该[Code]部分也被编译了(作为Pascal可执行文件还是Pascal DLL)?

换句话说,如果有人打开Inno Setup项目的包装,他是否可以将此[Code]部分视为原始源代码(该死的::))或作为已编译的可执行文件/ DLL(难于反汇编)?

我想在本[Code]节中插入一些字符串(密码和密钥),并且我不知道它们是否也可以在没有逆向工程知识的情况下很容易地恢复。

马丁·普里克里(Martin Prikryl)

该代码被编译为某种二进制表示形式(非常类似于.NET CILJava bytecode)。

Inno Setup Unpacker(及其他),可以从.exeInno Setup生成的文件中提取文件它可以提取代码的二进制表示形式CompiledCode.bin(如果使用-x -m标志)。

然后,您可以使用Inno Setup Decompiler项目,该项目能够将CompiledCode.bin文件反编译/反汇编为(伪)Pascal脚本代码。但是,与.NET或Java的逆向工程一样,它不会为您提供确切的代码。反编译后的代码甚至可能无法编译(至少是我上次尝试的时间),但是足以看出代码的作用。他们现在似乎有付费版本,这可能比我一段时间前尝试的免费版本更好。(最新版本的Inno Setup Decompiler甚至可以直接从中提取代码.exe,但尚未更新为最新版本的Inno Setup [5.6.1],因此对我不起作用。)

(Inno Setup Decompiler站点已消失,但是它在技术上可以反编译/反汇编已编译的代码这一事实方面没有任何改变)


即使在中,也很容易看到在代码中编译的文字字符串CompiledCode.bin

例如,这些凭证:

Username := 'secretusername';
Password := 'mysupersecretpassword';

CompiledCode.bin文件中可以看到如下所示

在此处输入图片说明

当然,您可以以某种方式混淆字符串(至少对它们进行十六进制编码)。但是,正如您希望知道的那样,无论您做什么,一旦(即使已编译的)代码出现在用户计算机上,实际上也就无法绝对保护它。

一个简单的支持代码,用于存储十六进制编码的字符串文字:

function CryptStringToBinary(
  sz: string; cch: LongWord; flags: LongWord; binary: AnsiString; var size: LongWord;
  skip: LongWord; flagsused: LongWord): Integer;
  external '[email protected] stdcall';

const
  CRYPT_STRING_HEX = $04;

function UnobfuscateString(S: string): string;
var
  Size: LongWord;
  Buffer: AnsiString;
begin
  SetLength(Buffer, (Length(S) div 2) + 1);
  Size := Length(S) div 2;
  if (CryptStringToBinary(S, Length(S), CRYPT_STRING_HEX, Buffer, Size, 0, 0) = 0) or
     (Size <> Length(S) div 2) then
  begin
    RaiseException('Error unobfuscating string');
  end;
  Result := Buffer;
end;

#define ObfuscateString(str S) \
  Local[0] = AddBackslash(GetEnv("TEMP")) + "ObfuscatedString.pas", \
  Local[1] = \
    "-ExecutionPolicy Bypass -Command """ + \
    "$bytes = [Text.Encoding]::ASCII.GetBytes('" + S + "'); " + \
    "$s = '''' + (($bytes | foreach { $_.ToString('X2') }) -join '') + ''''; " + \
    "Set-Content -Path '" + Local[0] + "' -Value $s;" + \
    """", \
  Exec("powershell.exe", Local[1], SourcePath, , SW_HIDE), \
  Local[2] = FileOpen(Local[0]), \
  Local[3] = FileRead(Local[2]), \
  FileClose(Local[2]), \
  DeleteFileNow(Local[0]), \
  "UnobfuscateString(" + Local[3] + ")"

(该代码已在Unicode版本的Inno Setup上进行了测试。不过,该代码只能与ASCII密码一起使用。)

在上面的代码的帮助下,您可以编写此代码(这样您就可以在源代码中轻松编辑凭据):

Username := {#ObfuscateString("secretusername")};
Password := {#ObfuscateString("mysupersecretpassword")};

但是代码将被编译为:

Username := UnobfuscateString('736563726574757365726E616D65');
Password := UnobfuscateString('6D79737570657273656372657470617373776F7264');

您可以通过将其添加到.iss脚本末尾并检查生成的Preprocessed.iss文件来进行验证。

#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")

因此,尽管凭据在源代码中是可读的,但它们不会按字面意义存储在编译后的代码中:

在此处输入图片说明

但是同样,这只是一种混淆。具有良好编程技能的任何人都可以取消混淆(解密)凭据。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章