diff --git a/.gitignore b/.gitignore index 8cc774f..6c07d24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.o *.obj *.exe +tests/*.dll +tests/*.res diff --git a/.travis.yml b/.travis.yml index 2af19ce..9182c08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,3 +19,4 @@ script: - cd example/DllLoader - WINEPREFIX=`pwd`/$WINE WINEPATH=/usr/lib/gcc/$PLATFORM-w64-mingw32/4.6/ $WINE ./DllLoader.exe - WINEPREFIX=`pwd`/$WINE WINEPATH=/usr/lib/gcc/$PLATFORM-w64-mingw32/4.6/ $WINE ./DllLoaderLoader.exe + - make test PLATFORM=$PLATFORM UNICODE=$UNICODE diff --git a/Makefile b/Makefile index d41c588..590c6e6 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SUBDIRS = example +SUBDIRS = example tests .PHONY: subdirs $(SUBDIRS) @@ -13,5 +13,8 @@ clean: $(CLEANDIRS) $(CLEANDIRS): $(MAKE) -C $(@:clean-%=%) clean +test: + $(MAKE) -C tests test + .PHONY: subdirs $(INSTALLDIRS) -.PHONY: clean +.PHONY: clean test diff --git a/tests/LoadDll.cpp b/tests/LoadDll.cpp new file mode 100644 index 0000000..b5074a7 --- /dev/null +++ b/tests/LoadDll.cpp @@ -0,0 +1,88 @@ +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include + +#include "../MemoryModule.h" + +typedef int (*addNumberProc)(int, int); + +BOOL LoadFromMemory(char *filename) +{ + FILE *fp; + unsigned char *data=NULL; + size_t size; + HMEMORYMODULE handle; + addNumberProc addNumber; + HMEMORYRSRC resourceInfo; + DWORD resourceSize; + LPVOID resourceData; + TCHAR buffer[100]; + BOOL result = TRUE; + + fp = fopen(filename, "rb"); + if (fp == NULL) + { + printf("Can't open DLL file \"%s\".", filename); + result = FALSE; + goto exit; + } + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + data = (unsigned char *)malloc(size); + fseek(fp, 0, SEEK_SET); + fread(data, 1, size, fp); + fclose(fp); + + handle = MemoryLoadLibrary(data); + if (handle == NULL) + { + _tprintf(_T("Can't load library from memory.\n")); + result = FALSE; + goto exit; + } + + addNumber = (addNumberProc)MemoryGetProcAddress(handle, "addNumbers"); + _tprintf(_T("From memory: %d\n"), addNumber(1, 2)); + + resourceInfo = MemoryFindResource(handle, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION); + _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo); + + if (resourceInfo != NULL) { + resourceSize = MemorySizeofResource(handle, resourceInfo); + resourceData = MemoryLoadResource(handle, resourceInfo); + _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData); + + MemoryLoadString(handle, 1, buffer, sizeof(buffer)); + _tprintf(_T("String1: %s\n"), buffer); + + MemoryLoadString(handle, 20, buffer, sizeof(buffer)); + _tprintf(_T("String2: %s\n"), buffer); + } else { + result = FALSE; + } + + MemoryFreeLibrary(handle); + +exit: + if (data) + free(data); + return result; +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + fprintf(stderr, "USAGE: %s \n", argv[0]); + return 1; + } + + if (!LoadFromMemory(argv[1])) { + return 2; + } + + return 0; +} diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..aafc6db --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,82 @@ +UNAME := $(shell uname) + +ifeq ($(UNAME), Linux) +ifndef PLATFORM +PLATFORM = i686 +endif +CC = $(PLATFORM)-w64-mingw32-g++ +CXX = $(PLATFORM)-w64-mingw32-g++ +LD = $(PLATFORM)-w64-mingw32-ld +RC = $(PLATFORM)-w64-mingw32-windres +else +CC = g++ +CXX = g++ +LD = ld +RC = rc +endif + +RM = rm +CFLAGS = -Wall -g +LDFLAGS = +RCFLAGS = -O coff + +ifdef UNICODE +CFLAGS += -DUNICODE -D_UNICODE +endif + +CFLAGS_DLL = -DSAMPLEDLL_EXPORTS +CFLAGS_EXE = +LDFLAGS_DLL = -shared +LDFLAGS_EXE = -static + +TEST_DLLS = \ + test-align-128.dll \ + test-align-256.dll \ + test-align-512.dll \ + test-align-768.dll \ + test-align-1024.dll \ + test-align-2048.dll \ + test-align-3072.dll \ + test-align-4096.dll \ + test-align-100.dll \ + test-align-200.dll \ + test-align-300.dll \ + test-align-400.dll \ + test-align-500.dll \ + test-align-600.dll \ + test-align-800.dll \ + test-align-900.dll \ + test-align-1000.dll \ + test-relocate.dll \ + +LOADDLL_OBJ = LoadDll.o ../MemoryModule.o +DLL_OBJ = SampleDLL.o SampleDLL.res + +all: LoadDll.exe $(TEST_DLLS) + +LoadDll.exe: $(LOADDLL_OBJ) + $(CC) $(LDFLAGS_EXE) $(LDFLAGS) -Wl,--image-base -Wl,0x20000000 -o LoadDll.exe $(LOADDLL_OBJ) + +LoadDll.o: LoadDll.cpp + $(CXX) $(CFLAGS) $(CFLAGS_EXE) -c $< + +test-align-%.dll: $(DLL_OBJ) + $(LD) $(LDFLAGS_DLL) $(LDFLAGS) --file-alignment $* --section-alignment $* -o $@ $(DLL_OBJ) + +test-relocate.dll: $(DLL_OBJ) + $(CXX) $(LDFLAGS_DLL) $(LDFLAGS) -Wl,--image-base -Wl,0x20000000 -o $@ $(DLL_OBJ) + +%.o: %.cpp + $(CXX) $(CFLAGS) $(CFLAGS_DLL) -c $< + +%.o: %.cc + $(CC) $(CFLAGS) $(CFLAGS_DLL) -c $< + +%.res: %.rc + $(RC) $(RCFLAGS) -o $*.res $< + +clean: + $(RM) -rf LoadDll.exe $(TEST_DLLS) $(LOADDLL_OBJ) $(DLL_OBJ) + +test: all + ./runtests.sh $(PLATFORM) "$(TEST_DLLS)" diff --git a/tests/SampleDLL.cpp b/tests/SampleDLL.cpp new file mode 100644 index 0000000..7bf03ef --- /dev/null +++ b/tests/SampleDLL.cpp @@ -0,0 +1,10 @@ +#include "SampleDLL.h" + +extern "C" { + +SAMPLEDLL_API int addNumbers(int a, int b) +{ + return a + b; +} + +} diff --git a/tests/SampleDLL.h b/tests/SampleDLL.h new file mode 100644 index 0000000..2662c3c --- /dev/null +++ b/tests/SampleDLL.h @@ -0,0 +1,11 @@ +extern "C" { + +#ifdef SAMPLEDLL_EXPORTS +#define SAMPLEDLL_API __declspec(dllexport) +#else +#define SAMPLEDLL_API __declspec(dllimport) +#endif + +SAMPLEDLL_API int addNumbers(int a, int b); + +} diff --git a/tests/SampleDLL.rc b/tests/SampleDLL.rc new file mode 100644 index 0000000..5a0da61 --- /dev/null +++ b/tests/SampleDLL.rc @@ -0,0 +1,34 @@ +1 VERSIONINFO +FILEVERSION 1,0,0,0 +PRODUCTVERSION 1,0,0,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "fancy.code" + VALUE "FileDescription", "SampleDLL" + VALUE "FileVersion", "1.0" + VALUE "InternalName", "SampleDLL" + VALUE "LegalCopyright", "Copyright (c) 2004-2015 Joachim Bauch" + VALUE "OriginalFilename", "SampleDLL.dll" + VALUE "ProductName", "MemoryModule" + VALUE "ProductVersion", "0.0.4" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + + +#define IDS_HELLO 1 +#define IDS_WORLD 20 + +STRINGTABLE +{ + IDS_HELLO, "Hello" + IDS_WORLD, "World!" +} diff --git a/tests/runtests.sh b/tests/runtests.sh new file mode 100755 index 0000000..f998f13 --- /dev/null +++ b/tests/runtests.sh @@ -0,0 +1,20 @@ +#!/bin/bash +if [ "$1" = "x86_64" ]; then + export WINEPREFIX=${HOME}/.wine64/ +else + export WINEPREFIX=${HOME}/.wine/ +fi + +read -a TEST_DLLS <<< $2 + +for filename in "${TEST_DLLS[@]}" +do + : + echo "Testing $filename" + ./LoadDll.exe $filename + if [ "$?" != "0" ]; then + exit 1 + fi +done + +echo "${#TEST_DLLS[@]} tests completed successfully"