Looks like nobody is interested so i tried converting it myself and i, of course, failed :roll:
Here is code, it is real mess because i commented out every line and then when i converted it i left original line as comment to check later if i converted it properly. I converted almost all in PB_LoadLibraryM() procedure since it is main procedure which is called first. Converted code is not working so i didn't converted other parts yet.
If anyone knows something more please look at this code and try to convert at least only small part of it so we won't need to buy commercial products like Molebox or BoxedApp or something similar.
Code: Select all
EnableExplicit
;{ header - comments
; /*
; * Memory DLL loading code
; * Version 0.0.2
; *
; * Copyright (c) 2004-2005 by Joachim Bauch / mail@joachim-bauch.de
; * http://www.joachim-bauch.de
; *
; * The contents of this file are subject To the Mozilla Public License Version
; * 1.1 (the "License"); you may not use this file except in compliance with
; * the License. You may obtain a copy of the License at
; * http://www.mozilla.org/MPL/
; *
; * Software distributed under the License is distributed on an "AS IS" basis,
; * WITHOUT WARRANTY OF ANY KIND, either express Or implied. See the License
; * For the specific language governing rights And limitations under the
; * License.
; *
; * The Original Code is MemoryModule.c
; *
; * The Initial Developer of the Original Code is Joachim Bauch.
; *
; * Portions created by Joachim Bauch are Copyright (C) 2004-2005
; * Joachim Bauch. All Rights Reserved.
; *
; */
;
; // disable warnings about pointer <-> DWORD conversions
; //#pragma warning( disable : 4311 4312 )
;
; #include <Windows.h>
; #include <winnt.h>
; #ifdef DEBUG_OUTPUT
; #include <stdio.h>
; #endif
;
; #include "MemoryModule.h"
;
;}
;
;
;{************************** TAKEN FROM PUREBASIC FORUMS *********************
Structure Misc
PhysicalAddress.l
VirtualSize.l
EndStructure
Structure IMAGE_SECTION_HEADER
Name.l
Misc.Misc
VirtualAddress.l
SizeOfRawData.l
PointerToRawData.l
PointerToRelocations.l
PointerToLinenumbers.l
NumberOfRelocations.w
NumberOfLinenumbers.w
Characteristics.l
EndStructure
ImportC "msvcrt.lib"
memset_ ( *str.l, char.l, length.l ) As "_memset@12"
EndImport
#IMAGE_DOS_SIGNATURE = $5A4D
#IMAGE_NT_SIGNATURE = $4550
;}****************************************************************************
Structure MEMORYMODULE ;typedef struct {
headers.IMAGE_NT_HEADERS ; PIMAGE_NT_HEADERS headers;
*codeBase.c ; unsigned char *codeBase;
*modules.HMODULE ; HMODULE *modules;
numModules.i ; int numModules;
initialized.i ; int initialized;
EndStructure ;} MEMORYMODULE, *PMEMORYMODULE;
Declare PB_FreeLibraryM(*mod.MEMORYMODULE)
;
; typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
;
; #define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx]
;
; #ifdef DEBUG_OUTPUT
; Static void
; OutputLastError(const char *msg)
; {
; LPVOID tmp;
; char *tmpmsg;
; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
; NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL);
; tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3);
; sprintf(tmpmsg, "%s: %s", msg, tmp);
; OutputDebugString(tmpmsg);
; LocalFree(tmpmsg);
; LocalFree(tmp);
; }
; #endif
;
; Static void
Procedure CopySections(*dData, *old_headers.IMAGE_NT_HEADERS, *module.MEMORYMODULE); CopySections(const unsigned char *Data, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module)
; {
Protected i, size; int i, size;
Protected *codeBase.c = *module\codeBase; unsigned char *codeBase = module->codeBase;
Protected *dest.c; unsigned char *dest;
Protected *section.IMAGE_SECTION_HEADER = *module\headers + 24 + *module\headers\FileHeader\SizeOfOptionalHeader; PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
For i=0 To *module\headers\FileHeader\NumberOfSections; For (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++)
; {
If *section\SizeOfRawData = 0; If (section->SizeOfRawData == 0)
; {
; // section doesn't contain data in the dll itself, but may define
; // uninitialized Data
size = *old_headers\OptionalHeader\SectionAlignment; size = old_headers->OptionalHeader.SectionAlignment;
If size > 0; If (size > 0)
; {
*dest = VirtualAlloc_(*codeBase + *section\VirtualAddress,size,#MEM_COMMIT,#PAGE_READWRITE); dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
; size,
; MEM_COMMIT,
; PAGE_READWRITE);
;
*section\Misc\PhysicalAddress = *dest; section->Misc.PhysicalAddress = (DWORD)dest;
memset_(*dest, 0, size); memset(dest, 0, size);
EndIf; }
;
; // section is empty
Continue; Continue;
EndIf; }
;
; // commit memory block And copy Data from dll
*dest = VirtualAlloc_(*section\VirtualAddress,*section\SizeOfRawData,#MEM_COMMIT,#PAGE_READWRITE); dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
; section->SizeOfRawData,
; MEM_COMMIT,
; PAGE_READWRITE);
CopyMemory(*dData + *section\PointerToRawData, *dest, *section\SizeOfRawData); memcpy(dest, Data + section->PointerToRawData, section->SizeOfRawData);
*section\Misc\PhysicalAddress = *dest; section->Misc.PhysicalAddress = (DWORD)dest;
i+1
*section+1 ;I know this is error, probably needed to declare *section as(?): Dim *section.IMAGE_SECTION_HEADER(*old_headers\FileHeader\NumberOfSections)
Next; }
EndProcedure; }
;
; // Protection flags For memory pages (Executable, Readable, Writeable)
; Static int ProtectionFlags[2][2][2] = {
; {
; // Not executable
; {PAGE_NOACCESS, PAGE_WRITECOPY},
; {PAGE_READONLY, PAGE_READWRITE},
; }, {
; // executable
; {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY},
; {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE},
; },
; };
;
; Static void
Procedure FinalizeSections(*module.MEMORYMODULE); FinalizeSections(PMEMORYMODULE module)
; {
; int i;
; PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
;
; // loop through all sections And change access flags
; For (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++)
; {
; DWORD protect, oldProtect, size;
; int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
; int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0;
; int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0;
;
; If (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
; {
; // section is Not needed any more And can safely be freed
; VirtualFree((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, MEM_DECOMMIT);
; Continue;
; }
;
; // determine protection flags based on characteristics
; protect = ProtectionFlags[executable][readable][writeable];
; If (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
; protect |= PAGE_NOCACHE;
;
; // determine size of region
; size = section->SizeOfRawData;
; If (size == 0)
; {
; If (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
; size = module->headers->OptionalHeader.SizeOfInitializedData;
; Else If (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
; size = module->headers->OptionalHeader.SizeOfUninitializedData;
; }
;
; If (size > 0)
; {
; // change memory access flags
; If (VirtualProtect((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, protect, &oldProtect) == 0)
; #ifdef DEBUG_OUTPUT
; OutputLastError("Error protecting memory page")
; #endif
; ;
; }
; }
EndProcedure; }
;
; Static void
Procedure PerformBaseRelocation(*module.MEMORYMODULE, delta); PerformBaseRelocation(PMEMORYMODULE module, DWORD delta)
; {
; DWORD i;
; unsigned char *codeBase = module->codeBase;
;
; PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC);
; If (directory->Size > 0)
; {
; PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)(codeBase + directory->VirtualAddress);
; For (; relocation->VirtualAddress > 0; )
; {
; unsigned char *dest = (unsigned char *)(codeBase + relocation->VirtualAddress);
; unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION);
; For (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++)
; {
; DWORD *patchAddrHL;
; int type, offset;
;
; // the upper 4 bits Define the type of relocation
; type = *relInfo >> 12;
; // the lower 12 bits Define the offset
; offset = *relInfo & 0xfff;
;
; switch (type)
; {
; Case IMAGE_REL_BASED_ABSOLUTE:
; // skip relocation
; Break;
;
; Case IMAGE_REL_BASED_HIGHLOW:
; // change complete 32 bit address
; patchAddrHL = (DWORD *)(dest + offset);
; *patchAddrHL += delta;
; Break;
;
; Default:
; //printf("Unknown relocation: %d\n", type);
; Break;
; }
; }
;
; // advance To Next relocation block
; relocation = (PIMAGE_BASE_RELOCATION)(((DWORD)relocation) + relocation->SizeOfBlock);
; }
; }
EndProcedure; }
;
; Static int
Procedure BuildImportTable(*module.MEMORYMODULE); BuildImportTable(PMEMORYMODULE module)
; {
; int result=1;
; unsigned char *codeBase = module->codeBase;
;
; PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
; If (directory->Size > 0)
; {
; PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)(codeBase + directory->VirtualAddress);
; For (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++)
; {
; DWORD *thunkRef, *funcRef;
; HMODULE handle = LoadLibrary((LPCSTR)(codeBase + importDesc->Name));
; If (handle == INVALID_HANDLE_VALUE)
; {
; #if DEBUG_OUTPUT
; OutputLastError("Can't load library");
; #endif
; result = 0;
; Break;
; }
;
; module->modules = (HMODULE *)realloc(module->modules, (module->numModules+1)*(SizeOf(HMODULE)));
; If (module->modules == NULL)
; {
; result = 0;
; Break;
; }
;
; module->modules[module->numModules++] = handle;
; If (importDesc->OriginalFirstThunk)
; {
; thunkRef = (DWORD *)(codeBase + importDesc->OriginalFirstThunk);
; funcRef = (DWORD *)(codeBase + importDesc->FirstThunk);
; } Else {
; // no hint table
; thunkRef = (DWORD *)(codeBase + importDesc->FirstThunk);
; funcRef = (DWORD *)(codeBase + importDesc->FirstThunk);
; }
; For (; *thunkRef; thunkRef++, funcRef++)
; {
; If IMAGE_SNAP_BY_ORDINAL(*thunkRef)
; *funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
; Else {
; PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)(codeBase + *thunkRef);
; *funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
; }
; If (*funcRef == 0)
; {
; result = 0;
; Break;
; }
; }
;
; If (!result)
; Break;
; }
; }
;
; Return result;
EndProcedure; }
;
Procedure PB_LoadLibraryM(*dData); extern HMEMORYMODULE PB_LoadLibraryM(const void *Data)
; {
Debug "[OK] Started PB_LoadLibraryM()"
Protected *result.MEMORYMODULE; PMEMORYMODULE result;
Protected *dos_header.IMAGE_DOS_HEADER; PIMAGE_DOS_HEADER dos_header;
Protected *old_header.IMAGE_NT_HEADERS; PIMAGE_NT_HEADERS old_header;
Protected *code.c, *headers.c; unsigned char *code, *headers;
Protected locationDelta; DWORD locationDelta;
Protected DllEntry; DllEntryProc DllEntry; ;!!!!!! needs this to be converted first: typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
Protected successfull.b; BOOL successfull;
;
*dos_header = *dData; dos_header = (PIMAGE_DOS_HEADER)Data;
If *dos_header\e_magic <> #IMAGE_DOS_SIGNATURE; If (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
; {
; #if DEBUG_OUTPUT
Debug "[Fail] Not a valid executable file"; OutputDebugString("Not a valid executable file.\n");
; #endif
ProcedureReturn #Null; Return NULL;
Else
Debug "[OK] Valid executable file"
EndIf; }
;
*old_header = *dData + *dos_header\e_lfanew ; old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(Data))[dos_header->e_lfanew];
If *old_header\Signature <> #IMAGE_NT_SIGNATURE; If (old_header->Signature != IMAGE_NT_SIGNATURE)
; {
; #if DEBUG_OUTPUT
Debug "[Fail] No PE header found"; OutputDebugString("No PE header found.\n");
; #endif
ProcedureReturn #Null; Return NULL;
Else
Debug "[OK] PE header found"
EndIf; }
;
; // reserve memory For image of library
*code = VirtualAlloc_(*old_header\OptionalHeader\ImageBase,*old_header\OptionalHeader\SizeOfImage,#MEM_RESERVE,#PAGE_READWRITE); code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase),
; old_header->OptionalHeader.SizeOfImage,
; MEM_RESERVE,
; PAGE_READWRITE);
;
If *code = #Null; If (code == NULL)
; // try To allocate memory at arbitrary position
*code = VirtualAlloc_(#Null,*old_header\OptionalHeader\SizeOfImage,#MEM_RESERVE,#PAGE_READWRITE); code = (unsigned char *)VirtualAlloc(NULL,
; old_header->OptionalHeader.SizeOfImage,
; MEM_RESERVE,
; PAGE_READWRITE);
EndIf;
If *code = #Null; If (code == NULL)
; {
; #if DEBUG_OUTPUT
Debug "[Fail] Can't reserve memory"; OutputLastError("Can't reserve memory");
; #endif
ProcedureReturn #Null; Return NULL;
EndIf; }
;
*result = HeapAlloc_(GetProcessHeap_(), 0, SizeOf(MEMORYMODULE)); result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, SizeOf(MEMORYMODULE));
*result\codeBase = *code; result->codeBase = code;
*result\numModules = 0; result->numModules = 0;
*result\modules = #Null; result->modules = NULL;
*result\initialized = 0; result->initialized = 0;
;
; // XXX: is it correct To commit the complete memory region at once?
; // calling DllEntry raises an exception If we don't...
VirtualAlloc_(*code,*old_header\OptionalHeader\SizeOfImage, #MEM_COMMIT,#PAGE_READWRITE); VirtualAlloc(code,
; old_header->OptionalHeader.SizeOfImage,
; MEM_COMMIT,
; PAGE_READWRITE);
;
; // commit memory For headers
*headers = VirtualAlloc_(*code,*old_header\OptionalHeader\SizeOfHeaders,#MEM_COMMIT,#PAGE_READWRITE); headers = (unsigned char *)VirtualAlloc(code,
; old_header->OptionalHeader.SizeOfHeaders,
; MEM_COMMIT,
; PAGE_READWRITE);
;
; // copy PE header To code
CopyMemory(*dos_header,*headers,*dos_header\e_lfanew + *old_header\OptionalHeader\SizeOfHeaders); memcpy(headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders);
;
;************** NEXT LINE IS NOT PROPERLY CONVERTED TO PUREBASIC !!!!!!!!!!! ***************
CopyMemory(*dos_header\e_lfanew,@*result\headers,4); result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew];
;
; // update position
;************** NEXT LINE IS NOT PROPERLY CONVERTED TO PUREBASIC !!!!!!!!!!! ***************
CopyMemory(@*code,@*result\headers\OptionalHeader\ImageBase,4); result->headers->OptionalHeader.ImageBase = (DWORD)code;
;
; // copy sections from DLL file block To new memory location
CopySections(*dData, *old_header, *result); CopySections(Data, old_header, result);
;
; // adjust base address of imported Data
locationDelta = *code - *old_header\OptionalHeader\ImageBase; locationDelta = (DWORD)(code - old_header->OptionalHeader.ImageBase);
If locationDelta <> 0; If (locationDelta != 0)
PerformBaseRelocation(*result, locationDelta); PerformBaseRelocation(result, locationDelta);
EndIf;
; // load required dlls And adjust function table of imports
If Not BuildImportTable(*result); If (!BuildImportTable(result))
Goto error; Goto error;
EndIf;
; // mark memory pages depending on section headers And release
; // sections that are marked As "discardable"
FinalizeSections(*result); FinalizeSections(result);
;
; // get entry point of loaded library
If *result\headers\OptionalHeader\AddressOfEntryPoint <> 0 ; If (result->headers->OptionalHeader.AddressOfEntryPoint != 0)
; {
DllEntry = *code + *result\headers\OptionalHeader\AddressOfEntryPoint; DllEntry = (DllEntryProc)(code + result->headers->OptionalHeader.AddressOfEntryPoint);
If DllEntry = 0; If (DllEntry == 0)
; {
; #if DEBUG_OUTPUT
Debug "[Fail] Library has no entry point"; OutputDebugString("Library has no entry point.\n");
; #endif
Goto error; Goto error;
EndIf; }
;
; // notify library about attaching To process
;*********** NEXT LINE NEEDS TO BE CONVERTED TO PUREBASIC **************
; successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);
If Not successfull; If (!successfull)
; {
; #if DEBUG_OUTPUT
Debug "[Fail] Can't attach library"; OutputDebugString("Can't attach library.\n");
; #endif
Goto error; Goto error;
EndIf; }
*result\initialized = 1; result->initialized = 1;
EndIf; }
;
ProcedureReturn *result; Return (HMEMORYMODULE)result;
;
error: ; error:
; // cleanup
PB_FreeLibraryM(*result); PB_FreeLibraryM(result);
ProcedureReturn #Null; Return NULL;
EndProcedure; }
;
Procedure PB_GetProcAddressM(*module.MEMORYMODULE, *name.c); extern FARPROC PB_GetProcAddressM(HMEMORYMODULE module, const char *name)
; {
; unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase;
; int idx=-1;
; DWORD i, *nameRef;
; WORD *ordinal;
; PIMAGE_EXPORT_DIRECTORY exports;
; PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT);
; If (directory->Size == 0)
; // no export table found
; Return NULL;
;
; exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress);
; If (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0)
; // DLL doesn't export anything
; Return NULL;
;
; // search function name in List of exported names
; nameRef = (DWORD *)(codeBase + exports->AddressOfNames);
; ordinal = (WORD *)(codeBase + exports->AddressOfNameOrdinals);
; For (i=0; i<exports->NumberOfNames; i++, nameRef++, ordinal++)
; If (strcmp(name, (const char *)(codeBase + *nameRef)) == 0)
; {
; idx = *ordinal;
; Break;
; }
;
; If (idx == -1)
; // exported symbol Not found
; Return NULL;
;
; If ((DWORD)idx > exports->NumberOfFunctions)
; // name <-> ordinal number don't match
; Return NULL;
;
; // AddressOfFunctions contains the RVAs To the "real" functions
; Return (FARPROC)(codeBase + *(DWORD *)(codeBase + exports->AddressOfFunctions + (idx*4)));
EndProcedure; }
;
Procedure PB_FreeLibraryM(*mod.MEMORYMODULE); extern void PB_FreeLibraryM(HMEMORYMODULE mod)
; {
; int i;
; PMEMORYMODULE module = (PMEMORYMODULE)mod;
;
; If (module != NULL)
; {
; If (module->initialized != 0)
; {
; // notify library about detaching from process
; DllEntryProc DllEntry = (DllEntryProc)(module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint);
; (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0);
; module->initialized = 0;
; }
;
; If (module->modules != NULL)
; {
; // free previously opened libraries
; For (i=0; i<module->numModules; i++)
; If (module->modules[i] != INVALID_HANDLE_VALUE)
; FreeLibrary(module->modules[i]);
;
; free(module->modules);
; }
;
; If (module->codeBase != NULL)
; // release memory of library
; VirtualFree(module->codeBase, 0, MEM_RELEASE);
;
; HeapFree(GetProcessHeap(), 0, module);
; }
EndProcedure; }
Debug "START"
Define file = ReadFile(#PB_Any,"C:\test.dll")
If file
Debug "[OK] Local file found"
Global *dll = AllocateMemory(Lof(file))
If *dll
Debug "[OK] Memory allocated"
ReadData(file,*dll,Lof(file))
CloseFile(file)
Else
Debug "[Fail] Couldn't allocate the requested memory"
EndIf
Define dllLoadResult = PB_LoadLibraryM(*dll)
If dllLoadResult
Debug "[OK] Success!!"
Else
Debug "[Fail] PB_LoadLibraryM() returned #False"
EndIf
Else
Debug "[Fail] File not found"
EndIf
Debug "END"