Skip to content

Commit a8bb97f

Browse files
committed
[WRAPPER] Improved bridge with a secondary function (inplace of the name)
1 parent 5adfb41 commit a8bb97f

File tree

6 files changed

+110
-15
lines changed

6 files changed

+110
-15
lines changed

src/emu/x64int3.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,12 @@ void print_wrapper_name(int level, x64emu_t* emu)
8181
{
8282
onebridge_t* bridge = (onebridge_t*)(R_RIP&~(sizeof(onebridge_t)-1));
8383
if (IsBridgeSignature(bridge->S, bridge->C)) {
84-
printf_log(level, "calling %s\n", bridge->name?bridge->name:"????");
84+
const char* name = NULL;
85+
if(bridge->func)
86+
name = GetNativeName(bridge->name_or_func);
87+
else
88+
name = bridge->name_or_func;
89+
printf_log(level, "calling %s\n", name?name:"????");
8590
} else {
8691
printf_log(level, "Could found the function name for fnc=%p\n", bridge->f);
8792
}
@@ -149,7 +154,7 @@ void x64Int3(x64emu_t* emu, uintptr_t* addr)
149154
uint64_t *pu64 = NULL;
150155
uint32_t *pu32 = NULL;
151156
uint8_t *pu8 = NULL;
152-
const char *s = bridge->name;
157+
const char *s = (bridge->func)?GetNativeName(bridge->name_or_func):bridge->name_or_func;
153158
if(!s)
154159
s = GetNativeName((void*)a);
155160
if(a==(uintptr_t)PltResolver64) {

src/emu/x86int3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void x86Int3(x64emu_t* emu, uintptr_t* addr)
8383
uint64_t *pu64 = NULL;
8484
uint32_t *pu32 = NULL;
8585
uint8_t *pu8 = NULL;
86-
const char *s = bridge->name;
86+
const char *s = (bridge->func)?GetNativeName(bridge->name_or_func):bridge->name_or_func;
8787
if(!s)
8888
s = GetNativeName((void*)a);
8989
if(a==(uintptr_t)PltResolver32) {

src/include/bridge.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ void FreeBridge(bridge_t** bridge);
1212

1313
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
1414
uintptr_t CheckBridged(bridge_t* bridge, void* fnc);
15+
uintptr_t CheckBridged2(bridge_t* bridge, void* fnc, void* fnc2);
16+
uintptr_t AddBridge2(bridge_t* bridge, wrapper_t w, void* fnc, void* fnc2, int N, const char* name);
1517
uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
18+
uintptr_t AddCheckBridge2(bridge_t* bridge, wrapper_t w, void* fnc, void* fnc2, int N, const char* name);
1619
uintptr_t AddAutomaticBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
1720
uintptr_t AddAutomaticBridgeAlt(bridge_t* bridge, wrapper_t w, void* fnc, void* alt, int N, const char* name);
1821
void* GetNativeFnc(uintptr_t fnc);
@@ -22,6 +25,7 @@ void* GetNativeOrAlt(void* fnc, void* alt);
2225
uintptr_t AddVSyscall(bridge_t* bridge, int num);
2326

2427
const char* getBridgeName(void* addr);
28+
void* getBridgeFnc2(void* addr);
2529

2630
void init_bridge_helper(void);
2731
void fini_bridge_helper(void);

src/include/khash.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ typedef unsigned long khint64_t;
142142
#else
143143
typedef unsigned long long khint64_t;
144144
#endif
145+
typedef __uint128_t khint128_t;
145146

146147
#ifdef _MSC_VER
147148
#define kh_inline __inline
@@ -393,6 +394,16 @@ static const double __ac_HASH_UPPER = 0.77;
393394
@abstract 64-bit integer comparison function
394395
*/
395396
#define kh_int64_hash_equal(a, b) ((a) == (b))
397+
/*! @function
398+
@abstract 128-bit integer hash function
399+
@param key The integer [khint128_t]
400+
@return The hash value [khint_t]
401+
*/
402+
#define kh_int128_hash_func(key) (khint32_t)((key)>>100^(key)>>66^(key)>>33^(key)^(key)<<11)
403+
/*! @function
404+
@abstract 128-bit integer comparison function
405+
*/
406+
#define kh_int128_hash_equal(a, b) ((a) == (b))
396407
/*! @function
397408
@abstract const char* hash function
398409
@param s Pointer to a null terminated string
@@ -696,7 +707,34 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
696707
#define KHASH_MAP_IMPL_INT64(name, khval_t) \
697708
__KHASH_IMPL(name, , khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
698709

699-
typedef const char *kh_cstr_t;
710+
/*! @function
711+
@abstract Instantiate a hash map containing 128-bit integer keys
712+
@param name Name of the hash table [symbol]
713+
*/
714+
#define KHASH_SET_INIT_INT128(name) \
715+
KHASH_INIT(name, khint128_t, char, 0, kh_int128_hash_func, kh_int128_hash_equal)
716+
717+
#define KHASH_SET_DECLARE_INT128(name) \
718+
KHASH_DECLARE(name, khint128_t, char)
719+
720+
#define KHASH_SET_IMPL_INT128(name) \
721+
__KHASH_IMPL(name, , khint128_t, char, 0, kh_int128_hash_func, kh_int128_hash_equal)
722+
723+
/*! @function
724+
@abstract Instantiate a hash map containing 128-bit integer keys
725+
@param name Name of the hash table [symbol]
726+
@param khval_t Type of values [type]
727+
*/
728+
#define KHASH_MAP_INIT_INT128(name, khval_t) \
729+
KHASH_INIT(name, khint128_t, khval_t, 1, kh_int128_hash_func, kh_int128_hash_equal)
730+
731+
#define KHASH_MAP_DECLARE_INT128(name, khval_t) \
732+
KHASH_DECLARE(name, khint128_t, khval_t)
733+
734+
#define KHASH_MAP_IMPL_INT128(name, khval_t) \
735+
__KHASH_IMPL(name, , khint128_t, khval_t, 1, kh_int128_hash_func, kh_int128_hash_equal)
736+
737+
typedef const char *kh_cstr_t;
700738
/*! @function
701739
@abstract Instantiate a hash map containing const char* keys
702740
@param name Name of the hash table [symbol]

src/tools/bridge.c

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "box32context.h"
2626
#endif
2727

28-
KHASH_MAP_INIT_INT64(bridgemap, uintptr_t)
28+
KHASH_MAP_INIT_INT128(bridgemap, uintptr_t)
2929

3030
typedef struct brick_s brick_t;
3131
typedef struct brick_s {
@@ -99,12 +99,8 @@ void FreeBridge(bridge_t** bridge)
9999
*bridge = NULL;
100100
}
101101

102-
#ifdef HAVE_TRACE
103-
void addBridgeName(void* addr, const char* name);
104-
#endif
105-
106102
//static const char* default_bridge = "bridge???";
107-
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name)
103+
uintptr_t AddBridge2(bridge_t* bridge, wrapper_t w, void* fnc, void* fnc2, int N, const char* name)
108104
{
109105
brick_t *b = NULL;
110106
int sz = -1;
@@ -120,7 +116,8 @@ uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char*
120116
sz = b->sz;
121117
b->sz++;
122118
// add bridge to map, for fast recovery
123-
khint_t k = kh_put(bridgemap, bridge->bridgemap, (uintptr_t)fnc, &ret);
119+
khint128_t key = (uintptr_t)fnc | (khint128_t)((uintptr_t)fnc2)<<64;
120+
khint_t k = kh_put(bridgemap, bridge->bridgemap, key, &ret);
124121
kh_value(bridge->bridgemap, k) = (uintptr_t)&b->b[sz].CC;
125122
mutex_unlock(&my_context->mutex_bridge);
126123

@@ -130,11 +127,17 @@ uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char*
130127
b->b[sz].f = (uintptr_t)fnc;
131128
b->b[sz].C3 = N?0xC2:0xC3;
132129
b->b[sz].N = N;
133-
b->b[sz].name = name/*?name:default_bridge*/;
130+
b->b[sz].func = fnc2?1:0;
131+
b->b[sz].name_or_func = fnc2?(void*)name:fnc2;
134132

135133
return (uintptr_t)&b->b[sz].CC;
136134
}
137135

136+
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name)
137+
{
138+
return AddBridge2(bridge, w, fnc, NULL, N, name);
139+
}
140+
138141
uintptr_t CheckBridged(bridge_t* bridge, void* fnc)
139142
{
140143
// check if function alread have a bridge (the function wrapper will not be tested)
@@ -144,6 +147,16 @@ uintptr_t CheckBridged(bridge_t* bridge, void* fnc)
144147
return kh_value(bridge->bridgemap, k);
145148
}
146149

150+
uintptr_t CheckBridged2(bridge_t* bridge, void* fnc, void* fnc2)
151+
{
152+
// check if function alread have a bridge (the function wrapper will not be tested)
153+
khint128_t key = (uintptr_t)fnc | (khint128_t)((uintptr_t)fnc2)<<64;
154+
khint_t k = kh_get(bridgemap, bridge->bridgemap, key);
155+
if(k==kh_end(bridge->bridgemap))
156+
return 0;
157+
return kh_value(bridge->bridgemap, k);
158+
}
159+
147160
uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name)
148161
{
149162
if(!fnc && w)
@@ -154,6 +167,16 @@ uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const
154167
return ret;
155168
}
156169

170+
uintptr_t AddCheckBridge2(bridge_t* bridge, wrapper_t w, void* fnc, void* fnc2, int N, const char* name)
171+
{
172+
if(!fnc && w)
173+
return 0;
174+
uintptr_t ret = CheckBridged2(bridge, fnc, fnc2);
175+
if(!ret)
176+
ret = AddBridge2(bridge, w, fnc, fnc2, N, name);
177+
return ret;
178+
}
179+
157180
uintptr_t AddAutomaticBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name)
158181
{
159182
if(!fnc)
@@ -260,8 +283,32 @@ const char* getBridgeName(void* addr)
260283
if (one->C3 == 0xC3 && IsBridgeSignature(one->S, one->C)) {
261284
if(one->w==NULL)
262285
return "ExitEmulation";
263-
else
264-
return one->name;
286+
else {
287+
if(one->func)
288+
return GetNativeName(one->name_or_func);
289+
else
290+
return one->name_or_func;
291+
}
292+
}
293+
return NULL;
294+
}
295+
296+
const char* getBridgeFunc2(void* addr)
297+
{
298+
if(!memExist((uintptr_t)addr))
299+
return NULL;
300+
if(!(getProtection((uintptr_t)addr)&PROT_READ))
301+
return NULL;
302+
onebridge_t* one = (onebridge_t*)(((uintptr_t)addr&~(sizeof(onebridge_t)-1))); // align to start of bridge
303+
if (one->C3 == 0xC3 && IsBridgeSignature(one->S, one->C)) {
304+
if(one->w==NULL)
305+
return NULL;
306+
else {
307+
if(one->func)
308+
return one->name_or_func;
309+
else
310+
return NULL;
311+
}
265312
}
266313
return NULL;
267314
}

src/tools/bridge_private.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ typedef union onebridge_s {
1414
uintptr_t f; // the function for the wrapper
1515
uint8_t C3; // C2 or C3 ret
1616
uint16_t N; // N in case of C2 ret
17-
const char* name; // name of the function bridged
17+
uint8_t func; // 1 if name_or_func is actualy a function (so no name in that case)
18+
void* name_or_func; // name of the function bridged
1819
};
1920
struct {
2021
uint8_t B8; // B8 00 11 22 33 mov eax, num

0 commit comments

Comments
 (0)