You are not logged in.
Pages: 1
Не получается вызвать функцию, которая использует "обработку исключений".
.text:005C1F50 ; CFxSystem *__thiscall CParticleData__RegisterFxSystem(CParticleData *list, char *flname, FILE *file) .text:005C1F50 CParticleData__RegisterFxSystem proc near .text:005C1F50 ; CODE XREF: CParticleData__ReadEffectsFile+140p .text:005C1F50 .text:005C1F50 var_120 = byte ptr -120h .text:005C1F50 param = dword ptr -114h .text:005C1F50 var_110 = dword ptr -110h .text:005C1F50 var_10C = byte ptr -10Ch .text:005C1F50 var_C = dword ptr -0Ch .text:005C1F50 var_4 = dword ptr -4 .text:005C1F50 flname = dword ptr 4 .text:005C1F50 file = dword ptr 8 .text:005C1F50 .text:005C1F50 000 push 0FFFFFFFFh .text:005C1F52 004 push offset _eh_handler_5c1f50 .text:005C1F57 008 mov eax, large fs:0 .text:005C1F5D 008 push eax .text:005C1F5E 00C mov large fs:0, esp .text:005C1F65 00C sub esp, 108h .text:005C1F6B 114 push ebx .text:005C1F6C 118 mov ebx, [esp+118h+file] .text:005C1F73 118 push esi .text:005C1F74 11C push edi .text:005C1F75 120 push 100h ; int .text:005C1F7A 124 lea eax, [esp+124h+var_10C] .text:005C1F7E 124 push eax ; char * .text:005C1F7F 128 push ebx ; FILE * .text:005C1F80 12C mov edi, ecx .text:005C1F82 12C call j_CFileMgr__GetLine
Два параметра в стеке, один в ecx.
.text:005C2555 loc_5C2555: ; CODE XREF: CParticleData__ReadEffectsFile+19Dj .text:005C2555 210 mov eax, [esp+210h+fileName] .text:005C255C 210 push ebx ; file .text:005C255D 214 push eax ; fileName .text:005C255E 218 mov ecx, ebp ; this .text:005C2560 218 call CParticleData__RegisterFxSystem
Обьявляю так (__thiscall в VC++ можно обьявить только в классе):
CFxSystem *(__fastcall *_RegisterFxSystem)(CParticleData *particleData, int i, const char *filename, FILE *file) = (CFxSystem *(__fastcall *)(CParticleData *, int, const char *, FILE *)) 0x5C1F50;
Вызов (без вызова вылета нет):
int RegisterFxSystem(const char* filename, FILE *file) { int i; fpos_t pos; char lineBuf[256], buf[8], name[32]; fgetpos(file, &pos); for(i=0; i<4; i++) fgets(lineBuf, 256, file); sscanf(lineBuf, "%s %s", buf, name); if(!FindFxSystemByName(g_PrtData, 0, name)) { if(g_Debug) { for(i=0; i<30; i++) { if(name[i] == '\0') { while(i<31) { name[i] = ' '; i++; } } } sprintf(lineBuf, " fx system %s loaded from ""%s""\n", name, filename); fputs(lineBuf, g_DebugFile); g_DebugNumEffects++; } fsetpos(file, &pos); _RegisterFxSystem(g_PrtData, i, filename, file); return TRUE; } if(g_Debug) { sprintf(lineBuf, "!fx system %s WAS NOT loaded from ""%s"" because it was already loaded\n", name, filename); fputs(lineBuf, g_DebugFile); } return FALSE; }
Вылетают получаю в ntdll.dll:
771D8C16 mov eax,ecx 771D8C18 sub eax,edx 771D8C1A mov ebx,eax 771D8C1C mov eax,ecx 771D8C1E lock cmpxchg dword ptr [edi],ebx 771D8C22 cmp eax,ecx 771D8C24 jne 771D8A82 771D8C2A xor eax,eax 771D8C2C mov dword ptr [ebp+0Ch],eax 771D8C2F mov dword ptr [ebp+8],eax 771D8C32 mov eax,dword ptr [esi] 771D8C34 cmp eax,0FFFFFFFFh 771D8C37 je 771D8C3C 771D8C39 inc dword ptr [eax+14h] //////////////////////////////// В EAX - 0 771D8C3C mov ebx,dword ptr [ebp-0Ch] 771D8C3F mov edi,dword ptr [ebp-10h] 771D8C42 cmp byte ptr ds:[7FFE0382h],0 771D8C49 jne 7722259B 771D8C4F mov eax,dword ptr [ebp-4] 771D8C52 push edi 771D8C53 push 0 771D8C55 cmp eax,0FFFFFFFFh 771D8C58 je 772225F3 771D8C5E push eax 771D8C5F call 771BF85C 771D8C64 cmp eax,102h
Last edited by DK22Pac (01-01-2013 14:51)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
CFxSystem *(__thiscall *_RegisterFxSystem)(CParticleData *particleData, int i, const char *filename, FILE *file) = (CFxSystem *(__thiscall *)(CParticleData *, int, const char *, FILE *)) 0x5C1F50;
Если объявить так, то имей введу, что перед вызовом, надо каким-то образом передать указатель на объект в регистр ecx.
DWORD address; //Сюда присваиваем наш адрес объекта через __asm mov ecx, address; _RegisterFxSystem(&particleData, i, filename, &file);
Что-то должно выглядеть так. Ибо функция начинает обращаться регистру ecx, где вообще нету нашего адреса нужного объекта.
Last edited by VintProg_Pro (02-08-2013 19:00)
Offline
__thiscall * мобжно объявлять где угодно. первый параметр автоматом пойдет в ECX.
__fastcall - это совсем не то (два параметра в регистрах). Вылет - по рассыпанию стека из-за несовпадения ожидаемого и реального количества параметров на стеке
Offline
Из разряда грязных хаков, fastcall можно использовать для более или менее компиляторо-независимого вызова MSVC методов:
void __fastcall a_method(void *obj, int dummy, int param1, ...)
Могу ошибаться, т.к. говорю на память, но в этом случае первый параметр передается в ecx, второй в eax - а он все равно clobbered для метода...
Offline
Мне еще ни разу не приходилось пользоваться fastcall. Обычные методы либо cdecl, либо stdcall, либо thiscall, а то, что генерируется линкером, обычно получает параметры так, что без declspec(naked) не обойтись (тем более, что о сохранении регистров там тоже стоит позаботиться самому).
auto _RegisterFxSystem = reinterpret_cast<CFxSystem * (__thiscall *)(CParticleData *particleData, const char *filename, FILE *file)>(0x5C1F50);
PS. Я, кстати, научился инжектить нормально методы, так что последняя часть соответствующей статьи будет дописана (не прошло и пяти лет)
Offline
@listener's PS - учитывая Ваш огромный опыт на этом поприще, было бы очень интересно почитать.
PS. Если "стол заказов" еще работает, то хотелось бы еще что-нибудь про ABI "альтернативных" платформ (PPC, ARM).:blush:
Offline
listener, увы, но проблема тут не в этом.
Стек не рассыпается, так как я заведомо передаю вторым дамми-параметр.
Получается такая картина:
CFxSystem *(__fastcall *_RegisterFxSystem)(CParticleData *_ecx, int _edx, const char *filename, FILE *file)
А вообще, я уже позже и как __thiscall пробовал вызывать, и используя asm-вставку.
Я уже пытался переписывать всё дерево этих функций, начиная от _RegisterFxSystem и далее. Но когда дошло до того, что мне нужно было обьявлять ~30 классов (для каждого из видов эмиттеров партиклов), со своими методами, - я сдался.
PS разве дамп-информация не говорит о том, что вылет происходит из-за того, что функция "прошита" exception-handler'ом?
Last edited by DK22Pac (05-08-2013 23:56)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
@Alien - Не надо на "Вы" - я чувствую себя от этого древним и ветхим.
Заказ принят. С ARM я сам особо не разбирался (это еще впереди: нужно будет покопаться CTW/iOS и VC/iOS), а вот очередная часть по PPC будет точно, предположительно, где-то в районе выхода пятерки.
@DK22Pac - Хорошо, доберусь до дома, попробую заглянуть в базу (у меня с собой ее нет). exception-handlerы, если не происходит исключения, ничем не отличаются от любых других функций. Место в ntdll гораздо больше похоже на случайное, чем на обработчик исключения (точно можно сказать, если включить в студии загрузку debug-info с микрософтовских серверов)
Offline
Pages: 1