Пример #1
0
static BOOL
PatchImports(char* name)
{
  LOADED_IMAGE image;

  if (!MapAndLoad(name, NULL, &image, FALSE, FALSE)) {
	  fprintf(stderr, "couldn't MapAndLoad '%s'\n", name);
	  return FALSE;
  }

  if (image.FileHeader->OptionalHeader.NumberOfRvaAndSizes >= 2) {
    PIMAGE_IMPORT_DESCRIPTOR importDesc =
      (PIMAGE_IMPORT_DESCRIPTOR) GetPtrFromRVA(
        image.FileHeader->OptionalHeader.DataDirectory[1].VirtualAddress,
	image.FileHeader,
	image.MappedAddress);
    while(1) {
      char *s;
      int len;

      // We've reached an empty IMAGE_IMPORT_DESCRIPTOR?
      if ((importDesc->TimeDateStamp == 0) && (importDesc->Name==0)) {
	break;
      }

      s = (char *) GetPtrFromRVA(importDesc->Name,
				 image.FileHeader,
				 image.MappedAddress);

      len = strlen(s);
      if (!strcasecmp(s, "kernel32.dll") ||
	  !strcasecmp(s, "msvcrt.dll") ||
	  !strcasecmp(s, "user32.dll") ||
	  !strcasecmp(s, "gdi32.dll") ||
	  !strcasecmp(s, "ole32.dll") ||
	  !strcasecmp(s, "advapi32.dll") ||
	  !strcasecmp(s, "comctl32.dll") ||
	  !strcasecmp(s, "ntdll.dll")) {
	printf("...patching %s ->", s);
	s[len - 5] = '_';
	printf(" %s\n", s);
      }
	  
      importDesc++;
    }
  }

  UnMapAndLoad(&image);
  return TRUE;
}
Пример #2
0
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;
}
Пример #3
0
//    Given a process ID, file pointer, NT header, and start of .idata, fix the imports
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.
        //    A neat alternative would be to load them all again.  This will help ensure
        //    we have a working copy for our own function calls which is hidden :O
        HMODULE localMod = LoadLibraryA(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 invisible as this one.
        if(!GetRemoteModuleHandle(pId, module))
            MapRemoteModule(pId, module);        
        
        // fix the time/date stamp
        impDesc->TimeDateStamp = ntHd->FileHeader.TimeDateStamp;

        //   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 forward 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;
}
Пример #4
0
LPVOID FindProcAddressByName(LPSTR ProcName, LPVOID ImageBase, PIMAGE_EXPORT_DIRECTORY ExportDirectory)
{
	LPVOID ProcAddress = NULL;
	
	printf("\n[*] Parsing Export Table...");
	printf("\n[*] Exports Name: %s", GetPtrFromRVA(ExportDirectory->Name, ImageBase));

#ifdef _DEBUG
	printf("\n[?] Ordinal Base: %d", ExportDirectory->Base);
#endif

	PDWORD AddressOfNames = (PDWORD) GetPtrFromRVA(ExportDirectory->AddressOfNames, ImageBase);
	PWORD AddressOfOrdinals = (PWORD) GetPtrFromRVA(ExportDirectory->AddressOfNameOrdinals, ImageBase);
	PDWORD AddressOfFunctions = (PDWORD) GetPtrFromRVA(ExportDirectory->AddressOfFunctions,ImageBase);

	for (DWORD i = 0; i < ExportDirectory->NumberOfFunctions; i++)
	{
		LPCSTR FunctionName = (LPCSTR) GetPtrFromRVA(AddressOfNames[i], ImageBase);
		WORD Ordinal = AddressOfOrdinals[i];
		ProcAddress = GetPtrFromRVA(AddressOfFunctions[Ordinal - ExportDirectory->Base + 1], ImageBase);
#ifdef _DEBUG
		printf("\n[?] Found Function: %s", FunctionName);
		printf("\n[?] Ordinal: %d, RVA: %08X", Ordinal, AddressOfFunctions[Ordinal]);
		printf("\n[?] Function Entry Ptr: %08X\n[?]--", ProcAddress);
#endif
		if (strcmp(ProcName,FunctionName) == 0)
		{
			printf("\n[*] Function Found @ %08X", ProcAddress);
			return ProcAddress;
		}
	}
	printf("\n[X] Function %s is not exported.");
	return NULL;
}
Пример #5
0
void DumpStringTable( 	DWORD base,
						PIMAGE_NT_HEADERS pNTHeader,
						DWORD resourceBase,
						PIMAGE_RESOURCE_DIRECTORY_ENTRY pStrResEntry,
						DWORD cStrResEntries )
{
	for ( unsigned i = 0; i < cStrResEntries; i++, pStrResEntry++ )
	{
		DWORD offsetToData
			= GetOffsetToDataFromResEntry( base, resourceBase, pStrResEntry );
			
 		PWORD pStrEntry = (PWORD)GetPtrFromRVA(	offsetToData,
												pNTHeader, base );
		if ( !pStrEntry)
			break;
		
		unsigned id = (pStrResEntry->Name - 1) << 4;

		for ( unsigned j = 0; j < 16; j++ )
		{
			WORD len = *pStrEntry++;
			if ( len )
			{
				printf( "%-5u: ", id + j );

				for ( unsigned k = 0; k < min(len, (WORD)64); k++ )
				{
					char * s;
					char szBuff[20];
					char c = (char)pStrEntry[k];
					switch( c )
					{
						case '\t': s = "\\t"; break;
						case '\r': s = "\\r"; break;
						case '\n': s = "\\n"; break;
						default:
							wsprintf( szBuff, "%c", isprint(c) ? c : '.' );
							s=szBuff;
							break;
					}

					printf( s );
				}

				printf( "\n" );
			}

			pStrEntry += len;
		}
	}
}
Пример #6
0
CPEFile::operator PIMAGE_COR20_HEADER() const
{
  if (!m_pBase) return NULL;

  DWORD dwRVA;

  if (m_bIs64Bit)
    dwRVA = ((PIMAGE_NT_HEADERS64)m_pNTHeader)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
  else
    dwRVA = m_pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
  if (!dwRVA)
  {
    return NULL;
  }

  return ((PIMAGE_COR20_HEADER)GetPtrFromRVA(dwRVA));
}
Пример #7
0
//
// Top level routine called to dump out the entire resource hierarchy
//
void DumpResourceSection(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
	DWORD resourcesRVA;
    PIMAGE_RESOURCE_DIRECTORY resDir;

	resourcesRVA = GetImgDirEntryRVA(pNTHeader, IMAGE_DIRECTORY_ENTRY_RESOURCE);
	if ( !resourcesRVA )
		return;

    resDir = (PIMAGE_RESOURCE_DIRECTORY)
    		GetPtrFromRVA( resourcesRVA, pNTHeader, base );

	if ( !resDir )
		return;
		
    printf("Resources (RVA: %X)\n", resourcesRVA );

    DumpResourceDirectory(resDir, (DWORD)resDir, 0, 0);

	printf( "\n" );

	if ( !fShowResources )
		return;
		
	if ( cStrResEntries )
	{
		printf( "String Table\n" );

		DumpStringTable( 	base, pNTHeader, (DWORD)resDir,
							pStrResEntries, cStrResEntries );
		printf( "\n" );
	}

	if ( cDlgResEntries )
	{
		printf( "Dialogs\n" );

		DumpDialogs( 	base, pNTHeader, (DWORD)resDir,
						pDlgResEntries, cDlgResEntries );
		printf( "\n" );
	}
}
Пример #8
0
void DumpDialogs( 	DWORD base,
					PIMAGE_NT_HEADERS pNTHeader,
					DWORD resourceBase,
					PIMAGE_RESOURCE_DIRECTORY_ENTRY pDlgResEntry,
					DWORD cDlgResEntries )
{
	for ( unsigned i = 0; i < cDlgResEntries; i++, pDlgResEntry++ )
	{
		DWORD offsetToData
			= GetOffsetToDataFromResEntry( base, resourceBase, pDlgResEntry );
			
 		PDWORD pDlgStyle = (PDWORD)GetPtrFromRVA(	offsetToData,
													pNTHeader, base );
		if ( !pDlgStyle )
			break;
													
		printf( "  ====================\n" );
		if ( HIWORD(*pDlgStyle) != 0xFFFF )
		{
			//	A regular DLGTEMPLATE
			DLGTEMPLATE * pDlgTemplate = ( DLGTEMPLATE * )pDlgStyle;

			printf( "  style: %08X\n", pDlgTemplate->style );			
			printf( "  extended style: %08X\n", pDlgTemplate->dwExtendedStyle );			

			printf( "  controls: %u\n", pDlgTemplate->cdit );
			printf( "  (%u,%u) - (%u,%u)\n",
						pDlgTemplate->x, pDlgTemplate->y,
						pDlgTemplate->x + pDlgTemplate->cx,
						pDlgTemplate->y + pDlgTemplate->cy );
			PWORD pMenu = (PWORD)(pDlgTemplate + 1);	// ptr math!

			//
			// First comes the menu
			//
			if ( *pMenu )
			{
				if ( 0xFFFF == *pMenu )
				{
					pMenu++;
					printf( "  ordinal menu: %u\n", *pMenu );
				}
				else
				{
					printf( "  menu: " );
					while ( *pMenu )
						printf( "%c", LOBYTE(*pMenu++) );				

					pMenu++;
					printf( "\n" );
				}
			}
			else
				pMenu++;	// Advance past the menu name

			//
			// Next comes the class
			//			
			PWORD pClass = pMenu;
						
			if ( *pClass )
			{
				if ( 0xFFFF == *pClass )
				{
					pClass++;
					printf( "  ordinal class: %u\n", *pClass );
				}
				else
				{
					printf( "  class: " );
					while ( *pClass )
					{
						printf( "%c", LOBYTE(*pClass++) );				
					}		
					pClass++;
					printf( "\n" );
				}
			}
			else
				pClass++;	// Advance past the class name
			
			//
			// Finally comes the title
			//

			PWORD pTitle = pClass;
			if ( *pTitle )
			{
				printf( "  title: " );

				while ( *pTitle )
					printf( "%c", LOBYTE(*pTitle++) );
					
				pTitle++;
			}
			else
				pTitle++;	// Advance past the Title name

			printf( "\n" );

			PWORD pFont = pTitle;
						
			if ( pDlgTemplate->style & DS_SETFONT )
			{
				printf( "  Font: %u point ",  *pFont++ );
				while ( *pFont )
					printf( "%c", LOBYTE(*pFont++) );

				pFont++;
				printf( "\n" );
			}
	        else
    	        pFont = pTitle; 

			// DLGITEMPLATE starts on a 4 byte boundary
			LPDLGITEMTEMPLATE pDlgItemTemplate = (LPDLGITEMTEMPLATE)pFont;
			
			for ( unsigned i=0; i < pDlgTemplate->cdit; i++ )
			{
				// Control item header....
				pDlgItemTemplate = (DLGITEMTEMPLATE *)
									(((DWORD)pDlgItemTemplate+3) & ~3);
				
				printf( "    style: %08X\n", pDlgItemTemplate->style );			
				printf( "    extended style: %08X\n",
						pDlgItemTemplate->dwExtendedStyle );			

				printf( "    (%u,%u) - (%u,%u)\n",
							pDlgItemTemplate->x, pDlgItemTemplate->y,
							pDlgItemTemplate->x + pDlgItemTemplate->cx,
							pDlgItemTemplate->y + pDlgItemTemplate->cy );
				printf( "    id: %u\n", pDlgItemTemplate->id );
				
				//
				// Next comes the control's class name or ID
				//			
				PWORD pClass = (PWORD)(pDlgItemTemplate + 1);
				if ( *pClass )
				{							
					if ( 0xFFFF == *pClass )
					{
						pClass++;
						printf( "    ordinal class: %u", *pClass++ );
					}
					else
					{
						printf( "    class: " );
						while ( *pClass )
							printf( "%c", LOBYTE(*pClass++) );

						pClass++;
						printf( "\n" );
					}
				}
				else
					pClass++;
					
				printf( "\n" );			

				//
				// next comes the title
				//

				PWORD pTitle = pClass;
				
				if ( *pTitle )
				{
					printf( "    title: " );
					if ( 0xFFFF == *pTitle )
					{
						pTitle++;
						printf( "%u\n", *pTitle++ );
					}
					else
					{
						while ( *pTitle )
							printf( "%c", LOBYTE(*pTitle++) );
						pTitle++;
						printf( "\n" );
					}
				}
				else	
					pTitle++;	// Advance past the Title name

				printf( "\n" );
				
				PBYTE pCreationData = (PBYTE)(((DWORD)pTitle + 1) & 0xFFFFFFFE);
				
				if ( *pCreationData )
					pCreationData += *pCreationData;
				else
					pCreationData++;

				pDlgItemTemplate = (DLGITEMTEMPLATE *)pCreationData;	
				
				printf( "\n" );
			}
			
			printf( "\n" );
		}
		else
		{
			// A DLGTEMPLATEEX		
		}
		
		printf( "\n" );
	}
}
Пример #9
0
////////////////////////////////////////////////////////////////////////////////////////////
// MapRemoteModuleW
////////////////////////////////////////////////////////////////////////////////////////////
BOOL
MapRemoteModuleW(
        DWORD dwProcessId,
        LPCWSTR lpModulePath
        )
{
        BOOL bRet = FALSE;
        HANDLE hFile = 0;
        DWORD fileSize = 0;
        BYTE *dllBin = 0;
        PIMAGE_NT_HEADERS nt_header = 0;
        PIMAGE_DOS_HEADER dos_header = 0;
        HANDLE hProcess = 0;
        LPVOID lpModuleBase = 0;
 
        PIMAGE_IMPORT_DESCRIPTOR pImgImpDesc = 0;
        PIMAGE_BASE_RELOCATION pImgBaseReloc = 0;
        PIMAGE_TLS_DIRECTORY pImgTlsDir = 0;
 
        __try
        {
                // Get a handle for the target process.
                hProcess = OpenProcess(
                        PROCESS_QUERY_INFORMATION       |       // Required by Alpha
                        PROCESS_CREATE_THREAD           |       // For CreateRemoteThread
                        PROCESS_VM_OPERATION            |       // For VirtualAllocEx/VirtualFreeEx
                        PROCESS_VM_WRITE                |       // For WriteProcessMemory
                        PROCESS_VM_READ,
                        FALSE,
                        dwProcessId);
                if(!hProcess)
                {
                        PRINT_ERROR_MSGA("Could not get handle to process (PID: 0x%X).", dwProcessId);
                        __leave;
                }
 
                hFile = CreateFileW(
                        lpModulePath,
                        GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL);
                if(hFile == INVALID_HANDLE_VALUE)
                {
                        PRINT_ERROR_MSGA("CreateFileW failed.");
                        __leave;
                }
 
                if(GetFileAttributesW(lpModulePath) & FILE_ATTRIBUTE_COMPRESSED)
                {
                        fileSize = GetCompressedFileSizeW(lpModulePath, NULL);
                }
                else
                {
                        fileSize = GetFileSize(hFile, NULL);
                }
 
                if(fileSize == INVALID_FILE_SIZE)
                {
                        PRINT_ERROR_MSGA("Could not get size of file.");
                        __leave;
                }
 
                dllBin = (BYTE*)malloc(fileSize);
 
                {
                        DWORD NumBytesRead = 0;
                        if(!ReadFile(hFile, dllBin, fileSize, &NumBytesRead, FALSE))
                        {
                                PRINT_ERROR_MSGA("ReadFile failed.");
                        }
                }
       
                dos_header = (PIMAGE_DOS_HEADER)dllBin;
               
                // Make sure we got a valid DOS header
                if(dos_header->e_magic != IMAGE_DOS_SIGNATURE)
                {
                        PRINT_ERROR_MSGA("Invalid DOS header.");
                        __leave;
                }
               
                // Get the real PE header from the DOS stub header
                nt_header = (PIMAGE_NT_HEADERS)( (DWORD_PTR)dllBin +
                        dos_header->e_lfanew);
 
                // Verify the PE header
                if(nt_header->Signature != IMAGE_NT_SIGNATURE)
                {
                        PRINT_ERROR_MSGA("Invalid PE header.");
                        __leave;
                }
 
                // Allocate space for the module in the remote process
                lpModuleBase = VirtualAllocEx(
                        hProcess,
                        NULL,
                        nt_header->OptionalHeader.SizeOfImage,
                        MEM_COMMIT | MEM_RESERVE,
                        PAGE_EXECUTE_READWRITE);
                if(!lpModuleBase)
                {
                        PRINT_ERROR_MSGA("Could not allocate memory in remote process.");
                        __leave;
                }
               
                // fix imports
                pImgImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)GetPtrFromRVA(
                        nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
                        nt_header,
                        (PBYTE)dllBin);
                if(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
                {
                        if(!FixIAT(dwProcessId, hProcess, (PBYTE)dllBin, nt_header, pImgImpDesc))
                        {
                                PRINT_ERROR_MSGA("@Fixing imports.");
                                __leave;
                        }
                }
               
                // fix relocs
                pImgBaseReloc = (PIMAGE_BASE_RELOCATION)GetPtrFromRVA(
                        (DWORD)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),
                        nt_header,
                        (PBYTE)dllBin);
                if(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
                {
                        if(!FixRelocations(dllBin, lpModuleBase, nt_header, pImgBaseReloc))
                        {
                                PRINT_ERROR_MSGA("@Fixing relocations.");
                                __leave;
                        }
                }
 
                // Write the PE header into the remote process's memory space
                {
                        SIZE_T NumBytesWritten = 0;
                        SIZE_T nSize = nt_header->FileHeader.SizeOfOptionalHeader +
                                sizeof(nt_header->FileHeader) +
                                sizeof(nt_header->Signature);
                       
                        if(!WriteProcessMemory(hProcess, lpModuleBase, dllBin, nSize, &NumBytesWritten) ||
                                NumBytesWritten != nSize)
                        {
                                PRINT_ERROR_MSGA("Could not write to memory in remote process.");
                                __leave;
                        }
                }
 
                // Map the sections into the remote process(they need to be aligned
                // along their virtual addresses)
                if(!MapSections(hProcess, lpModuleBase, dllBin, nt_header))
                {
                        PRINT_ERROR_MSGA("@Map sections.");
                        __leave;
                }
 
                // call all tls callbacks
                //
                pImgTlsDir = (PIMAGE_TLS_DIRECTORY)GetPtrFromRVA(
                        nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress,
                        nt_header,
                        (PBYTE)dllBin);
                if(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size)
                {
                        if(!CallTlsInitializers(dllBin, nt_header, hProcess, (HMODULE)lpModuleBase, DLL_PROCESS_ATTACH, pImgTlsDir))
                        {
                                PRINT_ERROR_MSGA("@Call TLS initializers.");
                                __leave;
                        }
                }
 
                // call entry point
                if(!RemoteDllMainCall(
                        hProcess,
                        (LPVOID)( (DWORD_PTR)lpModuleBase + nt_header->OptionalHeader.AddressOfEntryPoint),
                        (HMODULE)lpModuleBase, 1, 0))
                {
                        PRINT_ERROR_MSGA("@Call DllMain.");
                        __leave;
                }
 
                bRet = TRUE;
 
                wprintf(L"Successfully injected (%s | PID: %x):\n\n"
                        L"  AllocationBase:\t0x%p\n"
                        L"  EntryPoint:\t\t0x%p\n"
                        L"  SizeOfImage:\t\t0x%p\n"
                        L"  CheckSum:\t\t0x%p\n",
                        lpModulePath,
                        dwProcessId,
                        lpModuleBase,
                        (DWORD_PTR)lpModuleBase + nt_header->OptionalHeader.AddressOfEntryPoint,
                        nt_header->OptionalHeader.SizeOfImage,
                        nt_header->OptionalHeader.CheckSum);
        }
        __finally
        {
                if(hFile)
                {
                        CloseHandle(hFile);
                }
 
                if(dllBin)
                {
                        free(dllBin);
                }
 
                if(hProcess)
                {
                        CloseHandle(hProcess);
                }
        }
       
        return bRet;
}
Пример #10
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;
	  printf("invalid dos header\n");
      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;
	  printf("invalid nt header\n");
      return false;
   }

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

   if(!hProcess)
   {
	   printf("open process failed\n");
      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)
   {
	   printf("virtual alloc failed (moduleBase)\n");
      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)
   {
	   printf("virtual alloc failed(stubBase)\n");
      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;
}
Пример #11
0
bool MapRemoteModule(unsigned long pId, const char *module)
{
   IMAGE_DOS_HEADER *dosHd;
   IMAGE_NT_HEADERS *ntHd;
   IMAGE_NT_HEADERS64 *ntHd64 = NULL;

   HANDLE hFile = CreateFileA(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(GetFileAttributesA(module) & FILE_ATTRIBUTE_COMPRESSED)
      fSize = GetCompressedFileSizeA(module, NULL);
   else
      fSize = GetFileSize(hFile, NULL);

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

   // copy into our dllBin buffer the entire DLL
   ReadFile(hFile, dllBin, fSize, (LPDWORD)&nBytes, FALSE);
   CloseHandle(hFile);

   //   Every PE file contains a little DOS stub for backwards compatibility
   //   its 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)
   {
       wxMessageBox( _("The DOS header was invalid"), 
           _("Error:  Invalid DOS header"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   //   Get the real PE header from the DOS stub header
   //   This header contains pointers to the Optional Header and the 
   //   COFF File Header.
   ntHd = MakePtr(IMAGE_NT_HEADERS *, dllBin, dosHd->e_lfanew);

   //   Verify that the PE header is PE00
   if(ntHd->Signature != IMAGE_NT_SIGNATURE)
   {
       wxMessageBox( _("The PE Header was not found."), 
           _("Error:  PE Header not found"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   //   Verify that the image file is a DLL
   if( (ntHd->FileHeader.Characteristics & IMAGE_FILE_DLL) == false )
   {
       wxMessageBox( _("You may only inject DLL image files."), 
           _("Error:  Injected image file was not a DLL"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   // Open the target process
   HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);

   // We failed to open the process, so return false
   if(!hProcess)
   {
       wxMessageBox( _("Failed to open target process."), 
           _("Error:  Failed to open process"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   //   Determine whether the image is a PE32 or PE32+ executable
   if( ntHd->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC )
   {
        if( ntHd->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC )
        {
            ntHd64 = (IMAGE_NT_HEADERS64 *)ntHd;
            wxMessageBox( _("Image is a PE32+ executable.\nInjector Gadget doesn't support PE32+ executables yet."),
                _("Error:  Image is not a PE32 executable"),
                wxICON_ERROR );
        }
        else if( ntHd->OptionalHeader.Magic == IMAGE_ROM_OPTIONAL_HDR_MAGIC )
        {
            wxMessageBox( _("Image is a ROM image.\nInjector Gadget doesn't support ROM images."),
                _("Error:  Image is not a PE32 executable"),
                wxICON_ERROR );
        }
        delete [] dllBin;
        return false;
   }

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

   //   Make sure we got the memory space we wanted
   if(!imageBase)
   {
       delete [] dllBin;
       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)
   {
       delete [] dllBin;
       return false;
   }

   //   We now need to fix up the tables.
   //   The tables are as follows (in order):
   //   Export Table, Import Table, Resource Table, Exception Table,
   //   Certificate Table, Base Relocation Table, Debug, Architecture,
   //   Global Ptr, TLS Table, Load Config Table, Bound Import, IAT,
   //   Delay Import Descriptor, CLR Runtime Header, Reserved

   //   First important section is the Export Table.  We're going to skip this
   //   since the whole point of cloaking a DLL is to hide its presence.

   //   Second important section is the Import Table.  We really need this.
   if( ntHd->OptionalHeader.NumberOfRvaAndSizes > 1 )
   {
       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);
       else // size was 0 for the import directory entry
       {
           wxMessageBox(
               _("Size of import directory entry was 0"),
               _("Error:  Import Directory size is 0"),
               wxICON_ERROR);
           delete [] dllBin;
           return false;
       }
   }
   else // IMAGE_DIRECTORY_ENTRY_IMPORT didn't exist in the data directories
   {
       wxMessageBox( _("The import table referenced an invalid index in the data directory."),
           _("Error:  Import table could not be located"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   //   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,
         imageBase,
         ntHd,
         reloc,
         ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

   //   Write the PE header into the remote process's memory space
   WriteProcessMemory(hProcess,
      imageBase,
      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, imageBase, 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, imageBase, 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);

#ifdef __USING_DEBUGGER
   wxMessageBox(_("Calling CreateRemoteThread"));
   wxMessageBox( _("hProcess: ") + wxString::Format("%08X",hProcess) );
   wxMessageBox( _("stubBase: ") + wxString::Format("%08X",stubBase) );
   wxMessageBox( _("moduleBas: ") + wxString::Format("%08X",imageBase) );
#endif
   //   Execute our stub in the remote process
   CreateRemoteThread(hProcess,
      NULL,
      ntHd->OptionalHeader.SizeOfStackCommit,
      (LPTHREAD_START_ROUTINE)stubBase,
      imageBase,      //   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;
}
Пример #12
0
// Подменить Импортируемые функции в модуле
static bool SetHook( HMODULE Module, BOOL abExecutable )
{
    IMAGE_IMPORT_DESCRIPTOR* Import = 0;
    DWORD Size = 0;
    //HMODULE hExecutable = GetModuleHandle( 0 );
    //if( !Module )
    //    Module = hExecutable;
    //BOOL bExecutable = abExecutable;
    IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)Module;
    IMAGE_NT_HEADERS* nt_header = NULL;
    if( dos_header->e_magic == IMAGE_DOS_SIGNATURE /*'ZM'*/ )
    {
        nt_header = (IMAGE_NT_HEADERS*)((char*)Module + dos_header->e_lfanew);
        if( nt_header->Signature != 0x004550 )
            return false;
        else
        {
            Import = (IMAGE_IMPORT_DESCRIPTOR*)((char*)Module +
                                         (DWORD)(nt_header->OptionalHeader.
                                         DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
                                         VirtualAddress));
            Size = nt_header->OptionalHeader.
                                         DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
        }
    }
    else
        return false;

    // if wrong module or no import table
    if( Module == INVALID_HANDLE_VALUE || !Import )
        return false;

#ifdef _DEBUG
	PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(nt_header);
#endif

	#ifdef _WIN64
	_ASSERTE(sizeof(DWORD_PTR)==8);
	#else
	_ASSERTE(sizeof(DWORD_PTR)==4);
	#endif

	#ifdef _WIN64
		#define TOP_SHIFT 60
	#else
		#define TOP_SHIFT 28
	#endif

	TODO("!!! Сохранять ORDINAL процедур !!!");

    bool res = false, bHooked = false;
	int i;
	int nCount = Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
	//_ASSERTE(Size == (nCount * sizeof(IMAGE_IMPORT_DESCRIPTOR))); -- ровно быть не обязано
    for( i = 0; i < nCount; i++ )
    {
		if (Import[i].Name == 0)
			break;
        //DebugString( ToTchar( (char*)Module + Import[i].Name ) );
		//#ifdef _DEBUG
		char* mod_name = (char*)Module + Import[i].Name;
		//#endif

		DWORD_PTR rvaINT = Import[i].OriginalFirstThunk;
		DWORD_PTR rvaIAT = Import[i].FirstThunk;
		if ( rvaINT == 0 )   // No Characteristics field?
		{
			// Yes! Gotta have a non-zero FirstThunk field then.
			rvaINT = rvaIAT;
			if ( rvaINT == 0 ) {  // No FirstThunk field?  Ooops!!!
				_ASSERTE(rvaINT!=0);
				break;
			}
		}

		//PIMAGE_IMPORT_BY_NAME pOrdinalName = NULL, pOrdinalNameO = NULL;
		//PIMAGE_IMPORT_BY_NAME pOrdinalNameO = NULL;
		//IMAGE_IMPORT_BY_NAME** byname = (IMAGE_IMPORT_BY_NAME**)((char*)Module + rvaINT);
        //IMAGE_THUNK_DATA* thunk = (IMAGE_THUNK_DATA*)((char*)Module + rvaIAT);
		IMAGE_THUNK_DATA* thunk = (IMAGE_THUNK_DATA*)GetPtrFromRVA( rvaIAT, nt_header, (PBYTE)Module );
		IMAGE_THUNK_DATA* thunkO = (IMAGE_THUNK_DATA*)GetPtrFromRVA( rvaINT, nt_header, (PBYTE)Module );
		if (!thunk ||  !thunkO) {
			_ASSERTE(thunk && thunkO);
			continue;
		}

		int f = 0;
        for(f = 0 ; thunk->u1.Function; thunk++, thunkO++, f++)
        {
			//const char* pszFuncName = NULL;
			WORD ordinalO = -1;

			if (thunk->u1.Function!=thunkO->u1.Function)
			{
				PWORD pOrdinal = (PWORD)GetPtrFromRVA(thunkO->u1.Ordinal, nt_header, (PBYTE)Module);
				if (pOrdinal)
					ordinalO = *pOrdinal;

				//if ( IMAGE_SNAP_BY_ORDINAL(thunkO->u1.Ordinal) ) {
				//	ordinalO = IMAGE_ORDINAL(thunkO->u1.Ordinal);
				//	pOrdinalNameO = NULL;
				//}
				//TODO("Возможно стоит искать имя функции не только для EXE, но и для всех dll");
				//if (bExecutable) {
				//	if (!IMAGE_SNAP_BY_ORDINAL(thunkO->u1.Ordinal)) {
				//		pOrdinalNameO = (PIMAGE_IMPORT_BY_NAME)GetPtrFromRVA(thunkO->u1.AddressOfData, nt_header, (PBYTE)Module);
				//		BOOL lbValidPtr = !IsBadReadPtr(pOrdinalNameO, sizeof(IMAGE_IMPORT_BY_NAME));
				//		_ASSERTE(lbValidPtr);
				//		if (lbValidPtr) {
				//			lbValidPtr = !IsBadStringPtrA((LPCSTR)pOrdinalNameO->Name, 10);
				//			_ASSERTE(lbValidPtr);
				//			if (lbValidPtr)
				//				pszFuncName = (LPCSTR)pOrdinalNameO->Name;
				//		}
				//	}
				//}
			}

			int j = 0;
			for( j = 0; Hooks[j].Name; j++ )
			{
				//if (Hooks[j].NewAddress == (void*)thunk->u1.Function) {
				//	res = true; // это уже захучено
				//	break;
				//}
				//WARNING("??? сомнение в этом условии");
                //if( !Hooks[j].OldAddress || (void*)thunk->u1.Function != Hooks[j].OldAddress )
				//{
				//	if (!pszFuncName || !bExecutable) {
				//		continue;
				//	} else {
				//		if (strcmp(pszFuncName, Hooks[j].Name))
				//			continue;
				//	}
				//	// OldAddress уже может отличаться от оригинального экспорта библиотеки
				//	// Это происходит например с PeekConsoleIntputW при наличии плагина Anamorphosis
				//	Hooks[j].ExeOldAddress = (void*)thunk->u1.Function;
				//}
				//if (Hooks[j].nOrdinal == 0 && ordinalO != (ULONGLONG)-1)
				//	Hooks[j].nOrdinal = (DWORD)ordinalO;

				if (Hooks[j].nOrdinal != ordinalO || !cmpmod(mod_name,Hooks[j].DllName))
				{
					continue;
				}
				if (Hooks[j].NewAddress == (void*)thunk->u1.Function) {
					res = true; // это уже захучено
					break;
				}


				bHooked = true;
				DWORD old_protect = 0;
				VirtualProtect( &thunk->u1.Function, sizeof( thunk->u1.Function ),
					PAGE_READWRITE, &old_protect );
				thunk->u1.Function = (DWORD_PTR)Hooks[j].NewAddress;
				VirtualProtect( &thunk->u1.Function, sizeof( DWORD ), old_protect, &old_protect );
				#ifdef _DEBUG
				if (bExecutable)
					Hooks[j].ReplacedInExe = TRUE;
				#endif
				//DebugString( ToTchar( Hooks[j].Name ) );
				res = true;
				break;
			}
        }
    }

//#ifdef _DEBUG
//	if (bHooked) {
//		wchar_t szDbg[MAX_PATH*3], szModPath[MAX_PATH*2]; szModPath[0] = 0;
//		GetModuleFileNameW(Module, szModPath, MAX_PATH*2);
//		lstrcpyW(szDbg, L"  ## Hooks was set by conemu: ");
//		lstrcatW(szDbg, szModPath);
//		lstrcatW(szDbg, L"\n");
//		OutputDebugStringW(szDbg);
//	}
//#endif

    return res;
}
Пример #13
0
BOOL
FixIAT(
	DWORD dwProcessId,
	HANDLE hProcess,
	PBYTE imageBase,
	PIMAGE_NT_HEADERS pNtHeader,
	PIMAGE_IMPORT_DESCRIPTOR pImgImpDesc
	)
{
	BOOL bRet = FALSE;
	LPSTR lpModuleName = 0;
	HMODULE hLocalModule = 0;
	HMODULE hRemoteModule = 0;
	WCHAR modulePath[MAX_PATH + 1] = {0};
	WCHAR moduleNtPath[500 + 1] = {0};
	WCHAR targetProcPath[MAX_PATH + 1] = {0};
	WCHAR *pch = 0;

	__try
	{
		//printf("Fixing Imports:\n");

		// get target process path
		if(!GetModuleFileNameExW(hProcess, (HMODULE)0, targetProcPath, MAX_PATH))
		{
			PRINT_ERROR_MSGA("Could not get path to target process.");
			__leave;
		}

		pch = wcsrchr(targetProcPath, '\\');
		if(pch)
		{
			targetProcPath[ pch - targetProcPath + 1 ] = (WCHAR)0;
		}

		if(!SetDllDirectoryW(targetProcPath))
		{
			PRINT_ERROR_MSGW(L"Could not set path to target process (%s).", targetProcPath);
			__leave;
		}

		while((lpModuleName = (LPSTR)GetPtrFromRVA(pImgImpDesc->Name, pNtHeader, imageBase)))
		{
			PIMAGE_THUNK_DATA itd = 0;

			//printf("module: %s\n", lpModuleName);

			// ACHTUNG: LoadLibraryEx kann eine DLL nur anhand des Namen aus einem anderen
			// Verzeichnis laden wie der Zielprozess!
			hLocalModule = LoadLibraryExA(lpModuleName, 0, DONT_RESOLVE_DLL_REFERENCES);
			if(!hLocalModule)
			{
				PRINT_ERROR_MSGA("Could not load module locally.");
				__leave;
			}

			// get full path of module
			if(!GetModuleFileNameW(hLocalModule, modulePath, MAX_PATH))
			{
				PRINT_ERROR_MSGA("Could not get path to module (%s).", lpModuleName);
				__leave;
			}

			// get nt path
			if(!GetFileNameNtW(modulePath, moduleNtPath, 500))
			{
				PRINT_ERROR_MSGA("Could not get the NT namespace path.");
				__leave;
			}

			// Module already in process?
			hRemoteModule = (HMODULE)ModuleInjectedW(hProcess, moduleNtPath);
			if(!hRemoteModule)
			{
				if(!InjectLibraryW(dwProcessId, modulePath))
				{
					PRINT_ERROR_MSGW(L"Could not inject required module (%s).\n", modulePath);
					__leave;
				}
				
				hRemoteModule = (HMODULE)ModuleInjectedW(hProcess, moduleNtPath);
			}

			itd = (PIMAGE_THUNK_DATA)GetPtrFromRVA(pImgImpDesc->FirstThunk, pNtHeader, imageBase);

			while(itd->u1.AddressOfData)
			{
				IMAGE_IMPORT_BY_NAME *iibn =
					(PIMAGE_IMPORT_BY_NAME)GetPtrFromRVA(itd->u1.AddressOfData, pNtHeader, imageBase);
				itd->u1.Function = (DWORD_PTR)GetRemoteProcAddress(hProcess, hRemoteModule, (LPCSTR)iibn->Name);

				//printf("Function: %s\n", (LPCSTR)iibn->Name);

				itd++;
			}      

			pImgImpDesc++;
		}

		bRet = TRUE;
	}
	__finally
	{
		if(hLocalModule)
		{
			FreeLibrary(hLocalModule);
		}
	}

	return bRet;
}
Пример #14
0
BOOL
FixRelocations(
	PBYTE dllBin,
	LPVOID lpModuleBase,
	PIMAGE_NT_HEADERS pNtHeader,
	PIMAGE_BASE_RELOCATION pImgBaseReloc
	)
{
	LONG_PTR delta = (DWORD_PTR)lpModuleBase - pNtHeader->OptionalHeader.ImageBase;
	SIZE_T relocationSize = pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
	WORD *pRelocData = 0;

	//printf("FixRelocs:\n");

	// image has no relocations
	if(!pImgBaseReloc->SizeOfBlock)
	{
		//printf("Image has no relocations\n");
		return TRUE;
	}
	
	do
	{
		PBYTE pRelocBase = (PBYTE)GetPtrFromRVA(pImgBaseReloc->VirtualAddress, pNtHeader, dllBin);
		SIZE_T numRelocations = (pImgBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
		SIZE_T i = 0;

		//printf("numRelocations: %d\n", numRelocations);

		pRelocData = (WORD*)( (DWORD_PTR)pImgBaseReloc + sizeof(IMAGE_BASE_RELOCATION) );

		// loop over all relocation entries
		for(i = 0; i < numRelocations; i++, pRelocData++)
		{
			// Get reloc data
			BYTE RelocType = *pRelocData >> 12;
			WORD Offset = *pRelocData & 0xFFF;

			switch(RelocType)
			{
			case IMAGE_REL_BASED_ABSOLUTE:
				break;

			case IMAGE_REL_BASED_HIGHLOW:
				*(DWORD32*)(pRelocBase + Offset) += (DWORD32)delta;
				break;

			case IMAGE_REL_BASED_DIR64:
				*(DWORD64*)(pRelocBase + Offset) += delta;

				break;

			default:
				PRINT_ERROR_MSGA("Unsuppported relocation type.");
				return FALSE;
			}
		}

		pImgBaseReloc = (PIMAGE_BASE_RELOCATION)pRelocData;

	} while( *(DWORD*)pRelocData );

	return TRUE;
}