Random Access Violations

On lunes, 27 de diciembre de 2010 0 comentarios

by iPromise

As you guys well know I coded a memory scanner to simply find addresses that I can use for my hacks. However, whenever I do a next scan with my memory scanner it tends to give me a random access violation (mostly on games not other non-gaming applications). So I saw that maybe I needed to protect the memory to PAGE_READWRITE or any other memory readable constants. So I tested it and gave it a run and it kept giving me random access violations.

So heres my code for my next scan:


Code:

void NextScan(HWND hWndDlg)
{
   int Min = 0; int Max = SendMessage(GetDlgItem(hWndDlg, IDC_LIST1), LB_GETCOUNT, 0, 0);

   char TypeBuf[500] = {0};

   GetWindowTextA(GetDlgItem(hWndDlg, IDC_COMBO1), (LPSTR) TypeBuf, 500);

   char ValueBuf[500] = {0};

   GetWindowTextA(GetDlgItem(hWndDlg, IDC_EDIT1), (LPSTR) ValueBuf, 500);

   string ValueStr;

   ValueStr += (LPSTR) ValueBuf;

   stringstream ConvertValue; unsigned int Value;

   ConvertValue << (LPSTR) ValueBuf; ConvertValue >> Value;   

   char Scan[500] = {0};

   GetWindowTextA(GetDlgItem(hWndDlg, IDC_COMBO2), (LPSTR) Scan, 500);

   DWORD lpflOldProtect;

   if (!strcmp(Scan, "Exact Value"))
   {
      for (int i = Min; i <= Max; i ++)
      {
         char AddressBuf[500] = {0};

         SendMessage(GetDlgItem(hWndDlg, IDC_LIST1), LB_GETTEXT, (WPARAM) i, (LPARAM) (LPTSTR) AddressBuf);

         stringstream ConvertAddress(AddressBuf); LPVOID lpAddress;

         ConvertAddress >> lpAddress;

         DWORD dwAddress = (DWORD) lpAddress;         

         VirtualProtect((LPVOID) dwAddress, 4, PAGE_READWRITE, &lpflOldProtect);         
         
         if (((!strcmp(TypeBuf, "Byte")) && *(BYTE*) dwAddress != (BYTE) Value) ||
            ((!strcmp(TypeBuf, "2 Bytes")) && *(WORD*) dwAddress != (WORD) Value) ||
            ((!strcmp(TypeBuf, "4 Bytes")) && *(DWORD*) dwAddress != (DWORD) Value) ||
            ((!strcmp(TypeBuf, "8 Bytes")) && *(UINT64*) dwAddress != (UINT64) Value))
         {
            SendMessage(GetDlgItem(hWndDlg, IDC_LIST1), LB_DELETESTRING, (WPARAM) i, 0);
         }      

         VirtualProtect((LPVOID) dwAddress, 4, lpflOldProtect, &lpflOldProtect);   
      }

      GetResults(hWndDlg);
   }

   if (!strcmp(Scan, "Decreased.."))
   {
      for (int i = Min; i <= Max; i ++)
      {
         char AddressBuf[500] = {0};

         SendMessage(GetDlgItem(hWndDlg, IDC_LIST1), LB_GETTEXT, (WPARAM) i, (LPARAM) (LPTSTR) AddressBuf);

         stringstream ConvertAddress(AddressBuf); LPVOID lpAddress;

         ConvertAddress >> lpAddress;

         DWORD dwAddress = (DWORD) lpAddress;   

         VirtualProtect((LPVOID) dwAddress, 4, PAGE_READWRITE, &lpflOldProtect);      

         if (((!strcmp(TypeBuf, "Byte")) && ((*(BYTE*) dwAddress) >= ((BYTE) Value))) ||
            ((!strcmp(TypeBuf, "2 Bytes")) && ((*(WORD*) dwAddress) >= ((WORD) Value))) ||
            ((!strcmp(TypeBuf, "4 Bytes")) && ((*(DWORD*) dwAddress) >= ((DWORD) Value))) ||
            ((!strcmp(TypeBuf, "8 Bytes")) && ((*(UINT64*) dwAddress) >= ((UINT64) Value))))
         {
            SendMessage(GetDlgItem(hWndDlg, IDC_LIST1), LB_DELETESTRING, (WPARAM) i, 0);
         }         

         VirtualProtect((LPVOID) dwAddress, 4, lpflOldProtect, &lpflOldProtect);   
      }

      GetResults(hWndDlg);
   }

   if (!strcmp(Scan, "Increased.."))
   {
      for (int i = Min; i <= Max; i ++)
      {
         char AddressBuf[500] = {0};

         SendMessage(GetDlgItem(hWndDlg, IDC_LIST1), LB_GETTEXT, (WPARAM) i, (LPARAM) (LPTSTR) AddressBuf);

         stringstream ConvertAddress(AddressBuf); LPVOID lpAddress;

         ConvertAddress >> lpAddress;

         DWORD dwAddress = (DWORD) lpAddress;         

         VirtualProtect((LPVOID) dwAddress, 4, PAGE_READWRITE, &lpflOldProtect);      

         if (((!strcmp(TypeBuf, "Byte")) && *(BYTE*) dwAddress <= (BYTE) Value) ||
            ((!strcmp(TypeBuf, "2 Bytes")) && *(WORD*) dwAddress <= (WORD) Value) ||
            ((!strcmp(TypeBuf, "4 Bytes")) && *(DWORD*) dwAddress <= (DWORD) Value) ||
            ((!strcmp(TypeBuf, "8 Bytes")) && *(UINT64*) dwAddress <= (UINT64) Value))
         {
            SendMessage(GetDlgItem(hWndDlg, IDC_LIST1), LB_DELETESTRING, (WPARAM) i, 0);
         }         

         VirtualProtect((LPVOID) dwAddress, 4, lpflOldProtect, &lpflOldProtect);   
      }

      GetResults(hWndDlg);
   }
}


Please, suggestions and comments can help me out.
Read more ...»

Slow Scans <---

On 0 comentarios

by iPromise

I'm writing all my information into a buffer, and when the scan is finished I add the items into the listbox. Everything works but, when scanning a process that is very big, and not knowing where the address your looking for's region is, i'm going to have a big problem. I tried creating a thread for each region that I find which is readable but I can't pass on the T class, the structure or the value in CreateThread().


For instance:


Code:

template struct TMEMORY
{
   T Value;
   DWORD dwBaseAddr;
   DWORD dwEndAddr;
};

template void RunScan (TMEMORY *szMemInfo, T Value);

CreateThread (NULL, NULL, (LPTHREAD_START_ROUTINE) RunScan , ?, NULL, NULL);



Here is my current code:

Code:

template void Scan ( T Value )
   {
      SendMessageA (GetDlgItem (hWnd, IDC_LIST1), LB_RESETCONTENT, NULL, NULL);

      ofstream File ("C:\\File.txt");
      File.clear ();

      bool Fast = ( SendMessageA (GetDlgItem(hWnd, IDC_CHECKBOX1), BM_GETCHECK, 0, 0) == BST_CHECKED ) ? true : false;
      bool Slow = ( SendMessageA (GetDlgItem(hWnd, IDC_CHECKBOX2), BM_GETCHECK, 0, 0) == BST_CHECKED ) ? true : false;

      DWORD dwStartAddr = GetCurSel_2 (IDC_EDIT2);
      DWORD dwStopAddr  = GetCurSel_2 (IDC_EDIT3);

      for ( DWORD i = dwStartAddr;
                 i < dwStopAddr;
               i ++ )
      {
         MEMORY_BASIC_INFORMATION MBI = {0};
         VirtualQuery ((LPCVOID) i, &MBI, sizeof (MEMORY_BASIC_INFORMATION));

         if ( Fast )
         {
            if ( ( MBI.State == MEM_COMMIT ) &&
                ( MBI.Type  == MEM_PRIVATE ) &&
                ( MBI.RegionSize > 0 ) )
            {
               DWORD dwEndAddr = ( (DWORD) MBI.BaseAddress + (DWORD) MBI.RegionSize ) - 1 - sizeof (T);

               for ( DWORD addr = (DWORD) MBI.BaseAddress;
                        addr < (DWORD) dwEndAddr;
                        addr ++ )
               {
                  int read = read_for_except (addr, Value);

                  if ( read == 0 )
                  {
                     File << (LPVOID) addr << endl;
                  }
                  else if ( read == 2 )
                  {
                     addr = dwEndAddr;
                  }
               }

               i += (DWORD) MBI.RegionSize;
            }
            else
            {
               i += (DWORD) MBI.RegionSize;
            }
         }

         if ( Slow )
         {
            if ( ( MBI.Protect == PAGE_READWRITE ) &&
                ( MBI.RegionSize > 0 ) )
            {
               DWORD dwEndAddr = ( (DWORD) MBI.BaseAddress + (DWORD) MBI.RegionSize ) - 1 - sizeof (T);

               for ( DWORD addr = (DWORD) MBI.BaseAddress;
                        addr < (DWORD) dwEndAddr;
                        addr ++ )
               {
                  int read = read_for_except (addr, Value);

                  if ( read == 0 )
                  {
                     File << (LPVOID) addr << endl;
                  }
                  else if ( read == 2 )
                  {
                     addr = dwEndAddr;
                  }
               }

               i += (DWORD) MBI.RegionSize;
            }
            else
            {
               i += (DWORD) MBI.RegionSize;
            }
         }
      }

      File.close ();

      ifstream Read ("C:\\File.txt");

      while ( !Read.eof() )
      {
         LPVOID lpAddress;

         Read >> lpAddress;

         add_to_list ((DWORD) lpAddress, hWnd);
      }

      Read.close ();

      ObtainResults ();
   }
                
Read more ...»

memory.hpp by Flyte

On 0 comentarios

memory.hpp by Flyte

This interesting post is for people that want to make a memory editor...

Quote:
I feel sorry for you, so:
To user that was lost (iPromise) by Flyte.....

Link: memory.hpp

Your missions, should you choose to accept them:

1. Write a CachedRemoteMemory class that extends RemoteMemory for faster scans.
2. Add a cache for the value that was found on the last scan, enabling scans such as 'incremented'.
3. Understand what is going on... shouldn't be hard for one who has mastered C++ (lol). No comments, since comments are ezmode.


(As noted in the file, largely untested so something is probably broken somewhere... I suppose that's what you get for a 1 hour hack job.)

Here is how to use (part of) it.

Code:
#include 
#include 
#include "memory.hpp"

void ExampleOne(int i) {
   std::list
items; Scanner scanner; std::cout << "Starting..." << std::endl; if(scanner.Scan(i, items)) { do { std::cout << "Scanning..." << std::endl; } while(scanner.ScanNext(++i, items) > 1); if(items.size() == 1) { std::cout << "Done." << std::endl; std::cout << "i = " << i << std::endl << "&i = " << &i << std::endl; Address addr = items.front(); std::cout << "addr = " << (int)addr << std::endl << "&addr = " << (void *)addr.Value() << std::endl; std::cout << "Setting addr = " << i + 42 << std::endl; addr = i + 42; std::cout << "i = " << i << std::endl; } else { std::cout << "Something broke. Go fix it." << std::endl; } } } bool GreaterThan(int a, int b) { return a > b; } bool LessThan(int a, int b) { return a < b; } void ExampleTwo(int i) { std::list
items; Scanner scanner; std::cout << "Starting..." << std::endl; if(scanner.Scan(i-10, items, GreaterThan)) { std::cout << items.size() << " items greater than " << i-10 << "." << std::endl; if(scanner.ScanNext(i+10, items, LessThan)) { std::cout << items.size() << " items also less than " << i+10 << "." << std::endl; if(scanner.ScanNext(i-2, items, GreaterThan)) { std::cout << items.size() << " items also greater than " << i-2 << "." << std::endl; if(scanner.ScanNext(i+2, items, LessThan)) { std::cout << items.size() << " items also less than " << i+2 << "." << std::endl; } } } } } void PrintTestHeader(int i) { std::cout << std::endl << "Test " << i << std::endl << "--------------" << std::endl; } int main() { // Fast PrintTestHeader(1); ExampleOne(3); // Slow - Will probably crash (bad_alloc) on a big process. You need to store results in a file for such a situation. PrintTestHeader(2); ExampleOne(0); // Same as above. PrintTestHeader(3); ExampleTwo(100); return 0; }
Post: Cheat Engine :: View topic - Random Access Violations
Read more ...»

MEMORY.HPP

On 0 comentarios

// Coded by Paul 'Flyte'
// Provided as is, blah blah blah, give credit where credit is due, blah blah blah.

// Work in progress. Largely untested.

#ifndef MEMORY_HPP // Header guards. One of the few legit uses of the C preprocessor (lol)
#define MEMORY_HPP

#include 
#include 

class Memory;

class Address {
 friend class Memory;
 friend class Scanner;

 Memory & memory_;
 unsigned long const addr_;

 Address(Memory & memory, unsigned long addr) :
   memory_(memory), addr_(addr) {}

public:

    template <typename T>
 Address & operator=(T const & rhs) {
  memory_.WriteAddress(addr_, rhs);
  return *this;
 }

 template <typename T>
 operator T() const {
  return memory_.ReadAddress<T>(addr_);
 }

 unsigned long Value() const {
  return addr_;
 }
};

struct RegionInfo {
 bool IsReadable;
 bool IsWritable;
 unsigned long BaseAddress;
 unsigned long Size;

 RegionInfo() :
   IsReadable(false), IsWritable(false),
    BaseAddress(0), Size(0) {}

 RegionInfo(bool isReadable, bool isWritable, unsigned long baseAddress, unsigned long size) :
   IsReadable(isReadable), IsWritable(isWritable),
    BaseAddress(baseAddress), Size(size) {}


 template<typename T>
 bool IsInRegion(Address const & addr) const {
  if(Size < sizeof(T)) {
   return false;
  }
  return BaseAddress <= addr.Value() && addr.Value() < BaseAddress + Size - sizeof(T);
 }
};

class Memory {
 friend class Scanner;
 friend class Address;

protected:

 virtual bool WriteAddressInternal(void * addr, void const * value, unsigned int size) {
  ::memcpy(addr, value, size);
  return true;
 }

 virtual bool ReadAddressInternal(void const * addr, void * value, unsigned int size) {
  ::memcpy(value, addr, size);
  return true;
 }

 template <typename T>
 void WriteAddress(unsigned long addr, T const & value) {
  WriteAddressInternal((void *)addr, (const void *)&value, sizeof(T));
 }

 template <typename T>
 T ReadAddress(unsigned long addr) {
  T ret;
  ReadAddressInternal((const void *)addr, (void*)&ret, sizeof(T));
  return ret;
 }

public:

 virtual bool QueryMemory(unsigned long addr, RegionInfo & regionInfo) {
  ::MEMORY_BASIC_INFORMATION mbi = { 0 };

  if(::VirtualQuery((void*)addr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0) 
  {
   bool isReadable = false;
   bool isWriteable = false;

   if(mbi.State | MEM_COMMIT) 
   {
    if(mbi.AllocationProtect & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
     PAGE_EXECUTE_WRITECOPY | PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY)) {
      isReadable = true;
    }
    if(mbi.AllocationProtect & (PAGE_EXECUTE_READWRITE |
     PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY)) {
      isWriteable = true;
    }
   }

   regionInfo = RegionInfo(isReadable, isWriteable, (unsigned long)mbi.BaseAddress, mbi.RegionSize);
   return true;
  }

  return false;
 }

 Address Reference(unsigned long addr) {
  return Address(*this, addr);
 }
};

class RemoteMemory : public Memory {
 const ::HANDLE process_;

protected:

 virtual bool WriteAddressInternal(void * addr, void const * value, unsigned int size) {
  ::SIZE_T junk;
  return ::WriteProcessMemory(process_, addr, value, size, &junk) ? true : false;
 }

 virtual bool ReadAddressInternal(void const * addr, void * value, unsigned int size) {
  ::SIZE_T junk;
  return ::ReadProcessMemory(process_, addr, value, size, &junk) ? true : false;
 }

public:

 
 virtual bool QueryMemory(unsigned long addr, RegionInfo & regionInfo) {
  ::MEMORY_BASIC_INFORMATION mbi = { 0 };

  if(::VirtualQueryEx(process_, (void*)addr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0) 
  {
   bool isReadable = false;
   bool isWriteable = false;

   if(mbi.State | MEM_COMMIT) 
   {
    if(mbi.AllocationProtect & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
     PAGE_EXECUTE_WRITECOPY | PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY)) {
      isReadable = true;
    }
    if(mbi.AllocationProtect & (PAGE_EXECUTE_READWRITE |
     PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY)) {
      isWriteable = true;
    }
   }

   regionInfo = RegionInfo(isReadable, isWriteable, (unsigned long)mbi.BaseAddress, mbi.RegionSize);
   return true;
  }

  return false;
 }

 RemoteMemory(::HANDLE process) 
  : process_(process) {}
};

class Scanner {
 Memory & memory_;
 static Memory localMemory_;

 template <typename T, typename S>
 void ScanInternal(T const & value, RegionInfo & regInfo, std::list<Address> & items, S & comparer) {
  for(unsigned long x = regInfo.BaseAddress; x < regInfo.BaseAddress + regInfo.Size - sizeof(T); ++x) {
   T val;
   if(memory_.ReadAddressInternal((const void *)x, (void *)&val, sizeof(T))) {
    if(comparer(value, val)) {
     items.push_back(Address(memory_, x));
    }
   } else {
    break;
   }
  }
 }

 template <typename T, typename S>
 void ScanEnterTry(T const & value, RegionInfo & regInfo, std::list<Address> & items, S & comparer) {
  __try {
   ScanInternal(value, regInfo, items, comparer);
  } __except(true) {
   // Do nothing.
  }
 }

 template<typename T, typename S>
 int ScanNextInternal(T const & value, std::list<Address> & items, std::list<Address>::iterator & iter, RegionInfo & regInfo, S & comparer) {
  while(iter != items.end()) {
   if(!regInfo.IsInRegion<T>(*iter)) {
    if(!memory_.QueryMemory(iter->Value(), regInfo)) {
     while(regInfo.IsInRegion<T>(*iter)) {
      iter = items.erase(iter);
      if(iter == items.end()) {
       break;
      }
     }
     continue;
    } 
    if(!regInfo.IsReadable) {
     while(regInfo.IsInRegion<T>(*iter)) {
      iter = items.erase(iter);
      if(iter == items.end()) {
       break;
      }
     }
     continue;
    }
   }

   if(!comparer(value, (T)(*iter))) {
    iter = items.erase(iter);
   } else {
    ++iter;
   }
  }
  return items.size();
 }

 void IFuckingHateSEH(std::list<Address> & items, std::list<Address>::iterator & iter) {
  iter = items.erase(iter);
 }

 template<typename T, typename S>
 int ScanNextEnterTry(T const & value, std::list<Address> & items, std::list<Address>::iterator & iter, RegionInfo & regInfo, S & comparer) {
  int i = 0;
  for(;;) {
   __try {
    i = ScanNextInternal(value, items, iter, regInfo, comparer);
    break;
   } __except(true) {
    IFuckingHateSEH(items, iter);
   }
  }
  return i;
 }

 template<typename T>
 static bool Equal(T a, T b) {
  return a == b;
 }

public:

 Scanner() 
  : memory_(localMemory_) {}

 Scanner(Memory & memory) 
  : memory_(memory) {}


 template <typename T>
 int Scan(T const & value, std::list<Address> & items) {
  return Scan(value, items, Equal<T>);
 }

 template <typename T, class S>
 int Scan(T const & value, std::list<Address> & items, S & comparer) {
  ::SYSTEM_INFO sysInfo;
  GetSystemInfo(&sysInfo);

  for(unsigned long i = (unsigned long)sysInfo.lpMinimumApplicationAddress;
   i < (unsigned long)sysInfo.lpMaximumApplicationAddress - sizeof(T);) {

   RegionInfo regInfo;
   if(memory_.QueryMemory(i, regInfo)) {
    if(regInfo.IsReadable) {
     ScanEnterTry(value, regInfo, items, comparer);
    }
    i = regInfo.BaseAddress + regInfo.Size;
   } else {
    return 0;
   }
  }

  return items.size();
 }

 template <typename T>
 int ScanNext(T const & value, std::list<Address> & items) {
  return ScanNext(value, items, Equal<T>);
 }

 template <typename T, class S>
 int ScanNext(T const & value, std::list<Address> & items, S & comparer) {
  std::list<Address>::iterator iter = items.begin();
  RegionInfo regInfo;

  return ScanNextEnterTry(value, items, iter, regInfo, comparer);
 }
};

Memory Scanner::localMemory_ = Memory();

#endif
Read more ...»

Hook process functions via dll injection Cpp

On 0 comentarios

by Specific

This tutorial on how to hook process functions via dll injection is not for the beginning programmer.  I assume that you have knowledge of creating DLL (Dynamic Link Libraries) files in C++, as I do not cover this.  If you do not know how to inject a dll into a process, please read my tutorial "Inject DLL into running process with CPP."
Some of you may remember a release I had for MSN Gaming Zone called ZoneHook, this very code was used to hook the functions inside it's inner workings.  We start out planning how we will implement this code. Because ZoneHook was reasonably complex, I made a class so that implementing was easy as possible.
What we want to accomplish here is overwrite the address of the function to either jmp, or call our own function in the dll file.  Sounds really complicated, but it's not and with little knowledge of pointers and how programs work we can do this.
How do we accomplish what was just said?  We create a function that will render an instruction to jmp or call a specified offset.  With this instruction we then assign appropriate permissions to access and write to the original function call, we then write our new instruction in place of the original. 
Here is the basic structure (Redirect.h):
  1. #define CALL(a) _asm call [a]  
  2. #define JMP(a) _asm jmp [a]  
  3.   
  4. class Redirect    
  5. {  
  6. public:  
  7.     void RenderJMPInstruction(LPVOID address, LPVOID jumpto, char *buf);  
  8.     void JMPFunction(DWORD address, DWORD jumpto);  
  9.     void RenderCALLInstruction(LPVOID address, LPVOID jumpto, char *buf);  
  10.     void CALLFunction(DWORD address, DWORD jumpto);  
  11.     Redirect();  
  12.     virtual ~Redirect();  
  13.   
  14. };  


The class consists of one constructor and four methods. 

With the structure there, there is nothing more to do but code what we wanted to do.
  1. #include "Redirect.h"  
  2.   
  3. //////////////////////////////////////////////////////////////////////  
  4. // Construction/Destruction  
  5. //////////////////////////////////////////////////////////////////////  
  6.   
  7. Redirect::Redirect()  
  8. {  
  9.   
  10. }  
  11.   
  12. Redirect::~Redirect()  
  13. {  
  14.   
  15. }  
  16.   
  17. void Redirect::CALLFunction(DWORD address, DWORD jumpto)  
  18. {  
  19.     char instruction[5];  
  20.     RenderCALLInstruction((LPVOID)address,(LPVOID)jumpto,instruction);  
  21.     DWORD oldprot, dummy;  
  22.     VirtualProtect((void*)address,5,PAGE_EXECUTE_READWRITE,&oldprot);  
  23.     memcpy((LPVOID)address,(LPVOID)instruction,5);  
  24.     VirtualProtect((void*)address,5,oldprot,&dummy);  
  25. }  
  26.   
  27. void Redirect::RenderCALLInstruction(LPVOID address, LPVOID jumpto, char *buf)  
  28. {  
  29.     int offset = (int)jumpto - ((int)address + 5);  
  30.     buf[0] = (char)0xE8;  
  31.     *(DWORD*)(buf+1) = offset;  
  32. }  
  33.   
  34. void Redirect::JMPFunction(DWORD address, DWORD jumpto)  
  35. {  
  36.     char instruction[5];  
  37.     RenderJMPInstruction((LPVOID)address,(LPVOID)jumpto,instruction);  
  38.     DWORD oldprot, dummy;  
  39.     VirtualProtect((void*)address,5,PAGE_EXECUTE_READWRITE,&oldprot);  
  40.     memcpy((LPVOID)address,(LPVOID)instruction,5);  
  41.     VirtualProtect((void*)address,5,oldprot,&dummy);  
  42. }  
  43.   
  44. void Redirect::RenderJMPInstruction(LPVOID address, LPVOID jumpto, char *buf)  
  45. {  
  46.     int offset = (int)jumpto - ((int)address + 5);  
  47.     buf[0] = (char)0xE9;  
  48.     *(DWORD*)(buf+1) = offset;  
  49. }  
Redirecting the function is simple:
  1. /* This is just an example 
  2.  * 0x600542A5 would be the offset of the call in the original program you would like to redirect. 
  3.  */  
  4.   
  5. Redirect Hook;  
  6. Hook.CALLFunction(0x600542A5,(DWORD)OnZoneSend);  
Not done yet though, we still have to create the OnZoneSend function.  This is where people can run into problems if they don't know instruction flow in applications, it may require a little knowledge of assembly.
  1. int WINAPI OnZoneSend(...) {  
  2.    // ... your code here  
  3.    return ZoneSend(...);  
  4. }  
We now call a naked function which will jmp to the original function entry point.
  1. DWORD lpZoneSend = 0x6005484F; // original function entry point.  
  2. int __declspec(naked) WINAPI ZoneSend(...)  
  3. {  
  4.     JMP(lpZoneSend)  
  5. }  
Thats it!  Enjoy.
Read more ...»