mufeedvh / pdfrip

A multi-threaded PDF password cracking utility equipped with commonly encountered password format builders and dictionary attacks.
MIT License
589 stars 67 forks source link

Implement a PDFRip GUI App #18

Open mufeedvh opened 7 months ago

Pommaq commented 6 months ago

Easiest would probably be to add a REST API-like interface to engine instead of the current CLI implementation, then write a simple frontend in vue/whatever

Pommaq commented 6 months ago

Consider using macros to allow compiling PDFRip in two modes, cli and UI/REST since it would probably simplify argument parsing logic since the different interfaces would have widely different parameters. This would be easiest if all user interactions (read: Parameter parsing) is separated to a separated layer from the rest of the application.

Alternatively just add a new mode to the arguments that starts the REST api, but it would make the binary pretty big to run both cli and REST at once.

Running Axum + utoipa for Swagger documentation would be neat imo if this is the chosen approach

ApprenticeofEnder commented 6 months ago

I like the idea of this! Seems like something that could pretty easily be broken down into a handful of issues.

mufeedvh commented 6 months ago

Yep, a webview approach sounds good.

@Pommaq One implementation detail I am curious to know your input on is the progress bar. To implement a progress bar in the GUI that works in the same way as the indicatif progress bar in the console stdout, we would have to pass it on each channel message increments, which would affect performance since it involves network calls. We could show progress per 1000 (or n) increments which should solve it but I am curious to know if you have a better idea since you implemented the current channel-based cracker.

Pommaq commented 6 months ago

Engine.rs takes a callback now, one way would be to add an API endpoint where we can "poll" the progress similarly to what you've already thought of, which returns e.g. how many passwords have been consumed from the producer + it's size, then the UI simply uses that periodically (for example, once a second wouldn't be too much of a performance hit).

The callback can likely just increment an atomic (thread safety, race conditions) integer which said endpoint uses to track the progress.

I've only put like 5 seconds of thought into how this could be done, but I believe the borrow checker could be angry about this approach since the api and engine are likely to run in different threads, a solution is to just wrap the integer in an Arc.

Pommaq commented 6 months ago

Alternatively, open a websocket and send the progress through it to avoid polling but it would then have the performance issues you've already thought of. Unless that websocket was to be run in a separate and very slim thread from the crackers. Said socket would have the benefit that when the cracking has finished the results can be pushed to the UI instead of it being polled.

A future thing to keep in mind is that some crackers might be unable to estimate the number of passwords they will produce, an example would be a future implementation that simply reads passwords from a socket (This would allow a distributed producer approach) would be unable to know how many passwords it could get unless one were to implement some weird clunky protocol I think. The easiest solution would be that those types of producers don't show a progress bar, instead it just shows a spinner + time elapsed