Note: Purely Hypothetical
Not too long ago I went to a bookstore to buy a book:
"I'd like to buy this electronic book please," I said pointing at its cover.
"Yes, we have that one in the database. It is a PDF. It is popular. It is in your imaginary cart," they said.
"Thank you. PDF is the most exciting electronic book format I am told. I will buy it now please. Let me read you my credit card to you slowly. 4-"
"Bleep blorp. Transaction Processed Successfully. Expect a link to popular PDF #39 in the mail. Thank you and good day."
I went home and checked my mail and clicked the link to get my new book.
"The purchaser and buyer pursuant hencefurthermoreforth 'YOU THE BUYER' by purchasing and agreeing to said purchase and agreement do purchase of and self impregnate with a restricted computer license for SECURE PDF protected with Digits Rights Management (DRM) -"
I agree.
"Computer this you be using on?"
Uh, submit, yes.
"Please download launcher."
Sigh. OK.
"This book may only be read with Adobe Acrobat PDF Reader. You may download it."
Great, yes, sure, ok, ok, submit, agree, I do.
And after only fifteen or thirty minutes I, me the BUYER, could read my book on this computer and this computer only. The other computers, Kindle, and phone looked on mournfully. This won't do.
Can we share it using Adobe's website for this?
No. It just shares the secure PDF but not the password.
Can we Print > Printers > Save to PDF in Acrobat?
No.
Can we print with Send To Kindle?
No, and we'd lose links in the table of contents.
Where is the actual PDF file?
'Show Package Contents' on the launcher .app
package gives us the
PDF file itself. But the PDF is secured and prompts for a password
when opened without the launcher.
So the password is probably provided by the launcher.
Is the password encrypted?
Yes.
Dunno, let's blindly follow some advice from an old defcon presentation.
What does objdump -d
do?
Nothing, objdump
is a GNU tool. Homebrew installed it with the g
prefix. Try again with gobjdump
(highly recommended -x
option
segfaults). Gives a bunch formatted assembly with library methods
ending in $stub
.
How about readelf
?
Doesn't apply, OSX binaries are mach-o format not elf. otool
, the
OSX equivalent, gives similar output to objdump
when run with -Vt
.
And ktrace
?
OSX equivalent is dtrace
. sudo dapptrace
provides interesting
output of what the launcher needs from the kernel.
Run gdb --command=/Applications/${APP_NAME}.app/Contents/MacOS/${BIN_NAME}
,
and flail around learning gdb and trying to combine the assembly,
stubs, and the apptrace.
It looks like the launcher opens Acrobat and fills in the password.
Can we read the password field aloud?
No.
Or copy from the entered password to the clipboard?
No.
Screw around with GDB some more. Read about linkers, OSX executables, and x86 Registers.
It looks like the launcher checks for a dot-prefixed RC file in the home directory.
If it doesn't find it then it does an HTTP POST
of my MAC Address
(and maybe other stuff) to a remote web server then saves the returned
encrypted password to the RC file.
Once it reads the RC file it (roughly) goes through the open applications, opens Acrobat Reader with the PDF, focuses on the password field and enters the decrypted password.
So we just need to capture the text or keyboard events entered into the password field?
Can't hurt to try. Set breakpoints on calls to
AXUIElementSetAttributeValue
in GDB use the po
print object command to print the Objective-C
objects (printing with x/s
null terminated C strings gives garbage)
at
memory addresses corresponding to the second function argument
and recover the password.
Then open the PDF in Preview enter the password, save a copy without the password, and put it on my other devices to make them happy.
Next time, LLDB might be a good option since it's in the OSX toolchain by default and a lot of the time I just wanted to print out register values and library calls. The regexp matching and python scripting look useful, might be able to use print_object in display settings.
Learned a lot opening it repeatedly. Haven't gotten around to reading it yet. Nice pictures.
Looking at the external library function call stubs one point we have:
po $ecx
Cancel
po $edx
확인
# translates to Confirmation
So maybe cancel is 'Cancel' in Korean?