3

The Amazon KindleGen command line app (Windows, macOS, Linux download links) has several undocumented command line parameters that I'm curious about. One of these hidden command line parameters is:

-dont_append_source

However, this string can't be found with the strings app or any of the many dissassemblers that I tried. It's therefore highly likely that some of the command line parameters have been obfuscated.

There are at least 8 of them:

option: (hidden) Skip the HTML cleanup
option: (hidden) creates json position map file for debugging purpose.
option: (hidden) creates mobi for older devices.
option: (hidden) Using manual(tag based) fragmentation mode for building Webkit reader compatible mobi.
option: (hidden) Webkit reader Compatible mobi will be built
option: (hidden) fragsize
option: (hidden) custom image size will be used for resizing
option: (hidden) amazon creator tool or pipeline

Are there any special tools out there that I could use to deobfuscate these hidden command line parameters?

  • 1
    You'll have to disassemble the code and check how the app does its argument processing. If they really wanted to hide those hidden parameters, they could run a hash function over the parameter and compare the result to a blob within the binary, in which case you can't even find out what the original command string was. – Guntram Blohm Dec 7 '16 at 9:31
  • I'd suggest to create a memory dump of the process when it is running and running strings uility on it. There is a chance that these obfuscated parameters are deobfuscated/decrypted during program start-up and you'll find those switches in the memory dump – w s Dec 7 '16 at 11:02
  • @w s: Unfortunately creating a memory dump didn't help me find the parameters. – Nemo XXX Dec 7 '16 at 12:14
  • Rough attempt (you never know): a simple incremental XOR find. But not only does it not locate your example dont_append_source anywhere, it also does not find the 'regular' options, other than in the descriptions of the options themselves. Here is a tip, though: the Windows version seems to use Unicode throughout, but the Mac version does not. It may make things (fractionally) easier. – Jongware Dec 7 '16 at 21:31
  • – sorry, scratch that. The regular options are simple strings and tested inside a single routine. I don't see obvious testing of other strings, encrypted or not, though. – Jongware Dec 7 '16 at 21:44
6

those command line switches seems to be plainly visible in several languages

kind:>kindlegen.exe -dont_append_source

Info:I9018:option: -donotaddsource: Source files will not be added

kind:>strings -o kindlegen.exe | grep -i donotaddsource

5130184:option: -donotaddsource: Source files will not be added
5208360:Option: -donotaddsource: Quelldateien werden nicht hinzugef
5287768:option: -donotaddsource: Les fichiers sources se seront pas ajout
5367504:opzione: -donotaddsource: I file sorgente non verranno aggiunti
5448722:n: -donotaddsource: no se agregan los archivos fuente
5482150:-donotaddsource
5524610:: -donotaddsource:
5595760:o:-donotaddsource: Os arquivos de origem n
5673552:: -donotaddsource:
5748880:optie: -donotaddsource: bronbestanden worden niet toegevoegd

binary dump at offset as shown by strings.exe

kind:\>xxd -s 5130184 -g1 -l0x70 kindlegen.exe
04e47c8: 6f 00 70 00 74 00 69 00 6f 00 6e 00 3a 00 20 00  o.p.t.i.o.n.:. .
04e47d8: 2d 00 64 00 6f 00 6e 00 6f 00 74 00 61 00 64 00  -.d.o.n.o.t.a.d.
04e47e8: 64 00 73 00 6f 00 75 00 72 00 63 00 65 00 3a 00  d.s.o.u.r.c.e.:.
04e47f8: 20 00 53 00 6f 00 75 00 72 00 63 00 65 00 20 00   .S.o.u.r.c.e. .
04e4808: 66 00 69 00 6c 00 65 00 73 00 20 00 77 00 69 00  f.i.l.e.s. .w.i.
04e4818: 6c 00 6c 00 20 00 6e 00 6f 00 74 00 20 00 62 00  l.l. .n.o.t. .b.
04e4828: 65 00 20 00 61 00 64 00 64 00 65 00 64 00 00 00  e. .a.d.d.e.d...

searching in windbg

kindle:\>echo get bounds of exe & cdb -c "lm m kin*;q" kindlegen.exe | grep def
get bounds of exe
00400000 00bdd000   kindlegen   (deferred)
kindle:\>echo search string within bounds & cdb -c "lm m kin*;s -u kindlegen L?(0xbdd000
-0x400000) donotaddsource: ; q" kindlegen.exe | grep quit: -B 11
search for emitted string within bounds
start    end        module name
00400000 00bdd000   kindlegen   (deferred)
008e59da  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
008f8b3a  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
0090c16a  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
0091f8e4  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
0093361a  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
00945e88  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
00957476  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
0096a456  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
0097caa0  0064 006f 006e 006f 0074 0061 0064 0064  d.o.n.o.t.a.d.d.
quit:

maybe all the commandline switches

0:000> .foreach (place { s -[1]u 400000 bdd000 option:}) {du /c100 place }

00839650  "option: {0}"
008e5478  "option: -preserve_img: Original Image size will be preserved"
008e54f8  "option: -image64K: The maximum size of the image is restricted to 64K"
008e5588  "option: -image128K: The maximum size of the image is restricted to 128K"
008e5618  "option: -gif: gif image conversion (no jpeg)"
008e5674  "option: -c0: No compression"
008e56b0  "option: -c1: Standard DOC compression"
008e5700  "option: -c2: Kindle Huffdic compression"
008e5750  "option: -allscript: Authorize all scripting"
008e57a8  "option: -western: Forced Windows-1252 output"
008e5808  "option: -verbose: Verbose output"
008e5850  "option: -noparseback: Parse back won't be built"
008e58b0  "option: -regserver: The XOPFPlugin type library has been registered"
008e5938  "option: -unregserver: The XOPFPlugin type library has been unregistered"
008e59c8  "option: -donotaddsource: Source files will not be added"
008e5a38  "option: (hidden) Skip the HTML cleanup"
008e5a88  "option: (hidden) creates json position map file for debugging purpose."
008e5b18  "option: (hidden) creates mobi for older devices."
008e5b80  "option: (hidden) Using manual(tag based) fragmentation mode for building Webkit reader compatible mobi."
008e5c50  "option: (hidden) Webkit reader Compatible mobi will be built"
008e5ccc  "option: (hidden) fragsize"
008e5d00  "option: (hidden) custom image size will be used for resizing"
008e5d80  "option: (hidden) amazon creator tool or pipeline"
008e5de8  "option: -genhdcontainers: eMM will be built with given resolutions"
0090bbc0  "option: -preserve_img: La taille d'origine de l'image sera préservée"
0090bc50  "option: -image64K: La taille maximum de l'image est limitée à 64K"
0090bcd8  "option: -image128K: La taille maximum de l'image est limitée à 128K"
0090bd60  "option: -gif: Conversion d'image gif (pas jpeg)"
0090bdc0  "option: -c0: Aucune compression"
0090be00  "option: -c1: Compression DOC standard"
0090be50  "option: -c2: Compression Kindle Huffdic"
0090bea0  "option: -allscript: Autorise toutes les scénarisations"
0090bf10  "option: -western: Sortie Windows-1252 forcée"
0090bf70  "option: -verbose: Sortie Verbose"
0090bfb8  "option: -noparseback: Parse back ne sera pas construit"
0090c028  "option: -regserver: Le type de bibliothèque XOPFPlugin a été enregistré"
0090c0b8  "option: -unregserver: Le type de bibliothèque XOPFPlugin a été désenregistré"
0090c158  "option: -donotaddsource: Les fichiers sources se seront pas ajoutés"
0090c1e0  "option: (masquée) Sauter le nettoyage HTML"
0090c238  "option: (masquée) Crée fichier de carte de position json dans le but d'un débogage."
0090c2e0  "option: (masquée) crée un mobi pour les appareils plus anciens."
0090c360  "option: (masquée) Utilisation du mode de fragmentation manuelle (basé sur les balises) pour construire un lecteur Webkit compatible mobi."
0090c478  "option: (masquée) Un lecteur Webkit compatible mobi sera construit"
0090c500  "option: (masquée) fragsize"
0090c538  "option: (masquée) la taille d'image personnalisée sera utilisée pour redimmensionement"
0090c5e8  "option: (caché) amazon créateur outil ou d'un pipeline"
009bbe70  "option: {0}"

the argument strings are hashed with md5 and compared to blob it appears as Guntram blohm commented to your original query

with a fleet glance it appears the hashing function is an MD5 implementation

CPU Disasm
Address                                    Hex dump          Command                                       Comments
006836F0 thiscallhashestheargstring (MD5)  /$  83EC 68       SUB     ESP, 68                               ; kindlegen.thiscallhashestheargstring (MD5)(guessed Arg1)
006836F3                                   |.  8B50 08       MOV     EDX, DWORD PTR DS:[EAX+8]
006836F6                                   |.  8B48 04       MOV     ECX, DWORD PTR DS:[EAX+4]

the possible md5 constants are visible inside the procedure

CPU Disasm
Address   Command                                       Comments
006838FD  LEA     EAX, [EBX+EAX+D76AA478]<<<<<<<<<<<<<<<<<<<<<<<
00683904  ROL     EAX, 7
00683907  ADD     EAX, EDX
00683909  AND     EDI, EAX
0068390B  MOV     ECX, EAX
0068390D  NOT     ECX
0068390F  AND     ECX, ESI
00683911  OR      ECX, EDI
00683913  ADD     ECX, DWORD PTR SS:[ESP+3C]
00683917  MOV     DWORD PTR SS:[ESP+18], EBX
0068391B  LEA     ECX, [EBP+ECX+E8C7B756] <<<<<<<<<<<<<<<<<<<<<<
00683922  ROL     ECX, 0C
00683925  ADD     ECX, EAX
00683927  MOV     EDI, ECX
00683929  NOT     EDI
0068392B  AND     EDI, EDX
0068392D  MOV     EBX, ECX
0068392F  AND     EBX, EAX
00683931  OR      EDI, EBX
00683933  ADD     EDI, DWORD PTR SS:[ESP+40]
00683937  MOV     DWORD PTR SS:[ESP+30], ESI
0068393B  LEA     ESI, [ESI+EDI+242070DB] <<<<<<<<<<<<

the MD5 hash for some arg strings are

cat dontapp.py
import md5
print md5.md5("-dont_append_source").hexdigest()
print md5.md5("-intermediate_only").hexdigest()
print md5.md5("-releasenotes").hexdigest()

python dontapp.py
8465b444e1fe29390e2bb6b98b878829
f837e7c59aeba2cfa4a0ccb7c941e1b8
2368d23829ad7e680cd23385b9fcff6a 

and hash is compared to blob bytes here

Note passing invalid args like -abracadabra doesnt land in this comparison function so it is possible there is a pre check like argstr len etc

CPU Disasm
Address                  Command                                       Comments
006832B0 whoknowswhat    PUSH    EBP                                   ; kindlegen.whoknowswhat(guessed Arg1,Arg2)
006832B1                 MOV     EBP, DWORD PTR SS:[ESP+8]

a logging breakpoints yields this

-dont_append_source hash

006832B0  INT3: [esp+4] = 84 (132.)
006832B0  INT3: [esp+4] = 65 (101.)
006832B0  INT3: [esp+4] = 0B4 (180.)
006832B0  INT3: [esp+4] = 44 (68.)
006832B0  INT3: [esp+4] = 0E1 (225.)
006832B0  INT3: [esp+4] = 0FE (254.)
006832B0  INT3: [esp+4] = 29 (41.)
006832B0  INT3: [esp+4] = 39 (57.)
006832B0  INT3: [esp+4] = 0
006832B0  INT3: [esp+4] = 0E (14.)
006832B0  INT3: [esp+4] = 2B (43.)
006832B0  INT3: [esp+4] = 0B6 (182.)
006832B0  INT3: [esp+4] = 0B9 (185.)
006832B0  INT3: [esp+4] = 8B (139.)
006832B0  INT3: [esp+4] = 87 (135.)
006832B0  INT3: [esp+4] = 88 (136.)
006832B0  INT3: [esp+4] = 29 (41.)

-intermediate_only hash

006832B0  INT3: [esp+4] = 0F8 (248.)
006832B0  INT3: [esp+4] = 37 (55.)
006832B0  INT3: [esp+4] = 0E7 (231.)
006832B0  INT3: [esp+4] = 0C5 (197.)
006832B0  INT3: [esp+4] = 9A (154.)
006832B0  INT3: [esp+4] = 0EB (235.)
006832B0  INT3: [esp+4] = 0A2 (162.)
006832B0  INT3: [esp+4] = 0CF (207.)
006832B0  INT3: [esp+4] = 0A4 (164.)
006832B0  INT3: [esp+4] = 0A0 (160.)
006832B0  INT3: [esp+4] = 0CC (204.)
006832B0  INT3: [esp+4] = 0B7 (183.)
006832B0  INT3: [esp+4] = 0C9 (201.)
006832B0  INT3: [esp+4] = 41 (65.)
006832B0  INT3: [esp+4] = 0E1 (225.)
006832B0  INT3: [esp+4] = 0B8 (184.)

--releasenotes

006832B0  INT3: [esp+4] = 23 (35.)
006832B0  INT3: [esp+4] = 68 (104.)
006832B0  INT3: [esp+4] = 0D2 (210.)
006832B0  INT3: [esp+4] = 38 (56.)
006832B0  INT3: [esp+4] = 29 (41.)
006832B0  INT3: [esp+4] = 0AD (173.)
006832B0  INT3: [esp+4] = 7E (126.)
006832B0  INT3: [esp+4] = 68 (104.)
006832B0  INT3: [esp+4] = 0
006832B0  INT3: [esp+4] = 0C (12.)
006832B0  INT3: [esp+4] = 0D2 (210.)
006832B0  INT3: [esp+4] = 33 (51.)
006832B0  INT3: [esp+4] = 85 (133.)
006832B0  INT3: [esp+4] = 0B9 (185.)
006832B0  INT3: [esp+4] = 0FC (252.)
006832B0  INT3: [esp+4] = 0FF (255.)
006832B0  INT3: [esp+4] = 6A (106.)
  • If you look in your list, you will find the "option: (hidden) ..." command line options that OP is asking about. (And in several languages: 'masquée', 'verborgen', 'скрыто'.) – Jongware Dec 9 '16 at 10:18
  • dinotaddsource isnt hidden as said by op – blabb Dec 9 '16 at 10:49
  • 1
    @blabb: Thanks for looking into this. I really appreciate it! As other commenters have already pointed out, -donotaddsource is not one the hidden options. Actually, if -dont_append_source is specified, kindlegen will display -donotaddsource. I.e. they must have changed the name of this hidden option later. I.e. -donotaddsource is rejected as a command line parameter. – Nemo XXX Dec 9 '16 at 14:40
  • the args are md5ed it appears see the updated answer – blabb Dec 10 '16 at 7:29
  • @blabb: Thanks for the update!!! If you post the md5 hashes for: option: (hidden) creates mobi for older devices. and option: (hidden) Webkit reader Compatible mobi will be built, I'll accept the answer and award you the bounty. – Nemo XXX Dec 10 '16 at 8:49
-1

If you have basic reversing skills, then load the target in a debugger and put a breakpoint on GetCommandLine and start tracing from there until you reach where the app compares your command line parameter with the obfuscated ones.

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.