`
buliedian
  • 浏览: 1243726 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

powerbuilder P-code 中的JP跳转指令的反向工程

阅读更多

在我的decomplier中关闭JP to statement开关后,得到原始的未经过处理的跳转指令。

类似汇编中我们写的跳转。这就是高级语言和低级语言的差别。低阶语言更繁琐和趋近于机器处理过程。比如汇编中的寻址,基本就是cpu取数和处理数的一个过程。

P-code中,顺序结构倒好处理,直接把赋值,函数调用搞定也就没什么了,唯一需要处理的是这些跳转。

在汇编中,有许多种的跳转,比如等跳,不等跳等等。。但是在高级语言,如pb中,语言有bool的明确规定,所以if while等conditon部分都必须是bool类型的结构,这也就是c++中比较你写=,不写==不会发生错误的原因,你在pb中的条件判定处写=,编译器就知道是逻辑意义上的判断,而不是赋值。因为没有其他值到bool的隐式转化。所以在pb中,我们只有三种跳转,JTP,JFP,JXP,分别是“为真跳”,“为假跳”,“绝对跳”。当然只是知道这三种区别还不行,还没足够信息反向成高级语言中的statement,我们在分析代码时,顺便在前期已经将跳转时当前offset,和will to address做了比较,区分出了“往前跳”,还是“往后跳”,这样我们不会在长长的字符串中再来繁琐地判定(效率低)。

我们编写了几种结构加于分析区别,以便还原。找出其中一些规律。因为现代编程习惯中,已经废弃了goto的使用,虽然它还是关键字,但是我们约定,我们写的statement都是成块的。这样有助于我们得到一个模糊的表述。

代码 _0012: _L_ (1) = 2 _J_F_F_0032

意义: 地址 logic expression JP

我们拿两个相近似的结构来对比:

(A)

_0000:ls_note = "if ... end if"

_0012:_L_ (1) = 2 _J_F_F_0032
_0024:ll_1 = 1
_0032:

(B)

_0052:ls_note = "if ... else ... end if"
_0064:_L_ (1) = 2 _J_F_F_0088
_0076:ll_1 = 3
_0084:_J_X_F_0096
_0088:ll_1 = 3
_0096

在a结构中我们看到,可以这么描述我们即将编程的伪码:

如果存在logic(没有logic的话,那就只有goto语言产生的绝对跳转了),并且存在“往后跳”,并且遍历当前行到“跳转目标行”之间再无“logic”和“其他跳转指令”,那我们复活成一条“if ... then ... end if”语句。

在b结构中,我们描述为:

如果存在logic,并且存在“往后跳”,并且遍历当前行到“跳转目标行”之间存在“绝对往后跳”,那我们复活成“if ... then ...else ...end if”语句。

当然,这也存在嵌套问题,我想出于简化的设计思路,就没必要用递归。可以采用层层剥菜的方式,先处理内层,处理完后扫描一次即可。

就是必须把“最小的块”找到,然后先处理。

以上只是大致思路。还未具体实现,估计得耗时几天才能处理好。

//20090908:statement反向已经满意搞定,包括缩进显示,都搞好了。

//object name: lf_333.fun
global type lf_333 from lf_333
end type

forward prototypes
global subroutine lf_333() throws exception
end prototypes

global subroutine lf_333() throws exception;
//variables list
longll_1
longa
stringls_note
//global var: stringgs_id5

//expression lines: 66

gs_id5 = ""
ls_note = "if ... end if"

if 1 = 2 then
ll_1 = 1
end if

ls_note = "if .do loop unitl. end if"
1 = 2
ll_1 = 2

do
ll_1 = 8

if 1 = 2 then
ll_1 = 2
end if

loop while ll_1 = 0

ls_note = "if ... else ... end if"

if 1 = 2 then
ll_1 = 3
ll_1 = 3
ll_1 = 3
else
ll_1 = 3
ll_1 = 3
ll_1 = 3
end if

ls_note = "do while ... loop"

do while ll_1 = 0
ll_1 = 5
loop

ls_note = "do until ... loop"

do until ll_1 = 0
ll_1 = 6
loop

ls_note = "do ...loop while"

do
ll_1 = 7
loop while ll_1 = 0

ls_note = "do ...loop until"

do
ll_1 = 8
loop while ll_1 = 0

ls_note = "if if if if if end if end if end if end if"

if a = 0 then

if a = 0 then

if a = 0 then

if a = 0 then
a = 0
end if

end if

end if

end if

ls_note = "choose case.. end choose"

choose case ll_1
case 1
ll_1 = 111

case 2
ll_1 = 111

case 3
ll_1 = 111

case 4
ll_1 = 111

case 5
ll_1 = 111
end choose


choose case ll_1
case 1
ll_1 = 222

case 2 , 3 , 4 , 5
ll_1 = 222

case 2 to 5
ll_1 = 222

case is >= 3

do while 1 = 2
ll_1 = 222
loop

ll_1 = 222

case (1 ) , 2 to 5 , 5
ll_1 = 222
end choose


end function

////////////////////////////////////////////

顺便写写关键字的缩进处理。

声明结构并初始化:

const strc_INDENTATION KEY_INDENTATION[MAX_KEY_INDENTATION] = {
1,"if",2,
3,"else",4,
3,"elseif",6,
2,"end",3,
1,"for",3,
2,"next",4,
4,"choose",6, //特殊,因为case要 -t
5,"end choose",10, //特殊,因为case要 -t
3,"case",4,
1,"while",5,
1,"do",2,
2,"loop",4,
1,"try",3,
3,"catch",5,
3,"finally",7
};

//直接给代码,很简单也不用解释了。

int iIndent0 = 0; //current
short iChanged;
astring asIndent;
char chFirst;

ilines = MemoProcess->Lines->Count;

for(int i = 0;i < ilines;i++){
iChanged = 0; //是否改变缩进个数
chFirst = MemoProcess->Lines->Strings[i][1];
if ('i' == chFirst || 'e' == chFirst || 'f' == chFirst || 'n' == chFirst ||
'c' == chFirst || 'w' == chFirst || 'd' == chFirst || 'l' == chFirst || 't' == chFirst)
{
for(int k = 0;k < MAX_KEY_INDENTATION;k++){
if(LeftStr(MemoProcess->Lines->Strings[i],KEY_INDENTATION[k].cLen) == KEY_INDENTATION[k].KeyWords){
iChanged = KEY_INDENTATION[k].flag;
break; //匹配后退出for内层
}
}
}

switch (iChanged){
case 0: //no changed
if (iIndent0 > 0) {
MemoProcess->Lines->Strings[i] = asIndent + MemoProcess->Lines->Strings[i];
}
break;
case 1: //do this,next to change
if (iIndent0 > 0) {
MemoProcess->Lines->Strings[i] = asIndent + MemoProcess->Lines->Strings[i];
}

asIndent = AnsiString::StringOfChar('\t',++iIndent0);
break;
case 2: //change first,then do this row
if (iIndent0 > 0){
asIndent = AnsiString::StringOfChar('\t',--iIndent0);
}

if (iIndent0 > 0) {
MemoProcess->Lines->Strings[i] = asIndent + MemoProcess->Lines->Strings[i];
}
break;
case 3: //change +t,do this row,then -t for next
asIndent = AnsiString::StringOfChar('\t',++iIndent0);
if (iIndent0 > 0) {
MemoProcess->Lines->Strings[i] = asIndent + MemoProcess->Lines->Strings[i];
}

if (iIndent0 > 0) {
asIndent = AnsiString::StringOfChar('\t',--iIndent0);
}

break;
case 4: //using choose所以必须先加2t
++iIndent0;
asIndent = AnsiString::StringOfChar('\t',++iIndent0);
if (iIndent0 > 0) {
MemoProcess->Lines->Strings[i] = asIndent + MemoProcess->Lines->Strings[i];
}

if (iIndent0 > 0) {
asIndent = AnsiString::StringOfChar('\t',--iIndent0);
}

break;
case 5: //using end choose所以必须先 -2t
if (iIndent0 > 1) {
iIndent0 -=2;
asIndent = AnsiString::StringOfChar('\t',iIndent0);
}

if (iIndent0 > 0) {
MemoProcess->Lines->Strings[i] = asIndent + MemoProcess->Lines->Strings[i];
}

break;
}
}

//附:

global subroutine lf_333() throws exception;
//variables list
longll_1
longa
stringls_note

//exprssion lines: 42
_0000:ls_note = "if ... end if"
_0012:_L_ (1) = 2 _J_F_F_0032
_0024:ll_1 = 1
_0032:_L_ (1) = 2 _J_F_F_0052
_0044:ll_1 = 2
_0052:ls_note = "if ... else ... end if"
_0064:_L_ (1) = 2 _J_F_F_0088
_0076:ll_1 = 3
_0084:_J_X_F_0096
_0088:ll_1 = 3
_0096:ls_note = "if ... elseif ... end if"
_00A8:_L_ (1) = 2 _J_F_F_00CC
_00BA:ll_1 = 4
_00C8:_J_X_F_00EC
_00CC:_L_ (2) = 3 _J_F_F_00EC
_00DE:ll_1 = 4
_00EC:ls_note = "do while ... loop"
_00FE:_L_ (ll_1) = 0 _J_F_F_0120
_010E:ll_1 = 5
_011C:_J_X_B_00FE
_0120:ls_note = "do until ... loop"
_0132:_L_ (ll_1) = 0 _J_T_F_0154
_0142:ll_1 = 6
_0150:_J_X_B_0132
_0154:ls_note = "do ...loop while"
_0166:ll_1 = 7
_0174:_L_ (ll_1) = 0 _J_T_B_0166
_0184:ls_note = "do ...loop until"
_0196:ll_1 = 8
_01A4:_L_ (ll_1) = 0 _J_F_B_0196
_01B4:ls_note = "if if if if if end if end if end if end if"
_01C6:_L_ (a) = 0 _J_F_F_0214
_01D6:_L_ (a) = 0 _J_F_F_0214
_01E6:_L_ (a) = 0 _J_F_F_0214
_01F6:_L_ (a) = 0 _J_F_F_0214
_0206:a = 0
_0214:_END
end function

分享到:
评论

相关推荐

    Powerbuilder 11.5.1 - Patch (4897)

    在PowerBuilder 11.5.1版本中,补丁4897是一个重要的更新,它旨在解决用户在使用过程中可能遇到的问题,提高软件的稳定性和性能。本文将深入探讨这个补丁涉及的核心组件及其作用。 首先,我们关注到两个关键的DLL...

    Fast Track To Powerbuilder DEV-133

    Fast Track To Powerbuilder DEV-133 Material Study for Certification Exam, applies to for SAP Certification

    PowerBuilder12.5-12.6所有版本

    在PowerBuilder 12.5中,开发者可以期待以下关键特性: 1. **数据窗口增强**:数据窗口是PowerBuilder的核心组件,用于显示和操作数据库中的数据。12.5版本增加了对更多SQL语法的支持,改进了数据处理能力,以及...

    Powerbuilder 12.5 - ebf 4953

    EBF(Error-Bug-Fix)4953是一个更新补丁,旨在解决PowerBuilder 12.5中的错误和问题,提高软件的稳定性和性能。 在PowerBuilder开发环境中,DLL(动态链接库)文件如PBSHR125.DLL扮演着至关重要的角色。它们包含了...

    powerbuilder课件--powerbuilder函数

    powerbuilder课件之powerbuilder函数学习,通过此文档,变可学习进行开发,非常实用的课件。

    PowerBuilder 9.0-课件+实例源代码

    PowerBuilder 9.0-课件+实例源代码 【郑州大学升达经贸管理学院】 第一章pb简介 第二章 应用程序对象 第三章 PB基本语言 第四章 嵌入式SQL 第五章数据库创建和连接 第六章数据库管理 第七章窗口与菜单设计

    PowerBuilder-9.0-实用解析

    作 者:郭宝利编著 康海涛编著 李冬冬编著 价 格:CNY68.00 出版者:北京:电子工业...介绍PowerBuilder 9.0的开发环境、技巧以及笔者多年来的PowerBuilder开发经验,包括C/S开发,B/S应用开发和PowerBuilder扩展功能。

    Powerbuilder11-12.5破解补丁

    Powerbuilder11-12.5全部破解补丁

    PowerBuilder打印QR Code

    在IT行业中,PowerBuilder是一款经典的可视化数据库应用开发工具,它以其强大的数据窗口功能和便捷的编程环境深受开发者喜爱。在现代应用中,二维码(QR Code)作为一种高效的信息载体,广泛应用于各种场景。本主题...

    PowerBuilder-Oracle-环境

    本资源“PowerBuilder-Oracle-环境”专注于在不安装完整Oracle客户端的情况下,搭建和配置PowerBuilder与Oracle数据库的连接环境。这有助于减少系统资源占用,提高开发效率。 首先,了解PowerBuilder。PowerBuilder...

    PowerBuilder-Classic-12.5开发环境

    PowerBuilder-Classic-12.5开发环境,PowerBuilder Classic 12.5中的Workspace是增强的IDE,通过它,用户可以将开发整个应用程序所需的各种资源进行有效的组织和管理.

    PowerBuilder12.1-EBF18538-6639

    PowerBuilder12.1-EBF18538-6639 好不容易找到的,保证可用。本来想传破解文件的,但太大了传不了,想要的可以搜下网上都有的,或者可以邮件找我要:401882644@qq.com

    SQL SERVER 2005+POWER BUILDER 9.0-人力资源管理系统-含数据库

    《SQL SERVER 2005+POWER BUILDER 9.0-人力资源管理系统》是一个结合了两种强大技术的项目实例,旨在帮助开发者深入了解如何利用数据库管理工具SQL Server 2005与可视化开发环境PowerBuilder 9.0来构建高效、功能...

    powerbuilder-12.5.1-4953-破解

    powerbuilder-12.5.1-4953-破解

    powerbuilder9 连接 oracle 10g (使用 jdbc 来连接)

    本文将详细介绍如何在 PowerBuilder 9 中配置并实现与 Oracle 10g 数据库的连接。 #### 一、JDBC 概述 JDBC 是 Java 开发环境中用来连接各种关系型数据库的标准接口。它提供了一套标准 API,使 Java 应用程序能够...

    powerbuilder过去现在与未来

    PowerBuilder 11 --- 加速.NET应用程序开发 回首PowerBuilder发展史 简介PowerBuilder 11.0 新功能 展望PowerBuilder 的未来 PB .NET概述 .NET WebForm 应用程序开发等

    powerbuilder-保存为pdf和xsl文件

    PowerBuilder是一款强大的企业级开发工具,广泛应用于快速应用开发(RAD)环境中。随着版本更新,PowerBuilder 9引入了一项新特性——允许用户将DataWindow对象保存为PDF文件。这一功能的引入极大地提升了应用程序的...

    PowerBuilder2018破解+去试用标题补丁

    PowerBuilder2018破解补丁,使用本补丁可免费使用PowerBuilder2018,补丁仅供测试研究使用,请下载后24小时内删除。

    PowerBuilder-Access-DB.rar_Access db_PowerBuilder_access_db

    在提供的压缩包中,"PowerBuilder-Access-DB.doc"可能是详细的教程文档,它可能包含上述步骤的详细说明和示例代码。而"www.pudn.com.txt"可能是一个链接或者资源说明,指向更多关于这个主题的资料来源。 学习并掌握...

    PowerBuilder 9.0 中文帮助手册

    PowerBuilder是一款由Sybase公司推出的数据库应用快速开发工具,自1991年发布1.0版本以来,就因其高效快捷的集成开发环境、简洁友好的用户界面、功能强大的数据窗口技术以及性能优越的数据库访问能力而受到广大...

Global site tag (gtag.js) - Google Analytics