2011-01-28 2 views
1

У меня есть виртуальная машина, которая на VM_Create передает адрес функции (systemCalls) на виртуальную машину.Подключить функцию usercall?

Поэтому я перехватываю VM_Create и украл адрес системных вызовов, поместил его в указатель функции резервного копирования, а адрес моей измененной функции systemCalls перешел к исходной VM_Create, из которой я могу изменять аргументы, добавлять или удалять вызовы, а затем вызовите функцию резервных системных вызовов. Это сработало хорошо, до новой версии игры.

Я считаю, что нашел проблему:

Это начало функции неизмененном systemCalls:

intptr_t CL_CgameSystemCalls(intptr_t *args) { 

    switch (args[0]) { 

     case CG_PRINT: 
      Com_Printf("%s", (const char*)VMA(1)); 
      return 0; 

     case CG_ERROR: 
      Com_Error(ERR_DROP, "%s", (const char*)VMA(1)); 
      return 0; 

Это моя доработанная функция системного вызова:

intptr_t modified_CL_CgameSystemCalls (intptr_t *args) 
{ 
    switch (*args) 
    { 
     case CG_GETSNAPSHOT: 

      mysnap = mysnap ; 
      mynextSnap = (snapshot_t*) (CG_QVM2NATIVE(args[2])); 
      mysnap = mynextSnap; 

      retval = original_CL_CgameSystemCalls(args); 
      break ; 

Проблема заключается в том вызывая исходную функцию от измененного:

intptr_t modified_CL_CgameSystemCalls(intptr_t *args) 
    { 
     retval = original_CL_CgameSystemCalls(args); 
     return retval; 
    } 

уже не удается.

Как вы можете видеть из псевдокода в разборке, новое определение CL_CgameSystemCalls кажется:

char __usercall sub_4017B0<al>(int a1<ebx>, int a2) 

Это означает, что они изменили функцию, добавив атрибут __usercall и поставив первый аргумент в регистр ebx, если я интерпретирую право декомпиляции.

Теперь мой вопрос:

Как я могу получить * Args (арг [0]) в переменную?

И как я могу назвать немодифицированную функцию из измененной, которая теперь использует __usercall?

Это разборку systemcalls с usercall:

.text:004017B0 ; =============== S U B R O U T I N E ======================================= 
.text:004017B0 
.text:004017B0 
.text:004017B0 sub_4017B0  proc near    ; DATA XREF: sub_402670+5Co 
.text:004017B0 
.text:004017B0 var_18   = dword ptr -18h 
.text:004017B0 var_4   = dword ptr -4 
.text:004017B0 arg_0   = dword ptr 4 
.text:004017B0 
.text:004017B0 ; FUNCTION CHUNK AT .text:00401430 SIZE 00000026 BYTES 
.text:004017B0 ; FUNCTION CHUNK AT .text:00401459 SIZE 00000013 BYTES 
.text:004017B0 ; FUNCTION CHUNK AT .text:00410E90 SIZE 00000006 BYTES 
.text:004017B0 ; FUNCTION CHUNK AT .text:00412AC0 SIZE 00000006 BYTES 
.text:004017B0 
.text:004017B0     push esi 
.text:004017B1     mov  esi, [esp+0Ch+var_4] 
.text:004017B5     mov  eax, [esi] 
.text:004017B7     cmp  eax, 73h  ; switch 116 cases 
.text:004017BA     push edi 
.text:004017BB     ja  loc_402486  ; default 
.text:004017BB           ; jumptable 004017C1 cases 21,90-99,109,110 
.text:004017C1     jmp  ds:off_40249C[eax*4] ; switch jump 
.text:004017C8 
.text:004017C8 loc_4017C8:        ; DATA XREF: .text:off_40249Co 
.text:004017C8     mov  eax, [esi+4] ; jumptable 004017C1 case 0 
.text:004017CB     push eax 
.text:004017CC     call VM_ArgPtr 
.text:004017D1     push eax    ; char 
.text:004017D2     push offset aS_5  ; "%s" 
.text:004017D7     call Com_Printf 
.text:004017DC     add  esp, 0Ch 
.text:004017DF     pop  edi 
.text:004017E0     xor  eax, eax 
.text:004017E2     pop  esi 
.text:004017E3     retn 
.text:004017E4 ; --------------------------------------------------------------------------- 
.text:004017E4 
.text:004017E4 loc_4017E4:        ; CODE XREF: sub_4017B0+11j 
.text:004017E4           ; DATA XREF: .text:off_40249Co 
.text:004017E4     mov  ecx, [esi+4] ; jumptable 004017C1 case 1 
.text:004017E7     push ecx 
.text:004017E8     call VM_ArgPtr 
.text:004017ED     push eax    ; char 
.text:004017EE     push offset aS_5  ; "%s" 
.text:004017F3     push 1    ; int 
.text:004017F5     call Com_Error 
.text:004017F5 ; -------------------------------------------------------------- 

И это псевдокод создан из hexrays декомпилятором:

char __usercall sub_4017B0<al>(int a1<ebx>, int a2) 
{ 
    int v2;   // [email protected] 
    char result;  // [email protected] 
    int v4;   // [email protected] 
    int v5;   // [email protected] 
    int v6;   // [email protected] 
    int v7;   // [email protected] 
    int v8;   // [email protected] 
    int v9;   // [email protected] 
    int v10;   // [email protected] 
    int v11;   // [email protected] 
    int v12;   // [email protected] 
    int v13;   // [email protected] 
    int v14;   // [email protected] 
    int v15;   // [email protected] 
    int v16;   // [email protected] 
    int v17;   // [email protected] 
    int v18;   // [email protected] 
    signed int v19; // [email protected] 
    int v20;   // [email protected] 
    int v21;   // [email protected] 
    int v22;   // [email protected] 
    signed int v23; // [email protected] 
    int v24;   // [email protected] 
    int v25;   // [email protected] 
    signed int v26; // [email protected] 
    int v27;   // [email protected] 
    int v28;   // [email protected] 
    int v29;   // [email protected] 
    int v30;   // [email protected] 
    int v31;   // [email protected] 
    int v32;   // [email protected] 
    int v33;   // [email protected] 
    int v34;   // [email protected] 
    int v35;   // [email protected] 
    int v36;   // [email protected] 
    int v37;   // [email protected] 
    size_t v38;  // [email protected] 
    int v39;   // [email protected] 
    int v40;   // [email protected] 
    int v41;   // [email protected] 
    int v42;   // [email protected] 
    int v43;   // [email protected] 
    int v44;   // [email protected] 
    int v45;   // [email protected] 
    int v46;   // [email protected] 
    int v47;   // [email protected] 
    int v48;   // [email protected] 
    int v49;   // [email protected] 
    int v50;   // [email protected] 
    int v51;   // [email protected] 
    void *v52;  // [email protected] 
    int v53;   // [email protected] 
    int v54;   // [email protected] 
    int v55;   // [email protected] 
    int v56;   // [email protected] 
    int v57;   // [email protected] 
    int v58;   // [email protected] 
    int v59;   // [email protected] 
    signed int v60; // [email protected] 
    int v61;   // [email protected] 
    int v62;   // [email protected] 
    int v63;   // [email protected] 
    int v64;   // [email protected] 
    signed int v65; // [email protected] 
    int v66;   // [email protected] 
    int v67;   // [email protected] 
    int v68;   // [email protected] 
    int v69;   // [email protected] 
    int v70;   // [email protected] 
    int v71;   // [email protected] 
    int v72;   // [email protected] 
    int v73;   // [email protected] 
    signed int v74; // [email protected] 
    int v75;   // [email protected] 
    int v76;   // [email protected] 
    int v77;   // [email protected] 
    int v78;   // [email protected] 
    int v79;   // [email protected] 
    int v80;   // [email protected] 
    int v81;   // [email protected] 
    int v82;   // [email protected] 
    int v83;   // [email protected] 
    int v84;   // [email protected] 
    int v85;   // [email protected] 
    int v86;   // [email protected] 
    int v87;   // [email protected] 
    int v88;   // [email protected] 
    int v89;   // [email protected] 
    int v90;   // [email protected] 
    int v91;   // [email protected] 
    int v92;   // [email protected] 
    int v93;   // [email protected] 
    int v94;   // [email protected] 
    int v95;   // [email protected] 
    int v96;   // [email protected] 
    int v97;   // [email protected] 
    int v98;   // [email protected] 
    int v99;   // [email protected] 
    int v100;   // [email protected] 
    int v101;   // [email protected] 
    int v102;   // [email protected] 
    int v103;   // [email protected] 
    int v104;   // [email protected] 
    int v105;   // [email protected] 
    int v106;   // [email protected] 
    int v107;   // [email protected] 
    int v108;   // [email protected] 
    int v109;   // [email protected] 
    int v110;   // [email protected] 
    int v111;   // [email protected] 
    int v112;   // [email protected] 
    int v113;   // [email protected] 
    int v114;   // [email protected] 
    int v115;   // [email protected] 
    int v116;   // [email protected] 
    int v117;   // [email protected] 
    int v118;   // [email protected] 
    int v119;   // [email protected] 
    int v120;   // [email protected] 
    int v121;   // [email protected] 
    int v122;   // [email protected] 
    int v123;   // [email protected] 
    int v124;   // [email protected] 
    int v125;   // [email protected] 
    int v126;   // [email protected] 
    int v127;   // [email protected] 
    int v128;   // [email protected] 
    int v129;   // [email protected] 
    int v130;   // [email protected] 
    int v131;   // [email protected] 
    int v132;   // [email protected] 
    int v133;   // [email protected] 
    int v134;   // [email protected] 
    int v135;   // [email protected] 
    int v136;   // [email protected] 
    float v137;  // [email protected] 
    float v138;  // [email protected] 
    float v139;  // [email protected] 
    float v140;  // [email protected] 
    int v141;   // [email protected] 
    int v142;   // [email protected] 
    float v143;  // [email protected] 
    float v144;  // [email protected] 
    float v145;  // [email protected] 
    float v146;  // [email protected] 
    int v147;   // [email protected] 
    int v148;   // [email protected] 
    int v149;   // [email protected] 
    int v150;   // [email protected] 
    int v151;   // [email protected] 
    int v152;   // [email protected] 
    int v153;   // [email protected] 
    int v154;   // [email protected] 
    int v155;   // [email protected] 
    int v156;   // [email protected] 
    int v157;   // [email protected] 
    float v158;  // [email protected] 
    int v159;   // [email protected] 
    int v160;   // [email protected] 
    int v161;   // [email protected] 
    int v162;   // [email protected] 
    int v163;   // [email protected] 
    int v164;   // [email protected] 
    int v165;   // [email protected] 
    int v166;   // [email protected] 
    int v167;   // [email protected] 
    int v168;   // [email protected] 
    int v169;   // [email protected] 
    int v170;   // [email protected] 
    int v171;   // [email protected] 
    int v172;   // [email protected] 
    int v173;   // [email protected] 
    int v174;   // [email protected] 
    float v175;  // [email protected] 
    int v176;   // [email protected] 
    int v177;   // [email protected] 
    int v178;   // [email protected] 
    unsigned int v179;// [email protected] 
    int v180;   // [email protected] 
    int v181;   // [email protected] 
    int v182;   // [email protected] 
    signed int v183; // [email protected] 
    int v184;   // [email protected] 
    int v185;   // [email protected] 
    int v186;   // [email protected] 
    size_t v187;  // [email protected] 
    int v188;   // [email protected] 
    int v189;   // [email protected] 
    int v190;   // [email protected] 
    float v191;  // [email protected] 
    int v192;   // [email protected] 
    float v193;  // [email protected] 
    double v194;  // [email protected] 
    int v195;   // [email protected] 
    float v196;  // [email protected] 
    int v197;   // [email protected] 
    float v198;  // [email protected] 
    int v199;   // [email protected] 
    float v200;  // [email protected] 
    int v201;   // [email protected] 
    float v202;  // [email protected] 
    int v203;   // [email protected] 
    float v204;  // [email protected] 
    int v205;   // [email protected] 
    int v206;   // [email protected] 
    int v207;   // [email protected] 
    int v208;   // [email protected] 
    int v209;   // [email protected] 
    int v210;   // [email protected] 
    int v211;   // [email protected] 
    int v212;   // [email protected] 
    int v213;   // [email protected] 
    int v214;   // [email protected] 
    int v215;   // [email protected] 
    int v216;   // [email protected] 
    int v217;   // [email protected] 
    int v218;   // [email protected] 
    int v219;   // [email protected] 
    int v220;   // [email protected] 
    int v221;   // [email protected] 
    unsigned int v222;// [email protected] 
    int v223;   // [email protected] 
    int v224;   // [email protected] 
    int v225;   // [email protected] 
    int v226;   // [email protected] 
    int v227;   // [email protected] 
    int v228;   // [email protected] 
    int v229;   // [email protected] 
    int v230;   // [email protected] 
    int v231;   // [email protected] 
    int v232;   // [email protected] 
    int v233;   // [email protected] 
    int v234;   // [email protected] 
    int v235;   // [email protected] 
    int v236;   // [email protected] 
    int v237;   // [email protected] 
    int v238;   // ST2[email protected] 
    int v239;   // [email protected] 
    int v240;   // [email protected] 
    int v241;   // [email protected] 
    int v242;   // [email protected] 
    int v243;   // [email protected] 
    int v244;   // [email protected] 
    int v245;   // [email protected] 
    int v246;   // [email protected] 
    int v247;   // [email protected] 
    int v248;   // [email protected] 
    int v249;   // [email protected] 
    int v250;   // [sp-18h] [bp-30h]@28 
    int v251;   // [sp-14h] [bp-2Ch]@28 
    int v252;   // [sp-10h] [bp-28h]@28 
    int v253;   // [sp-Ch] [bp-24h]@28 
    int v254;   // [sp-8h] [bp-20h]@28 
    signed int v255; // [sp-4h] [bp-1Ch]@28 
    int v256;   // [sp+0h] [bp-18h]@28 
    int v257;   // [sp+4h] [bp-14h]@28 
    int v258;   // [sp+4h] [bp-14h]@31 

    switch (*(_DWORD *)v2) 
    { 
     case 0: 
      v5 = VM_ArgPtr(*(_DWORD *)(v4 + 4)); 
      Com_Printf("%s", v5); 
      return 0; 

     case 1: 
      v7 = VM_ArgPtr(*(_DWORD *)(v6 + 4)); 
      Com_Error(1, "%s", v7); 
      return result; 

     case 2: 
      return sub_447700(); 

     case 3: 
      v9 = *(_DWORD *)(v8 + 16); 
      v10 = VM_ArgPtr(*(_DWORD *)(v8 + 12)); 
      v11 = VM_ArgPtr(*(_DWORD *)(v8 + 8)); 
      v12 = VM_ArgPtr(*(_DWORD *)(v8 + 4)); 
      sub_4213C0(v12, (const char *)v11, v10, v9); 
      return 0; 

     case 4: 
     ... 

     default: 
      Com_Error(1, "Bad cgame system trap: %i", *(_DWORD *)v249); 
      return result; 
    } 
    return result; 
} 

Вы можете найти полный (последний известный официальный) источник здесь функция CL_CgameSystemCalls (слишком много для копирования-вставки):

http://ioqsrc.vampireducks.com/da/d3b/cl__cgame_8c-source.html

И это вот разборки старой версии, в которой вызова orig_syscall из модифицированного системного вызова работали:

.text:00402B40 ; =============== S U B R O U T I N E ======================================= 
.text:00402B40 
.text:00402B40 
.text:00402B40 sub_402B40  proc near    ; CODE XREF: sub_40B380+Bp 
.text:00402B40           ; sub_40E3B0+Bp ... 
.text:00402B40     mov  edx, dword_BBE104 
.text:00402B46     mov  eax, dword_CB60EC 
.text:00402B4B     and  edx, 0FFFFFFF7h 
.text:00402B4E     test eax, eax 
.text:00402B50     mov  dword_BBE104, edx 
.text:00402B56     mov  dword_BBE21C, 0 
.text:00402B60     jz  short locret_402B82 
.text:00402B62     push 1 
.text:00402B64     push eax 
.text:00402B65     call sub_43E360 
.text:00402B6A     mov  eax, dword_CB60EC 
.text:00402B6F     push eax 
.text:00402B70     call sub_43E270 
.text:00402B75     add  esp, 0Ch 
.text:00402B78     mov  dword_CB60EC, 0 
.text:00402B82 
.text:00402B82 locret_402B82:       ; CODE XREF: sub_402B40+20j 
.text:00402B82     retn 
.text:00402B82 sub_402B40  endp 
.text:00402B82 
.text:00402B82 ; --------------------------------------------------------------------------- 
.text:00402B83     align 10h 
.text:00402B90 
.text:00402B90 loc_402B90:        ; DATA XREF: sub_403AA0+5Co 
.text:00402B90     push ecx 
.text:00402B91     push ebx 
.text:00402B92     push esi 
.text:00402B93     push edi 
.text:00402B94     mov  edi, [esp+14h] 
.text:00402B98     mov  eax, [edi] 
.text:00402B9A     cmp  eax, 6Fh  ; switch 112 cases 
.text:00402B9D     ja  loc_4038C7  ; default 
.text:00402B9D           ; jumptable 00402BA3 cases 21,90-99,109,110 
.text:00402BA3     jmp  ds:off_4038E0[eax*4] ; switch jump 
.text:00402BAA 
.text:00402BAA loc_402BAA:        ; DATA XREF: .text:off_4038E0o 
.text:00402BAA     mov  eax, [edi+4] ; jumptable 00402BA3 case 0 
.text:00402BAD     push eax 
.text:00402BAE     call sub_43E300 
.text:00402BB3     push eax 
.text:00402BB4     push offset aS_7  ; "%s" 
.text:00402BB9     call sub_41BB90 
.text:00402BBE     add  esp, 0Ch 
.text:00402BC1     pop  edi 
.text:00402BC2     pop  esi 
.text:00402BC3     xor  eax, eax 
.text:00402BC5     pop  ebx 
.text:00402BC6     pop  ecx 
.text:00402BC7     retn 
.text:00402BC8 ; --------------------------------------------------------------------------- 
.text:00402BC8 
.text:00402BC8 loc_402BC8:        ; CODE XREF: .text:00402BA3j 
.text:00402BC8           ; DATA XREF: .text:off_4038E0o 
.text:00402BC8     mov  ecx, [edi+4] ; jumptable 00402BA3 case 1 
.text:00402BCB     push ecx 
.text:00402BCC     call sub_43E300 
.text:00402BD1     push eax 
.text:00402BD2     push offset aS_7  ; "%s" 
.text:00402BD7     push 1 
.text:00402BD9     call sub_41D850 
.text:00402BDE ; --------------------------------------------------------------------------- 
+0

Или есть компилятор, который поддерживает атрибут usercall? Я протестировал VS2008 + MinGW, usercall не удалось на обоих. –

+0

__usercall не является конвенцией о вызове. Это означает, что IDA обнаружил аргументы в местах, отличных от стандартных регистров (ecx, edx) или стека, таким образом, который не соответствует существующему соглашению о вызовах, например __stdcall или __fastcall. Это почти всегда результат оптимизации компилятора, а не программиста (подумайте об этом, почему кто-то хочет это сделать?). – wj32

+0

@ wj32: Потому что это затрудняет обман. Но вы можете быть правы, это, вероятно, выходит за рамки их интеллектуального потенциала, а скорее результат оптимизации компилятора вместо того, чтобы быть блестящей антихитовой техникой с их стороны. Но какова бы ни была причина, мне нужен ответ, а не дискуссионная дискуссия о том, что будет, если. –

ответ

3

Там нет такого понятия, как __usercall. Hex-лучи используют это для представления нестандартного соглашения о вызовах.Это может произойти тремя способами:

  1. Программист используется сборка
  2. Программист использует Open Watcom's#pragma aux для определения Таможенной конвенции
  3. Программист Пользуется Visual C++ 7+, которая оптимизирует распределение регистров для предотвращения пробуксовки

В таких случаях есть только два пути: использовать сборку или использовать Open Watcom (который только что получил обновление после нескольких лет оставления). Встроенная сборка работает лучше всего с IMO, но вам понадобится обертка (для вызова оригинала) и выходящая оболочка (чтобы зацепить оригинал).

+0

Другая возможность заключается в том, что используется LTCG (Generator Time Time Generation), что позволяет генерировать нестандартные функции. – Olipro