从Inno Setup拆卸字符串[代码] [英] Disassembling strings from Inno Setup [Code]
问题描述
当我编译一个Inno Setup项目时,[Code]
部分也会被编译(作为Pascal可执行文件或Pascal DLL)?
When I compile a Inno Setup project, the [Code]
section is also compiled (as Pascal executable or Pascal DLL)?
换句话说,如果有人打开Inno Setup项目的包装,他能否将[Code]
部分视为原始源代码(该死的::))或视为已编译的可执行文件/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)?
我想在[Code]
部分中插入一些字符串(密码和密钥),并且我不知道它们是否也可以在没有逆向工程知识的情况下很容易地恢复.
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.
推荐答案
该代码被编译为某种二进制表示形式(非常类似于 Java字节码).
The code is compiled into some kind of a binary representation (very roughly like .NET CIL or Java bytecode).
有一个 Inno Setup Unpacker (及其他),可以从由以下用户生成的.exe
中提取文件:创新设置.可以将代码的二进制表示形式提取到CompiledCode.bin
(如果使用-x -m
标志).
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).
然后,您可以使用Inno Setup Decompiler项目,该项目能够将 CompiledCode.bin
文件反编译/反汇编为(伪)Pascal脚本代码.但是,与.NET或Java的逆向工程一样,它不会为您提供确切的代码.反编译后的代码甚至可能无法编译(至少是上次尝试时才编译),但足以看出代码的作用.他们现在似乎有付费版本,这可能比我一段时间前尝试过的免费版本更好. (最新版本的Inno Setup Decompiler甚至可以直接从.exe
中提取代码,但尚未更新为最新版本的Inno Setup [5.6.1],因此对我不起作用.)
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站点已消失,但是它在技术上可以反编译/反汇编已编译的代码这一事实上没有任何改变)
(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)
即使在CompiledCode.bin
中,也很容易看到在代码中编译的文字字符串.
It is rather easy to see literal strings compiled in the code, even in the CompiledCode.bin
.
例如这些凭据:
Username := 'secretusername';
Password := 'mysupersecretpassword';
在CompiledCode.bin
文件中可以看到
:
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] + ")"
(该代码已在 Inno Setup的Unicode版本上进行了测试.尽管如此,它也可以使用ASCII密码
(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")};
但是代码将被编译为:
Username := UnobfuscateString('736563726574757365726E616D65');
Password := UnobfuscateString('6D79737570657273656372657470617373776F7264');
您可以通过将其添加到.iss
脚本的末尾并检查生成的Preprocessed.iss
文件来进行验证.
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.
这篇关于从Inno Setup拆卸字符串[代码]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!