How to “decode” eexec of font file?

人走茶凉 提交于 2019-12-01 06:14:10

Unless you really want to write your own eexec decryption, and then your own charstring decryption, I'd suggest you simply use t1disasm. If you are running on a Linux distribution you may be able to find a package for t1utils which should contain this, or you can get the source in a number of places (Google is your friend), here's one:

http://freepcb.googlecode.com/svn/clibpdf/trunk/util/t1utils-1.9/t1disasm.c

If you are on Windows you could look here for the t1utils package fopr WIndows :

http://gnuwin32.sourceforge.net/packages/t1utils.htm

I found this document very helpful in decrypting eexec encryption. A simple example in using the code mentioned there.

#Getting the eexec binary, make sure you exclude the ascii part in the end, after the binary portion 
text = open('fontfile.pfa').read()
raw_hex = text.split('eexec')[1]
decarr = list()
count = 0
hex_code = str()

#Converting pairs of the hexadecimal digits to decimal, e.g. ff -> 255, and storing it in an array decarr
for i in range(len(raw_hex)):
    if raw_hex[i] == '\n':
        decarr.append(raw_hex[i])
        continue
    else:
        hex_code = hex_code + raw_hex[i]
        count += 1
        if count == 2:
            decarr.append(int(hex_code, 16))
            count = 0
            hex_code = str()

Once we have an array of the decimal equivalents of pairs of hexadecimal digits, we perform decryption as mentioned in Chapter 7 of Adobe Type 1 Font Format Specification. The constants are as mentioned in the specification.

c1 = 52845
c2 =  22719
R = 55665
p = list()
for i in range(0,len(decarr)):
    if decarr[i] is not '\n':
        p.append(decarr[i]^(R >> 8))
        R = ((decarr[i] + R)*c1 + c2) & ((1 << 16) - 1)
    else:
        p.append(decarr[i])
decrypted = list()
for i in range(len(p)):
    if p[i] is not '\n':
        decrypted.append(chr(p[i]))
    else:
        decrypted.append(p[i])

Hope it helps!

I think KenS's answer is better, but, as a curiosity, here is an emacs function that does eexec decryption of a bynary input (i.e. no decryption of hexadecimal input and no charstring decryption). The algorithm is from the document in Henry's answer.

(defun eexec-decrypt ()
  "decrypt eexec binary block (see Type1 font);
   NB: no charstring decryption"
  (interactive)
  (search-forward "currentfile eexec")(forward-char 1)
  (with-output-to-temp-buffer (concat (buffer-name) "-eexec-decripted")
    (setq r 55665)
    (setq c1 52845)
    (setq c2 22719)
    (setq here (point))
    (setq count 4)
    (while (< here (point-max)) ; I'm not really sure where to stop...
      (setq cipher (get-byte here))
      (setq plain (logxor cipher (lsh r -8)))
      (cond ((> count 0) ; skip first 4 bytes
         (setq count (- count 1)))
        (t (princ (byte-to-string plain))))

      (setq r (mod (+ c2 (* c1 (+ cipher r))) 65536))
      (setq here (+ 1 here)))))

What was really neat is that any patient seventh grader could sight read an eexec file!

Just insert a random character and view both your stack and your error report. Repeat every few dozen characters.

Like a voice response safe "try three clicks to the left".

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!