diff options
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/bridge.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/tools/bridge.c b/src/tools/bridge.c index 7c697b22..3bc46713 100644 --- a/src/tools/bridge.c +++ b/src/tools/bridge.c @@ -300,3 +300,31 @@ void fini_bridge_helper() { cleanAlternate(); } + +int isNativeCall(uintptr_t addr, int is32bits, uintptr_t* calladdress, uint16_t* retn) +{ + if (is32bits) + addr &= 0xFFFFFFFFLL; + +#define PK(a) *(uint8_t*)(addr + a) +#define PK32(a) *(int32_t*)(addr + a) + + if (!addr || !getProtection(addr)) + return 0; + if (PK(0) == 0xff && PK(1) == 0x25) { // "absolute" jump, maybe the GOT (well, RIP relative in fact) + uintptr_t a1 = addr + 6 + (PK32(2)); // need to add a check to see if the address is from the GOT ! + addr = (uintptr_t)getAlternate(*(void**)a1); + } + if (!addr || !getProtection(addr)) + return 0; + onebridge_t* b = (onebridge_t*)(addr); + if (b->CC == 0xCC && b->S == 'S' && b->C == 'C' && b->w != (wrapper_t)0 && b->f != (uintptr_t)PltResolver64) { + // found ! + if (retn) *retn = (b->C3 == 0xC2) ? b->N : 0; + if (calladdress) *calladdress = addr + 1; + return 1; + } + return 0; +#undef PK32 +#undef PK +} |