frida / frida-gum

Cross-platform instrumentation and introspection library written in C
https://frida.re
Other
761 stars 248 forks source link

Stalker and C++ SEH problems. #565

Open WorksButNotTested opened 3 years ago

WorksButNotTested commented 3 years ago

When running the following C++ application under Stalker (using the below JS script) but with the libstdc++ library excluded it seems that the catch block of the SEH is never invoked and the process instead just terminates.

Target Application:

#include <cstdio>
#include <string>
#include <iostream>

using namespace std;

int main(void) {
    try {
        string("abc").substr(10);
    } catch(const exception& e) {
        cout << e.what() << endl;
    }
    return 0;
}

FRIDA Script:

Interceptor.attach(
    DebugSymbol.fromName("main").address,
    {
        onEnter(args) {
            Stalker.follow(Process.id,{});
            new ModuleMap().values().forEach(m => {
                console.log(`Found: ${m.name}`);
                if (m.name.startsWith('libstdc++')) {
                    console.log(`Excluding: ${m.name}`);
                    Stalker.exclude(m);
                }
            });
        },
        onLeave(ret) {
            Stalker.unfollow(Process.id);
            Stalker.flush();
        }
    }
)

Gadget configuration:

{
  "interaction": {
    "type": "script",
    "path": "./test.js"
  }
}

Actual output:

$ g++ -o test test.cpp  && LD_PRELOAD=./frida-gadget-14.2.18-linux-x86_64.so ./test
Found: test
Found: libm-2.31.so
Found: libpthread-2.31.so
Found: librt-2.31.so
Found: libresolv-2.31.so
Found: libdl-2.31.so
Found: libc-2.31.so
Found: libgcc_s.so.1
Found: libstdc++.so.6.0.28
Excluding: libstdc++.so.6.0.28
Found: frida-gadget-14.2.18-linux-x86_64.so
Found: ld-2.31.so
Found: linux-vdso.so.1
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 10) > this->size() (which is 3)
Aborted

Expected output (also achieved if Stalker.exclude is commented out):

$ g++ -o test test.cpp  && LD_PRELOAD=./frida-gadget-14.2.18-linux-x86_64.so ./test
Found: test
Found: libm-2.31.so
Found: libpthread-2.31.so
Found: librt-2.31.so
Found: libresolv-2.31.so
Found: libdl-2.31.so
Found: libc-2.31.so
Found: libgcc_s.so.1
Found: libstdc++.so.6.0.28
Excluding: libstdc++.so.6.0.28
Found: frida-gadget-14.2.18-linux-x86_64.so
Found: ld-2.31.so
Found: linux-vdso.so.1
basic_string::substr: __pos (which is 10) > this->size() (which is 3)

Affects versions:

WorksButNotTested commented 3 years ago

Even more minimal reproducer:

Stalker.trustThreshold = -1;
Stalker.follow(Process.id,{});
new ModuleMap().values().forEach(m => {
    console.log(`Found: ${m.name}`);
    if (m.name.startsWith('libstdc++')) {
        console.log(`Excluding: ${m.name}`);
        Stalker.exclude(m);
    }
});
s1341 commented 3 years ago

This is probably related to the fact that we don't have FDEs for the transformed code, as @oleavr and I discussed recently. You can see failing tests which reproduce this here: https://gist.github.com/s1341/d7357e8c5a6e84a2ed6ea00f77ceead8

tokatoka commented 2 years ago

hi guys! is this issue resolved by this pull request already? https://github.com/frida/frida-gum/pull/607

WorksButNotTested commented 2 years ago

I believe it will be if you call ‘ gum_stalker_activate_experimental_unwind_support’. Subject to any symbol resolution issues discussed in the PR.