LoadDll.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #define WIN32_LEAN_AND_MEAN
  2. #ifndef _CRT_SECURE_NO_WARNINGS
  3. #define _CRT_SECURE_NO_WARNINGS
  4. #endif
  5. #include <assert.h>
  6. #include <windows.h>
  7. #include <tchar.h>
  8. #include <stdio.h>
  9. #include <malloc.h>
  10. #include "../MemoryModule.h"
  11. typedef int (*addNumberProc)(int, int);
  12. // Thanks to Tim Cooper (from http://stackoverflow.com/a/8584708)
  13. const char *sstrstr(const char *haystack, const char *needle, size_t length) {
  14. size_t needle_length = strlen(needle);
  15. size_t i;
  16. for (i = 0; i < length; i++) {
  17. if (i + needle_length > length) {
  18. return NULL;
  19. }
  20. if (strncmp(&haystack[i], needle, needle_length) == 0) {
  21. return &haystack[i];
  22. }
  23. }
  24. return NULL;
  25. }
  26. const wchar_t *swcsstr(const wchar_t *haystack, const wchar_t *needle, size_t length) {
  27. size_t needle_length = wcslen(needle);
  28. size_t i;
  29. for (i = 0; i < length; i++) {
  30. if (i + needle_length > length) {
  31. return NULL;
  32. }
  33. if (wcsncmp(&haystack[i], needle, needle_length) == 0) {
  34. return &haystack[i];
  35. }
  36. }
  37. return NULL;
  38. }
  39. BOOL CheckResourceStrings(LPVOID data, DWORD size, const char *first, const wchar_t *second) {
  40. const char *first_pos;
  41. const wchar_t *second_pos;
  42. const wchar_t *src;
  43. if (data == NULL || size == 0) {
  44. return FALSE;
  45. }
  46. first_pos = sstrstr((const char *) data, first, size);
  47. if (first_pos == NULL) {
  48. fprintf(stderr, "ERROR: data doesn't start with %s\n", first);
  49. return FALSE;
  50. }
  51. src = (const wchar_t *) (((const char *) data) + strlen(first) + 1);
  52. second_pos = swcsstr(src, second, (size - strlen(first) - 1) / sizeof(wchar_t));
  53. if (second_pos == NULL) {
  54. fwprintf(stderr, L"ERROR: data doesn't continue with %s\n", second);
  55. return FALSE;
  56. }
  57. return TRUE;
  58. }
  59. BOOL LoadFromMemory(char *filename)
  60. {
  61. FILE *fp;
  62. unsigned char *data=NULL;
  63. long size;
  64. size_t read;
  65. HMEMORYMODULE handle = NULL;
  66. addNumberProc addNumber;
  67. addNumberProc addNumber2;
  68. HMEMORYRSRC resourceInfo;
  69. DWORD resourceSize;
  70. LPVOID resourceData;
  71. TCHAR buffer[100];
  72. BOOL result = TRUE;
  73. fp = fopen(filename, "rb");
  74. if (fp == NULL)
  75. {
  76. printf("Can't open DLL file \"%s\".", filename);
  77. result = FALSE;
  78. goto exit;
  79. }
  80. fseek(fp, 0, SEEK_END);
  81. size = ftell(fp);
  82. assert(size > 0);
  83. data = (unsigned char *)malloc(size);
  84. assert(data != NULL);
  85. fseek(fp, 0, SEEK_SET);
  86. read = fread(data, 1, size, fp);
  87. assert(read == static_cast<size_t>(size));
  88. fclose(fp);
  89. handle = MemoryLoadLibrary(data, size);
  90. if (handle == NULL)
  91. {
  92. _tprintf(_T("Can't load library from memory.\n"));
  93. result = FALSE;
  94. goto exit;
  95. }
  96. addNumber = (addNumberProc)MemoryGetProcAddress(handle, NULL);
  97. if (addNumber != NULL) {
  98. _tprintf(_T("MemoryGetProcAddress(NULL) returned %p\n"), addNumber);
  99. result = FALSE;
  100. goto exit;
  101. }
  102. addNumber = (addNumberProc)MemoryGetProcAddress(handle, reinterpret_cast<LPCSTR>(0xff));
  103. if (addNumber != NULL) {
  104. _tprintf(_T("MemoryGetProcAddress(0xff) returned %p\n"), addNumber);
  105. result = FALSE;
  106. goto exit;
  107. }
  108. addNumber = (addNumberProc)MemoryGetProcAddress(handle, "addNumbers");
  109. _tprintf(_T("From memory: %d\n"), addNumber(1, 2));
  110. // the DLL only exports one function, try to load by ordinal value
  111. addNumber2 = (addNumberProc)MemoryGetProcAddress(handle, reinterpret_cast<LPCSTR>(0x01));
  112. if (addNumber != addNumber2) {
  113. _tprintf(_T("MemoryGetProcAddress(0x01) returned %p (expected %p)\n"), addNumber2, addNumber);
  114. result = FALSE;
  115. goto exit;
  116. }
  117. resourceInfo = MemoryFindResource(handle, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
  118. _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
  119. if (resourceInfo != NULL) {
  120. resourceSize = MemorySizeofResource(handle, resourceInfo);
  121. resourceData = MemoryLoadResource(handle, resourceInfo);
  122. _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
  123. MemoryLoadString(handle, 1, buffer, sizeof(buffer));
  124. _tprintf(_T("String1: %s\n"), buffer);
  125. MemoryLoadString(handle, 20, buffer, sizeof(buffer));
  126. _tprintf(_T("String2: %s\n"), buffer);
  127. } else {
  128. result = FALSE;
  129. }
  130. resourceInfo = MemoryFindResource(handle, _T("stringres"), RT_RCDATA);
  131. _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
  132. if (resourceInfo != NULL) {
  133. resourceSize = MemorySizeofResource(handle, resourceInfo);
  134. resourceData = MemoryLoadResource(handle, resourceInfo);
  135. _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
  136. if (!CheckResourceStrings(resourceData, resourceSize, "This is a ANSI string", L"This is a UNICODE string")) {
  137. result = FALSE;
  138. }
  139. } else {
  140. result = FALSE;
  141. }
  142. resourceInfo = MemoryFindResource(handle, _T("stringres1"), RT_RCDATA);
  143. _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
  144. if (resourceInfo != NULL) {
  145. resourceSize = MemorySizeofResource(handle, resourceInfo);
  146. resourceData = MemoryLoadResource(handle, resourceInfo);
  147. _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
  148. if (!CheckResourceStrings(resourceData, resourceSize, "This is ANSI string 1", L"This is UNICODE string 1")) {
  149. result = FALSE;
  150. }
  151. } else {
  152. result = FALSE;
  153. }
  154. resourceInfo = MemoryFindResource(handle, _T("stringres2"), RT_RCDATA);
  155. _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
  156. if (resourceInfo != NULL) {
  157. resourceSize = MemorySizeofResource(handle, resourceInfo);
  158. resourceData = MemoryLoadResource(handle, resourceInfo);
  159. _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
  160. if (!CheckResourceStrings(resourceData, resourceSize, "This is ANSI string 2", L"This is UNICODE string 2")) {
  161. result = FALSE;
  162. }
  163. } else {
  164. result = FALSE;
  165. }
  166. resourceInfo = MemoryFindResource(handle, _T("stringres3"), RT_RCDATA);
  167. _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
  168. if (resourceInfo != NULL) {
  169. resourceSize = MemorySizeofResource(handle, resourceInfo);
  170. resourceData = MemoryLoadResource(handle, resourceInfo);
  171. _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
  172. if (!CheckResourceStrings(resourceData, resourceSize, "This is ANSI string 3", L"This is UNICODE string 3")) {
  173. result = FALSE;
  174. }
  175. } else {
  176. result = FALSE;
  177. }
  178. exit:
  179. MemoryFreeLibrary(handle);
  180. free(data);
  181. return result;
  182. }
  183. int main(int argc, char* argv[])
  184. {
  185. if (argc < 2) {
  186. fprintf(stderr, "USAGE: %s <filename.dll>\n", argv[0]);
  187. return 1;
  188. }
  189. if (!LoadFromMemory(argv[1])) {
  190. return 2;
  191. }
  192. return 0;
  193. }