Подключение функции usercall от ida pro

int CachedTag_NoCache_GetTagPos( CEntity* centity, int tag, Vector* worldpos )
{
void* funccall = (void*)0x7D5BD0;
__asm {
mov edi, worldpos
mov esi, centity
push tag
call funccall
add esp, 4
}
}

Функция вылетает при добавлении esp, 4 ….

Я знаю его сбой из-за очистки этой встроенной сборки. Я просто не знаю, как это исправить.

Вот что внутри ida pro:

int __usercall sub_7A7D20<eax>(int a1<ecx>, int a2<edi>, int a3<esi>, int a4)
{
int v4; // eax@2
int result; // eax@2
char *v6; // eax@3
char v7; // al@5
int v8; // [sp+0h] [bp-4h]@1

v8 = a1;
if ( *(_WORD *)(a3 + 678) == 1 )
{
LOBYTE(v8) = sub_5BB6F0(*(_BYTE *)(a3 + 4), *(_DWORD *)(a3 + 0x1E8));
v4 = sub_7A7C40();
result = sub_4DA2F0(a3, a2, a4, v4, v8);
}
else
{
v6 = sub_615EA0(*(_DWORD *)(a3 + 0x1E8), *(_BYTE *)(a3 + 4));
result = sub_4B2F50(a3, v6, a2, a4);
}
if ( !result )
{
v7 = sub_624C70(a2, 0);
result = sub_627380(1, "AimTarget_GetTagPos: Cannot find tag [%s] on entity\n", v7);
}
return result;
}

Сборка для этой функции от ida pro в тексте:

.text:007D5BD0 sub_7D5BD0      proc near               ; CODE XREF: sub_4DA2F0+76p
.text:007D5BD0                                         ; sub_62AE20+18p
.text:007D5BD0
.text:007D5BD0 arg_0           = dword ptr  4
.text:007D5BD0
.text:007D5BD0                 movzx   eax, byte ptr [esi+4]
.text:007D5BD4                 mov     ecx, [esi+1E8h]
.text:007D5BDA                 push    ebx
.text:007D5BDB                 mov     ebx, [esp+4+arg_0]
.text:007D5BDF                 push    eax
.text:007D5BE0                 push    ecx
.text:007D5BE1                 call    sub_615EA0
.text:007D5BE6                 add     esp, 8
.text:007D5BE9                 test    eax, eax
.text:007D5BEB                 jnz     short loc_7D5C00
.text:007D5BED                 fld     dword ptr [esi+30h]
.text:007D5BF0                 pop     ebx
.text:007D5BF1                 fstp    dword ptr [edi]
.text:007D5BF3                 fld     dword ptr [esi+34h]
.text:007D5BF6                 fstp    dword ptr [edi+4]
.text:007D5BF9                 fld     dword ptr [esi+38h]
.text:007D5BFC                 fstp    dword ptr [edi+8]
.text:007D5BFF                 retn
.text:007D5C00 ; ---------------------------------------------------------------------------
.text:007D5C00
.text:007D5C00 loc_7D5C00:                             ; CODE XREF: sub_7D5BD0+1Bj
.text:007D5C00                 push    edi
.text:007D5C01                 push    ebx
.text:007D5C02                 push    eax
.text:007D5C03                 push    esi
.text:007D5C04                 call    sub_4B2F50
.text:007D5C09                 add     esp, 10h
.text:007D5C0C                 test    eax, eax
.text:007D5C0E                 jnz     short loc_7D5C2B
.text:007D5C10                 push    eax
.text:007D5C11                 push    ebx
.text:007D5C12                 call    sub_624C70
.text:007D5C17                 push    eax             ; char
.text:007D5C18                 push    offset aCachedtag_noca ; "CachedTag_NoCache_GetTagPos: Cannot fin"...
.text:007D5C1D                 push    1               ; int
.text:007D5C1F                 call    sub_627380
.text:007D5C24                 add     esp, 14h
.text:007D5C27                 xor     eax, eax
.text:007D5C29                 pop     ebx
.text:007D5C2A                 retn
.text:007D5C2B ; ---------------------------------------------------------------------------
.text:007D5C2B
.text:007D5C2B loc_7D5C2B:                             ; CODE XREF: sub_7D5BD0+3Ej
.text:007D5C2B                 mov     edx, dword_D4F178
.text:007D5C31                 mov     eax, [edx+40688h]
.text:007D5C37                 pop     ebx
.text:007D5C38                 retn
.text:007D5C38 sub_7D5BD0      endp
.text:007D5C38
.text:007D5C38 ; ---------------------------------------------------------------------------
.text:007D5C39                 align 10h
.text:007D5C40

Сборка у меня работает. Я вхожу в игру, и она показывает мне, что я хочу около 3 минут. Затем он падает. Хотя визуальная студия подключена к процессу, она всегда говорит о сбое в моей функции выше при добавлении esp, 4.

Теперь при вызове пользователя, использующем edi и esi, нужно ли мне удалять их после вызова моей функции и / или мне тоже нужно что-то ретенировать?

Его явно не так хорошо, как у меня, потому что он работает только около 3 минут. Самый длинный код, на котором я работал, был около 3 игр. Которые были около 10 минут в длину.

Затем, после этих 3-х игр, это стало моей фатальной ошибкой.

Спасибо всем, у кого есть знания, чтобы ответить на этот вопрос.

Я знаю, что что-то глупо с очисткой после вызова этой функции во встроенной сборке.

1

Решение

Указанный вами код верен. Сама целевая функция нейтральна по отношению к стеку, и после вызова вы очищаете переданный параметр.

Вы уверены, что это правильная строка, в которой происходит сбой кода? Какое исключение вы получаете? Я не думаю, что добавление константы в регистр может даже вызвать исключение.

Интервалы аварии, о которых вы сообщаете, кажутся случайными. Это может быть проблема с многопоточностью, когда вы, например, передаете недопустимый CEntity, и вызываемая функция вылетает. Вы можете предотвратить это, подключив поток, который обычно вызывает эту функцию, и вызывать ее в этом потоке.

0

Другие решения

вам нужно сохранить и восстановить EDI а также ESI (ABI x86 определяет их как не-изменчивые регистры, что означает, что вы не можете их уничтожить), это также, вероятно, пролог и эпилог, сгенерированный MSVC, который вызывает проблемы, IMO, было бы лучше написать это чисто голая функция, это дает вам лучший контроль над созданной сборкой и гарантирует, что вы можете должным образом эмулировать нестандартные (оптимизированные) соглашения о вызовах:

__declspec(naked) int __fastcall CachedTag_NoCache_GetTagPos(CEntity* centity, int tag, Vector* worldpos)
{
__asm {
push edi
push esi
mov edi,worldpos
mov esi,centity
push tag
mov eax,0x7D5BD0
call eax
add esp,4
pop esi
pop edi
retn 4
}
}

С точки зрения исключений, которые вы получаете, похоже, что вы не получаете правильную строку, отладчик уровня сборки, такой как ollydbg, поможет вам точно определить точную причину и правильное местоположение.


Также, в качестве предостережения, никогда не используйте фиксированный адрес, используйте безопасный вариант перемещения, то есть: базовый адрес + RVA; в моем коде выше, вам нужно всего лишь изменить две строки для достижения этого:

mov eax,[base_address]
add eax,rva

где base_address по направлениям:

UINT_PTR base_address = (UINT_PTR)GetModuleHandle("some_module");

и является глобально доступным.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector