当前位置: 首页 > news >正文

Powerbuilder混淆,加密(powerbuilder防止反编译,pb混淆器,PB加壳,支持5-12) obfuscator for PowerBuilder

技术路线图:

版本:
pkb2.5
pb5,6,7,8,9,10,10.5,11,11.5,12
版本为pbvm.dll的版本,如pbvm115.dll。而不是指开发工具的版本。因为一个vm支持多个细微版本。

用于powerbuilder5-12的代码混淆和加密。做这程序的目的很简单,因为我一直在用powerbuilder做项目。时间大约有5年了。
曾撰文把pb比作钥匙链上的指甲剪,随拿随用,方便简单,但又不乏强大。防止破解是软件发行时最关心的问题。

自2009.6开始研究pbd文件格式。同期开始开发反编译器,现已基本成熟,因为有一些顾虑(不知道如何授权以及仅授权给需要的用户),
所以暂未释出。2010.3月研究PowerShield1.0简易版,并成功反混淆(估计是简易版的缘故,否则我不会感叹太容易反混淆)也撰文提到
PowerShield1.0简易版可能留有后门和安全系数不高的问题。PowerShield有点像三打祝家庄里的白杨树,一旦测试一个程序的不同加密
强度,其转弯标识清晰可见。如果在分析时设置一个检查栈,并适配假跳的规律,即可反混淆。尤以区分行间与行内为一个重要技巧,可完美反混淆。具体文字可见我blog中述。

其中代码混淆部分的思路参考LJTT的PowerShield1.0简易版,在此表示敬仰和感谢。鉴于pbkiller对pb9以下的程序造成极大伤害,
倒不是pbkiller有什么不对,关键在于它的授权泛滥。所以也给了极高的关注并在混淆时想办法加于克制。并对kivens表示敬仰。只要用
过混淆器的,pbkiller应该都不起作用。还有他对longlong类型的不支持,对unicode版本的不支持,基本无害,因为作者没针对性开发。把pb kill掉还要我们做什么呢?

主要特点:
1.修改了部分关键点参数,诱导早期的一些反编译器崩溃。没有人维护的反编译器就让他退出破解的应用场合吧。至于工程恢复,那是另话。


2.代码混淆部分原理参考LJTT的PowerShield1.0简易版,并在其基础上扩展出一些新的方式。还有些东西在脑子里,暂未实现。
2.1加入随机变化因子,这样使得反混淆器算法难度增加;
2.2增加了欺骗和逻辑陷阱,这些陷阱靠人眼是可以分析和发现的,但因为人脑是有逻辑思维能力,而靠编程是无法去理解我伪造的假代码的逻辑性的。从而会陷入我预设的逻辑陷阱中。

Beta后会扩展:
2.3在当前的工作基础上(9种)增加至36种(or 100种)左右的混淆方式,并限制在单机能测试到所有混淆方式,这样开发反编译器的人因为无法测试到所有可能性,从而加大反混淆的难度。最主要是混杂一些看似是正常代码的假跳转,(包括直接伪造本地变量参与的表达式,让人难辨真伪)相似性越高,越不容易判定,致使反混淆无法运用程序进行归纳识别。
2.4混淆前,查看变量列表中有否有一些可利用的变量,如int,long类型,可以进行伪造假的代码并添加进来与真实代码混杂在一起,或者对真实代码形成包裹与混杂,相似性更高。
2.5将多种方式离散在多个发行版本中。从而让反编译器无所适从。离散也包括按机器特征,时间,版本,授权种类等。尽量分散。
2.6其他动态语言的混淆器还没去参考,因为想先有个基本实现。java,c#等的混淆器应该已经很成熟,可以借鉴。
2.7还将在更多的数据段进行伪造。伪造的一个好处是,想反编译必须得先理顺并归置到伪造前。这个有点难。还有一个公理是:pb执行时是动态的,他用到的才会去呼叫并调用内存。而伪造的绝对不会被呼叫。但,但,反编译器并不知道,所以任何东东都会去屁颠屁颠地分析。
2.8数字和文字的等效替换,防止pj者直接搜索敏感位置。
2.9考虑到我的实现受制于代码长度,可利用代码太少,版本差异等因素,想到可给编程者预留陷阱标志(混淆器代为扰乱),程序员在代码编写上主动防御,则混淆后真假难分,模糊程度更好,陷阱隐蔽性更好。

3.抹掉所有不必要的可视文字,如RefListObject文字,var变量名,function名字和参数等文字。如此反编译器只能重新命名,从而无法还原可读性。代码功能的阅读在没有备注的情况下,很大程度依赖变量名,函数名。我们都是程序员,这个道理都懂。因函数与时间都可能被全局呼叫或动态呼叫(写在引号内),所以目前暂未对函数和事件名字采取措施。处理上应该也相当麻烦。

4.增加了欺骗对象或函数。虽然借助对本软件的反复调试,反混淆器作者可以发现规律,但是因为欺骗对象带随机因子,在没有参考物的情况下,要校验一个对象的格式完整性和正确性,目前还没人有那个能力。除非就是到处用断言,总归很难判定。就如用视觉鉴别一瓶纯净水和一瓶汽油一样。反混淆器就会不小心陷入其中。

5.增加对象内函数或事件造假功能。因为考虑到反编译器会提供单点反编的调试开关,所以尽量细化到每个pbd文件,每个对象,每个函数事件,每段代码都可能出现阻止反编译器的有效手段。如果能轻易绕过,那岂不是白搭。上2.9就是居于这种考虑。除反混淆和反编译开发者外,一些使用反编译器的普通人是不知道反编译器为什么会中途异常退出的,因为他们没反编译器源码,也无法单步调试。他们对此种情况也无能为力(要的就是这种效果)。反编译器开发者也不会去为一个不确定的规律而修改程序。

6.对一些可有可无,但对pbd格式肉眼分析有帮助的地方都尽数抹掉了,从而增加肉眼人工分析的错觉感。我的原则是抹掉一切可抹掉之字节,扰乱一切可扰乱的字节。


目前可以确定在格式解析和基本框架上无错。但是码表依然不完整(截止2010.5.12尚差30个),如果测试到错误(unknown pcode),请告知。但是请注意,请用full编译通过的程序测试,不要用那种编译出错,或者编译到一半异常退出的pbd来测试,它本身就是有问题(这在反编译器开发时遇到过)


还有种错误如link error。实际就是失败了。

建议:

强烈建议只对系列号管制,注册,在线人数限制等关键代码或关键算法等地方进行加密混淆,对于一般的数据录入查询等,没必要进行加密混淆,因为加密混淆数倍,数十倍冗余代码,从而造成执行效率低下。并不是其他混淆器所说的只减慢一点点。我测试我的pb11项目时发现有能感觉得到的延迟。当然是设置的强度非常大的情况下。同时为避免不必要的麻烦,系列号管制等代码,请放在一定数量的代行之后,如100行,不管怎么说,测试版的反编译器都会对可以阅览的代码行有一个限制(因为那个原因...)。这在一定程度也保护了自己的代码。程序的写法上也有一些技巧,并非如平常代码一样编写。


使用:

1.把你的以p-code编译方式的文件放入到一个临时文件夹,如d:/123
为什么要放入一个临时文件夹,而不是直接对文件操作,因为混淆过程可能失败,失败情况下文件会被写入一些数据,pbd在被处理前先会备份成".bac"为扩展名的备份文件(bak跟ue的自动备份冲突),当处理后发现问题,可以第一时间恢复,但是当您选择另外一个文件名后,就无法恢复前一个文件了,你可以打开临时文件夹,自行恢复。
处理过程必须一气呵成,不能分几次进行。


2.按软件界面的"load files"按钮,选择一个exe,dll,pbd格式文件(machine-code编译方式的单一exe文件和pbni方式的除外,提示: dll文件,如果不是单一exe文件, dll还是含有伪代码),随即,文件内的所有对象将在左边的两个CheckListBox中列出(仅仅处理uo,win,func,其他对象类型我认为没必要处理如menu)。其中上面一个CheckListBox中勾选的对象将被加密和混淆下面一个CheckListBox中勾选会将此对象扰乱,主要是欺骗和让反编译软件运行时崩溃。利用的一个普遍真理是:反编译程序很难校验文件的格式有效性。就比如我从一个对象的二进制系列中随机删除一个。你看不出问题,但是你分析立马死掉。道理很简单。虽然你能用uo的二进制对比发现我修改了哪些地方,当然我是随机地。但最终用户使用混淆器处理后,他的原始pbd是不会给你的。你就无法对比了。就好比被修改过的电影剧本,你拿到
新版本你无法知道跟老版本的差异在哪里一样。这是公理,不是歪理。只有一个可以检测得到,那就是反编译器的崩溃,或者是从外部调用它会崩溃。所谓兵不厌诈。
一般建议在10个对象中放置2-3个这样的“从来都不会用到“的废对象作为欺骗对象。一般来说,按照我的经验,必然使得反编译器崩溃。在对象命名上要同其他对象名字无什么差别,就是不要让人一眼看出即可。切忌不可以有什么规律,否则pj者给你屏蔽掉。就如同正常对象一样命名。


3.点"Confuse"按钮,代码被处理。
正常情况下显示如下:
FilePath: D:/pbr测试样本/pb9/ //文件信息
FileName: pxx.pbd
FileLength: 20480bytes
ObjQty: 5
Unicode/Ansi: Ansi

Version: PowerBuilder/vm:9.0/vi:108691/build:8836 //版本信息


-########Write File finished,Object: uf_bitshl.fun //修改后写入“########”为正常标志
Old Len: 1394,New Len: 4552

Close File normally. //关闭文件

如果出现其他提示,就是不正确(提示前有"++++++++"连续加号标志,就是重大错误或失败,如空间不足等提示就表示处理不成功,如下:
Obj:n_cst_dw2excel.udo,Ctrl:n_cst_dw2excel,funcID: 21
-++++++++Can't find enough space to dispose Code-Chip,[failing] //程序切片不能够放在既有的空间里。程序会

//跳过。如果是你的注册函数,

Code = 0x39,step: 4600 of 5481 //那肯定不行.因为寻址空间为0xFFFF,所以

//5481个是会出现问题的。

你必须调整扩展的空间大小(在options标签页,9-30倍可选,但是因为寻址空间oxFFFF,是有限的,如果切片太多就放不下),当然在调整空间前,你可以尝试2-3次,因为程序在寻找一个放代码的空间时会尝试100次,但是有时还是会存在本来有空间,但是却不凑巧的可能。程序采用随机寻找位置而非遍历来找空间。

但是类似这些信息是正常的:-------------Empty expression,Skip.Ctrl:usv_datawindow,funcID: 1
它表示跳过空的代码段,但是现在这些无聊信息我已经屏蔽掉。只显示关键信息了。

为了不给其他人蓄意调试本软件的处理结果,调试也无所谓。我有我的思路应对,options中除了"代码扩展倍数"和"插入冗余的密度"可以选择外,其他选项都不可以改变。代码太少,大约小于20行(100个切分段),也不会被混淆。因为代码太少,如一句。用眼睛就可以反编译。

4.2010.5.12新增移除dll编译方式下的PCODE伪码,虽然用ue手工移除过几个进行测试,发现能运行正常(就是Pcode是多余的,只是产生机器码的临时过渡),但我仍然不保证结果正常,以前听说过pb的机器码编译方式是机器码和伪码参半的,也没去研究。编译机器码时动辄几十分钟,够Lan的。所以作为一个选项给你自己勾选。移除后是否能运行正常,你自己测试。

5.2010.5.12新增伪造一个对象的内部函数,如你写有一个函数,如of_today,你想让他变成一个阻止反编译的地雷,那请在左下方的memo里输入该函数名“of_today”,可以输入多个,每行一个。处理对象时,将核对如果函数名符合,则将func或者event的码进行扰乱。比如用随机数覆盖开头的几个码即可达到目的。当然这个函数肯定应该是废函数。只要名字相同,不管他在哪个对象,哪个控件的哪个地方。当然,你混淆其他的项目时应该及时删除它否则会把其它程序里同函数名的函数搞乱了。你最好约定使用一个名字来命名你的地雷,在你的整个项目里。

2.VM解析的修改+pbd文件格式的修改加密,目前还没足够时间去跟踪调试。技术方面的实现有些难度。
但是我想在不久的一段时间,在我项目空暇时间,必然会走这个思路。说到安全系数问题,可能"定制vm+pbd格式加密",才能称得上牢靠。这个ljtt早说过,但是很遗憾未见其形。因为定制vm和加密pbd文件时都可以设置很多随机因子,致使每家的文件不一样,加之pbd和vm互为配合(狼狈为J),从而从根本上防止反编译。当然并不是看到我这个提示你就去完成一个对文件格式的全部加密的代码嵌入到vm中,那样必然有人去研究如果反。因为太明显了。不过并非易事。

重申安全性:
混淆器理论上是无任何安全保障的,它只能保障反编译器在基于机械反向时对打乱的statement无法做到真实还原,也无法还原文字可读性,还有无法还原已经被模糊化或者做等效替换的部分。除此之外,因为程序的逻辑顺序并未打乱,所以如果靠人工,不管欺骗,陷阱,冗余,都能被去除,如果辅于工具,假以时间,是可以正确还原的!!!这其中主要的症结在于伪码编译不是太低阶,甚至于很容易理解和还原成高级语言。这就是伪码本身的不安全性。这和java,c#,以及早期的vb等类似。当然也得说说伪码的反面,因为偏偏是那种编译成机器码的程序,往往容易被跟踪调试。从而在高手的一个NOP就搞定了。喜欢看汇编的人看汇编时跟我们看程序可能是一样的。就说pb开发工具,每每都是放出来几天,高手就贴出补丁来。就如最近的v12,就被一串空操作简单搞定。所以混淆器并不保障程序安全。只是提高反编译的难度系数。

可以预见的错误:
因为永远不可能掌握跟sybase一样的p-code码表,所以无法保证切分代码时正确无误,但是基本可以保障常用写法时能正确。码表会在足够数量的测试下逐渐命中那些小概率的码。代码的正确切分是混淆的必要保证,否则就一错到底了。所以,在进行混淆后请自行测试程序。万一出错,造成授权或限制不起作用那就不要怪我了。现在我未掌握的未知码,都有标示出来,在混淆时都会提示unknown pcode,所以会很快完善,包括我自己也会大量测试自己的项目,pb sample和网上下载的代码,会很快完善的。

如果遇到错误或者混淆后无法运行,或者运行时报错,请将截图和测试用的pbd文件一起发给我(如果纯粹测试的pbd可以发给我,如果是商业的程序,请不要发给我,但为了能完善混淆器,可以单独将出问题的对象复制到一个新的pbl中并编译成pbd然后发给我,这样我不会太了解你的程序是干嘛使的)

额外提示:
请在发行程序时进行full编译,full编译通过后再进行混淆。

附图:

选项:

正在改成中文界面并推出正式版:

http://www.jsqmd.com/news/898941/

相关文章:

  • 告别纹理模糊和卡顿:一份给UE4开发者的纹理流送(Texture Streaming)优化配置清单
  • 避坑指南:RK3588 MIPI DSI显示调试中常见的5个问题与解决方法(附Log分析)
  • 买商标去哪里好?2026 商标交易平台精选 + 完整选购攻略 - 资讯纵览
  • 智能电网多智能体系统与IEC 61850融合:技术框架与工程实践
  • brooks-lint v0.7.0:基于经典软件工程原则的AI代码审查工具
  • Honey Select 2一站式汉化补丁:5分钟完成完整汉化与MOD整合
  • Cadence OrCAD Capture CIS实战:从零构建原理图与元件库
  • 用MIPSsim模拟器手把手教你理解CPU流水线冲突(附定向技术实战对比)
  • vETSTStudio CAPL脚本实战:3个函数搞定CAN/CANFD网络管理中的未使用位自动化测试
  • 接口测试Moco
  • 电商网站利用Taotoken大模型API实现智能客服与商品描述的自动化生成
  • 阿里云发布RCA Benchmark:业界首个解决AI Agent评估难题,构建运维智能体评估体系
  • 2026年AI智能体监控新选择:TraceHawk与Datadog深度对比
  • 如何免费解锁12种加密音乐格式:Unlock Music终极指南
  • METADEF 元数据定义 - 算子元数据管理机制
  • 实战复盘:用Python+Requests搞定那个烦人的WIPO六宫格验证码(附完整代码)
  • 解锁学术创作新思路:paperxie 论文智能撰写功能实用使用指南
  • 液体处理技术核心参数与自动化优化实践
  • 告别重复劳动!用AutoHotKey脚本一键搞定文件整理与备份(附完整代码)
  • 告别V4L2的复杂性?试试用libuvc库在Linux上更灵活地控制USB摄像头
  • RISC-V RV32I指令集编码实战:手把手教你用Python解析指令二进制(附完整代码)
  • 在 Taotoken 模型广场对比主流模型特性与定价进行选型
  • 基于Amazon Bedrock与HTTP流式传输实现Web应用实时AI摘要
  • 博弈论视角下的多域NFV资源编排:竞争与联盟策略解析
  • MRAE自编码器:混合正则化实现鲁棒特征提取
  • 深入解析STM32控制张大头闭环步进驱动器:从数据帧到多电机协同的避坑指南
  • 告别命令行恐惧!用nTopology可视化工具5分钟搞定三维Voronoi泡沫建模
  • 学术创作效率升级:paperxie 学术写作模块解锁毕业论文高效撰写模式
  • ShotgunWSD 2.0:基于k-means聚类的无监督词义消歧算法详解
  • 回声消除实战:用MATLAB手把手实现频域分块LMS(FDAF)算法