[Release]ManualMap.cpp - Even more protection. ;)

Dark_Mage-

Member!
Joined
Dec 29, 2004
Messages
100
Reaction score
0
Website
www.realmgx.com
Unlike other methods, this will make the DLL undetectable even on injection. ;)

Code:
//         ManualMap - by Darawk - RealmGX.com
//
//   The purpose of ManualMap is to "manually map" a dll
//   module into a remote process's address space.  This
//   means that instead of just manipulating the remote
//   process into calling the LoadLibrary function, we
//   have our own emulation of what LoadLibrary does
//   without all those annoying detectability issues ^^.
//   The advantage of this method over using something
//   like my CloakDll function, is that this method never
//   has to call a function like LoadLibrary inside the
//   remote process.  Since LoadLibrary can be hooked,
//   the dll   could still be caught at the injection stage.
//   Or possibly also through the weakness I discussed in
//   the comment header of that file, which is not present
//   when using this technique.
#include <windows.h>
#include <tlhelp32.h>
#include <shlwapi.h>

#pragma comment(lib, "shlwapi.lib")

#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5

//   Pietrek's macro
//
//   MakePtr is a macro that allows you to easily add to values (including
//   pointers) together without dealing with C's pointer arithmetic.  It
//   essentially treats the last two parameters as DWORDs.  The first
//   parameter is used to typecast the result to the appropriate pointer type.
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))

//   This one is mine, but obviously..."adapted" from matt's original idea =p
#define MakeDelta(cast, x, y) (cast) ( (DWORD_PTR)(x) - (DWORD_PTR)(y))

bool MapRemoteModule(unsigned long, char *);

unsigned long GetProcessIdByName(char *);
HMODULE GetRemoteModuleHandle(unsigned long, char *);
FARPROC GetRemoteProcAddress(unsigned long, char *, char *);

bool FixImports(unsigned long, void *, IMAGE_NT_HEADERS *, IMAGE_IMPORT_DESCRIPTOR *);
bool FixRelocs(void *, void *, IMAGE_NT_HEADERS *, IMAGE_BASE_RELOCATION *, unsigned int);
bool MapSections(HANDLE, void *, void *, IMAGE_NT_HEADERS *);

PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD, PIMAGE_NT_HEADERS);
LPVOID GetPtrFromRVA(DWORD, PIMAGE_NT_HEADERS, PBYTE);

//   Stub that calls the Dll from within the remote process.
//   This is necessary because a DllMain function takes 3
//   arguments, and CreateRemoteThread can pass only 1.
__declspec(naked) void DllCall_stub(HMODULE hMod)
{
   _asm
   {
      push 0
      push 1
      push [esp+0Ch]      //   Pointer to the hMod argument
        mov eax, 0xDEADBEEF   //   Patch this in with the real value at run-time

      call eax         //   MSVC++ doesn't like direct absolute calls, so we have to be
                     //   clever about it.

      ret               //   Don't have to clean up the stack because the calling function
                     //   is just going to call ExitThread() immediately after this
                     //   function returns.
   }
}

//   Marker for the end of the DllCall_stub function
__declspec(naked) void DC_stubend(void) { }   

int main(int argc, char **argv)
{
   //   Just my test values...Cmdline.dll is a plugin that comes with
   //   Olly Debug 1.10
   MapRemoteModule(GetProcessIdByName("notepad.exe"), "Cmdline.dll");
   return 0;
}

bool MapRemoteModule(unsigned long pId, char *module)
{
   IMAGE_DOS_HEADER *dosHd;
   IMAGE_NT_HEADERS *ntHd;

   HANDLE hFile = CreateFile(module,
      GENERIC_READ,
      FILE_SHARE_READ | FILE_SHARE_WRITE,
      NULL,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      NULL);

   if(hFile == INVALID_HANDLE_VALUE)
      return false;

   unsigned int fSize;

   if(GetFileAttributes(module) & FILE_ATTRIBUTE_COMPRESSED)
      fSize = GetCompressedFileSize(module, NULL);
   else
      fSize = GetFileSize(hFile, NULL);

   unsigned char *dllBin = new unsigned char[fSize];
   unsigned int nBytes;

   ReadFile(hFile, dllBin, fSize, (LPDWORD)&nBytes, FALSE);
   CloseHandle(hFile);

   //   Every PE file contains a little DOS stub for backwards compatibility
   //   it's only real relevance is that it contains a pointer to the actual
   //   PE header.
   dosHd = MakePtr(IMAGE_DOS_HEADER *, dllBin, 0);

   //   Make sure we got a valid DOS header
   if(dosHd->e_magic != IMAGE_DOS_SIGNATURE)
   {
      delete dllBin;
      return false;
   }

   //   Get the real PE header from the DOS stub header
   ntHd = MakePtr(IMAGE_NT_HEADERS *, dllBin, dosHd->e_lfanew);

   //   Verify the PE header
   if(ntHd->Signature != IMAGE_NT_SIGNATURE)
   {
      delete dllBin;
      return false;
   }

   HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);

   if(!hProcess)
      return false;

   //   Allocate space for the module in the remote process
   void *moduleBase = VirtualAllocEx(hProcess,
      NULL,
      ntHd->OptionalHeader.SizeOfImage,
      MEM_COMMIT | MEM_RESERVE,
      PAGE_EXECUTE_READWRITE);

   //   Make sure we got the memory space we wanted
   if(!moduleBase)
      return false;

   //   Allocate space for our stub
   void *stubBase = VirtualAllocEx(hProcess,
      NULL,
      MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      MEM_COMMIT | MEM_RESERVE,
      PAGE_EXECUTE_READWRITE);

   //   Make sure we got the memory space we wanted
   if(!stubBase)
      return false;

   //   Fix up the import table of the new module
   IMAGE_IMPORT_DESCRIPTOR *impDesc = (IMAGE_IMPORT_DESCRIPTOR *)GetPtrFromRVA(
      (DWORD)(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress),
      ntHd,
      (PBYTE)dllBin);

   if(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
      FixImports(pId,
         (unsigned char *)dllBin,
         ntHd,
         impDesc);
   
   //   Fix "base relocations" of the new module.  Base relocations are places
   //   in the module that use absolute addresses to reference data.  Since
   //   the base address of the module can be different at different times,
   //   the base relocation data is necessary to make the module loadable
   //   at any address.
   IMAGE_BASE_RELOCATION *reloc = (IMAGE_BASE_RELOCATION *)GetPtrFromRVA(
      (DWORD)(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),
      ntHd,
      (PBYTE)dllBin);

   if(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
      FixRelocs(dllBin,
         moduleBase,
         ntHd,
         reloc,
         ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

   //   Write the PE header into the remote process's memory space
   WriteProcessMemory(hProcess,
      moduleBase,
      dllBin,
      ntHd->FileHeader.SizeOfOptionalHeader + sizeof(ntHd->FileHeader) + sizeof(ntHd->Signature),
      (SIZE_T *)&nBytes);

   //   Map the sections into the remote process(they need to be aligned
   //   along their virtual addresses)
   MapSections(hProcess, moduleBase, dllBin, ntHd);
   
   //   Change the page protection on the DllCall_stub function from PAGE_EXECUTE_READ
   //   to PAGE_EXECUTE_READWRITE, so we can patch it.
   VirtualProtect((LPVOID)DllCall_stub,
      MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      PAGE_EXECUTE_READWRITE,
      (DWORD *)&nBytes);

   //   Patch the stub so it calls the correct address
   *MakePtr(unsigned long *, DllCall_stub, 9) =
      MakePtr(unsigned long, moduleBase, ntHd->OptionalHeader.AddressOfEntryPoint);


   //   Write the stub into the remote process
   WriteProcessMemory(hProcess,
      stubBase,
      (LPVOID)DllCall_stub,
      MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      (SIZE_T *)&nBytes);

   //   Execute our stub in the remote process
   CreateRemoteThread(hProcess,
      NULL,
      0,
      (LPTHREAD_START_ROUTINE)stubBase,
      moduleBase,      //   Pass the base address of the module as the argument to the stub.
                  //   All a module handle is, is the base address of the module(except
                  //   in windows CE), so we're really passing a handle to the module
                  //   so that it can refer to itself, create dialogs, etc..
      0,
      NULL);

   delete dllBin;
   return true;
}

bool MapSections(HANDLE hProcess, void *moduleBase, void *dllBin, IMAGE_NT_HEADERS *ntHd)
{
   IMAGE_SECTION_HEADER *header = IMAGE_FIRST_SECTION(ntHd);
   unsigned int nBytes = 0;
   unsigned int virtualSize = 0;
   unsigned int n = 0;

   //   Loop through the list of sections
   for(unsigned int i = 0; ntHd->FileHeader.NumberOfSections; i++)
   {
      //   Once we've reached the SizeOfImage, the rest of the sections
      //   don't need to be mapped, if there are any.
      if(nBytes >= ntHd->OptionalHeader.SizeOfImage)
         break;
      
      WriteProcessMemory(hProcess,
         MakePtr(LPVOID, moduleBase, header->VirtualAddress),
         MakePtr(LPCVOID, dllBin, header->PointerToRawData),
         header->SizeOfRawData,
         (LPDWORD)&n);

      virtualSize = header->VirtualAddress;
      header++;
      virtualSize = header->VirtualAddress - virtualSize;
      nBytes += virtualSize;

      //   Set the proper page protections for this section.
      //   This really could be skipped, but it's not that
      //   hard to implement and it makes it more like a
      //   real loader.
      VirtualProtectEx(hProcess,
         MakePtr(LPVOID, moduleBase, header->VirtualAddress),
         virtualSize,
         header->Characteristics & 0x00FFFFFF,
         NULL);
   }

   return true;
}

bool FixImports(unsigned long pId, void *base, IMAGE_NT_HEADERS *ntHd, IMAGE_IMPORT_DESCRIPTOR *impDesc)
{
   char *module;

   //   Loop through all the required modules
   while((module = (char *)GetPtrFromRVA((DWORD)(impDesc->Name), ntHd, (PBYTE)base)))
   {
      //   If the library is already loaded(like kernel32.dll or ntdll.dll) LoadLibrary will
      //   just return the handle to that module.
        HMODULE localMod = LoadLibrary(module);

      //   If the module isn't loaded in the remote process, we recursively call the
      //   module mapping code.  This has the added benefit of ensuring that any of
      //   the current modules dependencies will be just as invisble as this one.
      if(!GetRemoteModuleHandle(pId, module))
         MapRemoteModule(pId, module);
       
      //   Lookup the first import thunk for this module
      //   NOTE: It is possible this module could forward functions...which is something
      //   that I really should handle.  Maybe i'll add support for forwared functions
      //   a little bit later.
      IMAGE_THUNK_DATA *itd =
         (IMAGE_THUNK_DATA *)GetPtrFromRVA((DWORD)(impDesc->FirstThunk), ntHd, (PBYTE)base);

      while(itd->u1.AddressOfData)
      {
         IMAGE_IMPORT_BY_NAME *iibn;
         iibn = (IMAGE_IMPORT_BY_NAME *)GetPtrFromRVA((DWORD)(itd->u1.AddressOfData), ntHd, (PBYTE)base);

             itd->u1.Function = MakePtr(DWORD, GetRemoteProcAddress(pId,
            module,
            (char *)iibn->Name), 0);

         itd++;
      }       
      impDesc++;
   }
   
   return true;
}

bool FixRelocs(void *base, void *rBase, IMAGE_NT_HEADERS *ntHd, IMAGE_BASE_RELOCATION *reloc, unsigned int size)
{
   unsigned long ImageBase = ntHd->OptionalHeader.ImageBase;
   unsigned int nBytes = 0;

   unsigned long delta = MakeDelta(unsigned long, rBase, ImageBase);

   while(1)
   {
      unsigned long *locBase =
         (unsigned long *)GetPtrFromRVA((DWORD)(reloc->VirtualAddress), ntHd, (PBYTE)base);
      unsigned int numRelocs = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);

      if(nBytes >= size) break;

      unsigned short *locData = MakePtr(unsigned short *, reloc, sizeof(IMAGE_BASE_RELOCATION));
      for(unsigned int i = 0; i < numRelocs; i++)
      {       
         if(((*locData >> 12) & IMAGE_REL_BASED_HIGHLOW))
             *MakePtr(unsigned long *, locBase, (*locData & 0x0FFF)) += delta;

         locData++;
      }

      nBytes += reloc->SizeOfBlock;
      reloc = (IMAGE_BASE_RELOCATION *)locData;
   }

   return true;
}


FARPROC GetRemoteProcAddress(unsigned long pId, char *module, char *func)
{
   HMODULE remoteMod = GetRemoteModuleHandle(pId, module);
   HMODULE localMod = GetModuleHandle(module);

   //   Account for potential differences in base address
   //   of modules in different processes.
   unsigned long delta = MakeDelta(unsigned long, remoteMod, localMod);
   return MakePtr(FARPROC, GetProcAddress(localMod, func), delta);
}

unsigned long GetProcessIdByName(char *process)
{
   PROCESSENTRY32 pe;
   HANDLE thSnapshot;
   BOOL retval, ProcFound = false;

   thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

   if(thSnapshot == INVALID_HANDLE_VALUE)
   {
      MessageBox(NULL, "Error: unable to create toolhelp snapshot", "Loader", NULL);
      return false;
   }

   pe.dwSize = sizeof(PROCESSENTRY32);

    retval = Process32First(thSnapshot, &pe);

   while(retval)
   {
      if(StrStrI(pe.szExeFile, process) )
      {
         ProcFound = true;
         break;
      }

      retval    = Process32Next(thSnapshot,&pe);
      pe.dwSize = sizeof(PROCESSENTRY32);
   }

   return pe.th32ProcessID;
}

HMODULE GetRemoteModuleHandle(unsigned long pId, char *module)
{
   MODULEENTRY32 modEntry;
   HANDLE tlh = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pId);

   modEntry.dwSize = sizeof(MODULEENTRY32);
    Module32First(tlh, &modEntry);

   do
   {
      if(!stricmp(modEntry.szModule, module))
         return modEntry.hModule;
      modEntry.dwSize = sizeof(MODULEENTRY32);
   }
   while(Module32Next(tlh, &modEntry));

   return NULL;
}

//   Matt Pietrek's function
PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva, PIMAGE_NT_HEADERS pNTHeader)
{
    PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
    unsigned int i;
   
    for ( i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
    {
      // This 3 line idiocy is because Watcom's linker actually sets the
      // Misc.VirtualSize field to 0.  (!!! - Retards....!!!)
      DWORD size = section->Misc.VirtualSize;
      if ( 0 == size )
         size = section->SizeOfRawData;
         
        // Is the RVA within this section?
        if ( (rva >= section->VirtualAddress) &&
             (rva < (section->VirtualAddress + size)))
            return section;
    }
   
    return 0;
}

//   This function is also Pietrek's
LPVOID GetPtrFromRVA( DWORD rva, IMAGE_NT_HEADERS *pNTHeader, PBYTE imageBase )
{
   PIMAGE_SECTION_HEADER pSectionHdr;
   INT delta;
      
   pSectionHdr = GetEnclosingSectionHeader( rva, pNTHeader );
   if ( !pSectionHdr )
      return 0;
 
   delta = (INT)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData);
   return (PVOID) ( imageBase + rva - delta );
}
 

Tupac Amaru Shakur

BattleForums Senior Member
Joined
Feb 18, 2005
Messages
1,869
Reaction score
0
Soooooo if you use this it can make ez map undetectable??
 

w00t3r

Member!
Joined
Jun 21, 2005
Messages
26
Reaction score
0
Basically he invented a new DLL injector, which doesnt really inject a DLL but rather writes it to the memory (so it is undetectable). If he would compile it, I might be able to show you.
 

binny

Member!
Joined
Apr 13, 2005
Messages
208
Reaction score
0
Location
canaDa
well played again mage.
 

chocofilez

Member!
Joined
Jun 5, 2005
Messages
760
Reaction score
0
Location
USA NY
Well, interesting, but im sure blizz has some way of dealing with this. Try letting some one else trying it before you get bann...i mean go ahead. Great idea. Im sure its fine. Dark mage, im not insulting your handiwork. Good job, im just not so sure after the last "incident" with warden and blizzs other anti hack programs.
 

fattyxp

Member!
Joined
Feb 13, 2004
Messages
221
Reaction score
0
Website
shawnjcox.sh.funpic.org
Can't use visual basic for this dumb dumb... it's C++ code. Most of this prolly can't even be done in visual basic because of it's lack of memory handling functionality.
 

_Ace

BattleForums Senior Member
Joined
May 17, 2003
Messages
1,474
Reaction score
0
Location
Under my bed (Spain)
Website
Visit site
Dragnskull said:
*waits for ace to show his face in this thread*
Rofl

Let's see, first of all, stop saying "good work darkmage" because Darawk made this, Dark-Mage- only posted it.

This method is in no way detectable unless Blizzard's antidetection system scans not only Diablo II memory, but the whole Computer memory (and I'm pretty sure they can't do that).
So basically what this does is load the dll into memory and then instead of calling the LoadDLL function inside D2 (which could be easily detected by Blizzard if they wanted to) it manipulates your memory and "emulates" that LoadDLL.
This means we have the DLL running, inside, and at the same time "outside" of Diablo II's process (the DLL can "work" inside D2 but D2 can't find the DLL in its own process).

I know Darawk doesn't browse BF, but anyway, good ****ing job. I may test this when I get my damn VC++ CD back ><.

Edit: And for those who thought "Map" in "ManualMap" meant something about maphack, mapping is what this code does, maps "your" DLL into D2 without directly injecting it :eek:.

I need a coffee -.-
 

d4rk.one

Member!
Joined
Oct 23, 2003
Messages
15
Reaction score
0
Website
Visit site
Thanks to TheAids, now i sort of understand. My question is how would i use it though....do i need some sort of program or...?
 

newbiemc

Member!
Joined
Jun 10, 2005
Messages
35
Reaction score
0
How do we do this? Can someone inplement this in ezmap and release a new version?
 

Forged

Premium Member
Joined
Nov 28, 2002
Messages
5,433
Reaction score
0
Location
Texas
Website
www.securegamers.com
Pretendo said:
why doesnt he just compile it for us damn
Because compiling it wouldn't do anything either. It is a .dll file that has to be used and called into the program that is using it. Soooo unless the hack maker used it in his program it really wouldn't do anything for you.

of this prolly can't even be done in visual basic because of it's lack of memory handling functionality
You could do it in vb.
#Edit
after actually looking at I don't think you can. It would be extremlly hard to do to say the least.
 

w00t3r

Member!
Joined
Jun 21, 2005
Messages
26
Reaction score
0
I would like to see that. VB really has no place in hacking, it is a dead end language for noobs. No offense to the people who program in it, but it isnt for hacking.

And this is quite awesome. I just want it compiled into a lib so I can use it in mASM. Anybody have VC++ on their comp?
 

silent_trades

Member
Joined
Jul 31, 2005
Messages
7
Reaction score
0
I got vc++ but im not sure how to compile a lib (asuming dll?) I messed around with it for a little while but I couldn't get it to create a dll file.
I only took a semester of very basic c++ and java so far, so I'm still a noob when it comes to programing. Just let me know how to do this and I will compile it. and is there anyway to make loader undetectable? cuz i realy need the multiclient...
 

Mongyu

Member!
Joined
Aug 16, 2005
Messages
98
Reaction score
0
Location
California
Website
www.Myspace.Com
Who ever makes the new Maphack will be like the famous hack of 1.1.. Hopes somebody comes up with it.. ****ing tired of buying 20 pots just for 1 run..
 

Forged

Premium Member
Joined
Nov 28, 2002
Messages
5,433
Reaction score
0
Location
Texas
Website
www.securegamers.com
w00t3r said:
I would like to see that. VB really has no place in hacking, it is a dead end language for noobs. No offense to the people who program in it, but it isnt for hacking.

And this is quite awesome. I just want it compiled into a lib so I can use it in mASM. Anybody have VC++ on their comp?
I've made hacks with visual basic, for simple memory hacking it is much more practical than c++.
 

NewPosts

New threads

Top