2010-03-07 5 views
1

J'ai un code de jeu (du projet ioquake3) qui compile une partie des binaires de gameplay à la volée (le système qvm). Maintenant, on pourrait potentiellement l'accélérer en chargeant les binaires précédemment sauvegardés de cette opération (avec toutes les précautions de changement de fichiers en place). Mais, les pointeurs vers les fonctions enregistrées dans ces binaires ne sont pas persistants via les sessions.Quelle est la bonne façon de remplacer par programme de très petites parties d'un fichier binaire?

Quelle serait la bonne façon de changer à la volée? (en considérant qu'on a l'assembleur et l'ensemble pour cela disponible dans l'application principale)

+0

Quel système d'exploitation? les réponses seront probablement spécifiques au système d'exploitation. –

+0

Je comprends que vous voulez éditer le binaire, mais je ne suis pas si sûr sur le reste de votre question. Pourquoi les pointeurs changent-ils en premier lieu? Et comment savez-vous ce que les changements à faire sans recompiler de toute façon? Peut-être que j'ai raté quelque chose, mais je ne comprends tout simplement pas votre problème. – zdav

Répondre

2

C'est à peu près ce que fait un chargeur normal pour les exécutables. Ils fonctionnent habituellement en stockant une table des endroits il y a des références aux adresses qui devront être changées selon où le dossier est chargé. Généralement, ils stockent une adresse relative dans chacun de ces emplacements, ainsi pour charger le fichier, vous regardez la table et ajoutez l'adresse de chargement de base à chacune de ces adresses, et mettez ce résultat dans l'image comme chargé dans la mémoire.

2

Passez un tableau de pointeurs de fonction pertinents en tant que paramètre. Alternativement, vous pouvez avoir généré du code basé sur une zone de données qui est placée à un emplacement fixe par rapport au code. Je me rappelle que lorsque je jouais avec ce genre de choses, j'avais mis en place une page de lecture/écriture/exécution de la mémoire, utiliser la première moitié pour le code généré, et la seconde moitié pour les données. Le code, une fois qu'il a obtenu le contrôle, irait comme ceci:

call l 
l: 
pop eax ; eax has the current eip 
and eax, 0fffff000h ;round down to the page size, 4K AKA 0x1000 
add eax, 800h ;now eax points at the data area 

... et ainsi de suite.

Pour le code généré à grande échelle, vous pouvez le stocker en tant que DLL complètes et utiliser les services de relocalisation et de correction d'adresse fournis par le système.

Questions connexes