When I use the library on a simple C program with LoadLibraryA(), it works 
properly but with the DLL loaded in a virtual memory page happens something 
different, it gets stuck in WaitForSingleObject after running the exported 
method.

I did all the base relocations and proper IAT refactor, even when the image 
module gets loaded in the prefered address the following happens:

I initialize the go runtime by running fist the entrypoint of the DLL 
(after IAT and base relocations), it runs properly and the returns to the 
main C program, after that I parse the EAT looking for the exported 
function i.e OnProcessAttach, after locating the export by it's ordinal / 
name I tried to execute it (process receives no arguments, and returns 
nothing), and it starts running, then starts calling to 
RtlInitializeCriticalSection and follows the system calls, after that it 
just gets in a deadlock on WaitSingleObject (inside the go DLL), with 
LastStatus C000000D (STATUS_INVALID_PARAMETER) -but the exported function 
doesn't receives any argument-

Go DLL

package main
import "C"
import (
    "unsafe"
    "syscall"
)

//export OnProcessAttach
func OnProcessAttach() {
    const (
        NULL  = 0
        MB_OK = 0
    )
    caption := "Hola"
    title := "desdegoo"
    ret, _, _ := 
syscall.NewLazyDLL("user32.dll").NewProc("MessageBoxW").Call(
        uintptr(NULL),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
        uintptr(MB_OK))

    if ret != 1 {
        return
    }
    return 
}

func main() {}


C code:


    // resolve base relocations
    IMAGE_DATA_DIRECTORY relocations = 
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
    DWORD_PTR relocationTable = relocations.VirtualAddress + 
(DWORD_PTR)dllBase;
    DWORD relocationsProcessed = 0;

    while (relocationsProcessed < relocations.Size)
    {
        PBASE_RELOCATION_BLOCK relocationBlock = 
(PBASE_RELOCATION_BLOCK)(relocationTable + relocationsProcessed);
        relocationsProcessed += sizeof(BASE_RELOCATION_BLOCK);
        DWORD relocationsCount = (relocationBlock->BlockSize - 
sizeof(BASE_RELOCATION_BLOCK)) / sizeof(BASE_RELOCATION_ENTRY);
        PBASE_RELOCATION_ENTRY relocationEntries = 
(PBASE_RELOCATION_ENTRY)(relocationTable + relocationsProcessed);
        for (DWORD i = 0; i < relocationsCount; i++)
        {
            relocationsProcessed += sizeof(BASE_RELOCATION_ENTRY);
            if (relocationEntries[i].Type == 0)
            {
                continue;
            }

            DWORD_PTR relocationRVA = relocationBlock->PageAddress + 
relocationEntries[i].Offset;
            DWORD_PTR addressToPatch = 0;
            ReadProcessMemory(GetCurrentProcess(), 
(LPCVOID)((DWORD_PTR)dllBase + relocationRVA), &addressToPatch, 
sizeof(DWORD_PTR), NULL);
            addressToPatch += deltaImageBase;
            memcpy((PVOID)((DWORD_PTR)dllBase + relocationRVA), 
&addressToPatch, sizeof(DWORD_PTR));
        }
    }
    
    // resolve IAT
    PIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL;
    IMAGE_DATA_DIRECTORY importsDirectory = 
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
    importDescriptor = 
(PIMAGE_IMPORT_DESCRIPTOR)(importsDirectory.VirtualAddress + 
(DWORD_PTR)dllBase);
    LPCSTR libraryName = "";
    HMODULE library = NULL;

    while (importDescriptor->Name != NULL)
    {
        libraryName = (LPCSTR)importDescriptor->Name + (DWORD_PTR)dllBase;
        library = LoadLibraryA(libraryName);
        if (library)
        {
            PIMAGE_THUNK_DATA thunk = NULL;
            thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)dllBase + 
importDescriptor->FirstThunk);
            while (thunk->u1.AddressOfData != NULL)
            {
                if (IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal))
                {
                    LPCSTR functionOrdinal = 
(LPCSTR)IMAGE_ORDINAL(thunk->u1.Ordinal);
                    thunk->u1.Function = (DWORD_PTR)GetProcAddress(library, 
functionOrdinal);
                }
                else {
                    PIMAGE_IMPORT_BY_NAME functionName = 
(PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)dllBase + thunk->u1.AddressOfData);
                    DWORD_PTR functionAddress = 
(DWORD_PTR)GetProcAddress(library, functionName->Name);
                    thunk->u1.Function = functionAddress;
                }
                ++thunk;
            }
        }
        importDescriptor++;
    }

    FARPROC entrypoint2 = ((DWORD_PTR)dllBase + 
ntHeaders->OptionalHeader.AddressOfEntryPoint);
    (*entrypoint2)();

        // Locate exported OnProcessAttach function in EAT
        IMAGE_DATA_DIRECTORY exportsDirectory = 
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
        PIMAGE_EXPORT_DIRECTORY exportsDescriptor = 
(PIMAGE_EXPORT_DIRECTORY)(exportsDirectory.VirtualAddress + 
(DWORD_PTR)dllBase);
        DWORD numberOfNames = exportsDescriptor->NumberOfNames;

        PDWORD exportAddressTable = (PDWORD)((DWORD_PTR)dllBase + 
exportsDescriptor->AddressOfFunctions);
        PWORD nameOrdinalsPointer = (PWORD)((DWORD_PTR)dllBase + 
exportsDescriptor->AddressOfNameOrdinals);
        PDWORD exportNamePointerTable = (PDWORD)((DWORD_PTR)dllBase + 
exportsDescriptor->AddressOfNames);

        char procedureName[] = { 
'O','n','P','r','o','c','e','s','s','A','t','t','a','c','h', 0 };
        int nameIndex = 0;
        for (nameIndex = 0; nameIndex < numberOfNames; nameIndex++)
        {
            char* name = (char*)((unsigned char*)dllBase + 
exportNamePointerTable[nameIndex]);
            if (strncmp(procedureName, name, 15) == 0)
            {
                WORD ordinal = nameOrdinalsPointer[nameIndex];
                PDWORD targetFunctionAddress = (PDWORD)((unsigned 
char*)dllBase + exportAddressTable[ordinal]);
               FARPROC entrypoint = targetFunctionAddress;
               (*entrypoint)();
            }
        }
}

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/18320f31-c66d-4105-a8c9-26dceae9061dn%40googlegroups.com.

Reply via email to