Skip to content

Loading a protected DLL #44

Open
Open

Description

@Massayu

I'm testing loading a dll proteted with Themida using your MemoryModule project.
I protected the a.dll that comes with the project, when i try to load it the code fail at this line: status = STATUS_NO_MEMORY;

		//
		// Allocate and copy sections
		//
		PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(new_header);
		for (DWORD i = 0; i < new_header->FileHeader.NumberOfSections; ++i, ++section) {

			DWORD size = AlignValueUp(
				section->Misc.VirtualSize,
				new_header->OptionalHeader.SectionAlignment
			);
			if (size < section->SizeOfRawData) {
				status = STATUS_INVALID_IMAGE_FORMAT;
				break;
			}

			LPVOID dest = VirtualAlloc(
				(LPSTR)new_header->OptionalHeader.ImageBase + section->VirtualAddress,
				size,
				MEM_COMMIT,
				PAGE_READWRITE
			);
			if (!dest) {
				status = STATUS_NO_MEMORY;  // <---- failed here
				break;
			}

			if (section->SizeOfRawData) {
				RtlCopyMemory(
					dest,
					LPBYTE(data) + section->PointerToRawData,
					section->SizeOfRawData
				);
			}

		}

It does fail in the latest section, could you please, help debug this?

Activity

  1. added a commit that references this issue on Feb 19, 2024
  2. bb107 commented on Feb 19, 2024

    @bb107
    Owner

    Hello. Please check out the code and try again.

  3. Massayu commented on Feb 19, 2024

    @Massayu
    Author

    @bb107 thanks for the quick reply, i think it worked now, doing some tests!

    Isn't possible to debug the DLL injected with this lib right?
    I mean, breakpoints on Visual Studio doesn't get hit

  4. bb107 commented on Feb 20, 2024

    @bb107
    Owner

    Simply put this doesn't prevent debugging, it just makes it harder. The breakpoint is essentially an assembly instruction int3 (0xCC), so the attacker can still set a breakpoint, and when the program executes to the breakpoint, it will be captured by the debugger.

  5. Massayu commented on Feb 20, 2024

    @Massayu
    Author

    I'm referring if its possible to debug our own DLL that has been loaded using the memory module using Visual Studio.

    When i set #define MMPP_USE_TLS 0
    It fails when checking the NtVersion

    	case 10: {
    		if (MmpGlobalDataPtr->NtVersions.MinorVersion) return STATUS_NOT_SUPPORTED;
    
    		if (MmpGlobalDataPtr->NtVersions.BuildNumber >= 22621) {
    #ifdef _WIN64
    			Feature = "\x74\x34\x48\x8B\x08\x48\x39\x41\x08\x75\x65\x48\x8B\x40\x08\x48\x39\x18\x75\x5C\x48\x89\x08";
    			Size = 24;
    			OffsetOfFunctionBegin = 0x2F;
    #else
    			return STATUS_NOT_SUPPORTED;
    #endif
    		}
    		//
    		// Add more conditions here.
    		//
    		// else if (MmpGlobalDataPtr->NtVersions.BuildNumber >= XXXXXXXXX)
    		else {
    			return STATUS_NOT_SUPPORTED; // <-- fail, NtVersions.BuildNumber 19045
    		}
    
    		break;
    	}

    My NtVersions.BuildNumber is 19045
    Could you share how do you got these values? so i could add support for older Windows versions.

    Also, there's no case for Windows 11, there's no support for Win11 when using LdrpTls?

  6. bb107 commented on Feb 20, 2024

    @bb107
    Owner

    DLLs loaded from memory can be debugged in Visual Studio, but only at the assembly level and not at the source code level. Because this loading process is not handled by the kernel, the debugger does not know it is a DLL.

    LdrpTls is implemented by ntdll, but the related functions(such as ntdll!LdrpHandleTlsData) are not exported, so it needs to be located based on the signature. Since each version of ntdll may have different signatures, I don't have much energy to maintain these signatures, so I implemented MmpTls to replace it. It is undeniable that there are still many problems with MmpTls, so I kept the original LdrpTls option for those who need it.

    For how to extract the signature, you can refer to #6. You can also refer to BlackBone, which updates the signature for Windows 11.

  7. CycloneRing commented on Nov 16, 2024

    @CycloneRing

    @bb107 I had a funny behavior I think worth mentioning, Before your push on init/shutdown i used to load dlls from memory using dllname and path with Ex method, And in debug it was showing the dll and all functions just like a normal dll and could be debugged in Visual Studio! I have no idea how but it was happening, even if app crash the information was provided on memory mapped dll.

  8. added a commit that references this issue on May 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions