[C] Inzynieria wsteczna - wlasciwosci klasy

0

Witam,

Mam nastepujacy problem. Probuje dobrac sie do nastepujacej klasy (skrocona wersja):

class Entity : public Listener
	{
	public:
		CLASS_PROTOTYPE( Entity );

		// spawning variables
		int					entnum;
      gentity_t         *edict;
		gclient_t			*client;
		int					spawnflags;

      // standard variables
		str					model;

		// physics variables
      float             move_time;     // how much time total_delta will take
      Vector            total_delta;   // total unprocessed movement
		Vector				mins;
		Vector				maxs;
		Vector				absmin;
		Vector				absmax;
		Vector				centroid;
		Vector				velocity;
		Vector				avelocity;
      Vector            origin;
      Vector            angles;
      Vector            size;
		int					movetype;
		int					mass;
		float					gravity;			// per entity gravity multiplier (1.0 is normal)
		float					orientation[3][3];

      gentity_t         *groundentity;
		cplane_t				groundplane;
		int					groundcontents;

      // Model Binding variables
      int               numchildren;
      int               children[MAX_MODEL_CHILDREN];

      // Surface variables
      int               numsurfaces;

      // Light variables
      float             lightRadius;

      // Team variables
		str					moveteam;
		Entity				*teamchain;
		Entity 				*teammaster;

		// Binding variables
		Entity 				*bindmaster;
		qboolean				bind_use_my_angles;
      Vector            localorigin;
      Vector            localangles;

		// targeting variables
		str					target;
		str					targetname;
		str			      killtarget;

		// Character state
		float					health;
		float             max_health;
		int					deadflag;
		int					flags;

		// underwater variables
		int					watertype;
		int					waterlevel;

		// Pain and damage variables
		damage_t				takedamage;
		EntityPtr			enemy;
		float					pain_finished;
		float					damage_debounce_time;
      int               damage_type;

// tutaj dosc duzo wycialem, nie jest to potrzebne

      virtual void      VelocityModified( void );
      virtual void      Archive( Archiver &arc );
	};

Definicja CLASS_PROTOTYPE:

#define CLASS_PROTOTYPE( nameofclass )											\
	public:																				\
	static	ClassDef			ClassInfo;											\
	static	void				*_newInstance( void );			            \
	virtual	ClassDef			*classinfo( void );			               \
	static	ResponseDef<nameofclass>	Responses[]

Chodzi mi o to, zeby dobrac sie do wlasciwosci tej klasy majac do dyspozycji tylko wskaznik do niej. Sprawe komplikuje to, ze ten kod pochodzi z wczesniejszej wersji, a do kodu zrodlowego nowszej nie mam dostepu, wiec uklad wlasciwosci i metod mogl sie zmienic (ale jestem pewien, ze jest z grubsza ten sam), przez co nie moge po prostu wrzucic tej definicji do swojego kodu i uzyc go. Zeby bylo smieszniej, ta klasa Entity dziedziczy z 2 innych (Listener, ktory jest pochodna Class).

Czy mozna cos z tym zrobic? Chodzi mi tylko o dostanie sie do rzeczy typu entnum, spawnflags etc. Myslalem, zeby moze przesunac wskaznik o odpowiedna ilosc bajtow i czytac to jak strukture, mozna tak?

Z gory dziekuje,

Rookie One

<EDIT>Stad wiem, ze moge czytac klasy jak struktury, ale co z klasami dziedziczacymi?</EDIT>

0

No nie wiem, chyba nie ma prostego sposobu. A gdyby to zdesassemblowac i porownac roznice?

Asembler to juz dla mnie w ogole czarna magia. :/

Z tekstow pod podanym przeze mnie w poprzednim poscie adresem wynika, ze przodkowie klas moga byc traktowane jako struktura na samym poczatku. Widzialem kiedys w takim zreversowanym kodzie zastepowanie brakujacych struktur przez DWORD (unsigned long int), czy cos takiego mogloby zadzialac?

0

Hmm, chyba nic z tego nie bedzie. :/ Wlasnie sprobowalem zrobic cos takiego:

int main(int argc, char argv[]) {
	ClassDef *cls;
	cls = new ClassDef;
	Entity *ent = (Entity *)cls->newInstance;
	long entaddr = (long)&ent;
	long clsaddr = (long)&cls;
	long classdefaddr = (long)&ent->ClassInfo.classname;
	long entnumaddr = (long)&ent->entnum;
	printf("Size of Entity: %i\nEntity class address: %i\nClassname address: %i\nEntnum address: %i\n", sizeof(Entity), entaddr, classdefaddr, entnumaddr);
	return 0;
}

Wynik:

Size of Entity: 404
Entity class address: 1245028
Classname address: 5651008
Entnum address: 8

Myslalem, ze moze w ten sposob dowiem sie, jaki jest offset danych od poczatku klasy, ale chyba nic z tego. Chyba, ze zrobilem cos zle?
<EDIT>A teraz sprobowalem inaczej:

int main(int argc, char argv[]) {
	ClassDef *cls;
	cls = new ClassDef;
	Entity *ent = (Entity *)cls->newInstance;
	cout << "&cls: " << (long)&cls << endl;
	cout << "&*cls: " << (long)&*cls << endl;
	cout << "&ent: " << (long)&ent << endl;
	cout << "&*ent: " << (long)&*ent << endl;
	cout << "&ent->ClassInfo: " << (long)&ent->ClassInfo << endl;
	cout << "&ent->entnum: " << (long)&ent->entnum << endl;
	cout << "&ent->edict: " << (long)&ent->edict << endl;
	return 0;
}
&cls: 1245036
&*cls: 7090640
&ent: 1245040
&*ent: 0
&ent->ClassInfo: 5699264
&ent->entnum: 8
&ent->edict: 12

&ent to adres wskaznika, &*ent to adres samej klasy, tak?</EDIT>

<EDIT2>Dobra, zadzialalo zgodnie z tym artykulem. :D</EDIT2>

Z gory przepraszam moderatorow za kilka postow pod rzad, ale chce, zeby byl znowu zaznaczony jako nieprzeczytany.

Problem teraz mam nastepujacy.

struct Entity_s {
	DWORD			dummy1[8];

		// spawning variables
		int					entnum;
		struct gentity_s	*edict;
		gclient_t			*client;

Dummy1[8] zastepuje klasy, z ktorych dziedziczy klasa Entity i inny niepotrzebny mi szmelc. :P Potem mamy int entnum, ktore z tego, co bylem w stanie sprawdzic dziala jak trzeba, a potem jest gentity_t edict. I tu sie zaczynaja schody - ten wskaznik (edict) wskazuje na miejsce w pamieci o 776 bajtow dalej, niz powinien... :/ Ma ktos jakies sugestie?

// masz przycisk edycja, nie przepraszaj tylko korzystaj z niego [mf]

0

Rookie One: piszesz ze strukturami nie ma problemu... a ja wlasnie mam identyczny problem tyle ze ze strukturami... mozesz podac cos wiecej o strukturach ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1