longpelaexpertise.com.au/ezine/DisAssemblers.php?ezinemode=printfriend

LongEx Mainframe Quarterly - August 2012

technical: Assembler Disassemblers

At a recent client site, I came across a suspicious load module that didn‘t seem to be a part of any software product. It was APF authorized, but no one knew what it did. Browsing the load module showed no copyright statements, so it was probably 'home-grown.' To find out more, the next step was one that few are brave enough to try - disassemble the module.

A disassembly takes the module, and produces corresponding assembler code - even if the program was not originally written in assembler. From this code, assembler programmers can determine what is going on inside. Although reading a disassembled module requires good assembler skills, producing a disassembled listing doesn't. In this article, we're going to look at disassembling programs. But first a warning:

Laws and software license agreements often prohibit reverse-engineering of software products. Never disassemble a module that forms part of a licensed software product without confirming that no laws or agreements will be broken. As a rule of thumb, I never disassemble a module if I can find a copyright statement from ISPF browse, unless I'm working with the copyright owner.

Commercial Disassemblers

Let's take an example program. Below is a simple assembler program that outputs a WTO, and returns.

DZSTST1  CSECT            
         BAKR  R14,0      
         LR    R12,R15    
         USING DZSTST1,R15
         WTO   'DZSTST1'  
*         DC    X'00000000'   Force abend
         XGR   R15,R15    
         PR               
         YREGS ,          
         END

This is a good test program: it has a 64-bit instruction (XGR), and an SVC (WTO). The commented instruction is used to force an abend. I'll show you why shortly.

There are several commercial disassemblers on the market. The best-known is the disassembler that forms part of the IBM HLASM Toolkit. This is called from a batch job that will look something like:

//DAVIDD1  JOB MSGCLASS=C,MSGLEVEL=(1,1)
//DISASM   EXEC PGM=ASMDASM             
//STEPLIB  DD DISP=SHR,DSN=HLA.SASMMOD2 
//SYSLIB   DD DISP=SHR,DSN=DAVID.LOADLIB
//SYSPRINT DD SYSOUT=*   
//SYSPUNCH DD SYSOUT=* 
//SYSIN DD *  
DZSTST1

It can be used to disassemble traditional load modules, object modules and PDSE program libraries. SYSIN specifies the load module, and CSECT name if there are more than one. For our example program, the HLASM Toolkit produces the following disassembled output.

DZSTST1  CSECT       
         BAKR  R14,0
         LR    R12,R15
         NOPR  0
         BRAS  R1,*+16
         DC    XL4'000B0000'
         DC    CL7'DZSTST1'
         DC    XL1'00'
         SVC   35                             WTO/WTOR
         XGR   R15,R15
         PR
         ASMDREG
         END

The output is almost the same as our original. The HLASM Toolkit obviously cannot reproduce any comments or labels - it’s ‘bare bones’. The WTO macro is also shown in its pure assembler format, though the HLASM Toolkit is nice enough to let us know that SVC 35 is the WTO SVC.

Serena's StarTool SDM needs no JCL. Simply list the load library, and type DI next to the module.

** DISASM   DZSTST1
 PDS141I AT 00000000:00000020 IN:B_TEXT/DZSTST1
 00000000 DZSTST1 CSECT
 00000000 DZSTST1 AMODE 24
 00000000         RMODE 24
 00000000         BAKR  R14,R0              B240 00E0         *. .\*
 00000004         LR    R12,R15             18CF              *..*
 00000006         NOPR  R0                  0700              *..*
 00000008         BRAS  R1,*+16             A715 0008         *x...*
 0000000C         DC    X'000B0000'         000B0000          *....*
 00000010         DC    C'DZSTST1',X'00'    C4E9E2E3E2E3F100  *DZSTST1.*
 00000018         DC    X'0A23B98200FF'     0A23B98200FF      *...b..*
 0000001E         DC    X'0101'             0101              *..*
 PDS142I 1 CSECTS in this member

The StarTool ISPF interface is very nice, and it handles modules with multiple CSECTs with ease. However the disassembly didn‘t cope well with our SVC instruction.

An often forgotten utility, the IBM AMASPZAP program comes free with z/OS, though its use is usually restricted to Systems Programmers. A little known fact is that AMASPZAP can also be used to output a semi-disassembled format of a module. The following is the JCL:

//DAVIDAMB JOB MSGCLASS=C,MSGLEVEL=(1,1)
//STEP1    EXEC PGM=AMASPZAP
//SYSPRINT DD   SYSOUT=*
//SYSLIB   DD   DISP=SHR,DSN=DAVID.LOADLIB
//SYSIN    DD   *
  DUMPT DZSTST1

This job produces output like:

B240 00E0  18CF 0700  A715 0008  000B 0000
 BAKR       LR   BCR   BRAS

C4E9 E2E3  E2E3 F100  0A23 B982  00FF 0101
UNPKUUNPKU MVO   SVC  XGR        PR 

AMASPZAP will translate the instructions, but not much else. It also gets confused with our WTO macro‘s data constants and SVC.

Other commercial disassemblers can be found in software such as Colesoft z/XDC.

Free Disassemblers

There are also several free disassemblers on the CBT website. Dick Thornton's disassembler is in File 234, and for our test program produced:

DZSTST1  CSECT                                                           
         BAKR  R14,R0                               000000 B24000E0
         LR    R12,R15                              000004 18CF
         NOPR  0                                    000006 0700
         BRAS  R1,*+16                              000008 A7150008
         DC    XL4'000B0000'                        00000C 000B0000
         DC    CL6'DZSTST'                          000010 C4E9E2E3... 
         MVO   2595(1,),2434(1,R11)                 000016 F1000A23B982
         DC    XL2'00FF'                            00001C 00FF
         PR                                         00001E 0101

Unfortunately, his utility did not cope well with our WTO data constants and SVC. His disassembler is no longer being updated, though he does include source code in File 234.

Arthur Fichtl's disassembler is in File 773, and is written entirely in REXX. Unlike other disassemblers, it is designed to disassemble short opcode strings displayed on a screen. For our test program, it produces:

     Instructions
---- -----------------------------------
+000    B24000E0     BAKR    R14,R0
+004    18CF         LR      R12,R15
+006    0700         NOPR    R0
+008    A7150008     BRAS    R1,*+16

In other words, it stops when it comes across the data constant (DC) statements from our WTO.

Disassembling Modules in Dumps

The previous programs are great if disassembling a module. However there are times when disassembly of a module from a dump is needed. The solution is dump analysis software such as Compuware FileAid and IBM Fault Analyzer.

For our testing, we removed that commented out instruction in our sample program to force a x'0C1' abend and dump. The DISASM primary command in Fault Analyzer produces the following output from this dump:

JOBNAME: DAVIDRUN  SYSTEM ABEND: 0C1            S0W1      2012/07
Address  Offset    Hex            Instruction
00007FD8        +0 B240 00E0      BAKR    R14,0
00007FDC        +4 18CF           LR      R12,R15
00007FDE        +6 0700           BCR     0,0
00007FE0        +8 A715 0008      BRAS    R1,*+16
00007FE4        +C 000B0000
00007FE8       +10 C4E9E2E3
00007FEC       +14 E2E3 F100 0A23 UNPKU   256(228,R15),2595
00007FF2       +1A 0000
00007FF4       +1C 0000
00007FF6       +1E B982 00FF      XGR     R15,R15
00007FFA       +22 0101           PR

Not bad, though it was confused by our WTO SVC.

Commercial dump analysis software isn't the only solution. IPCS can also help. The primary IPCS command

LIST address.  LENGTH(len) INSTRUCTION
will provide a disassembled output from a dump. IPCS produces the following for our (abending) example:
LIST 7FD8. ASID(X'002F') LENGTH(X'64') INSTRUCTION
00007FD8 | B240 00E0      | BAKR    R14,0
00007FDC | 18CF           | LR      R12,R15
00007FDE | 0700           | BCR     X'0',0
00007FE0 | A715 0008      | BRAS    R1,*+X'10'
00007FE0 LENGTH(X'0C')==>Skipped by jump. Displayed as AREA
00007FE4. 000B0000 C4E9E2E3 E2E3F100          |....DZSTST1.    |
00007FF0 | 0A23           | SVC   X'23' WTO/WTOR, type 4, calls IEAVM600
00007FF2 LENGTH(X'4A')==>Displayed as AREA
00007FF2.     0000 0000B982 00FF0101 00000000 |  .....b........|
00008000 LENGTH(X'30')==>All bytes contain X'00'
00008030. 00000000 00000000 00000000          |............    |

IPCS has done better than Fault Analyzer, disassembling our code up to our data constant of zeroes. It's even identified data constants, and let us know that SVC 23 is the WTO SVC. IPCS can also be used to disassemble programs currently in memory by setting the source to ‘ACTIVE’.

An interesting alternate for Websphere Application Server users is the Dump Utility program of the Switched Virtual Circuit (SVC) Analyzer utility, svcdump.jar. The -dis command will produce a disassembled output of an address.

Conclusion

Disassemblers are in many cases your only option to determine the processing performed by a module without source code. Although there are several commercial products, free z/OS features and software can also get you close. The reality is that good assembler knowledge is essential to get benefit from disassemblies. There is rarely a perfect disassembly, and so good skills will be needed to fill in any gaps.


David Stephens