+- +-

+-User

Welcome, Guest.
Please login or register.
 
 
 
Forgot your password?

+-Stats

Members
Total Members: 130
Latest: REEG
New This Month: 1
New This Week: 0
New Today: 0
Stats
Total Posts: 319
Total Topics: 160
Most Online Today: 2
Most Online Ever: 159
(June 29, 2021, 10:20:55 pm)
Users Online
Members: 0
Guests: 1
Total: 1

Author Topic: ManuelMap Injection-- CreateThreadProblem  (Read 422 times)

Pikqex

  • Newbie
  • *
  • Posts: 1
    • View Profile
ManuelMap Injection-- CreateThreadProblem
« on: May 16, 2017, 07:59:18 pm »
Hey i'm using zwclose's manuel injection method, everything is fine until CreateRemoteThread part but this part crashes on Windows 10 64 bit os, 32bit Process-32bit dll. So i've tried to use another apis to createthread. When i research i've found RtlCreateUserThread and example uses for this api(Of course one of zwclose's codecave example). I'm a good copy paster  i know problem can't fixed but just one change but i like learning something with that way and  of course  iknow i'll face with another problems whatever, here is my codes(actually zwclose's codes)
Code: [Select]
#include <windows.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <string>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <conio.h>
//#include <string.h>
using namespace std;

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

#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5

#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))
#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);

typedef struct _CLIENT_ID
{
PVOID UniqueProcess;
PVOID UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef long (*_RtlCreateUserThread)(HANDLE,
PSECURITY_DESCRIPTOR,
BOOLEAN,ULONG,
PULONG,PULONG,
PVOID,PVOID,
PHANDLE,PCLIENT_ID);

_RtlCreateUserThread RtlCreateUserThread;

   HANDLE hThd;

__declspec(naked) void DllCall_stub(HMODULE hMod)
{
   _asm
   {
      push 0
      push 1
      push [esp+0Ch]
      mov eax, 0xDEADBEEF
      call eax
      ret
   }
}

__declspec(naked) void DC_stubend(void) { }





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);

   dosHd = MakePtr(IMAGE_DOS_HEADER *, dllBin, 0);

   if(dosHd->e_magic != IMAGE_DOS_SIGNATURE)
   {
      delete dllBin;
      return false;
   }

   ntHd = MakePtr(IMAGE_NT_HEADERS *, dllBin, dosHd->e_lfanew);

   if(ntHd->Signature != IMAGE_NT_SIGNATURE)
   {

      delete dllBin;
      return false;
   }

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

   if(!hProcess)
      return false;

   void *moduleBase = VirtualAllocEx(hProcess,
      NULL,
  ntHd->OptionalHeader.SizeOfImage,
      MEM_COMMIT | MEM_RESERVE,
      PAGE_EXECUTE_READWRITE);
printf("ModuleBase: %#x\n",moduleBase);
   if(!moduleBase)
      return false;

   void *stubBase = VirtualAllocEx(hProcess,
      NULL,
  MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      MEM_COMMIT | MEM_RESERVE,
      PAGE_EXECUTE_READWRITE);
  printf("StubBase: %#x\n",stubBase);
   if(!stubBase)
      return false;

   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)
   {
       if(!FixImports(pId,
         (unsigned char *)dllBin,
         ntHd,
         impDesc)) return FALSE;

   };

   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);
   }
   else
   {
       return false;
   };

   WriteProcessMemory(hProcess,
  moduleBase,
      dllBin,
      ntHd->FileHeader.SizeOfOptionalHeader + sizeof(ntHd->FileHeader) + sizeof(ntHd->Signature),
      (SIZE_T *)&nBytes);

   MapSections(hProcess, moduleBase, dllBin, ntHd);

   VirtualProtect((LPVOID)DllCall_stub,
      MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      PAGE_EXECUTE_READWRITE,
      (DWORD *)&nBytes);

   *MakePtr(unsigned long *, DllCall_stub, 9) =
  MakePtr(unsigned long, moduleBase, ntHd->OptionalHeader.AddressOfEntryPoint);

   WriteProcessMemory(hProcess,
      stubBase,
      (LPVOID)DllCall_stub,
      MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      (SIZE_T *)&nBytes);
//printf("31");
getch();

HMODULE ntdll=LoadLibrary("ntdll.dll");
//HMODULE k32=LoadLibrary("kernel32.dll");

RtlCreateUserThread=(_RtlCreateUserThread)GetProcAddress(ntdll,"RtlCreateUserThread");


RtlCreateUserThread(hProcess,NULL,false,0,0,0,stubBase,0,&hThd,NULL);
//RtlCreateUserThread(hProcess,NULL,false,0,0,0,(PVOID)GetProcAddress(k32,"ExitProcess"),0,&hThd,&cid);
//Rtlcre
   /*
   CreateRemoteThread(hProcess,
  NULL,
  0,
  (LPTHREAD_START_ROUTINE)stubBase,
  moduleBase,
  0,
  NULL);
*/
   //delete dllBin;
   getch();
   printf("Finished..");
  // WaitForSingleObject(hThd,INFINITE);
   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;
   printf("Section Number: %#x\n",ntHd->FileHeader.NumberOfSections);
   for(unsigned int i = 0; ntHd->FileHeader.NumberOfSections; i++)
   {

  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;

      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;
   bool retfix=1;
   char tempstr[MAX_PATH]="";

   while((module = (char *)GetPtrFromRVA((DWORD)(impDesc->Name), ntHd, (PBYTE)base)))
   {

      if(!GetRemoteModuleHandle(pId, module))
      {
wsprintf(tempstr,"Module %s not load",module);
retfix=0;
         break;
         //MapRemoteModule(pId, module);
      };

      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 retfix;
}

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);

   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)
   {
      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;
}

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++ )
    {

      DWORD size = section->Misc.VirtualSize;
      if ( 0 == size )
size = section->SizeOfRawData;

        if ( (rva >= section->VirtualAddress) &&
             (rva < (section->VirtualAddress + size)))
            return section;
    }

    return 0;
}

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 );
}


// retrieves the full path and file name for our executable file
DWORD GetProcId(const char * ProcName)
{
   PROCESSENTRY32 pe;
   HANDLE thSnapShot;
   BOOL retval, ProcFound = false;

   thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   if(thSnapShot == INVALID_HANDLE_VALUE)
   {
//
  return false;
   }
   pe.dwSize = sizeof(PROCESSENTRY32);
   retval = Process32First(thSnapShot, &pe);
   while(retval)
   {
  if(StrStrI(pe.szExeFile, ProcName))
  {
return pe.th32ProcessID;
  }
  retval = Process32Next(thSnapShot, &pe);
   }
   return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{

DWORD PIDx=GetProcId("Vc.exe");
getch();
   // printf("%lu", PIDx);
MapRemoteModule(GetCurrentProcessId(), "Project2.dll");



return 0;
}
My test dll gives me msgbox when in dll main "DLL loaded",  and it needs to give me msgbox again when dll deatached but it doesn't give me "DLL unloaded" message. It gives me just "DLL loaded" Message on createthread. I've tried to inject same dll to same exe with Xenos manuelmap injector it gives two msgbox(Loaded/Unloaded) so that means i'm wrong..
« Last Edit: May 16, 2017, 08:06:22 pm by Pikqex »

Share on Facebook Share on Twitter


xchg

  • Administrator
  • Newbie
  • *****
  • Posts: 35
    • View Profile
Re: ManuelMap Injection-- CreateThreadProblem
« Reply #1 on: May 17, 2017, 01:04:55 pm »
Hey i'm using zwclose's manuel injection method, everything is fine until CreateRemoteThread part but this part crashes on Windows 10 64 bit os, 32bit Process-32bit dll. So i've tried to use another apis to createthread. When i research i've found RtlCreateUserThread and example uses for this api(Of course one of zwclose's codecave example). I'm a good copy paster  i know problem can't fixed but just one change but i like learning something with that way and  of course  iknow i'll face with another problems whatever, here is my codes(actually zwclose's codes)

My test dll gives me msgbox when in dll main "DLL loaded",  and it needs to give me msgbox again when dll deatached but it doesn't give me "DLL unloaded" message. It gives me just "DLL loaded" Message on createthread. I've tried to inject same dll to same exe with Xenos manuelmap injector it gives two msgbox(Loaded/Unloaded) so that means i'm wrong..

At first glance the code looks like an odd mix of Darawk's Manual Mapping code:
https://github.com/LiamKarlMitchell/InfiniteSky/blob/master/TSX_Client/PrivateServerLauncher/ManualMapDLLInject.h

At a closer look it appears as though it's a complete skid of Darawk's manual mapping code. I don't know what part of this is supposed to resemble zwClose7's code, (per your OP) perhaps the overall method?

I'm no longer going to look through the code or give advice on where you should take it; if it's not yours, then why should I bother? Why should anyone bother? It feels less and less like you actually care on understanding the information rather than just replicating the effect.

If it so happens like you said, this is how you learn, and you do wish to reap the knowledge of such a project, perhaps I can point you in a direction that was beneficial to me in a similar project.

First and foremost, ensure your knowledge of the PE file format. Know how all of the referenced sections apply to the loading process, and finally, understand the loading process. The two usually go hand-at-hand.

Some of the resources I used for the PE file format:
https://www.youtube.com/watch?v=ls8I__h1IYE&list=PLUFkSN0XLZ-n_Na6jwqopTt1Ki57vMIc3
http://opensecuritytraining.info/LifeOfBinaries.html
https://msdn.microsoft.com/en-us/library/ms809762.aspx
http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf
https://www.curlybrace.com/archive/PE%20File%20Structure.pdf

Couldn't live without CFF:
http://www.ntcore.com/exsuite.php

Look into de/compressors, preferably with well-commented code. Cut through the noise, and examine the programs conclusion (epilogue?) functions. Most compressors end up executing the compressed PE file post decompression.

Some other sources that come to mind:
http://www.cultdeadcow.com/tools/pewrap.html
https://www.codeproject.com/Tips/430684/Loading-Win-DLLs-manually-without-LoadLibrary
https://github.com/thereals0beit/remoteloader-2012
https://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/

As for the unloading notifications, think about what you're actually doing.
You're loading the bare-bones portions of the module into a remote process, and creating a thread on the entry point.

DLL's aren't really meant to do much, other than to provide modular segments of code (which is typically intended for use by the host processes)[01]. Therefore, if you are to look at any sort-of decompilation of a typical DLL entry point, there really isn't anything interesting inside. The module itself will never (typically) call it's own entry point passing different parameters. Any notification back should be invoked extrinsically. The fact that you don't receive unload notifications isn't the fault of your manual mapping code, but rather the manual mapping process in general. See the below.

From the FreeLibrary (WinAPI function) documentation:
"Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value."[00]

Your confusion in regards to Xenos is understandable. I myself had to test this out to ensure the theory above stood up; and out of fear that Xenos had implemented a method to notify manually mapped modules of (either process or thread) detachment, the logic stood up. When compared with at test DLL created specifically for this purpose injected using 'Native Inject', I received all standard notifications including DLL_PROCESS_DETACH upon killing the host process.

However, when specifically selecting the manual mapping method, I only ever received the DLL_PROCESS_ATTACH notification. This leads me to believe that perhaps you did not specifically select 'Manual Map' in the drop-down list of injection methods, for whatever reason.

Hope this was of use to you.

Citations:
[00] https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152(v=vs.85).aspx
[01] https://support.microsoft.com/en-us/help/815065/what-is-a-dll

 

+-Recent Topics

Independent Call Girls in Chandigarh by dilpreetkaur
June 21, 2021, 01:02:52 pm

Hi zwclose7. How to create process by using NT apis? by zwclose7
June 01, 2021, 03:09:52 pm

Poison of the Day by zwclose7
March 16, 2020, 06:45:08 pm

IRC by AzeS
February 17, 2020, 08:18:01 am

Native API tutorial by hMihaiDavid
January 08, 2019, 02:11:02 am

The properties of GP nerve agent by xchg
October 19, 2018, 07:40:57 pm

A new route of synthesis for G-series agents by Basquyatti
October 15, 2018, 06:12:57 am

Synthesis of Methylisobutylcarbinylsarin (GH) by APC process by Basquyatti
October 14, 2018, 07:55:33 am

Synthesis conventional of Sarin by Basquyatti
October 02, 2018, 07:57:32 am

Reaction CX-7 (Experimental) by zwclose7
October 02, 2018, 12:46:47 am