杉宫竹苑工作室

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2851|回复: 0

关于 Inno Setup 的防止通用解包方法

[复制链接]
发表于 2016-12-31 13:22:47 | 显示全部楼层 |阅读模式

正式会员享受无限制浏览网站功能和高速网盘下载,赶快加入本站吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. ; -- Example_Password.iss --
  2. ; 演示如何防止 通用解包程序。Update: 2008-12-07
  3. ; 脚本: restools ( http://restools.hanzify.org )

  4. ; 如果该修改版本在编译脚本或者运行的时候出现问题请提出来.

  5. ;build 081207
  6. ;1. 修改 GetPassword 定义。
  7. ;     function GetPassword(PrePassword: String): String;
  8. ;2. 增加 1 个密码设置函数 SetPassword,具体使用方法可以参考例子。
  9. ;     procedure SetPassword(const Password: String);

  10. [Setup]
  11. AppName=My Application
  12. AppVerName=My Application Ver 1.5
  13. DefaultDirName={pf}\My Application
  14. DefaultGroupName=My Application
  15. UninstallDisplayIcon={app}\MyProg.exe
  16. SolidCompression=yes
  17. Compression=lzma/ultra
  18. UserInfoPage=true
  19. Password=123456abcdef
  20. UsePreviousTasks=yes
  21. Encryption=true

  22. [Tasks]
  23. Name: task1; Description: my task1; GroupDescription: Tasks;

  24. [Types]
  25. Name: "full"; Description: "full"
  26. Name: "compact"; Description: "compact"
  27. Name: "custom"; Description: "custom"; Flags: iscustom

  28. [Components]
  29. Name: "program"; Description: "app files"; Types: full compact custom; Flags: fixed
  30. Name: "help"; Description: "help files"; Types: full
  31. Name: "readme"; Description: "readme files"; Types: full

  32. [Files]
  33. Source: "MyProg.exe"; DestDir: "{app}"; Components: program
  34. Source: "MyProg1.chm"; DestDir: "{app}"; Components: help
  35. Source: "Readme1.txt"; DestDir: "{app}"; Components: readme; Flags: isreadme
  36. Source: "logo.gif"; Flags: dontcopy

  37. [Icons]
  38. Name: "{group}\my application"; Filename: "{app}\MyProg.exe"

  39. [code]
  40. Var
  41.   P1, P2: Integer;
  42.   
  43. function TmpPassword: String;
  44. begin
  45. // 这个临时的密码提供函数是用户自己定义的,函数名字可以随便起,里面的代码随便写,
  46. // 但是不能写成 Result := '123456abcdef'; 否则密码会是以常规字符串出现。
  47. // 这个函数只是用来提供给安装程序临时释放文件用,如无必要,请不要使用这种方式。
  48. // 如果使用这种方式,所有用户文件都可以加密,包括预释放文件都可以不用 noencryption 标记。
  49.   Result := chr(ord('2')-1);
  50.   Result := Result + chr(ord('3')-1);
  51.   Result := Result + chr(ord('4')-1);
  52.   Result := Result + chr(ord('5')-1);
  53.   Result := Result + chr(ord('6')-1);
  54.   Result := Result + chr(ord('7')-1);
  55.   Result := Result + chr(ord('b')-1);
  56.   Result := Result + chr(ord('c')-1);
  57.   Result := Result + chr(ord('d')-1);
  58.   Result := Result + chr(ord('e')-1);
  59.   Result := Result + chr(ord('f')-1);
  60.   Result := Result + chr(ord('g')-1);
  61. end;

  62. function CheckPassword(Password: String): Boolean;
  63. begin
  64. // 无论密码是否正确都要关闭 password 页面。
  65. // 因为我们不需要这个页面来提供正确密码。
  66.   Result := True;
  67. end;
  68.   
  69. // 这里是一个 Inno Setup 内部支持函数, GetPassword,
  70. // 当发现脚本中有此函数时并里面提供正确的密码时, 将会自动跳过 password 页面
  71. // 参数 PrePassword 是上一次提供的密码,当你需要多段密码重组的时候就用它。否则你可以不必理会这个参数,直接提供正确的密码就可以了。
  72. function GetPassword(PrePassword: String): String;
  73. begin
  74. // P1 的赋值可以在任何脚本的函数中进行,以确保脚本真正的由你的安装程序运行来获取密码。如果任何非本安装程序运行了脚本,因为未知 P1 的值,直接通过外部程序运行该函数是不能成功获得正确密码的。
  75.   if (P1 = 5) and (P2 = 6) then
  76.   begin
  77.     Result := chr(ord('2')-1);
  78.     Result := Result + chr(ord('3')-1);
  79.     Result := Result + chr(ord('4')-1);
  80.     Result := Result + chr(ord('5')-1);
  81.     Result := Result + chr(ord('6')-1);
  82.     Result := Result + chr(ord('7')-1);
  83.   end else
  84.   if (P1 = 5) and (P2 = 9) then
  85.   begin
  86. // 取前 6 位来组合密码,因为这是上一次提供的半段正确密码。接下来是添加正确的后半段密码。
  87.     Result := Copy(PrePassword, 1, 6) + chr(ord('b')-1);
  88.     Result := Result + chr(ord('c')-1);
  89.     Result := Result + chr(ord('d')-1);
  90.     Result := Result + chr(ord('e')-1);
  91.     Result := Result + chr(ord('f')-1);
  92.     Result := Result + chr(ord('g')-1);
  93.   end else
  94.     Result := PrePassword + 'FakePassword'; // 凡是未符合要求的一律返回假密码。
  95.    
  96. // P2 由 GetPassword 内部增加,这样做代表了当 GetPassword 被第 7 次和第 10 次调用后 2 次合并就会获得正确密码。
  97.   P2 := P2 + 1;
  98.   
  99. // 上面的代码如果你愿意,可以做得更复杂,这样会令到真假密码在内存中错综复杂,不利程序自动获取。
  100. // 以下代码用来查看一下密码提供的情况。
  101. //  MsgBox(PrePassword+' , '+Result, mbInformation, MB_OK);
  102. end;


  103. procedure InitializeWizard();
  104. begin
  105. // P1 放到 InitializeWizard 赋值,表示了脚本必须同时运行了 InitializeWizard 才能够获取正确密码。
  106. // 你可以在安装正体文件之前进行的任何函数中运行多层赋值动作,令到你的密码提供函数(GetPassword)可以遍及整个安装程序脚本而无法分离出来单独运行这一部分函数代码。
  107.   P1 := 5;
  108. {
  109. // 以下被注释的代码是实现取用临时创建的密码来初期使用释放文件。
  110. // 但是我认为这是可免则免的事情。
  111. // 因为要尽可能在安装文件的时候才提供正确密码。

  112.   SetPassword(TmpPassword);
  113.   ExtractTemporaryFile('logo.gif');
  114.   SetPassword('FakePassword'); // 用完后最好重新清空一下密码。
  115. }

  116. // 接下来如何会获得正确密码呢?在文件真正释放的时候,会有 10 次获取正确密码的机会,只要在 10 次之内提供正确的密码(GetPassword 会被运行 10 次)。程序仍然会被正确安装。
  117. // 如非必要,请不要直接用 SetPassword 来提供密码,尽可能用 GetPassword 来在安装文件时自动获取,因为这样做,如果你下面的代码并不能有效防止密码获取程序,至少你的安装程序文件需要被正常安装一次。

  118. // 那么接下来再要写些什么代码呢?因为程序到了安装文件前才提供正确密码,所以任何程序想获取密码就必须运行你的安装程序到开始安装文件那一步,到那里为止有足够的脚本运行时间给你发挥你的想象力来阻止任何这类程序的密码获取行为:
  119. // 1. 选择自动退出安装程序。
  120. // 2. 选择提供一个假密码,导致安装程序不能安装。
  121. // 3. 选择阻止监视程序的密码获取(不建议,因为技术有难度,不适合普通用户实现)
  122. // 检测方法有很多种,进程查看,窗口检查等等,总之你想到什么方法用什么方法。反正脚本是自由的。
  123. // ...... 更多的防止脚本,你们自己发挥吧。我只提供一个大概框架。
  124. end;
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SgzyStudio

GMT+8, 2024-5-15 18:02 , Processed in 0.113589 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表