Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Easy C++ Trainer maker (Need input)

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
ParoXsitiC
Newbie cheater
Reputation: 0

Joined: 22 Aug 2006
Posts: 10

PostPosted: Sun Aug 27, 2006 10:39 pm    Post subject: Easy C++ Trainer maker (Need input) Reply with quote

Hello all. It's been a while since I've dove into C++. 2-3 years and recently I've been getting into messing around with assembly and memory editing. I noticed there are alot of pages about using the WriteProcessMemory and ReadProcessMemory but I haven't found simple things that put all the variables together in order to make a quick memory editor (Trainer). The things like getting PIDs from process or window names, or simple calls to inject data. I've seen pages worth on how to do it but none the simplify it for someone to just copy and paste some code in and know how to do 80% of memory hacking with 3-4 commands. This class/code will allow beginners of memory hacking or C++ to simply paste the code, write a few lines and then compile. At least that is what I hope.

The reason I am posting this is simply for feedback. I want your suggestions on how to do things better, because I know there are better ways. Don't be shy about being overcritical. I want to meet all accepted standards and I want this code to be SUPER compatible and require few headers and libs. I also want all of it to make perfect sense to the novice C++ coder. If my comments don't do the job well enough or I just simply did something in a messed up way, let me know. I hope to improve this in the future and hopefully allow for inline ASM along with POKE commands.

Ideally someone who has never touched C++ or memory hacking could read a tutorial on the web and use a program like TSearch to convert BASIC POKEs to this program.

Code:

// Injection class
// This class is made to simplify injecting code into processes
// it uses the functions POKE and PEEK based mostly on from BASIC
// a popular memory hacker called TSearch converts ASM to BASIC POKEs
// Author: Brian Hare

#include "stdafx.h"
#include <afxwin.h>
#include <windows.h>
#include "psapi.h"
#pragma comment(lib, "psapi.lib")

// Macros used to call an object and pass it's name
#define win(object) object(#object)
#define exe(object) object(#object".exe")

// Macros used to convert varibles of no type
#define POKE(a, b) POKE_(#a, #b)
#define PEEK(a, b) PEEK_(#a, b)

// Type definitions
#define HWND struct HWND__ *
#define BYTE unsigned char *
#define HANDLE void *
#define DWORD unsigned long

// Constant Global varibles
const bool AUTO_PEEK = true;
const bool PROCESS_LIST = false;
const bool SYSTEM_ERRORS = true;

// Global variable used for detecting the process handle of the last inject class object
char * sProcessGlobal;
HANDLE hProcessGlobal;
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

// General functions
void printError( char *);
void printLine(int);
void EnableDebugPriv();

// Main functions
void PEEK_(char *, int, HANDLE, char *);
void POKE_(char *, char *, int, HANDLE, char *);

class inject
{
     private:
          char * sProcessPrivate;
          HANDLE hProcessPrivate;
          DWORD FindProcess(char *);
     public:
          inject(char *);
          ~inject();
          void PEEK_(char * sAddress, int iBytesHighlighted = 0)
          {
               ::PEEK_(sAddress, iBytesHighlighted, hProcessPrivate, sProcessPrivate);
          }
          void POKE_(char * sAddress, char * sBytes, int iPeek = 1)
          {
               ::POKE_(sAddress, sBytes, iPeek, hProcessPrivate, sProcessPrivate);
          }
};


inject::inject(char * sProcess) // inject Constructor
{
     DWORD dPID;

     // Check is the incoming string has a .exe or not
     if (strstr (sProcess,".exe") != NULL)
     {
          // Find the PID based on process name
          dPID = FindProcess(sProcess);
          if (dPID == NULL)
          {
               SetConsoleTextAttribute(hConsole, 12);
               printf( "\nWARNING: FindProcess failed (%s was not found)\n", sProcess);
               SetConsoleTextAttribute(hConsole, 7);
               return;
          }

     }
     // Find the PID based on window name
     else {     
          HWND hwndWindow = FindWindow(NULL, sProcess);
          if (GetLastError() != 0)
          {
               SetConsoleTextAttribute(hConsole, 12);
               printf( "\nWARNING: FindWindow failed (%s was not found)\n", sProcess);
               SetConsoleTextAttribute(hConsole, 7);
               printError("FindWindow");
               return;
          }

          GetWindowThreadProcessId(hwndWindow, &dPID);
     }

     // Set the private and global varibles so you can use them interchangably
     hProcessPrivate = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dPID);
     if (GetLastError() != 0) { printError("OpenProcess"); return; }
     hProcessGlobal = hProcessPrivate;
     sProcessGlobal = sProcess;
     sProcessPrivate = sProcess;
}

inject::~inject()  // inject Deconstructor
{
     CloseHandle(hProcessPrivate);
     if (GetLastError() != 0) { printError("CloseHandle"); return; }
}

// Find the process handle by name
DWORD inject::FindProcess(char * InputProcessName)
{
     HANDLE hProcess;

     DWORD aProcesses[1024];
     DWORD cbNeeded;
     DWORD cProcesses;
      HMODULE hMod;

     // Get the list of proccess and put them in aProccesses
     EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded );
     if (GetLastError() != 0) { printError("EnumProcesses"); return 0; }
   
     // Calculate the number of processes
     cProcesses = cbNeeded / sizeof(DWORD);

     char szProcessName[MAX_PATH] = "UnknownProcess";

     if (PROCESS_LIST == true)
     {
          SetConsoleTextAttribute(hConsole, 15);
          printf("  PID   HANDLE   PROCESS NAME\n");
          printf("  ---   ------   ------------\n");
          SetConsoleTextAttribute(hConsole, 7);
     }

     DWORD dPID = NULL;
     EnableDebugPriv();
     for (unsigned int i = 2; i < cProcesses; i++ )
     {
          hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, aProcesses[i] );
          if (GetLastError() != 0)
          {
               printError("OpenProcess");
               CloseHandle( hProcess );
               continue;
          }
          if (hProcess != NULL)
          {
               if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
               {
                    GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName));
                    if(!_stricmp(szProcessName, InputProcessName))
                    {
                         if (PROCESS_LIST == true) SetConsoleTextAttribute(hConsole, 10);
                         dPID = aProcesses[i];
                    }
                    if (PROCESS_LIST == true)
                    {
                         printf("%5d   %5d    %s\n", aProcesses[i], hProcess, szProcessName);
                         SetConsoleTextAttribute(hConsole, 7);
                    }
               }
          }
          CloseHandle( hProcess );
     }
     printf("\n");
     return dPID;
}

// printError: shortcut for displaying error messages better.
void printError( char * func)
{
     if (SYSTEM_ERRORS != true){ return;}
     DWORD eNum;
     char sysMsg[256];
     char * p;

     eNum = GetLastError( );
     FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
          NULL, eNum,
          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
          sysMsg, 256, NULL );

     // Trim the end of the line and terminate it with a null
     p = sysMsg;
     while( ( *p > 31 ) || ( *p == 9 ) )
          ++p;
     do { *p-- = 0; } while( ( p >= sysMsg ) &&
                                   ( ( *p == '.' ) || ( *p < 33 ) ) );

  // Display the message
  SetConsoleTextAttribute(hConsole, 12);
  printf( "\nWARNING: %s failed with error %d (%s)\n", func, eNum, sysMsg );
  SetConsoleTextAttribute(hConsole, 7);
}

// printLine: Print a line that is based on the number of columns
void printLine(int iCols)
{
     printf("---------");
     for (int i = 1; i <= iCols; i++)
          printf ("---");
     printf("\n");
}

// EnableDebugPriv: Toggle for enabling privleges to get process handles
void EnableDebugPriv()
{
     HANDLE hToken;
     TOKEN_PRIVILEGES tp;

     if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))
     if (GetLastError() != 0) { printError("OpenProcessToken"); return; }
     
     if(!LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
     if (GetLastError() != 0) { printError("LookupPrivilegeValue"); return; }
     
     tp.PrivilegeCount = 1;
     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

     if(!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL))
     if (GetLastError() != 0) { printError("AdjustTokenPrivileges"); return; }
}

// PEEK_: Used as reference function for the PEEK macro.
//            This will output the address specified in the first parameter
//            and all the bytes to that address.
//            Defaults: 3 lines above and below hightlighted byte lines (iLineOffset)
//                       16 columns (iCols)
void PEEK_(char * sAddress, int iBytesHighlighted = 0, HANDLE hProcess = hProcessGlobal, char * sProcess = sProcessGlobal)
{
     // Convert the Address string into a hexadecimal DWORD value and store into dAddress
     DWORD dAddress;
     sscanf(sAddress, "%8X", &dAddress);

     // iLineOffset: Number of lines above and below the highlighted line(s).
     // iCols:          Number of columns (NOTE: Anything less than 16 won't generate correct byte header)
     int iLineOffset = 3;
     int iCols = 16;

     // iLinesHighlighted:     Always round up. Similar to ceil function of math.h
     int iLinesHighlighted = iBytesHighlighted/double(iCols) + 0.999999;
     int iLines = (iLineOffset * 2)+ iLinesHighlighted;
     int iBytesTotal = iLines * iCols;
     int iHighlightStart = iLineOffset * iCols;
     int i, ii, iByte = 0;

     // new and memset are used to allow VLA (variable length arrays)
     // vectors could of been used but might want to use in calculation later on.
     BYTE bBuffer = new unsigned char [iBytesTotal];
     memset (bBuffer,0x00,iBytesTotal);

     // Look back iLineOffset * iCols bytes. This is to make the lines above.
     dAddress -= iHighlightStart;
     
     // Set console color to white (15) and echo the PEEK command they ran
     SetConsoleTextAttribute(hConsole, 15);
     printf ("PEEK %X %d -> ", dAddress + iHighlightStart, iBytesHighlighted);
     SetConsoleTextAttribute(hConsole, 7);

     // API to read memory of process
     ReadProcessMemory(hProcess, (void *)dAddress, bBuffer, iBytesTotal, NULL);
     if (GetLastError() != 0) { printError("ReadProcessMemory"); return; }

     // Status message
     printf ("Read %d bytes from %X\n",iBytesTotal,dAddress + iHighlightStart);
     printLine(iCols);
         
     // Set console color to white (15)
     SetConsoleTextAttribute(hConsole, 15);
     printf("ADDRESS ");

     // Print the correct byte header for each column. Only correct if iCols = 16
     if (iCols == 16)
     {
          int iLastByte = (dAddress + iHighlightStart) % 16;
          int iColHeader = iLastByte;
          do
          {
               printf("  %X", iColHeader);
               if (iColHeader == 15)
                    iColHeader = 0;
               else
                    iColHeader++;
          } while (iColHeader != iLastByte);
     } else {
          for (i = 1; i <= iCols; i++)
          printf ("  ?");
     }

     printf("\n");
         
     // Reset console color
     SetConsoleTextAttribute(hConsole, 7);

     printLine(iCols);

     // For each line print the correct address and bytes that belong in that address
     // iByte is used for a counter of each byte, once its time to start hightlighting
     // the console color will change. When it's time to stop it will stop.
     for (i = 0; i < iLines; i++)
     {
          if (iByte == iHighlightStart)
          SetConsoleTextAttribute(hConsole, 10);
          printf ("%08X:", dAddress + i * iCols);

          for (ii = 1; ii <= iCols; ii++)
          {
               printf (" %02X",bBuffer[iByte]);
               iByte++;
               if(iByte >= iHighlightStart + iBytesHighlighted)
               SetConsoleTextAttribute(hConsole, 7);
          }
          printf("\n");
     }
     printLine(iCols);
     printf("\n");
     // Clear the memory used for the new BYTE buffer
     delete [] bBuffer;
}

// POKE_: Used as reference function for the POKE macro.
//            This will inject the bytes specificed into the address passed.
//            Defaults: PEEK_ function will follow this command to view results (iPeek)
//                         Process handle is recieved from the last call to the inject class
void POKE_(char * sAddress, char * sBytes, int iPeek = 1, HANDLE hProcess = hProcessGlobal, char * sProcess = sProcessGlobal)
{     

     // Convert the Address string into a hexadecimal DWORD value and store into dAddress
     DWORD dAddress;
     sscanf(sAddress, "%8X", &dAddress);

     // Each byte is delimited by a space
     int iBytecount = (strlen(sBytes) +1) / 3;
     DWORD lBytes;

     // new and memset are used to allow VLA (variable length arrays)
     // vectors could of been used but might want to use in calculation later on.
     BYTE bBuffer = new unsigned char [iBytecount+3];
     
     // Convert the string of bytes passed into single bytes stored in the BYTE buffer
     for (int i = 0; i < iBytecount; i++)
     sscanf(sBytes+3*i, "%2X", bBuffer+i);

     // Set console color to white (15) and echo the POKE command they ran
     SetConsoleTextAttribute(hConsole, 15);
     printf ("POKE %X %s -> ", dAddress, sBytes);
     SetConsoleTextAttribute(hConsole, 7);

     // API function that will inject the bytes into the address. Function outputs to lBytes
     WriteProcessMemory(hProcess, (void *)dAddress, bBuffer, iBytecount, &lBytes );
     if (GetLastError() != 0) { printError("WriteProcessMemory"); return; }
     
     // Display information
     printf("Wrote %d bytes into %X \n", lBytes, dAddress);

     // If AUTO_PEEK is true then PEEK after POKE
     if (AUTO_PEEK == true) PEEK_(sAddress, iBytecount);

     // Clear the memory used for the new BYTE buffer
     delete [] bBuffer;
}

void main()
{
     // This example will show you the basis of commands

     inject exe(winmine); // or inject win(Minesweeper)

     // View the code before the injection
     PEEK(01002ff5, 5); // or winmine.PEEK(01002ff5, 5) (Minesweeper if you used win)

     // Disable timer
     POKE(01002ff5,90 90 90 90 90 90);  // or POKE(01002ff5,90 90 90 90 90 90); (Minesweeper if you used win)

     // View the code before the ejection
     //PEEK(01002ff5, 6);

     // Enable timer
     //POKE(01002ff5,FF 05 9C 57 00 01);

     exit(0);
}
Back to top
View user's profile Send private message AIM Address
IssacTang2
Newbie cheater
Reputation: 0

Joined: 26 Aug 2006
Posts: 24

PostPosted: Mon Aug 28, 2006 2:59 am    Post subject: Reply with quote

excuse me I want to ask is memory editing a part of C++ and writing programs such as dll and exe is those also for C++ ?
and also the web languages are they are c++ but having diff branches?
Back to top
View user's profile Send private message
ParoXsitiC
Newbie cheater
Reputation: 0

Joined: 22 Aug 2006
Posts: 10

PostPosted: Mon Aug 28, 2006 8:34 am    Post subject: Reply with quote

http://www.google.com/search?hl=en&hs=glh&lr=&client=firefox-a&rls=org.mozilla:en-US:official&defl=en&q=define:C%2B%2B&sa=X&oi=glossary_definition&ct=title

"C++ is an object-oriented programming (OOP) language that is viewed by many as the best language for creating large-scale applications. C++ is a superset of the C language. A related programming language, Java, is based on C++ but optimized for the distribution of program objects in a network such as the Internet. Java is somewhat simpler and easier to learn than C++ and has characteristics that give it other advantages over C++. However, both languages require a considerable amount of study."
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites