#include <windows.h>
#include <iostream>
#include <tlhelp32.h>

using namespace std;

/*
***** Structure de PROCESSENTRY32 *****

typedef struct tagPROCESSENTRY32 {
  DWORD dwSize;
  DWORD cntUsage;
  DWORD th32ProcessID;
  ULONG_PTR th32DefaultHeapID;
  DWORD th32ModuleID;
  DWORD cntThreads;
  DWORD th32ParentProcessID;
  LONG pcPriClassBase;
  DWORD dwFlags;
  TCHAR szExeFile[MAX_PATH];
} PROCESSENTRY32, 
 *PPROCESSENTRY32;
 
***** Prototype de la fonction CreateToolhelp32Snapshot() *****

HANDLE WINAPI CreateToolhelp32Snapshot(
  __in  DWORD dwFlags,
  __in  DWORD th32ProcessID
);


***** Prototype de la fonction OpenProcess() *****

HANDLE WINAPI OpenProcess(
  __in  DWORD dwDesiredAccess,
  __in  BOOL bInheritHandle,
  __in  DWORD dwProcessId
);

***** Prototype de la fonction ReadProcessMemory() *****

BOOL WINAPI ReadProcessMemory(
  __in   HANDLE hProcess,
  __in   LPCVOID lpBaseAddress,
  __out  LPVOID lpBuffer,
  __in   SIZE_T nSize,
  __out  SIZE_T* lpNumberOfBytesRead
);

*/

int main()
{
    /* Ce programme permet d'établir un dump d'un processus. 
    Il vous faut donc connaitre l'Original Entry Point du processus.
    Il vous faudra également rétablir la table des imports (IAT) sinon vous ne pourrez pas executer le dump.
    */
    
    char process[] = "dumpme.exe"; //Le processus que vous voulez dumper
    char save[] = "dumped.exe"; //Le dump de votre processus
    int offset = 0x00400000; //L'offset à partir duquel on commence le dump. Mettez donc l'OEP du programme
    
    
    //Création d'un fichier vide que l'on va remplir par le code de notre processus à dumper
    FILE *pFile = NULL;
    pFile = fopen(save, "ab+");
    
    if(pFile != NULL)
    {
             //On liste tous les processus jusqu'à trouver celui qu'on cherche
             HANDLE hSnapShot;
             PROCESSENTRY32 uProcess;
             
             hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//On établi une liste de tous les processus
             uProcess.dwSize = sizeof(PROCESSENTRY32);
             
             int p;
             DWORD PID;
             
             p = Process32First(hSnapShot, &uProcess);//On récupère le premier processus de la liste en remplissant la strcture PROCESSENTRY32
             while(p)
             {
                     if(strstr(uProcess.szExeFile, process)) //On a trouvé le processus à dumper
                     {
                                                   cout<<"\n\n[+]Process found : "<<uProcess.szExeFile;
                                                   
                                                   //On récupère l'id du processus
                                                   PID = uProcess.th32ProcessID;
                                                   
                                                   //On récupère un handle sur le processus
                                                   HANDLE hTemp = NULL;
                                                   hTemp = OpenProcess(PROCESS_ALL_ACCESS, 0, PID);
                                                   
                                                   char buffer[15]; //buffer qui recevra les octets du programme en mémoire
                                                   memset(buffer, 0, sizeof(buffer));
                                                   
                                                   int nul = 0x00; //null char
                                                   
                                                   if(hTemp != NULL)
                                                   {
                                                           while(ReadProcessMemory(hTemp,  (LPVOID)offset, &buffer, 1, NULL)) //On lit chaque octet du programme en mémoire
                                                           {
                                                                                           if(!strcmp(buffer,""))//On rétabli tout les 0->0x00
                                                                                           {
                                                                                                     fputc(nul, pFile);
                                                                                           }
                                                                                           else
                                                                                           {
                                                                                                     fprintf(pFile, "%s", buffer); //On écris les octets un à un dans le fichier
                                                                                           }
                                                                                           offset += 0x01;
                                                                                           memset(buffer, 0, sizeof(buffer));
                                                           }
                                                   }
                                                   else
                                                       cout<<"\n\n[-]Failed to get process handle\nError : "<<GetLastError();
                     }
                     
                     p = Process32Next(hSnapShot, &uProcess); //On récupère le processus suivant de la liste en remplissant la strcture PROCESSENTRY32
             }
             fclose(pFile);
    }
    else
        cout<<"\n\n[-]Failed to create file\n---Error : "<<GetLastError();
        
    cout<<"\n\n";
    system("pause");
    return 0;
}
    

