Disassembling strings from Inno Setup [Code]

早过忘川 提交于 2019-12-18 17:07:51

问题


When I compile a Inno Setup project, the [Code] section is also compiled (as Pascal executable or Pascal DLL)?

In other words, if someone unpacks a Inno Setup project, can he see the [Code] section as original source code (damn! :) ) or as compiled executable/DLL (difficult to disassemble)?

I would like to insert in the [Code] section some strings (password and keys) and I don't know if they would be easily recoverable also with little knowledge of reverse engineering.


回答1:


The code is compiled into some kind of a binary representation (very roughly like .NET CIL or Java bytecode).

There's Inno Setup Unpacker (and others), which can extract the files from .exe generated by Inno Setup. It can extract the binary representation of the code to CompiledCode.bin (if you use -x -m flags).

Then you can use Inno Setup Decompiler project that is able to decompile/disassemble the CompiledCode.bin file into (pseudo) Pascal Script code. But as with a reverse engineering of .NET or Java, it won't give you exact code. The decompiled code possibly won't even compile (at least it was so the last time I tried), but it is good enough to see, what the code does. They seem to have a paid version now, which may be better than the free one I've tried some time ago. (The latest version of Inno Setup Decompiler can even directly extract code from .exe, but it was not updated to the latest version of Inno Setup [5.6.1] yet, so it did not work for me.)

(Inno Setup Decompiler site is gone, but it does not change anything about the fact that it is technically possible to decompile/disassemble the compiled code)


It is rather easy to see literal strings compiled in the code, even in the CompiledCode.bin.

For example these credentials:

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

can be seen like this in the CompiledCode.bin file:

Of course, you can obfuscate the strings somehow (at least hex-encode them). But as you are hopefully aware, no matter what you do, once the (even compiled) code is on user's machine, there's really no way you can protect it absolutely.

A simple support code to store the string literal hex-encoded:

function CryptStringToBinary(
  sz: string; cch: LongWord; flags: LongWord; binary: AnsiString; var size: LongWord;
  skip: LongWord; flagsused: LongWord): Integer;
  external 'CryptStringToBinaryW@crypt32.dll 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] + ")"

(The code was tested on Unicode version of Inno Setup. Though, it can work with ASCII passwords only.)

With the help of the code above, you can write this (so you have the credentials easily editable in the source code):

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

But the code will be compiled as:

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

You can verify that by adding this to the end of your .iss script and checking the generated Preprocessed.iss file.

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

So despite the credentials being readable in the source code, they won't be stored literally to the compiled code:

But again, this is only an obfuscation. Anyone with decent programming skills will be able to unobfuscate (decrypt) the credentials.



来源:https://stackoverflow.com/questions/49194957/disassembling-strings-from-inno-setup-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!