Didier Stevens has produced a programme which is called "pdfid" (https://blog.didierstevens.com/2009/03/31/pdfid/ and https://blog.didierstevens.com/programs/pdf-tools/#pdfid).

He says:

"I’ve developed a new tool to triage PDF documents, PDFiD. It helps you differentiate between PDF documents that could be malicious and those that are most likely not."

And that´s what I want to use it for.

"PDFiD will scan a PDF document for a given list of strings and count the occurrences (total and obfuscated) of each word:"




















As far as I know the values of "obj" and "endobj" should match which means that there´s no object opened that wasn´t closed (perhaps causing buffer-overflow or something else).

And ideally

/JS /JavaScript /AA /OpenAction /AcroForm

should have zero value.

Yet I´ve seen quite a lot of pdf-documents with "obj" and "endobj" not matching but the other values seem to be o.k.

Example: Using_FreeDOS.pdf from http://www.freedos.org/ebook/download/using-freedos-24.pdf .

The pdfid-results:

 PDF Header: %PDF-1.4

 obj                  520

 endobj               519

 stream               193

 endstream            193

 xref                   1

 trailer                1

 startxref              1

 /Page                100

 /Encrypt               0

 /ObjStm                0

 /JS                    0

 /JavaScript            0

 /AA                    0

 /OpenAction            1

 /AcroForm              0

 /JBIG2Decode           0

 /RichMedia             0

 /Launch                0

 /EmbeddedFile          0

 /XFA                   0

 /URI                   8

 /Colors > 2^24         0

Yet this one has also "/OpenAction 1". I´m not quite sure how relevant that one is.


how important is the fact that "obj" and "endobj" match when the rest of the list of strings and count are o.k?

As already said: there are quite a few pdf-documents out there with "obj" and "endobj" not matching.


pdfid is apparently doing a lousy job at counting the obj/endobj pairs -- in your particular example, the odd "obj" is part of a FlateDecode stream:

$ cat pdf.pl
use Compress::Zlib qw(inflateInit Z_STREAM_END);
use strict;
my ($o);
        $o -= s/\bendobj\b//g;
        $o += s/\b\d+\s+\d+\s+obj\b//g;
                local $/ = "endstream"; my $s = <>; $s =~ s/\s*endstream$//;
                if($s =~ /(\w*obj)/){
                        my ($d, $err) = inflateInit->inflate($s);
                        if(length($s) == 0 && $err == Z_STREAM_END){
                                warn "innocuous '$1' in well formed stream\n";
                                warn "WARNING: inflateInit: $err\n";
        if(/(\w*obj)\b/){ warn "WARNING: possible stray $1\n" }
warn "WARNING: unbalanced obj/endobj: $o\n" if $o;
$ perl pdf.pl using-freedos-24.pdf
innocuous 'obj' in well formed stream

Note: that little is to illustrate the problem at hand; don't use it to check if a pdf is secure ;-)

The pdf format is quite nasty & complex; you really need a full-blown parser to make sense of its structure. And a program that's able to do it (in order to correctly identify malicious pdfs) is becoming an attack vector itself -- there is no reason to believe that an ad-hoc parser is more secure than libpoppler or libmupdf.

  • Hi mosvy. Tnx a lot for your assessment. Obviously you understand the whole matter way better than I do. Nevertheless I´ve now used pdfinfo from libpoppler to evaluate the example-file: Creator: Writer Producer: LibreOffice 6.0 CreationDate: Sun Aug 19 15:57:02 2018 Tagged: no UserProperties: no Suspects: no Form: none JavaScript: no Pages: 100 Encrypted: no Page size: 611.972 x 791.972 pts (letter) Page rot: 0 File size: 2405845 bytes Optimized: no PDF version: 1.4 So I looks fine. – Rosika Sep 6 '18 at 11:52
  • Hi mosvy, thanks for the perl-script of yours. I tried it out and it gave me the same result. Yet you said I shouldn´t use it to check if a pdf is secure. But are there any objections against using it in addition to libpoppler/pdinfo? – Rosika Sep 24 '18 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.