Skip to content

Hacking

Tavis Ormandy edited this page Nov 10, 2022 · 4 revisions

This page contains some hints on patching, hooking, debugging or extending word perfect.

Symbols

It is possible to get debug symbols to help diagnose crashes or other problems. There is an article on how this works here.

This means that gdb can set breakpoints and show useful stack traces.

In order to use this, download the wordperfect8-dbg.tar.gz package from the most recent release, and then type a command like this into gdb:

(gdb) add-symbol-file /path/to/wp.dbg

Hooking

There is a simple x86 hooking library called libintercept that can be used to hook or replace any function within WordPerfect. This is useful to fix bugs or add or replace features.

bool insert_function_redirect(void *function, void *redirect, uint32_t flags);
bool remove_function_redirect(void *function);
bool redirect_call_within_function(void *function, void *target, void *redirect);

// Flags recognised by insert_function_redirect.
enum {
    HOOK_DEFAULT            = 0,
    HOOK_REPLACE_FUNCTION   = (1 << 0),     // Replace call, don't hook.
    HOOK_FASTCALL           = (1 << 1),     // Try to minimize damage to registers.
};

In order to add your redirect, it needs to be added to libwppatch.so.

Printing

There are three main components involved in printing, the print server wpexc, the print formatter wpp and the queue manager wpq. These three commands all need to work for any printer output to be produced. They communicate over a fifo called /tmp/wpc-${HOSTNAME}/excmsg7, and create various temporary files while working.

Troubleshooting

If something isn't working, the first thing to check is the Printer Control screen within wp, access it from the print menu. There might be helpful error messages, or perhaps a print job is stuck and removing it will fix the fix problem.

If that didn't work, run wpexc -k as root to terminate any running print server. You can run wpexc -v/tmp/print.log to restart it with debug logging.

If that is not enough debugging information, it is possible to enable protocol debugging, but it isn't user accessible - you need to use gdb to enable it.

$ gdb -ex 'b fork' -ex 'r' -ex 'set *0x8069E9E|=8' -ex 'detach' -ex 'q' --args /opt/wp70/shbin10/wpexc -v/tmp/logfile

This will log all IPC messages received to /tmp/logfile.

Protocol

The three print components send messages - like network packets - over the excmsg fifo. A message looks something like this:

struct EXMSG
{
...
  int srcpid;
  int srcuid;
...
  enum MSGNUM msgtype;
  uin16_t datasize;
  uint8_t data[0];
};

The type can be any one of these messages:

enum MSGNUM
{
  MSG_ACK = 0x0,
  MSG_IGN = 0x1,
  MSSG_IPAGE = 0x2,
  MSG_FORM = 0x3,
  PAUSE_PTR = 0x4,
  JOB_PARAMS = 0x5,
  JOB_BEGIN = 0x6,
  JOB_DONE = 0x7,
  JOB_START = 0x8,
  JOB_RESTART = 0x9,
  JOB_CONT = 0xA,
  JOB_MOVE = 0xB,
  JOB_PRIORITY = 0xC,
  JOB_KILL = 0xD,
  JOB_BEEP = 0xE,
  JOB_PRMPT = 0xF,
  JOB_DWNLD = 0x10,
  EXC_VERB = 0x11,
  EXC_DOWN = 0x12,
  EXC_RSTRT = 0x13,
  DEV_JSTOP = 0x14,
  DEV_JHOLD = 0x15,
  DEV_JCANCEL = 0x16,
  DEV_HOLD = 0x17,
  DEV_START = 0x18,
  DEV_GROUP = 0x19,
  WP_BEGIN = 0x1A,
  WP_RSTRCT = 0x1B,
  WP_DONE = 0x1C,
  WP_PARAMS = 0x1D,
  DEV_GETGRP = 0x1E,
  DEV_SNDGRP = 0x1F,
  JOB_PSTHRU = 0x20,
  JOB_NEEDGO = 0x21,
  JOB_WPP = 0x22,
  EXC_LOCK = 0x23,
  WPPQ_BEGIN = 0x24,
  WPPQ_DONE = 0x25,
  JOB_CANCEL = 0x26,
  JOB_HOLD = 0x27,
  JOB_STOP = 0x28,
};