PDFをバイナリから編集しよう
前にexeをバイナリから編集する方法を説明しました。
じゃあ今度はPDFをバイナリから編集できないかと思い、調べてここにまとめようと考えました。
調べると同じような記事がなんこか見つかりました。
まあ、でも、実際に自分でやってみないとわからないことってあると思うので、ここに自分がやってみるとどうだったかを残しておきます。
てかexeのバイナリ編集も似たような記事たくさんあるしね。
はじめに
じゃあさっそくPDFをバイナリから見ていこうと思ったのですが、正直
を読めばPDFからテキストファイルの場所がわかります。
そのためその部分のバイナリを変えればテキストを編集できます。
しかし、ここのサイトのにあるPDFのサンプルの文字を書き換えてみると
こんな感じになります。これはHをeに変え、WをXに書き換えたものです。
するとXだけ文字化けしました。
この理由はフォントが使用されている文字しか埋め込まれていなかったためです。
そのためにXに対応するフォントが存在せず、こうなってしまったということです。
しかしXの文字は存在しているため、コピーするとXorldが得られます。
普通にwordからPDFを作るときは基本文字は全て埋め込まれます。
使用した文字だけ埋め込むのは
オプション>保存>次の文書を共有するときに再現性を保つ>ファイルにフォントを埋め込む>文書で使用されている文字だけを埋め込む
にチェックを入れればできます。
このPDFがどう作られたかはわかりませんが、おそらくそんな感じの設定で作られたんだと思います。
PDFを編集する
一応PDFに存在するテキストを編集する方法をまとめると
1.PDFtkというフリーソフトで
PDFファイル output 保存先PDFファイル uncompress
というコマンドでPDFの圧縮された部分を解凍しておく。
2.PDFの一番下の部分をバイナリで見る。
すると
startxref アドレス
と書かれているため、そのアドレスに飛ぶとxrefというオブジェクトのアドレス表にたどり着く。
PDFはこのxrefというオブジェクトを指し示す表と、オブジェクトというデータの単位が集まって構成されている。
xrefは
アドレス 世代番号 n
というように書かれており例として上から3行だけ見ると
0000000000 65535 f
0000000016 00000 n
0000000268 00000 n
こんな感じのが何列もある。
上から0,1,2番目のオブジェクトのアドレスを指し示している。
0番目のオブジェクトは使わないっぽい。
とりあえず1番目のオブジェクトの場所を見てみると
/Type Catalog
のオブジェクトがあります。
そこに /Pages 3 0 R と書かれているため3番目のオブジェクトをxrefを参考に見る。
(何番目に何のオブジェクトがあるかはPDFによって変化します。)
xrefを参考にしなくてもオブジェクトは 3 0 obj~endobj のように書かれるため、
3 0 obj を検索すれば見つかります。
こんな感じで
Catalog>Pages>Page>Contents まで辿ってみてみると
stream~endstreamで囲まれた中にBT~ETに囲まれた部分がある。
この中に <文字列>Tj という部分があるからバイナリからこの文字列を編集できる。
フォントをいじってみる
もうテキストは編集できるようになりました。
しかしテキストを編集してもうまく表示されないこともあり、見た目はフォントの方で決まることがわかります。
ならばフォントの方を変えれば見た目だけ変えられるのではないかと考えました
やっぱりさっきのサイトみたいにアドレスを辿ってみるのをやりたいのでやってみます。
先ほどのサイトのPDFサンプルをPDFtkでuncompressしたものを見ていきます。
これからオブジェクトを辿っていきますが、ここに何番目に何のオブジェクトがあったかまとめておきます。
1 Catalog
2 DestOutputProfile
3 Pages
4 Metadata
5 Kids
6 GS0 //ExtGState
7 C0_0 //Font
8 Contents //テキストとか
9 DescendantFonts //10へのアドレス
10 Font
11 CIDSystemInfo
12 FontDescriptor
13 FontFile3
14 CIDSet
15
まずPDFの最後を見ると
startxref 607246
とあるためxrefをみると(xrefは見なくてもいいけど一応)
xref
xref
0 16
0000000000 65535 f
0000000015 00000 n 1 0 obj
0000047056 00000 n 2 0 obj
0000046997 00000 n 3 0 obj
こんな感じであるため1 0 objを見ると
Catalog
1 0 obj
<<
/OutputIntents [
<<
/OutputCondition ()
/Info (Japan Color 2001 Coated)
/DestOutputProfile 2 0 R
/OutputConditionIdentifier (JC200103)
/RegistryName (http://www.color.org)
/Type /OutputIntent
/S /GTS_PDFX
>>]
/Pages 3 0 R
/Metadata 4 0 R
/Type /Catalog
>>
endobj
今度は/Pagesを見てみると
Pages
3 0 obj
<<
/Kids [5 0 R]
/Type /Pages
/Count 1
>>
endobj
Kidsを見ると
Kids
5 0 obj
<<
/pdftk_PageNum 1
/TrimBox [0.0 0.0 595.276 841.89]
/CropBox [0.0 0.0 595.276 841.89]
/MediaBox [0.0 0.0 595.276 841.89]
/Resources
<<
/ExtGState
<<
/GS0 6 0 R
>>
/Font
<<
/C0_0 7 0 R
>>
/ProcSet [/PDF /Text]
>>
/Parent 3 0 R
/Contents 8 0 R
/LastModified (D:20200119182202+09'00')
/BleedBox [0.0 0.0 595.276 841.89]
/Type /Page
>>
endobj
リソースの中にFontという項目がありました。
これがフォント関係のオブジェクトっぽいので7 0 objを見ていきます。
Font (Subtype Type0)
7 0 obj
<<
/DescendantFonts 9 0 R
/BaseFont /VUSVFG+KozGoPr6N-Regular
/Subtype /Type0
/Type /Font
/Encoding /Identity-H
>>
endobj
KozGoPr6N-Regularというフォント名っぽいものがありましたね。
DescendantFontsというまたフォントの情報が入ってそうなオブジェクトがあるので見てみます。
DescendantFonts
9 0 obj [10 0 R]
endobj
なんか10 0 objを見ろと書いてありますね。
見てみます。
Font (Subtype CIDFontType0)
10 0 obj
<<
/BaseFont /VUSVFG+KozGoPr6N-Regular
/Subtype /CIDFontType0
/DW 1000
/CIDSystemInfo 11 0 R
/FontDescriptor 12 0 R
/W [1 [233] 41 [700] 56 [919] 69 [604 539] 77 [248] 80 [589] 83 [346]]
/Type /Font
>>
endobj
またフォント名がありますね。
あとは/Wで文字の幅とかを表しているらしいです。
今度はCIDSystemInfoとFontDescriptorというものを参照しています。
PDFのFormatをみてみると、
CIDSystemInfo:CIDFontの文字コレクションを定義するエントリを含む辞書
FontDescriptor:CIDFontのグリフ幅以外のデフォルトメトリクスを記述するフォント記述子
らしいです。あんまよくわかんないのでとりあえず見てみます。
CIDSystemInfo
11 0 obj
<<
/Supplement 6
/Registry (Adobe)
/Ordering (Japan1)
>>
endobj
Adobe関係の情報が書かれている?
FontDescriptor
12 0 obj
<<
/FontName /VUSVFG+KozGoPr6N-Regular
/StemV 84
/FontFile3 13 0 R
/Ascent 1409
/Flags 4
/FontWeight 400
/XHeight 545
/FontFamily (Kozuka Gothic Pr6N R)
/FontStretch /Normal
/Descent -339
/ItalicAngle 0
/CIDSet 14 0 R
/FontBBox [-529 -339 1214 1409]
/Type /FontDescriptor
/CapHeight 763
>>
endobj
フォントに関する情報がなんかあります。
FontFile3:ここにフォントデータがあるそうです。
CIDSet:CIDを識別するストリーム。これが文字コードとグリフの対応表?
見ていきます。
FontFile
ストリームの中にフォント名、コピーライト、/FSTypeなどがありました。
埋め込みフォントのフォーマットがってどっかにあるんですかね。
このバイナリが読めないです。
CIDSet
これが文字コードとグリフとの対応表だと思うんですよね。ストリームをひとつずつ見てみると
C0 00 00 00 00 40 00 80 06 04 90
いやーわからん。
Embedded OpenType (EOT) File Format
Embedded OpenType From Wikipedia
How can I extract embedded fonts from a PDF as valid font files? stack overflow
ここら辺になんかヒントがありそうなんですけどね。
やりたかったことは、文字コードとグリフIDの一部を入れ替えて、ContentにはHello Worldと書いてあるが、PDFではWello Horldと表示される、みたいなことです。
なんか面白いかなーって思ったんですがねー。
分かる人いたら教えて下さい。。
コメント
0 件のコメント :
コメントを投稿