panda-re / panda

Platform for Architecture-Neutral Dynamic Analysis
https://panda.re
Other
2.48k stars 479 forks source link

Sleep before async commands #1224

Open IridiumXOR opened 2 years ago

IridiumXOR commented 2 years ago

Hi, using PyPanda, I need to perform some async operation on the machine (take snapshot, send serial command etc) delayed by XX seconds in which the machine has to free run. For example:

sleep(600) -> the machine free runs for 10 minutes snap() -> take a snapshot of the vm sleep(10) run_serial_cmd("bla bla") sleep(60) -> the machine free runs for 1 minutes etc. however I don't understand how to do that because if I insert sleep(XX) in a @panda.queue_blocking function it does not work (the guest remains "stuck" for XX seconds?) and also it does not work if i create a separate thread started before panda.run() which injects async events with panda.queue_async(fn). So, how can i solve this problem?

lacraig2 commented 2 years ago

The run_serial_cmd waits for the command (e.g. "bla bla") to complete and give a terminal back. Is that command completing?

I'm not sure what you mean by "the guest remains stuck". If you sleep in the queue_blocking thread you should be able ot get callbacks and other guest interaction during that time.

Another way to do this is to run_serial_cmd("sleep 10") inside the guest.

IridiumXOR commented 2 years ago
panda = Panda(arch="x86_64", mem=str(args.mem), extra_args=args.extra_args,expect_prompt=args.prompt,serial_kwargs={"unansi": False})

@panda.queue_blocking
def run_cmd():

    # Restore snapshot
    if args.loadvm:
        print(f"Restoring snapshot {args.loadvm}...")
        panda.revert_sync(args.loadvm) 

    # Take snapshot of the disk if time is passed
    if args.snap >= 0:
        print(f"Snap disk after {args.snap} seconds...")
        time.sleep(args.snap)
        panda.snap(args.record)
        print(f"Snapshot completed")

    panda.end_analysis()
    return

panda.run()

If i run this script, sometimes the snapshot is created, sometimes not, sometimes the script remains stacked after "Snapshot completed" print..

IridiumXOR commented 2 years ago

If I use panda.run_monitor_cmd(f"savevm {args.record}") instead panda.snap() it works correctly... it is a bug in panda.snap() implementation?

lacraig2 commented 1 year ago

That's interesting. We have previously seen issues in queue_main_loop_wait functionality.

https://github.com/panda-re/panda/blob/04a89db90c9134bc60b142dffdaad5775622c8c5/panda/python/core/pandare/panda.py#L409-L415

In theory panda.snap could simply be mapped to run_monitor_cmd, but I think the idea was that you could use snap from within a running analysis point and not just in the queue_blocking thread.