panda-re / panda

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

Snake_hook script fails to load OSI in docker container #1177

Open AndrewFasano opened 2 years ago

AndrewFasano commented 2 years ago

I'm analyzing an x86_64 recording of the generic image using proc_trace and trying to use the snake_hook plugin to run graph.py :

panda-system-x86_64 -m 1g -replay myrecording -panda proc_trace \
-os linux-64-ubuntu:4.15.0-72-generic-noaslr-nokaslr -pandalog foo.plog \
-panda snake_hook:files=graph.py

After snake_hook is loaded, PANDA raises a fatal error that it's unable to load OSI, but I'm not sure why. The panda_osi.so file does exist and I believe I've specified the right OS name.

PANDA[core]:initializing snake_hook
[snake_hook] Initialized
[PYPANDA] Panda args: [/usr/local/bin/libpanda-x86_64.so -L /usr/local/lib/python3.8/dist-packages/pandare/data/pc-bios -m 128M -monitor unix:/tmp/pypanda_m0c3n6yqm,server,nowait]
Warning: disabling TB chaining to support before_block_exec callback
PPP automatically loaded plugin osi
PANDA[core]:loading required plugin osi
Failed to load libpanda: (null) from /usr/local/lib/python3.8/dist-packages/pandare/data/x86_64-softmmu/libpanda-x86_64.so
PANDA[core]:FAILED to load required plugin osi from /usr/local/lib/python3.8/dist-packages/pandare/data//x86_64-softmmu/panda/plugins//panda_osi.so
Aborted
gnat79 commented 2 years ago

I've had the same problem, running locally without Docker, with PyPanda installed from source Why is dlerror null? The error originates in callbacks.c:198, with the call to dlopen (see below). I'm not familiar enough with dlopen to understand the implications of using those three flags together:

https://github.com/panda-re/panda/blob/5fb39520452302ad02c1a4a375fd88c20f158ecc/panda/src/callbacks.c#L198

whoismissing commented 1 year ago

I've been running into this problem as well when running locally in Ubuntu 22 installed from source.

As a small test of dlopen, the use of the RTLD_NOLOAD flag means that if it is the first time libpanda-x86_64.so is being loaded, then dlopen will return NULL.

As an example POC:

#include <stdio.h>
#include <dlfcn.h>

int main() {

    void * rv = dlopen("/usr/local/lib/python3.10/dist-packages/pandare/data//x86_64-softmmu/libpanda-x86_64.so", RTLD_LAZY | RTLD_NOLOAD | RTLD_GLOBAL);

    void * rv2 = dlopen("/usr/local/lib/python3.10/dist-packages/pandare/data//x86_64-softmmu/libpanda-x86_64.so", RTLD_LAZY | RTLD_LOCAL);

    void * rv3 = dlopen("/usr/local/lib/python3.10/dist-packages/pandare/data//x86_64-softmmu/libpanda-x86_64.so", RTLD_LAZY | RTLD_NOLOAD | RTLD_GLOBAL);

    printf("rv = %p\n", rv);
    printf("rv2 = %p\n", rv2);
    printf("rv3 = %p\n", rv3);

    return 0;
}
$ gcc test_dlopen.c
$ ./a.out
rv = (nil)
rv2 = 0x55ac517ea300
rv3 = 0x55ac517ea300
whoismissing commented 1 year ago

My workaround right now is just to use the Panda API like in run_dbg.py instead of using snake_hook.