Comment remplacer les appels de fonctions WinAPI dans le projet MS VC++ par ma propre implémentation (le nom et les paramètres définis sont les mêmes) ?

StackOverflow https://stackoverflow.com/questions/60641

  •  09-06-2019
  •  | 
  •  

Question

Je dois remplacer tous les appels WinAPI du

  • Créer un fichier,
  • Lire le fichier,
  • SetFilePointer,
  • FermerPoignée

avec ma propre implémentation (qui utilise la lecture de fichiers de bas niveau via Bluetooth).Le code, où les fonctions seront remplacées, est Video File Player et il fonctionne déjà avec les fichiers HDD standards.Il est également nécessaire que Video Player puisse toujours lire les fichiers du disque dur, si le fichier dans l'entrée VideoPlayer est un fichier HDD ordinaire.

Quelle est la meilleure pratique pour une telle tâche ?

Était-ce utile?

La solution

Je vous suggère de suivre ces étapes :

  1. Écrivez un ensemble de fonctions wrapper, par exemple MyCreateFile, MyReadFile, etc., qui appellent initialement simplement l'API correspondante et transmettent les mêmes arguments, sans modification.
  2. Utilisez votre éditeur de texte pour rechercher tous les appels aux API d'origine et remplacez-les par des appels à vos nouvelles fonctions wrapper.
  3. Testez que l'application fonctionne toujours correctement.
  4. Modifiez les fonctions du wrapper en fonction de vos propres besoins.

Notez que CreateFile est une macro qui se développe en CreateFileW ou CreateFileA, selon qu'UNICODE est défini ou non.Pensez à utiliser LPCTSTR et le Fonctions TCHAR afin que votre application puisse être construite en ANSI ou Unicode.

Veuillez ne pas utiliser #define, comme suggéré dans d'autres réponses ici, car cela entraînerait simplement des problèmes de maintenance, et comme Maximilian le souligne à juste titre, ce n'est pas une bonne pratique.

Autres conseils

Vous pouvez simplement écrire vos nouvelles fonctions dans un espace de noms personnalisé.par exemple.

namespace Bluetooth
{
  void CreateFile(/*params*/);
  void etc...
}

Ensuite, dans votre code, la seule chose que vous devrez modifier est :

if (::CreateFile(...))
{
}

à

if (Bluetooth::CreateFile(...))
{
}

Facile!:)

Si vous essayez d'intercepter les appels vers ces API à partir d'une autre application, envisagez Détours.

Si vous pouvez modifier le code, vous devez simplement le réécrire pour utiliser une API personnalisée qui fait ce que vous voulez.A défaut, utilisez la technique de Maximilien, mais sachez qu'il s'agit d'une horreur de maintenance.

Si vous ne pouvez pas modifier le code, vous pouvez patcher les tables d'importation pour rediriger les appels vers votre propre code.Une description de cette technique peut être trouvée dans Cet article - recherchez la section intitulée "Espionnage par modification de la table des adresses d'importation".

C'est dangereux, mais si vous faites attention, vous pouvez y arriver.Consultez également Détours Microsoft, qui fait le même genre de chose mais ne vous oblige pas à vous soucier des correctifs proprement dits.

Si vous voulez vraiment détourner l'API, regardez seringue.dll (L-GPL).

Je ne pense pas que ce soit la meilleure pratique, mais cela devrait fonctionner si vous le placez dans un fichier d'inclusion inclus partout où la fonction que vous souhaitez modifier est appelée :

#define CreateFile MyCreateFile

HRESULT MyCreateFile(whatever the params are);

L'implémentation de MyCreateFile ressemble à ceci :

#undef CreateFile
HRESULT MyCreateFile(NobodyCanRememberParamListsLikeThat params)
{
    if (InputIsNormalFile())
        CreateFile(params);
    else
        // do your thing
}

En gros, vous faites de chaque appel CreateFile un appel MyCreateFile où vous pouvez décider si vous souhaitez utiliser votre propre implémentation ou celle d'origine.

Clause de non-responsabilité:Je pense que faire ça est moche et je ne le ferais pas.Je préfère rechercher et remplacer toutes les occurrences ou quelque chose comme ça.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top