找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 462|回复: 0

[原创] 《Ren'Py强化之旅:Windows下引擎潜力探索》04.外置PE文件实现renpy资源加密解密

[复制链接]
发表于 2023-9-30 02:11:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
本帖最后由 Furau 于 2023-10-1 14:42 编辑

《Ren'Py强化之旅:Windows下引擎潜力探索》04.外置PE文件实现renpy资源加密解密
转载请标注Furau.com
前置说明
第一个综合练习程序,利用PE的特性实现一个加解密程序
RSA算法简介:https://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
方便大家理解过程我绘制了一个流程图:
Snipaste_2023-09-30_02-20-20.png

下面是我制作的demo,一份最小演示程序。
RSA生成公钥私钥:
[RenPy] 纯文本查看 复制代码
import rsa
import time
# 生成公钥私钥 
key_strength = 128
start_time = time.time()
(public_key, private_key) = rsa.newkeys(key_strength * 8)
print('Time consumed:', time.time() - start_time)
with open('public_key.pem', 'w+') as f:
    f.write(public_key.save_pkcs1().decode())
with open('private_key.pem', 'w+') as f:
    f.write(private_key.save_pkcs1().decode())

加密程序:
[RenPy] 纯文本查看 复制代码
import rsa
import time
# 加密程序 
with open('public_key.pem', 'r') as f:
    public_key = rsa.PublicKey.load_pkcs1(f.read().encode())
# 需要加密的文件 
with open(file='main_menu.png', mode='rb') as f:
    data_to_encrypt = f.read()
key_strength = 128  
split_length = int(key_strength - 11)  
data_length = int(len(data_to_encrypt))  
 
if data_length % split_length == 0:  
    split_count = int(data_length / split_length)
else:
    split_count = int(data_length / split_length + 1)
 
start = time.time()
encrypted_data = bytes()
for i in range(split_count):
    a = i * split_length
    b = a + split_length
    encrypted_chunk = rsa.encrypt(data_to_encrypt[a:b], public_key)
    encrypted_data = encrypted_data + encrypted_chunk
 
print('Encryption time:', time.time() - start)
#  加密后的文件
with open(file='encrypted_image.png', mode='wb') as f:
    f.write(encrypted_data)

解密程序:(我编写了一个GUI页面,方便大家理解交互)

[RenPy] 纯文本查看 复制代码
import tkinter as tk
import rsa
import time
from tkinter import messagebox
def decrypt_image():
    with open(file='private_key.pem', mode='r') as f:
        key = rsa.PrivateKey.load_pkcs1(f.read().encode())
    with open(file='game/gui/encrypted_image.png', mode='rb') as f:
        edata = f.read()
    key_strength = 128
    v_length = len(edata)
    v_sq = int(key_strength)
    split_count = int(v_length / v_sq)
    start = time.time()
    # 解密
    v_s = bytes()
    for i in range(split_count):
        a = i * key_strength
        b = a + key_strength
        v_text = rsa.decrypt(edata[a:b], key)
        v_s = v_s + v_text
    decryption_time = time.time() - start
    messagebox.showinfo("激活(解密成功!)", "解密资源成功!\nDecryption Time: {:.2f} seconds".format(decryption_time))
    # 路径按照自己的包体进行定义
    with open(file='game/gui/main_menu.png', mode='wb') as f:
        f.write(v_s)
def on_button_click():
    input_value = input_entry.get()
    if input_value == '123':
        decrypt_image()
root = tk.Tk()
root.title("键入激活码")
root.geometry("300x100")
input_label = tk.Label(root, text="输入激活码:")
input_label.pack()
input_entry = tk.Entry(root)
input_entry.pack()
button = tk.Button(root, text="Decrypt", command=on_button_click)
button.pack()
root.mainloop()


构建包体
Snipaste_2023-09-30_01-33-59.png

向目录中置入对应的文件,加密后的和解密的key文件+私钥文件置入

分发的目录结构一览
Snipaste_2023-09-30_01-42-43.png
完整demo效果:

                               
登录/注册后可看大图


总结:
1.因为PE文件的开放性质,理论上PE可以写的更小,更脏(不容易被反编译),性能更高(可以使用不同语言比如CPP,win32asm,basic,Go等等可以自己产生标准PE的语言编写,不同的语言的代码混淆器产生的文件也不相同)
2.外置PE的优点就是目录干净,对本体的影响最小,即使本体被解包,资源也需要单独解密。
3.笔者仅仅给出demo思路,可以理解完整流程后,编制属于自己的加密解密程序,可以尝试把笔者给出的demo改成内嵌到Renpy中(方法可以参考前面的几个帖子)
4.外置加密和内置加密各有不同的优点,内置可以无缝的配合renpy进行交互操作,外置更适合小型工作室,因为需求明确,可以外包出去让专业人员去编制特定的key文件。内置与renpy交互更加完美,也可以使用DLL按照我第一个帖子的方法尽可能的给用户最好的交互
5.编写配置合理外置PE解密,可以拖延破解时间到2周甚至一个月

工程文件:https://www.123pan.com/s/ADdHjv-hdMd3.html

评分

参与人数 1活力 +300 干货 +3 收起 理由
blackpineapple + 300 + 3 感谢分享!

查看全部评分

本帖被以下淘专辑推荐:

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

本版积分规则

小黑屋|RenPy中文空间 ( 苏ICP备17067825号|苏公网安备 32092302000068号 )

GMT+8, 2024-4-29 21:40 , Processed in 0.096099 second(s), 18 queries , File On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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