Skip to content

Commit 054f57f

Browse files
committed
initial commit
1 parent 759c37d commit 054f57f

File tree

3 files changed

+153
-2
lines changed

3 files changed

+153
-2
lines changed

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CC ?= gcc
2+
3+
all: pdfjpg.c
4+
$(CC) pdfjpg.c -o pdfjpg
5+
6+
clean:
7+
rm -f pdfjpg
8+

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,20 @@
1-
# polyglot-jpg-pdf
2-
A tool to combine a PDF and a JPG into one valid (polyglot) file which is both a PDF and JPG
1+
# Polyglot: JPG+PDF
2+
3+
A tool to combine a PDF and a JPG into one polyglot file which is both a PDF and JPG.
4+
The tool is based on [Ange Albertini](https://twitter.com/@angealbertini)'s PoC from [PoC||GTFO 0x03](https://github.com/angea/pocorgtfo/blob/master/contents/issue03.pdf#page=8).
5+
6+
# Usage
7+
8+
Compile the tool by running
9+
10+
make
11+
12+
Then, just run
13+
14+
./pdfjpg <pdf file> <jpg file> <output file>
15+
16+
to generate a file which is both a PDF and a JPG file. See PoC||GTFO 0x03 for more details.
17+
18+
# Limitations
19+
20+
Acrobat Reader since version 10 cannot open the resulting PDF.

pdfjpg.c

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
int main(int argc, char* argv[]) {
5+
if(argc != 4) {
6+
printf("Usage: %s <PDF file> <JPG file> <output>\n", argv[0]);
7+
return 1;
8+
}
9+
10+
char buffer[4096];
11+
FILE *pdf = NULL, *jpg = NULL, *out = NULL;
12+
unsigned char *jpg_buf = NULL, *pdf_buf = NULL;
13+
size_t size = 0;
14+
15+
pdf = fopen(argv[1], "rb");
16+
if(!pdf) {
17+
fprintf(stderr, "Could not open PDF '%s'\n", argv[1]);
18+
goto error;
19+
}
20+
21+
jpg = fopen(argv[2], "rb");
22+
if(!jpg) {
23+
fprintf(stderr, "Could not open JPG '%s'\n", argv[2]);
24+
goto error;
25+
}
26+
27+
out = fopen(argv[3], "wb");
28+
if(!out) {
29+
fprintf(stderr, "Could not open output file '%s'\n", argv[3]);
30+
goto error;
31+
}
32+
33+
// header
34+
if(fread(buffer, 1, 0x14, jpg) != 0x14) {
35+
fprintf(stderr, "Could not read JPG header\n");
36+
goto error;
37+
}
38+
if(fwrite(buffer, 1, 0x14, out) != 0x14) {
39+
fprintf(stderr, "Could not write JPG header\n");
40+
goto error;
41+
}
42+
43+
// get jpg data
44+
fseek(jpg, 0, SEEK_END);
45+
size = ftell(jpg);
46+
fseek(jpg, 0, SEEK_SET);
47+
48+
if(!size) {
49+
fprintf(stderr, "Invalid JPG\n");
50+
goto error;
51+
}
52+
53+
jpg_buf = (unsigned char*)malloc(size);
54+
if(!jpg_buf) {
55+
fprintf(stderr, "Could not allocate memory\n");
56+
goto error;
57+
}
58+
if(fread(jpg_buf, 1, size, jpg) != size) {
59+
fprintf(stderr, "Could not read JPG file\n");
60+
goto error;
61+
}
62+
63+
// write magic
64+
if(fwrite("\xff\xfe\x00\x22\x0a%PDF-1.5\x0a""999 0 obj\x0a<<>>\x0astream\x0a", 1, 36, out) != 36) {
65+
fprintf(stderr, "Could not write PDF comment\n");
66+
goto error;
67+
}
68+
69+
// write jpeg data
70+
for(size_t i = 0; i < size - 1; i++) {
71+
if(jpg_buf[i] == 0xff && jpg_buf[i + 1] == 0xdb) {
72+
if(fwrite(jpg_buf + i, 1, size - i, out) != size - i) {
73+
fprintf(stderr, "Could not write JPG data\n");
74+
goto error;
75+
}
76+
break;
77+
}
78+
}
79+
80+
free(jpg_buf);
81+
jpg_buf = NULL;
82+
83+
// close magic pdf object
84+
if(fwrite("endstream\x0aendobj\x0a", 1, 17, out) != 17) {
85+
fprintf(stderr, "Could not close PDF comment\n");
86+
goto error;
87+
}
88+
89+
// get pdf data
90+
fseek(pdf, 0, SEEK_END);
91+
size = ftell(pdf);
92+
fseek(pdf, 0, SEEK_SET);
93+
pdf_buf = (unsigned char*)malloc(size);
94+
if(!pdf_buf) {
95+
fprintf(stderr, "Could not allocate memory for PDF\n");
96+
goto error;
97+
}
98+
if(fread(pdf_buf, 1, size, pdf) != size) {
99+
fprintf(stderr, "Could not read PDF data\n");
100+
goto error;
101+
}
102+
103+
// write pdf data
104+
if(fwrite(pdf_buf, 1, size, out) != size) {
105+
fprintf(stderr, "Could not write PDF data\n");
106+
goto error;
107+
}
108+
free(pdf_buf);
109+
pdf_buf = NULL;
110+
111+
fclose(pdf);
112+
pdf = NULL;
113+
fclose(jpg);
114+
jpg = NULL;
115+
fclose(out);
116+
out = NULL;
117+
return 0;
118+
119+
error:
120+
if(pdf) fclose(pdf);
121+
if(jpg) fclose(jpg);
122+
if(out) fclose(out);
123+
if(jpg_buf) free(jpg_buf);
124+
return 1;
125+
}

0 commit comments

Comments
 (0)