[Tex/LaTex] How to attach AND HIDE a file in a PDF using Latex

embeddingpdfsourcesteganography

Embedding a file is fairly easy using LaTeX (see, for example: Embed link to an embedded file).

Hiding an embedded file is also possible and fairly easy to do outside LaTeX (see, for example: https://blog.didierstevens.com/2009/07/01/embedding-and-hiding-files-in-pdf-documents/)

But I'm almost certain that it is possible to do the same (i.e., embed a file AND hide it from the attachment list) using only Latex…

Motivation: to be able to include the tex source code as an attachment that is hidden from the attachment list.

Any grey beard out there knowing the answer to this one?

Best Answer

The "hidden" embedded file in the blog post is not an embedded file in the sense of the PDF standard, so the question is what you really want:

If you only want to include the content from the file in the generated PDF, you can add a PDF stream: If you write \immediate\pdfobj file{some-filename.tex}, the file some-filename.tex is copied into the PDF as a stream. If you want to see this without writing a PDF parser, you can use

\documentclass{article}
\pdfobjcompresslevel=0% Don't hide the objects
...
\begin{document}
...
% Disable compression for this one object
{\pdfcompresslevel=0\immediate\pdfobj file{some-filename.tex}}
...
\end{document}

If you open the resulting PDF file in an editor, somewhere you will something like: (The first number may vary)

11 0 obj
<Here comes the content of some-filename.tex>
endobj

This object will not be visible in any PDF viewer.

Of course, this isn't really embedded. A second attempt: Embed the file, but do not list it in /EmbeddedFiles. You can use

\documentclass{article}
\usepackage{embedfile}
\pdfobjcompresslevel=0% Don't hide the objects
...
\begin{document}
...
{\pdfcompresslevel=0\embedfile{some-filename.tex}}
\makeatletter
\global\let\EmFi@list\empty
\makeatother
...
\end{document}

I partially disabled compression again so that you can find the file in the resulting PDF. The \global\let\EmFi@list\empty makes the embedfile package forget about all the files up to this point, so they will never be written into the list of embedded files, but the /EmbeddedFile PDF object with the file content and some metadata is still written. You can't easily make this visible, because the catalog entries are missing.

If you try to reproduce the blog post you referenced and change the case of /EmbeddedFiles, you have to replace the output routine of embedfile:

\documentclass{article}
\usepackage{embedfile}
\pdfobjcompresslevel=0% Don't hide the objects, otherwise you can't see
                      % /Embeddedfiles, so you also can't change it back
\makeatletter
% The following is mostly copied from embedfile.sty, (C) by Heiko Oberdiek
% But all the errors are propably introduced by me
\def\embedfilefinish{%
  \ifEmFi@finished
    \EmFi@Error{%
      Too many invocations of \string\embedfilefinish
    }{%
      The list of embedded files is already written.%
    }%
  \else
    \ifx\EmFi@list\empty
    \else
      \global\EmFi@finishedtrue
      \begingroup
        \def\do##1##2{%
          (##1)##2%
        }%
        \immediate\pdfobj{%
          <<%
            /Names[\EmFi@list]%
          >>%
        }%
        \pdfnames{%
          % Changed name to make this invalid
          /Embeddedfiles \the\pdflastobj\space 0 R%
        }%
      \endgroup
    \fi
  \fi
}
\makeatother
\begin{document}
...
\embedfile{hidden.tex}
...
\end{document}