Copyright 2024 - BV TallVision IT

Worried about someone stealing your code ? Do you want to copy-protect your coding ? But SAP is an open source system: Abap developers can look under the rug and sift through all coding with great tools like the Abap editor and the debugger. So what's to stop a third party from stealing your ideas ? The copywiter. 

The copywriter does the following to your coding:

  1. Copy the original source and park it somewhere. Encrypted. 
  2. Strip all non-essentials from the coding. 
  3. Generate new names for all local variables (that is: in methods and routines).
  4. Generate new names for any name, as specified through copywriter directive in the comments of your report. 
  5. Multiply the number of coding lines by about 4

Effectively this means there is no change in actual functionality, but there are lots of changes "under the hood". When you need to fix a problem or add something to your "product", simply run the Copywriter to restore the original source code. And yes: you'll need your password for that. 

How the Copywriter should be used

Your coding holds comments, sensible names for classes, methods, variables and maybe still even routines. The pretty printer was probably used as well making your coding a structured document. The copywriter will strip the document from it's structure by performing a series of steps, which should not damage the syntaxtual or semantical structure of the report. The overall plan is to develop your report, test it on the development system and run the copywriter each time a transport is released. Thus the coding that is moved through the system landscape is "copy-righted" and the only system where Copywriting actions are done is the development system. 

The disadvantage to this setup is the ability to do a debug round in a production system or even the acceptance system and this is quite a serious disadvantage. It's the price for protecting your coding. As an emergency procedure, the original coding can be re-instated into the report/include and the report can be transported to acceptance or even production, where the error can be pin-pointed. Copywriting is a fully reversible process. After the issue is resolved the Copywriter can again wrap things up and a new transport can hide your coding again. The one flaw in this emergency procedure is the version history of the report, it will hold the regular version of your report. 

This is what Copyright protected Abap coding looks like

The report allows you to state the copyright owner, in this case "AbapcadabrA 2016". Coding for any report or include can be processed by the copywriter. The comments in your report will be replaced with the following comment block:

After this coding block, the actual report coding will begin. This could look like so:

  REPORT                                            "    ___   AbapcadabrA 2016
  ZHRC_HRCHANNELS_MAP_REPORT_TST                    "   / __\  AbapcadabrA 2016
  NO                                                "  / /     AbapcadabrA 2016
  STANDARD                                          " / /___   AbapcadabrA 2016
  PAGE                                              " \____/   AbapcadabrA 2016
  HEADING                                           "   ___    AbapcadabrA 2016
  .                                                 "  / _ \   AbapcadabrA 2016
  INCLUDE                                           " | (_) |  AbapcadabrA 2016
  ZHRC_HRCHANNELS_EASY_ALV                          "  \___/   AbapcadabrA 2016
  .                                                 "  _ __    AbapcadabrA 2016
  INCLUDE                                           " | '_ \   AbapcadabrA 2016
  ZHRC_HRCHANNELS_EASY_DOCU                         " | |_) |  AbapcadabrA 2016
  .                                                 " | .__/   AbapcadabrA 2016
  INCLUDE                                           " |_|      AbapcadabrA 2016
  ZHRC_HRCHANNELS_EASY_XML                          "  _   _   AbapcadabrA 2016
  .                                                 " | | | |  AbapcadabrA 2016
  TABLES                                            " | |_| |  AbapcadabrA 2016
  ZHRC_MAPPINGS                                     "  \__, |  AbapcadabrA 2016
  .                                                 "  |___/   AbapcadabrA 2016
  TABLES                                            "  _ __    AbapcadabrA 2016
  ZHRC_CONTROLS                                     " | '__|   AbapcadabrA 2016
  .                                                 " | |      AbapcadabrA 2016
  TABLES                                            " |_|      AbapcadabrA 2016
  SSCRFIELDS                                        "  _       AbapcadabrA 2016
  .                                                 " (_)      AbapcadabrA 2016
  TYPES                                             " | |      AbapcadabrA 2016
  BEGIN                                             " | |      AbapcadabrA 2016
  OF                                                " |_|      AbapcadabrA 2016
  GTY_DATASET                                       "   __ _   AbapcadabrA 2016
  .                                                 "  / _` |  AbapcadabrA 2016
  TYPES                                             " | (_| |  AbapcadabrA 2016
  DATASET                                           "  \__, |  AbapcadabrA 2016
  TYPE                                              "  |___/   AbapcadabrA 2016
  ZHRC_MAPPINGS-DATASET                             "  _       AbapcadabrA 2016
  .                                                 " | |__    AbapcadabrA 2016
  TYPES                                             " | '_ \   AbapcadabrA 2016
  DESCRIPTION                                       " | | | |  AbapcadabrA 2016
  TYPE                                              " |_| |_|  AbapcadabrA 2016
  C                                                 "  _       AbapcadabrA 2016
  LENGTH                                            " | |_     AbapcadabrA 2016
  80                                                " | __|    AbapcadabrA 2016
  .                                                 " | |_     AbapcadabrA 2016
  TYPES                                             "  \__|    AbapcadabrA 2016
  PRIMARYTABLE                                      "          AbapcadabrA 2016
  TYPE                                              "          AbapcadabrA 2016

The Copywriter selection screen

The selection screen can hold up to 20 Abap sources in a single run. Each source will be stored/scrambled with the (same) password, where are retrieving (or adding) the sources can be done on individual basis. Use a variant to specify all reports and includes that are to be captured and place copyright coding or re-instate original coding for all sources involved. 

The icon on the right indicates whether a source is currently protected. On larger projects, the source codes that are to be locked are typically stored in their own variant. In the example report ZHRD_DOCUMENTS_BROWSER has an include ZHRD_PLUGIN_FORM_CONTROLLER which will both be scrambled. If you want to find out which reports have been copy protected - simply use F4. 

If an example source code was protected, it shows with date and time of the conversion:

When the report is started, a popup requesting a password will be shown:

This popup will appear on locking as well as unlocking requests. When locking coding, an extra popup "Reenter your passcode" is requested, so a simple typing error does not result in lost coding. After running the report, the lock-icons will show the sources are locked and the actual source code of the reports will have changed.

Meaningful names of local variables

All local variables that are declared in a method or a routine have a clearly defined work-scope. The name of a local variable contains valuable information, which is hidden in the copy protection process. Local variables that adhere to the naming convention: LV_, LW_, LT_, LO_ or LR_ (local variable, work area, table, object or range) are replaced by a GUID (Globally Unique Identifier) or 30 characters long unique hexadecimal coding, starting with HX. An example:

  METHOD                                            " | |      AbapcadabrA 2016
  CONSTRUCTOR                                       " |_|      AbapcadabrA 2016
  .                                                 "  _       AbapcadabrA 2016
  DATA                                              " (_)      AbapcadabrA 2016
  HX29C3D9911EE6A884974F17393B44                    " | |      AbapcadabrA 2016
  TYPE                                              " | |      AbapcadabrA 2016
  REF                                               " |_|      AbapcadabrA 2016
  TO                                                "   __ _   AbapcadabrA 2016
  CL_SALV_EVENTS_TABLE                              "  / _` |  AbapcadabrA 2016
  .                                                 " | (_| |  AbapcadabrA 2016
  GO_SALV                                           "  \__, |  AbapcadabrA 2016
  =                                                 "  |___/   AbapcadabrA 2016
  R_OBJECT                                          "  _       AbapcadabrA 2016
  .                                                 " | |__    AbapcadabrA 2016
  HX29C3D9911EE6A884974F17393B44                    " | '_ \   AbapcadabrA 2016
  =                                                 " | | | |  AbapcadabrA 2016
  GO_SALV->GET_EVENT(                               " |_| |_|  AbapcadabrA 2016
  )                                                 "  _       AbapcadabrA 2016
  .                                                 " | |_     AbapcadabrA 2016
  SET                                               " | __|    AbapcadabrA 2016
  HANDLER                                           " | |_     AbapcadabrA 2016
  ON_USER_COMMAND                                   "  \__|    AbapcadabrA 2016
  FOR                                               "          AbapcadabrA 2016
  HX29C3D9911EE6A884974F17393B44                    "          AbapcadabrA 2016
  .                                                 "    ___   AbapcadabrA 2016
  SET                                               "   / __\  AbapcadabrA 2016

Copywriter directives - controls for the Copywriter

There are 2 types of copywriter directive, which are both set up in the comments of the Abap source you want to copy-protect. Copywriter directives are interpreted by the Copywriter much like Pragmas or the #EC NEEDED directives for the code inspector. The Copywriter can be instructed to do the following:

Directive: comment lines (become comment header)

As many companies/customers have guidelines on how the comment header should be filled in, e.g. with the change history of the coding, there is a way to keep comment lines in the copy-protected version of your report. Comment lines that start with ** instead of a single will be placed in the report header with a single *. Thus:

** program          : ZABAPCADABRA_COPYWRITER
** title            : AbapcadabrA CopyWriter, Copy-protect your coding, hang on to original
** functional area  : Development tool
** Developer name   : Wim Maasdam 
** Development date : 01/11/2016, version 0.2

Will show as "normal" at the beginning of the copy-protected program:

* program          : ZABAPCADABRA_COPYWRITER
* title            : AbapcadabrA CopyWriter, Copy-protect your coding, hang on to original
* functional area  : Development tool
* Developer name   : Wim Maasdam 
* Development date : 01/11/2016, version 0.2

Directive: "search and replace"

The default setup of the copywriter is aimed at (1) effective protection and (2) unchanged syntax and semantics. But even copy protected coding will look exactly the same when using SE80, that is when focusing on the left side panel only. There is a way to instruct the copywriter to generate GUID codes for other elements as well, such as method names, routine names or classes. The left side panel would turn into something like this:

Do make sure these directives are "tried" first, e.g. if you have a method with the same name as a function module, the copywriter will also alter the actual function module call. Directives are passed to the copywriter by simply adding the following comments anywhere in your source:

* Copywriter: lcl_event_manager_east, lcl_event_manager_west, lcl_settings
* Copywriter: report_focus_east, report_focus_west, GV_CONTROLS

In the above example, AS_STRING is in fact a method, LCL_XML a (locally defined) class and GV_CONTROLS is a globally defined variabele in one of the (local) classes.

So if you want more protection of your own coding, the copywriter directive will inform the copywriter what to do. Make sure you don't copy protect variables that are defined in an include and used from another report. Have method names been used multiple times ? The copy protection is applied multiple times as well. Think of these directives as instructions to the Abap editor to "replace all occurrences of something with something else" - if that poses no issues, the directive is fine.

Directive: light

The Copywriter also has a "light" mode, which will render more readable coding without applying new names for local variables. The "Search and replace" directives can still be specified. If your coding doesn't work anymore after pushing it through Copywriter, you could try directive:

* Copywriter: light

An example coding of the "light" version of Copywriting is also available (as a download) on this article. 

Good to know that the (all) directives are part of the coding that is copy-protected, so using directives really does have a protective effect.

The syntax checker

The copywriter can also be used in a "safe mode" - which requires the newly generated coding to pass the syntax check. If the new code contains errors, they are reported and the original source code is not overwritten. Mind you, if the original source code does get overwritten and you didn't want it to: don't worry, the original is stored and can be re-instated. An example of a syntax check that failed:

Forgot the password ?

Don't call me, I cooked this whole thing up, but the role of the password is of paramount importance. I can not help you there. As you can see for yourselves in the actual coding, there is no backdoor.

Download it here

Needles to say - this is software for the development system only. The original version of the coding is held in an INDX storage which was scrambled with the password (and source code name) so this setup is not picknick when it comes to hacking it. Even with this sourcecode freely available.


The aim for this tooling is never to destroy coding, only copy-protect it. The copyright owner can restore the original coding whenever he/she wants, on the development system. Do make sure you test this mechanism on a test report, just to make sure it also works on your system. How ? Copy the report to a $TMP version and protect it with the copywriter. Then unlock and run transaction SE39 to compare the original version with the copied version. No unexplained differences should be there. The actual encryption is quite simple: each character is replaced by another character, but be aware that each source (report or include) has it's own character-translation-table, so it is truly hard work to decrypt a report by hand. 

This freely downloadable report can not be used on standard SAP reports, inactive reports or reports that are being edited or any reports on a productive system. In fact, it should itself have development class $TMP. This setup is only a development tool, for the development system. 

Copy-protect the Copywriter

The Copywriter is itself an Abap report that can undergo it's own treatment. So have a look for yourselves to see whether the coding below can be "read and understood" from Abap development perspective. It's a fast and effective way to a headache. Mind you, the coding does the exact same as the original coding, so it can be used as-is !


And another copy-protected version, this time using directive "Light". Much easier to read. Third working version of the same coding, as alternate coding.