#1 12-08-2011 08:37

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Верно ли перевел функцию в C++?

Вот код из IDA.

.text:004C3C80     ; int __cdecl createMarker(int type, float x, float y, float z, int flag1, int flag2)
.text:004C3C80     _createMarker   proc near               ; CODE XREF: CScriptThread__opcodeHandler_03+A08p
.text:004C3C80                                             ; CScriptThread__opcodeHandler_03+1566p
.text:004C3C80                                             ; CScriptThread__opcodeHandler_03+1634p
.text:004C3C80                                             ; CScriptThread__opcodeHandler_06+408p ...
.text:004C3C80
.text:004C3C80     type            = dword ptr  4
.text:004C3C80     x               = dword ptr  8
.text:004C3C80     y               = dword ptr  0Ch
.text:004C3C80     z               = dword ptr  10h
.text:004C3C80     flag1           = dword ptr  14h
.text:004C3C80     flag2           = dword ptr  18h
.text:004C3C80
.text:004C3C80 000                 xor     edx, edx
.text:004C3C82 000                 xor     eax, eax
.text:004C3C84 000                 fld     [esp+z]
.text:004C3C88 000                 fld     [esp+y]
.text:004C3C8C 000                 jmp     short loc_4C3C94
.text:004C3C8C     ; ---------------------------------------------------------------------------
.text:004C3C8E 000                 align 10h
.text:004C3C90
.text:004C3C90     loc_4C3C90:                             ; CODE XREF: _createMarker+20j
.text:004C3C90 000                 add     eax, 38h
.text:004C3C93 000                 inc     edx
.text:004C3C94
.text:004C3C94     loc_4C3C94:                             ; CODE XREF: _createMarker+Cj
.text:004C3C94 000                 cmp     ds:_radarBlips.inUse[eax], 0
.text:004C3C9B 000                 jz      short loc_4C3CA2
.text:004C3C9D 000                 cmp     edx, 75
.text:004C3CA0 000                 jb      short loc_4C3C90
.text:004C3CA2
.text:004C3CA2     loc_4C3CA2:                             ; CODE XREF: _createMarker+1Bj
.text:004C3CA2 000                 cmp     edx, 75
.text:004C3CA5 000                 jnb     loc_4C3D70
.text:004C3CAB 000                 mov     ecx, edx
.text:004C3CAD 000                 mov     eax, [esp+type]
.text:004C3CB1 000                 imul    ecx, 38h
.text:004C3CB4 000                 fld     [esp+x]
.text:004C3CB8 000                 mov     ds:_radarBlips.type[ecx], eax
.text:004C3CBE 000                 mov     dword ptr ds:_radarBlips.id_color[ecx], 5
.text:004C3CC8 000                 mov     ds:_radarBlips.field_26[ecx], 1
.text:004C3CCF 000                 mov     ds:_radarBlips.inUse[ecx], 1
.text:004C3CD6 000                 mov     ds:_radarBlips.field_28[ecx], 0
.text:004C3CDD 000                 mov     ds:_radarBlips.field_2C[ecx], 3F800000h
.text:004C3CE7 000                 fstp    ds:_radarBlips.pos.x[ecx]
.text:004C3CED 000                 fst     ds:_radarBlips.pos.y[ecx]
.text:004C3CF3 000                 fld     st(1)
.text:004C3CF5 000                 fstp    ds:_radarBlips.pos.z[ecx]
.text:004C3CFB 000                 fld     [esp+x]
.text:004C3CFF 000                 mov     eax, [esp+flag2]
.text:004C3D03 000                 fstp    ds:_radarBlips.field_18.x[ecx]
.text:004C3D09 000                 fst     ds:_radarBlips.field_18.y[ecx]
.text:004C3D0F 000                 fld     st(1)
.text:004C3D11 000                 fstp    ds:_radarBlips.field_18.z[ecx]
.text:004C3D17 000                 mov     ds:_radarBlips.entityHandle[ecx], 0
.text:004C3D21 000                 mov     ds:_radarBlips.field_30[ecx], 1
.text:004C3D2A 000                 mov     ds:_radarBlips.field_32[ecx], ax
.text:004C3D31 000                 mov     eax, edx
.text:004C3D33 000                 imul    eax, 38h
.text:004C3D36 000                 mov     ds:_radarBlips.iconID[ecx], 0
.text:004C3D3F 000                 cmp     ds:_radarBlips.field_24[eax], 0FFFEh
.text:004C3D47 000                 jnb     short loc_4C3D52
.text:004C3D49 000                 inc     ds:_radarBlips.field_24[eax]
.text:004C3D50 000                 jmp     short loc_4C3D5B
.text:004C3D52     ; ---------------------------------------------------------------------------
.text:004C3D52
.text:004C3D52     loc_4C3D52:                             ; CODE XREF: _createMarker+C7j
.text:004C3D52 000                 mov     ds:_radarBlips.field_24[eax], 1
.text:004C3D5B
.text:004C3D5B     loc_4C3D5B:                             ; CODE XREF: _createMarker+D0j
.text:004C3D5B 000                 movzx   eax, ds:_radarBlips.field_24[eax]
.text:004C3D62 000                 fcompp
.text:004C3D64 000                 shl     eax, 10h
.text:004C3D67 000                 or      eax, edx
.text:004C3D69 000                 retn
.text:004C3D69     ; ---------------------------------------------------------------------------
.text:004C3D6A 000                 align 10h
.text:004C3D70
.text:004C3D70     loc_4C3D70:                             ; CODE XREF: _createMarker+25j
.text:004C3D70 000                 or      eax, 0FFFFFFFFh
.text:004C3D73 000                 fcompp
.text:004C3D75 000                 retn
.text:004C3D75     _createMarker   endp

А вот я ее перевел в C++:

DWORD __cdecl Create_Marker(DWORD type, float x, float y, float z, DWORD flag1, DWORD flag2)
{
DWORD index = 0;


for (int i=0; index < 75; i++)
{
  index = i;


if ( VCRadarBlips[index].inUse == 0)
   {
	   VCRadarBlips[index].typeMarker = type;
	   VCRadarBlips[index].id_color = 5;
	   VCRadarBlips[index].field_26 = 1;
	   VCRadarBlips[index].inUse = 1;
	   VCRadarBlips[index].field_28 = 0;
	   VCRadarBlips[index].field_2C = 0x3F800000;
	   VCRadarBlips[index].pos.x = x;
	   VCRadarBlips[index].pos.y = y;
	   VCRadarBlips[index].pos.z = z;
	   VCRadarBlips[index].field_18 = VCRadarBlips[index].pos;
	   VCRadarBlips[index].entityHandle = 0;
	   VCRadarBlips[index].scale = 1;
	   VCRadarBlips[index].field_32 = flag2;
	   VCRadarBlips[index].iconID = 0;

	   if (VCRadarBlips[index].field_24 <= 0xFFFE)
     	   {
             VCRadarBlips[index].field_24 = 1;
			 return ((VCRadarBlips[index].field_24 << 16) | index);
	       }

	   VCRadarBlips[index].field_24 += VCRadarBlips[index].field_24;
	   return ((VCRadarBlips[index].field_24 << 16) | index);
   }


}

 return ((VCRadarBlips[index].field_24 << 16) | index);
};

Верно ли я сделал?

Offline

#2 12-08-2011 14:07

listener
From: Vice City
Registered: 09-11-2006
Posts: 615
Website

Re: Верно ли перевел функцию в C++?

Нет, конечно. В целом-то правильно, но есть некоторые нюансы.

Вот, например, что это?
VCRadarBlips[index].field_2C = 0x3F800000;

Хотя, это бы прокатило. Не прокатит то, что условие для wGenerationId перепутано.

Вообще, при переводе кода рекомендуется не передирать тупо подстрочник, а, хотя бы, попытаться понять, что этот код делает. Зачем нужна отдельная переменная index, если она дублирует i ?


C5 - GTA IV/RDR/GTA V script compiler.
~ 60% done.

Offline

#3 12-08-2011 14:23

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Re: Верно ли перевел функцию в C++?

А так:

DWORD __cdecl Create_Marker(DWORD type, float x, float y, float z, DWORD flag1, DWORD flag2)
{
DWORD result = -1;


for (int i=0; i < 75; i++)
{



if ( VCRadarBlips[i].inUse == 0)
   {
	   VCRadarBlips[i].typeMarker = type;
	   VCRadarBlips[i].id_color = 5;
	   VCRadarBlips[i].field_26 = 1;
	   VCRadarBlips[i].inUse = 1;
	   VCRadarBlips[i].field_28 = 0;
	   VCRadarBlips[i].field_2C = 1.0f; 
	   VCRadarBlips[i].pos.x = x;
	   VCRadarBlips[i].pos.y = y;
	   VCRadarBlips[i].pos.z = z;
	   VCRadarBlips[i].field_18 = VCRadarBlips[i].pos;
	   VCRadarBlips[i].entityHandle = 0;
	   VCRadarBlips[i].scale = 1;
	   VCRadarBlips[i].field_32 = flag2;
	   VCRadarBlips[i].iconID = 0;

	   VCRadarBlips[i].field_24++;
	   if ((VCRadarBlips[i].field_24 & 0xFFFF)==0) VCRadarBlips[i].field_24 = 1;

result = ((VCRadarBlips[index].field_24 << 16) | i)
break;
	       }

   }


}

 return result;
};

Offline

#4 12-08-2011 14:46

listener
From: Vice City
Registered: 09-11-2006
Posts: 615
Website

Re: Верно ли перевел функцию в C++?

Должно быть как-то так (у меня названия полей слегка отличаются):

DWORD CBlips::createBlip (DWORD dwEntityType, float fX, float fY, float fZ, WORD wFlags1, WORD wFlags2) {
	CBlip * pBlip = m_blips; 
	for (DWORD i = 0; i < 75; i++, pBlip++) 
		if (!pBlip->m_bInUse) {
			pBlip->m_dwColor = 5;
			pBlip->m_dwEntityType = dwEntityType;
			pBlip->m_hEntity = 0;
			pBlip->m_vPos.x = pBlip->_f18.x = fX;
			pBlip->m_vPos.y = pBlip->_f18.y = fY;
			pBlip->m_vPos.z = pBlip->_f18.z = fZ;
			pBlip->_f26 = 1;
			pBlip->m_bInUse = 1;
			pBlip->_f28 = 0;                        
			pBlip->_f2C = 1.f;
			pBlip->m_wScale = 1;
			pBlip->m_wFlag2 = wFlags2;
			pBlip->m_wIconId = 0;
			if (pBlip->m_wGenerationId < 0xFFFE)
				pBlip->m_wGenerationId++;
			else
				pBlip->m_wGenerationId = 1;
			return (pBlip->m_wGenerationId << 16)|i;
		}
	return 0xFFFFFFFF;	
}

C5 - GTA IV/RDR/GTA V script compiler.
~ 60% done.

Offline

#5 13-08-2011 06:20

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Re: Верно ли перевел функцию в C++?

Вот еще:

.text:004C3840     _showMarkerOnRadar proc near            ; CODE XREF: CScriptThread__opcodeHandler_03+A4Ap
.text:004C3840                                             ; CScriptThread__opcodeHandler_03+13C3p
.text:004C3840                                             ; CScriptThread__opcodeHandler_03+1434p
.text:004C3840                                             ; CScriptThread__opcodeHandler_03+14A5p ...
.text:004C3840
.text:004C3840     arg_0           = dword ptr  4
.text:004C3840     arg_4           = dword ptr  8
.text:004C3840
.text:004C3840 000                 mov     edx, [esp+arg_0] ; 131072
.text:004C3844 000                 push    ebx
.text:004C3845 004                 mov     eax, edx
.text:004C3847 004                 push    ebp
.text:004C3848 008                 mov     ecx, eax
.text:004C384A 008                 mov     ebp, [esp+8+arg_4]
.text:004C384E 008                 and     ecx, 0FFFFh
.text:004C3854 008                 cmp     edx, 0FFFFFFFFh
.text:004C3857 008                 jz      short loc_4C3878
.text:004C3859 008                 mov     ebx, ecx        ; ebx = id
.text:004C385B 008                 and     eax, 0FFFF0000h ; ; 131072
.text:004C3860 008                 lea     edx, ds:0[ebx*8] ; edx = 8*0
.text:004C3867 008                 shr     eax, 10h
.text:004C386A 008                 sub     edx, ebx
.text:004C386C 008                 movzx   edx, ds:_radarBlips.field_24[edx*8]
.text:004C3874 008                 cmp     eax, edx
.text:004C3876 008                 jz      short loc_4C387B
.text:004C3878
.text:004C3878     loc_4C3878:                             ; CODE XREF: _showMarkerOnRadar+17j
.text:004C3878 008                 or      ecx, 0FFFFFFFFh
.text:004C387B
.text:004C387B     loc_4C387B:                             ; CODE XREF: _showMarkerOnRadar+36j
.text:004C387B 008                 cmp     ds:_menu.field_35, 0
.text:004C3882 008                 jz      short loc_4C3889
.text:004C3884 008                 mov     ebp, 1
.text:004C3889
.text:004C3889     loc_4C3889:                             ; CODE XREF: _showMarkerOnRadar+42j
.text:004C3889 008                 cmp     ecx, 0FFFFFFFFh
.text:004C388C 008                 jnz     short loc_4C3891
.text:004C388E 008                 pop     ebp
.text:004C388F 004                 pop     ebx
.text:004C3890 000                 retn
.text:004C3891     ; ---------------------------------------------------------------------------
.text:004C3891
.text:004C3891     loc_4C3891:                             ; CODE XREF: _showMarkerOnRadar+4Cj
.text:004C3891 008                 lea     eax, ds:0[ecx*8]
.text:004C3898 008                 sub     eax, ecx
.text:004C389A 008                 mov     ds:_radarBlips.Scale[eax*8], bp
.text:004C38A2 008                 pop     ebp
.text:004C38A3 004                 pop     ebx
.text:004C38A4 000                 retn
.text:004C38A4     _showMarkerOnRadar endp

Пойдет так как я перевел?

void __cdecl ScaleMarkerOnRadar(DWORD id_marker, DWORD Scale)
{
DWORD _menu_field_35 = 0x0869630 + 0x35;
DWORD id_, s_id;
WORD f24;

//131072
id_ = 0x0ffff & id_marker;  //ID = 0 
s_id = id_marker >> 16;
f24 = VCRadarBlips[0].field_24;

 if (id_marker == 0xFFFFFFFF)
	    return;

if (s_id == VCRadarBlips[id_].field_24) 
   {

   if ( *(BYTE*)_menu_field_35 == 0 )
	   VCRadarBlips[id_].scale = Scale;
  
   }

};

Offline

#6 14-08-2011 01:01

listener
From: Vice City
Registered: 09-11-2006
Posts: 615
Website

Re: Верно ли перевел функцию в C++?

Работать должно, но код получается совершенно нечитабельным.

Для начала, я бы вынес получение маркера в отдельную функцию (эта операция используется очень часто).

__inline CMarker * getMarkerByHandle (DWORD dwHandle) {
  if (0xFFFFFFFF == dwHandle) 
    return NULL;       
  CMarker * pBlip = VCRadarMarkers+(dwHandle & 0xFFFF);
  return pBlip->field_24 == (dwHandle >> 16) ? pBlip : NULL;
}

Дальше, получается так:

void CRadar::changeBlipScale (DWORD dwHandle, DWORD dwScale) {
   BYTE * _menu_f35 = reinterpret_cast<BYTE *>(0x0869630 + 0x35);
   CMarker * pBlip = getMarkerByHandle (dwHandle);
   if (pBlip && !(*_menu_f35))
      pBlip->scale = dwScale;
}

Несколько замечаний:
* Венгерская нотация для отреверсенного кода увеличивает читабельность в разы.
* Никогда, никогда-никогда, нельзя использовать C-шное приведение типа за пределами чистого C. Первый же опретор приведения типа или класс с множественным наследованием, приведут к появлению странных, очень трудно отлавливаемых ошибок.


C5 - GTA IV/RDR/GTA V script compiler.
~ 60% done.

Offline

#7 11-09-2011 08:06

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Re: Верно ли перевел функцию в C++?

vPos.x

А почему тип отсутствует, по нотации? Как же указать что это переменная структуры?

Offline

#8 14-09-2011 09:09

Alien
Registered: 12-10-2008
Posts: 564

Re: Верно ли перевел функцию в C++?

listener wrote:

* Никогда, никогда-никогда, нельзя использовать C-шное приведение типа за пределами чистого C. Первый же опретор приведения типа или класс с множественным наследованием, приведут к появлению странных, очень трудно отлавливаемых ошибок.

А можно вот тут вопрос? Я читал где-то тут на форуме про низкоуровневую имплементацию множественного наследования в C++, но не понимаю, почему не возникает такой же неоднозначности при приведении типов для классов с множественной реализацией COM-интерфейсов? И вообще с интерфейсами, как в Java, Delphi или .NET. Ведь интерфейс тоже имеет ненулевой размер (хотя бы для хранения указателя на VMT)...

PS: Позравляю с прошедшим днем программиста. Хотел вчера создать темку с позравлением, но сайт неожиданно упал...=(

Offline

#9 20-09-2011 06:07

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Re: Верно ли перевел функцию в C++?

Вот эту еще надо перевести в C++

.text:004C3C00                                   ; int __cdecl createRadarBlip(int, float, float, float, int, int)
.text:004C3C00                                   _createRadarBlip proc near              ; CODE XREF: CScriptThread__opcodeHandler_13+1B08p
.text:004C3C00                                                                           ; CScriptThread__opcodeHandler_12+9FAp
.text:004C3C00
.text:004C3C00                                   type            = dword ptr  4
.text:004C3C00                                   x               = dword ptr  8
.text:004C3C00                                   y               = dword ptr  0Ch
.text:004C3C00                                   z               = dword ptr  10h
.text:004C3C00                                   flag1           = dword ptr  14h
.text:004C3C00                                   flag2           = dword ptr  18h
.text:004C3C00
.text:004C3C00 000 8B 44 24 14                                   mov     eax, [esp+flag1]
.text:004C3C04 000 8B 54 24 18                                   mov     edx, [esp+flag2]
.text:004C3C08 000 53                                            push    ebx
.text:004C3C09 004 55                                            push    ebp
.text:004C3C0A 008 52                                            push    edx             ; flag2
.text:004C3C0B 00C 50                                            push    eax             ; flag1
.text:004C3C0C 010 8B 44 24 14                                   mov     eax, [esp+10h+type]
.text:004C3C10 010 FF 74 24 20                                   push    [esp+10h+z]     ; z
.text:004C3C14 014 FF 74 24 20                                   push    [esp+14h+y]     ; y
.text:004C3C18 018 FF 74 24 20                                   push    [esp+18h+x]     ; x
.text:004C3C1C 01C 50                                            push    eax             ; type
.text:004C3C1D 020 E8 5E 00 00 00                                call    _createMarker
.text:004C3C22 020 83 C4 18                                      add     esp, 18h
.text:004C3C25 008 83 F8 FF                                      cmp     eax, 0FFFFFFFFh
.text:004C3C28 008 75 06                                         jnz     short loc_4C3C30 ; !=
.text:004C3C2A 008 83 C8 FF                                      or      eax, 0FFFFFFFFh
.text:004C3C2D 008 5D                                            pop     ebp
.text:004C3C2E 004 5B                                            pop     ebx
.text:004C3C2F 000 C3                                            retn
.text:004C3C30                                   ; ---------------------------------------------------------------------------
.text:004C3C30
.text:004C3C30                                   loc_4C3C30:                             ; CODE XREF: _createRadarBlip+28j
.text:004C3C30 008 89 C1                                         mov     ecx, eax
.text:004C3C32 008 89 CA                                         mov     edx, ecx
.text:004C3C34 008 81 E2 FF FF 00 00                             and     edx, 0FFFFh
.text:004C3C3A 008 83 F8 FF                                      cmp     eax, 0FFFFFFFFh
.text:004C3C3D 008 74 20                                         jz      short loc_4C3C5F
.text:004C3C3F 008 89 D5                                         mov     ebp, edx
.text:004C3C41 008 81 E1 00 00 FF FF                             and     ecx, 0FFFF0000h
.text:004C3C47 008 8D 1C ED 00 00 00 00                          lea     ebx, ds:0[ebp*8]
.text:004C3C4E 008 C1 E9 10                                      shr     ecx, 10h
.text:004C3C51 008 29 EB                                         sub     ebx, ebp
.text:004C3C53 008 0F B7 1C DD 5C 7D 7D 00                       movzx   ebx, ds:_radarBlips.field_24[ebx*8]
.text:004C3C5B 008 39 D9                                         cmp     ecx, ebx
.text:004C3C5D 008 74 03                                         jz      short loc_4C3C62
.text:004C3C5F
.text:004C3C5F                                   loc_4C3C5F:                             ; CODE XREF: _createRadarBlip+3Dj
.text:004C3C5F 008 83 CA FF                                      or      edx, 0FFFFFFFFh
.text:004C3C62
.text:004C3C62                                   loc_4C3C62:                             ; CODE XREF: _createRadarBlip+5Dj
.text:004C3C62 008 8D 0C D5 00 00 00 00                          lea     ecx, ds:0[edx*8]
.text:004C3C69 008 29 D1                                         sub     ecx, edx
.text:004C3C6B 008 C6 04 CD 60 7D 7D 00 01                       mov     ds:_radarBlips.field_28[ecx*8], 1
.text:004C3C73 008 5D                                            pop     ebp
.text:004C3C74 004 5B                                            pop     ebx
.text:004C3C75 000 C3                                            retn
.text:004C3C75                                   _createRadarBlip endp

Вот начало перевода:

DWORD __cdecl CreateRadarBlip(DWORD type, float x, float y, float z, DWORD flag1, DWORD flag2)
{
DWORD res = Create_Marker(type, x,y,z,flag1,flag2);

 if(x != 0xFFFFFFFF)
       return ( res | 0xFFFFFFFF);


};

Last edited by VintProg_Pro (20-09-2011 06:27)

Offline

#10 21-09-2011 18:11

Sw[ee]t
From: Нижний Новгород
Registered: 16-02-2009
Posts: 686
Website

Re: Верно ли перевел функцию в C++?

хочешь написать свою ф-цию создания маркера? там ведь не только тот приведённый кусок, для "полноты ощущений" нужно ещё и свою структуру забабахать в которой хранятся эти самые блипы.

Offline

#11 21-09-2011 23:10

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Re: Верно ли перевел функцию в C++?

забобахана давно уже CMarker

Offline

#12 22-09-2011 00:16

listener
From: Vice City
Registered: 09-11-2006
Posts: 615
Website

Re: Верно ли перевел функцию в C++?

Alien wrote:

А можно вот тут вопрос? Я читал где-то тут на форуме про низкоуровневую имплементацию множественного наследования в C++, но не понимаю, почему не возникает такой же неоднозначности при приведении типов для классов с множественной реализацией COM-интерфейсов? И вообще с интерфейсами, как в Java, Delphi или .NET. Ведь интерфейс тоже имеет ненулевой размер (хотя бы для хранения указателя на VMT)...

В случае, в .net и всем, что на нем основано - приведение типа делается с учетом типа (т.е., применительно к объектам, любой cast рассматривается, как dynamic). В delphi - нет множественного наследования. Приводить указатель на объекты COM нельзя. (вернее, можно, но результат абсолютно непредсказуем). Для них нужно делать QueryInterface (и там легко может генерироваться промежуточный объект, никак не связанный с приводимым - я с таким встречался).


C5 - GTA IV/RDR/GTA V script compiler.
~ 60% done.

Offline

#13 22-09-2011 02:21

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Re: Верно ли перевел функцию в C++?

Как насчет моей функции?

Offline

#14 26-09-2011 12:49

Alien
Registered: 12-10-2008
Posts: 564

Re: Верно ли перевел функцию в C++?

listener wrote:

В случае, в .net и всем, что на нем основано - приведение типа делается с учетом типа (т.е., применительно к объектам, любой cast рассматривается, как dynamic). В delphi - нет множественного наследования. Приводить указатель на объекты COM нельзя. (вернее, можно, но результат абсолютно непредсказуем). Для них нужно делать QueryInterface (и там легко может генерироваться промежуточный объект, никак не связанный с приводимым - я с таким встречался).

Хм, понятно... Я видимо не совсем верно понял суть COM-программирования. Надо будет поэкспериментировать с этим как-нибудь.

Offline

Board footer

Powered by FluxBB