Recherche d'adresse mémoire d'un DLL dans un processus

Résolu
empathe Messages postés 4 Date d'inscription jeudi 2 septembre 2004 Statut Membre Dernière intervention 26 octobre 2009 - 17 oct. 2009 à 15:11
empathe Messages postés 4 Date d'inscription jeudi 2 septembre 2004 Statut Membre Dernière intervention 26 octobre 2009 - 26 oct. 2009 à 20:49
Bonjour,

je recherche une fonction pouvant me retourner l'adresse mémoire Hexa d'ou est stocké une DLL d'un processus.

le code:

#include <windows.h>
#include <stdio.h>

int main(int argc, char *argv[])
    {
     RecherchePid(); //fonction pour vérifier que le processus est bien là.

h_Read_Process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID);
     phandle = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPID);
//dwPID = Pid du processus
long resultat;
ReadProcessMemory(h_Read_Process,(LPCVOID)0X00001234, &resultat, sizeof(resultat), NULL);
//ReadProcessMemory(h_Read_Process,(LPCVOID)"Game.dll"+0X00001234, &resultat, sizeof(resultat), NULL);
//il me faudrait un truc comme sa

printf("Resultat= %.2f\n", resultat);//Affiche le résultat en Hexa
Sleep(10000);


quelqu'un sais faire ou à déja fait ?
Merci de votre lecture

6 réponses

cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
25 oct. 2009 à 16:53
Salut,

Il se trouve que "GetModuleHandle" est une fonction sympathique dans le sens où elle prend un seul argument, un pointeur.
En quoi cela la rend-elle sympathique ? Eh bien cela veut dire que l'on peut utiliser CreateRemoteThread sur celle-ci.
Donc on a pas besoin d'injecter une dll appelant GetModuleHandle : on va simplement appeler GetModuleHandle dans le processus cible.

Le code ci-dessous lance une calculatrice et affiche l'adresse de la dll ole32.dll chargée par celle-ci.
Dans ton cas, je suppose que tu récupères un handle sur le processus du jeu via un autre moyen.

Quoiqu'il en soit, c'est curieux que Game.dll ne soit pas toujours chargée au même endroit... Le code ci-dessous ne fonctionnera pas si kernel32 n'est pas chargée au même endroit dans les deux processus. Normalement kernel32 ne bouge jamais : c'est la deuxième dll chargée après ntdll.dll. Mais il peut arriver qu'un système de protection soit mis en place au niveau de l'OS pour que les dlls soient chargées à des endroit différents (Mais je l'ai jamais constaté).

#include <windows.h>
#include <stdio.h>

HMODULE GetProcessModuleHandle(HANDLE hProcess, char* lpModuleName)
{
  HMODULE hKernel32;
  LPTHREAD_START_ROUTINE lpGetModuleHandleAddress;
  DWORD nModuleNameSize;
  char* lpRemoteModuleName;
  DWORD nWritten;
  HANDLE hThread;
  HMODULE hResult;

  hResult = NULL;

  nModuleNameSize = lstrlen(lpModuleName) + 1;

  /* Récupération de l'adresse de GetModuleHandle dans le processus courant */
  /* En pratique, c'est toujours la même dans le processus cible */
  hKernel32 = GetModuleHandle("kernel32.dll");
  lpGetModuleHandleAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "GetModuleHandleA");

  /* Allocation d'une zone dans le processus cible, qui va contenir le nom de la dll à trouver */
  lpRemoteModuleName = (char*)VirtualAllocEx(hProcess, NULL, nModuleNameSize, MEM_COMMIT, PAGE_READWRITE);
  if (! lpRemoteModuleName) goto the_end;

  /* Ecriture du nom de la dll dans le processus distant */
  if (! WriteProcessMemory(hProcess, lpRemoteModuleName, lpModuleName, nModuleNameSize, &nWritten))
    goto free_memory;

  /* Création du thread */
  hThread = CreateRemoteThread(hProcess, NULL, 0, lpGetModuleHandleAddress, lpRemoteModuleName, 0, NULL);
  if (! hThread) goto free_memory;

  /* Attente du thread */
  WaitForSingleObject(hThread, INFINITE);

  /* Récupération du résultat de GetModuleHandle */
  GetExitCodeThread(hThread, (DWORD*)&hResult);
  CloseHandle(hThread);

free_memory:
  VirtualFreeEx(hProcess, lpRemoteModuleName, 0, MEM_RELEASE);
the_end:
  return hResult;
}

int main()
{
  STARTUPINFO startupInfo;
  PROCESS_INFORMATION processInfo;
  HMODULE hModule;
  
  ZeroMemory(&startupInfo, sizeof(startupInfo));
  startupInfo.cb = sizeof(startupInfo);
  startupInfo.dwFlags = STARTF_USESHOWWINDOW;
  startupInfo.wShowWindow = SW_SHOW;

  CreateProcess(NULL, "calc", NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo);

  /* Très moche, mais dans le cas de la question, le jeu est lancé séparément */
  Sleep(500);

  hModule = GetProcessModuleHandle(processInfo.hProcess, "ole32.dll");
  printf("%#08x\n", (unsigned int)hModule);

  CloseHandle(processInfo.hThread);
  CloseHandle(processInfo.hProcess);

  return 0;
}
3
empathe Messages postés 4 Date d'inscription jeudi 2 septembre 2004 Statut Membre Dernière intervention 26 octobre 2009
26 oct. 2009 à 20:49
Merci d'avoir répondu rt15,
et merci de ton aide qui m'a orienté,
voilà la fonction:
en premier on récupére le PID avec:

DWORD GetPidByName(char *szProcName)
      {
       PROCESSENTRY32 pe = {sizeof(PROCESSENTRY32)};
       HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 

       if(hSnap != INVALID_HANDLE_VALUE)
                {
                if(Process32First(hSnap, &pe))
                 { 
                  do
                  {
                   if(strcmpi(pe.szExeFile, szProcName) == 0)
                   {
                    dwPID = pe.th32ProcessID;

                    break;
                   }    
                  } 
                 while(Process32Next(hSnap, &pe));
                 }
                CloseHandle(hSnap);
                }
       return dwPID;
      } 


exemple utilser:
if (GetPidByName("Aion.bin") != 0){// OK
}else{}//rien trouvé





Ensuite on utilise une autre fonction pour lister toutes les DLL et trouver la bonne.


DWORD GetDLL(char* DllName, DWORD tPid){
HANDLE snapMod;
MODULEENTRY32 me32;

if (tPid == 0) return 0;
snapMod = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, tPid);
me32.dwSize = sizeof(MODULEENTRY32);

if (Module32First(snapMod, &me32)){
do{
if (strcmp(DllName,me32.szModule) == 0){
CloseHandle(snapMod);
return (DWORD) me32.modBaseAddr;
}
}while(Module32Next(snapMod,&me32));
}

CloseHandle(snapMod);
return 0;
}


et là pareil:

     gameDll = GetDLL("Game.dll", dwPID);
     if(gameDll == 0) {
                textcolor(1);
                printf("erreur: gameDll non trouve\n");
                textcolor(6);
                Sleep(5000);
                exit(0);
     }
    printf("gameDll %x\n", gameDll);
    int timee=11;
      while(timee--){
                     system("cls");
                     printf("Depart du BoT dans %d s!\n",timee);
                     Sleep(1000);
                     }


merci, et si sa peut aider ... dur à trouver :)
3
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
17 oct. 2009 à 19:21
Salut,
Tu peux essayer d'utiliser GetModuleHandle() suivie de GetModuleInformation() associée à la structure MODULEINFO. Le membre lpBaseOfDll contient l'adresse de base de la dll.
0
empathe Messages postés 4 Date d'inscription jeudi 2 septembre 2004 Statut Membre Dernière intervention 26 octobre 2009
17 oct. 2009 à 19:39
Merci de m'avoir répondu racpp,

j'ai essayé avec:

gameDll = (DWORD)GetModuleHandle(TEXT("game.dll")); 
//et
gameDll = (DWORD)GetModuleHandle("game.dll"); 
     printf("res %x\n", gameDll);


et ça me retourne toujours 0,

Aurais-tu une autre idée?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
17 oct. 2009 à 19:50
Il faut que cette dll soit chargée avant d'appeler GetModuleHandle().
0
empathe Messages postés 4 Date d'inscription jeudi 2 septembre 2004 Statut Membre Dernière intervention 26 octobre 2009
17 oct. 2009 à 20:06
En fait la dll est chargée, mais pas par mon programme (c'est la dll d'un jeu). J'essaye de faire un petit bot, j'ai récupéré la position des variables via cheat engine, ce dernier me les référence sous la forme "Game.dll+0x123.."

J'arrive à les lire en utilisant la fonction 'ReadProcessMemory' en utilisant les adresses absolues données par cheatEngine, mais ces adresses changent à chaque lancement du jeu, d'ou la nécessite de recompiler à chaque lancement du jeu ... :(
0
Rejoignez-nous