示例#1
0
HMODULE MemLoadLibrary(PBYTE data)
{
    IMAGE_FILE_HEADER        *pFileHeader        = NULL;
    IMAGE_OPTIONAL_HEADER    *pOptionalHeader    = NULL;
    IMAGE_SECTION_HEADER    *pSectionHeader        = NULL;
    IMAGE_IMPORT_DESCRIPTOR *pImportDscrtr        = NULL;
    USHORT                    e_lfanew            = *((USHORT*)(data+0x3c));
    PCHAR                    ImageBase            = NULL;
    PCHAR                    SectionBase            = NULL;

    DWORD dwSize, dwOldProt, ImageBaseDelta;
    int i;

    pFileHeader = (IMAGE_FILE_HEADER *)(data+e_lfanew+4);
    pOptionalHeader = (IMAGE_OPTIONAL_HEADER *)(data+e_lfanew+4+sizeof(IMAGE_FILE_HEADER));
    if (pOptionalHeader->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC)
        return NULL;

    //    Let's try to reserv memory
    ImageBase = (PCHAR)VirtualAlloc(
        (PVOID)pOptionalHeader->ImageBase,
        pOptionalHeader->SizeOfImage,
        MEM_RESERVE,PAGE_NOACCESS);

    if(ImageBase==NULL)
    {
        ImageBase=(PCHAR)VirtualAlloc(NULL,
            pOptionalHeader->SizeOfImage,
            MEM_RESERVE,PAGE_NOACCESS);
        if(ImageBase==NULL)
            return NULL;
    }

    //    copy the header
    SectionBase=(PCHAR)VirtualAlloc(ImageBase,
        pOptionalHeader->SizeOfHeaders,
        MEM_COMMIT,PAGE_READWRITE);
    memcpy(SectionBase,data,pOptionalHeader->SizeOfHeaders);
    //    Do headers read-only (to be on the safe side)
    VirtualProtect(SectionBase,pOptionalHeader->SizeOfHeaders,PAGE_READONLY,&dwOldProt);

    //    find sections ...
    pSectionHeader = (IMAGE_SECTION_HEADER *)(pOptionalHeader+1);
    for (i=0; i<pFileHeader->NumberOfSections; i++)
    {
        SectionBase = (PCHAR)VirtualAlloc(
            ImageBase+pSectionHeader[i].VirtualAddress,
            pSectionHeader[i].Misc.VirtualSize,
            MEM_COMMIT,PAGE_READWRITE);
        if (SectionBase==NULL)
        {
            VirtualFree(ImageBase, 0, MEM_RELEASE);
            return NULL;
        }
        //    ... and copy initialization data
        SectionBase = ImageBase+pSectionHeader[i].VirtualAddress;
        dwSize = MIN(pSectionHeader[i].SizeOfRawData,pSectionHeader[i].Misc.VirtualSize);
        memcpy(SectionBase, data+pSectionHeader[i].PointerToRawData,dwSize);
    }

    //    check addersses
    ImageBaseDelta = (DWORD)ImageBase-pOptionalHeader->ImageBase;
    if (ImageBaseDelta!=0 && 
        pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress!=0
        )
    {
        IMAGE_BASE_RELOCATION    *pBaseReloc    = (IMAGE_BASE_RELOCATION *)(ImageBase+
            pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
        IMAGE_BASE_RELOCATION    *pBaseReloc0    = pBaseReloc;
        WORD *wPointer = NULL;
        DWORD dwModCount;
        int i;

        while ((DWORD)pBaseReloc0-(DWORD)pBaseReloc < pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
        {
            dwModCount = (pBaseReloc0->SizeOfBlock-sizeof(pBaseReloc))/2;
            wPointer = (WORD *)(pBaseReloc+1);
            for (i=0; i<dwModCount; i++, wPointer++)
                if ((*wPointer & 0xf000) !=0)
                {
                    PDWORD pdw = (PDWORD)(ImageBase+pBaseReloc0->VirtualAddress+((*wPointer)&0xfff));
                    (*pdw)+=ImageBaseDelta;
                }
                pBaseReloc = (IMAGE_BASE_RELOCATION *)wPointer;
        }
    }
    else if (ImageBaseDelta!=0)
    {
        VirtualFree(ImageBase, 0, MEM_RELEASE);
        return NULL;
    }

    pImportDscrtr = (IMAGE_IMPORT_DESCRIPTOR *)(ImageBase+
        pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

    for (;pImportDscrtr->Name!=0; pImportDscrtr++)
    {
        PCHAR pLibName        = (PCHAR)(ImageBase+pImportDscrtr->Name);
        PCHAR pImortName    = NULL;
        HMODULE hLibModule    = LoadLibrary(pLibName);
        DWORD    *pImport    = NULL,
            *pAddress    = NULL;
        DWORD ProcAddress;

        pAddress=(DWORD *)(ImageBase+pImportDscrtr->/*Original*/FirstThunk);
        if (pImportDscrtr->TimeDateStamp==0)
            pImport=(DWORD *)(ImageBase+pImportDscrtr->FirstThunk);
        else
            pImport=(DWORD *)(ImageBase+pImportDscrtr->OriginalFirstThunk);
        for (i=0; pImport[i]!=0; i++)
        {
            if (IsImportByOrdinal(pImport[i]))
                ProcAddress=(DWORD)GetProcAddress(hLibModule, (PCHAR)(pImport[i]&0xFFFF));
            else  // import by name
            {
                pImortName=(PCHAR)(ImageBase+(pImport[i])+2);
                ProcAddress=(DWORD)GetProcAddress(hLibModule, pImortName);
            }
            pAddress[i]=ProcAddress;
        }
    }

    //    set section protection
    for (i=0; i<pFileHeader->NumberOfSections; i++)
        VirtualProtect((PVOID)(ImageBase+pSectionHeader[i].VirtualAddress),
        pSectionHeader[i].Misc.VirtualSize,
        GetSectionProtection(pSectionHeader[i].Characteristics),
        &dwOldProt);

    //    call DLLMain
    if (pOptionalHeader->AddressOfEntryPoint!=0)
    {
        DLLMAIN dllMain=(DLLMAIN)(ImageBase+pOptionalHeader->AddressOfEntryPoint);
        if (!dllMain((HMODULE)ImageBase, DLL_PROCESS_ATTACH, NULL))
        {
            VirtualFree(ImageBase, 0, MEM_RELEASE);
            return NULL;
        }
    }

    return (HMODULE)ImageBase;
}
BOOL CRemoteLoader::ProcessSections( PVOID BaseAddress, PVOID RemoteAddress, BOOL MapPEHeader )
{
	IMAGE_NT_HEADERS* ImageNtHeaders = ToNts( BaseAddress );

	if( ImageNtHeaders == NULL ) 
		return FALSE;

	// Write PE header

	if( MapPEHeader )
	{
		if( WriteProcessMemory( GetProcess(), RemoteAddress, BaseAddress, ImageNtHeaders->OptionalHeader.SizeOfHeaders, NULL ) == FALSE )
		{
			DebugShout( "[ProcessSections] Failed to map PE header!" );
		}
		else
		{
			DebugShout( "[ProcessSections] Mapped PE Header successfully!" );
		}
	}
	else
	{
		DebugShout( "[ProcessSections] PE Header mapping disabled, skipping." );
	}

	// Write individual sections

	PIMAGE_SECTION_HEADER ImageSectionHeader = ( PIMAGE_SECTION_HEADER )
		( ( ( ULONG_PTR ) &ImageNtHeaders->OptionalHeader ) + ImageNtHeaders->FileHeader.SizeOfOptionalHeader );

	for( DWORD i = 0; i < ImageNtHeaders->FileHeader.NumberOfSections; i++ )
	{
		ULONG Protection = GetSectionProtection( ImageSectionHeader[ i ].Characteristics );

		if( !_stricmp( ".reloc", ( CHAR* ) ImageSectionHeader[ i ].Name ) )
		{
			DebugShout( "[ProcessSections] Skipping \".reloc\" section." );

			continue; // NOPE
		}

		if( ProcessSection( 
			ImageSectionHeader[ i ].Name,
			BaseAddress,
			RemoteAddress,
			ImageSectionHeader[ i ].PointerToRawData,
			ImageSectionHeader[ i ].VirtualAddress,
			ImageSectionHeader[ i ].SizeOfRawData,
			ImageSectionHeader[ i ].Misc.VirtualSize,
			Protection ) == FALSE )
		{
			DebugShout( "[ProcessSections] Failed %s", ImageSectionHeader[ i ].Name );
		}
		else
		{
			DebugShout( "[ProcessSections] Success %s", ImageSectionHeader[ i ].Name );
		}
	}

	return TRUE;
}