- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
int Sys_FunctionCmp(void *f1, void *f2) {
int i, j, l;
byte func_end[32] = {0xC3, 0x90, 0x90, 0x00};
byte *ptr, *ptr2;
byte *f1_ptr, *f2_ptr;
ptr = (byte *) f1;
if (*(byte *)ptr == 0xE9) {
//Com_Printf("f1 %p1 jmp %d\n", (int *) f1, *(int*)(ptr+1));
f1_ptr = (byte*)(((byte*)f1) + (*(int *)(ptr+1)) + 5);
}
else {
f1_ptr = ptr;
}
//Com_Printf("f1 ptr %p\n", f1_ptr);
ptr = (byte *) f2;
if (*(byte *)ptr == 0xE9) {
//Com_Printf("f2 %p jmp %d\n", (int *) f2, *(int*)(ptr+1));
f2_ptr = (byte*)(((byte*)f2) + (*(int *)(ptr+1)) + 5);
}
else {
f2_ptr = ptr;
}
//Com_Printf("f2 ptr %p\n", f2_ptr);
#ifdef _DEBUG
sprintf((char *)func_end, "%c%c%c%c%c%c%c", 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC3);
#endif
for (i = 0; i < 1024; i++) {
for (j = 0; func_end[j]; j++) {
if (f1_ptr[i+j] != func_end[j])
break;
}
if (!func_end[j]) {
break;
}
}
#ifdef _DEBUG
l = i + 7;
#else
l = i + 2;
#endif
//Com_Printf("function length = %d\n", l);
for (i = 0; i < l; i++) {
// check for a potential function call
if (*((byte *) &f1_ptr[i]) == 0xE8) {
// get the function pointers in case this really is a function call
ptr = (byte *) (((byte *) &f1_ptr[i]) + (*(int *) &f1_ptr[i+1])) + 5;
ptr2 = (byte *) (((byte *) &f2_ptr[i]) + (*(int *) &f2_ptr[i+1])) + 5;
// if it was a function call and both f1 and f2 call the same function
if (ptr == ptr2) {
i += 4;
continue;
}
}
if (f1_ptr[i] != f2_ptr[i])
return qfalse;
}
return qtrue;
}
codemonkey 03.12.2014 11:44 # +1
gost 03.12.2014 12:47 # 0
govnokod3r 03.12.2014 22:38 # +3
Ищет конец функции по
RETN
NOP
NOP
Если выравнивание сделано не нопами, то будет фейл с определением размера.
bormand 04.12.2014 07:36 # +1
gost 04.12.2014 11:45 # +1