ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MemLoadLibraryCPP

2021-09-15 10:00:43  阅读:269  来源: 互联网

标签:RESOURCE module codeBase MemLoadLibraryCPP result PIMAGE NULL


  1 /*
  2  * Memory DLL loading code
  3  * Version 0.0.3
  4  *
  5  * Copyright (c) 2004-2013 by Joachim Bauch / mail@joachim-bauch.de
  6  * http://www.joachim-bauch.de
  7  *
  8  * The contents of this file are subject to the Mozilla Public License Version
  9  * 2.0 (the "License"); you may not use this file except in compliance with
 10  * the License. You may obtain a copy of the License at
 11  * http://www.mozilla.org/MPL/
 12  *
 13  * Software distributed under the License is distributed on an "AS IS" basis,
 14  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 15  * for the specific language governing rights and limitations under the
 16  * License.
 17  *
 18  * The Original Code is MemoryModule.c
 19  *
 20  * The Initial Developer of the Original Code is Joachim Bauch.
 21  *
 22  * Portions created by Joachim Bauch are Copyright (C) 2004-2013
 23  * Joachim Bauch. All Rights Reserved.
 24  *
 25  */
 26 
 27 #include "StdAfx.h"
 28 #ifndef __GNUC__
 29 // disable warnings about pointer <-> DWORD conversions
 30 #pragma warning( disable : 4311 4312 )
 31 #endif
 32 
 33 #ifdef _WIN64
 34 #define POINTER_TYPE ULONGLONG
 35 #else
 36 #define POINTER_TYPE DWORD
 37 #endif
 38 
 39 #include <windows.h>
 40 #include <winnt.h>
 41 #include <tchar.h>
 42 #ifdef DEBUG_OUTPUT
 43 #include <stdio.h>
 44 #endif
 45 
 46 #ifndef IMAGE_SIZEOF_BASE_RELOCATION
 47 // Vista SDKs no longer define IMAGE_SIZEOF_BASE_RELOCATION!?
 48 #define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION))
 49 #endif
 50 
 51 #include "MemoryModule.h"
 52 
 53 typedef struct {
 54     PIMAGE_NT_HEADERS headers;
 55     unsigned char *codeBase;
 56     HCUSTOMMODULE *modules;
 57     int numModules;
 58     int initialized;
 59     CustomLoadLibraryFunc loadLibrary;
 60     CustomGetProcAddressFunc getProcAddress;
 61     CustomFreeLibraryFunc freeLibrary;
 62     void *userdata;
 63 } MEMORYMODULE, *PMEMORYMODULE;
 64 
 65 typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
 66 
 67 #define GET_HEADER_DICTIONARY(module, idx)    &(module)->headers->OptionalHeader.DataDirectory[idx]
 68 
 69 #ifdef DEBUG_OUTPUT
 70 static void
 71 OutputLastError(const char *msg)
 72 {
 73     LPVOID tmp;
 74     char *tmpmsg;
 75     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
 76         NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL);
 77     tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3);
 78     sprintf(tmpmsg, "%s: %s", msg, tmp);
 79     OutputDebugString(tmpmsg);
 80     LocalFree(tmpmsg);
 81     LocalFree(tmp);
 82 }
 83 #endif
 84 
 85 static void
 86 CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module)
 87 {
 88     int i, size;
 89     unsigned char *codeBase = module->codeBase;
 90     unsigned char *dest;
 91     PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
 92     for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) {
 93         if (section->SizeOfRawData == 0) {
 94             // section doesn't contain data in the dll itself, but may define
 95             // uninitialized data
 96             size = old_headers->OptionalHeader.SectionAlignment;
 97             if (size > 0) {
 98                 dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
 99                     size,
100                     MEM_COMMIT,
101                     PAGE_READWRITE);
102 
103                 section->Misc.PhysicalAddress = (DWORD) (POINTER_TYPE) dest;
104                 memset(dest, 0, size);
105             }
106 
107             // section is empty
108             continue;
109         }
110 
111         // commit memory block and copy data from dll
112         dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
113                             section->SizeOfRawData,
114                             MEM_COMMIT,
115                             PAGE_READWRITE);
116         memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData);
117         section->Misc.PhysicalAddress = (DWORD) (POINTER_TYPE) dest;
118     }
119 }
120 
121 // Protection flags for memory pages (Executable, Readable, Writeable)
122 static int ProtectionFlags[2][2][2] = {
123     {
124         // not executable
125         {PAGE_NOACCESS, PAGE_WRITECOPY},
126         {PAGE_READONLY, PAGE_READWRITE},
127     }, {
128         // executable
129         {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY},
130         {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE},
131     },
132 };
133 
134 static void
135 FinalizeSections(PMEMORYMODULE module)
136 {
137     int i;
138     PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
139 #ifdef _WIN64
140     POINTER_TYPE imageOffset = (module->headers->OptionalHeader.ImageBase & 0xffffffff00000000);
141 #else
142     #define imageOffset 0
143 #endif
144     
145     // loop through all sections and change access flags
146     for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) {
147         DWORD protect, oldProtect, size;
148         int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
149         int readable =   (section->Characteristics & IMAGE_SCN_MEM_READ) != 0;
150         int writeable =  (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0;
151 
152         if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) {
153             // section is not needed any more and can safely be freed
154             VirtualFree((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), section->SizeOfRawData, MEM_DECOMMIT);
155             continue;
156         }
157 
158         // determine protection flags based on characteristics
159         protect = ProtectionFlags[executable][readable][writeable];
160         if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) {
161             protect |= PAGE_NOCACHE;
162         }
163 
164         // determine size of region
165         size = section->SizeOfRawData;
166         if (size == 0) {
167             if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) {
168                 size = module->headers->OptionalHeader.SizeOfInitializedData;
169             } else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
170                 size = module->headers->OptionalHeader.SizeOfUninitializedData;
171             }
172         }
173 
174         if (size > 0) 
175         {
176             // change memory access flags
177             if (VirtualProtect((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), size, protect, &oldProtect) == 0)
178             {
179 #ifdef DEBUG_OUTPUT
180                 OutputLastError("Error protecting memory page");
181 #endif 
182             }
183         }
184     }
185 #ifndef _WIN64
186 #undef imageOffset
187 #endif
188 }
189 
190 static void
191 PerformBaseRelocation(PMEMORYMODULE module, SIZE_T delta)
192 {
193     DWORD i;
194     unsigned char *codeBase = module->codeBase;
195 
196     PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC);
197     if (directory->Size > 0) {
198         PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION) (codeBase + directory->VirtualAddress);
199         for (; relocation->VirtualAddress > 0; ) {
200             unsigned char *dest = codeBase + relocation->VirtualAddress;
201             unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION);
202             for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++) {
203                 DWORD *patchAddrHL;
204 #ifdef _WIN64
205                 ULONGLONG *patchAddr64;
206 #endif
207                 int type, offset;
208 
209                 // the upper 4 bits define the type of relocation
210                 type = *relInfo >> 12;
211                 // the lower 12 bits define the offset
212                 offset = *relInfo & 0xfff;
213                 
214                 switch (type)
215                 {
216                 case IMAGE_REL_BASED_ABSOLUTE:
217                     // skip relocation
218                     break;
219 
220                 case IMAGE_REL_BASED_HIGHLOW:
221                     // change complete 32 bit address
222                     patchAddrHL = (DWORD *) (dest + offset);
223                     *patchAddrHL += (DWORD) delta;
224                     break;
225                 
226 #ifdef _WIN64
227                 case IMAGE_REL_BASED_DIR64:
228                     patchAddr64 = (ULONGLONG *) (dest + offset);
229                     *patchAddr64 += (ULONGLONG) delta;
230                     break;
231 #endif
232 
233                 default:
234                     //printf("Unknown relocation: %d\n", type);
235                     break;
236                 }
237             }
238 
239             // advance to next relocation block
240             relocation = (PIMAGE_BASE_RELOCATION) (((char *) relocation) + relocation->SizeOfBlock);
241         }
242     }
243 }
244 
245 static int
246 BuildImportTable(PMEMORYMODULE module)
247 {
248     int result=1;
249     unsigned char *codeBase = module->codeBase;
250     HCUSTOMMODULE *tmp;
251 
252     PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
253     if (directory->Size > 0) {
254         PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (codeBase + directory->VirtualAddress);
255         for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) {
256             POINTER_TYPE *thunkRef;
257             FARPROC *funcRef;
258             HCUSTOMMODULE handle = module->loadLibrary((LPCSTR) (codeBase + importDesc->Name), module->userdata);
259             if (handle == NULL) {
260                 SetLastError(ERROR_MOD_NOT_FOUND);
261                 result = 0;
262                 break;
263             }
264 
265             tmp = (HCUSTOMMODULE *) realloc(module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE)));
266             if (tmp == NULL) {
267                 module->freeLibrary(handle, module->userdata);
268                 SetLastError(ERROR_OUTOFMEMORY);
269                 result = 0;
270                 break;
271             }
272             module->modules = tmp;
273 
274             module->modules[module->numModules++] = handle;
275             if (importDesc->OriginalFirstThunk) {
276                 thunkRef = (POINTER_TYPE *) (codeBase + importDesc->OriginalFirstThunk);
277                 funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk);
278             } else {
279                 // no hint table
280                 thunkRef = (POINTER_TYPE *) (codeBase + importDesc->FirstThunk);
281                 funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk);
282             }
283             for (; *thunkRef; thunkRef++, funcRef++) {
284                 if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) {
285                     *funcRef = module->getProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef), module->userdata);
286                 } else {
287                     PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef));
288                     *funcRef = module->getProcAddress(handle, (LPCSTR)&thunkData->Name, module->userdata);
289                 }
290                 if (*funcRef == 0) {
291                     result = 0;
292                     break;
293                 }
294             }
295 
296             if (!result) {
297                 module->freeLibrary(handle, module->userdata);
298                 SetLastError(ERROR_PROC_NOT_FOUND);
299                 break;
300             }
301         }
302     }
303 
304     return result;
305 }
306 
307 static HCUSTOMMODULE _LoadLibrary(LPCSTR filename, void *userdata)
308 {
309     HMODULE result = LoadLibraryA(filename);
310     if (result == NULL) {
311         return NULL;
312     }
313     
314     return (HCUSTOMMODULE) result;
315 }
316 
317 static FARPROC _GetProcAddress(HCUSTOMMODULE module, LPCSTR name, void *userdata)
318 {
319     return (FARPROC) GetProcAddress((HMODULE) module, name);
320 }
321 
322 static void _FreeLibrary(HCUSTOMMODULE module, void *userdata)
323 {
324     FreeLibrary((HMODULE) module);
325 }
326 
327 HMEMORYMODULE MemoryLoadLibrary(const void *data)
328 {
329     return MemoryLoadLibraryEx(data, _LoadLibrary, _GetProcAddress, _FreeLibrary, NULL);
330 }
331 
332 HMEMORYMODULE MemoryLoadLibraryEx(const void *data,
333     CustomLoadLibraryFunc loadLibrary,
334     CustomGetProcAddressFunc getProcAddress,
335     CustomFreeLibraryFunc freeLibrary,
336     void *userdata)
337 {
338     PMEMORYMODULE result;
339     PIMAGE_DOS_HEADER dos_header;
340     PIMAGE_NT_HEADERS old_header;
341     unsigned char *code, *headers;
342     SIZE_T locationDelta;
343     DllEntryProc DllEntry;
344     BOOL successfull;
345 
346     dos_header = (PIMAGE_DOS_HEADER)data;
347     if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
348         SetLastError(ERROR_BAD_EXE_FORMAT);
349         return NULL;
350     }
351 
352     old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew];
353     if (old_header->Signature != IMAGE_NT_SIGNATURE) {
354         SetLastError(ERROR_BAD_EXE_FORMAT);
355         return NULL;
356     }
357 
358     // reserve memory for image of library
359     // XXX: is it correct to commit the complete memory region at once?
360     //      calling DllEntry raises an exception if we don't...
361     code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase),
362         old_header->OptionalHeader.SizeOfImage,
363         MEM_RESERVE | MEM_COMMIT,
364         PAGE_READWRITE);
365 
366     if (code == NULL) {
367         // try to allocate memory at arbitrary position
368         code = (unsigned char *)VirtualAlloc(NULL,
369             old_header->OptionalHeader.SizeOfImage,
370             MEM_RESERVE | MEM_COMMIT,
371             PAGE_READWRITE);
372         if (code == NULL) {
373             SetLastError(ERROR_OUTOFMEMORY);
374             return NULL;
375         }
376     }
377     
378     result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, sizeof(MEMORYMODULE));
379     if (result == NULL) {
380         SetLastError(ERROR_OUTOFMEMORY);
381         VirtualFree(code, 0, MEM_RELEASE);
382         return NULL;
383     }
384 
385     result->codeBase = code;
386     result->numModules = 0;
387     result->modules = NULL;
388     result->initialized = 0;
389     result->loadLibrary = loadLibrary;
390     result->getProcAddress = getProcAddress;
391     result->freeLibrary = freeLibrary;
392     result->userdata = userdata;
393 
394     // commit memory for headers
395     headers = (unsigned char *)VirtualAlloc(code,
396         old_header->OptionalHeader.SizeOfHeaders,
397         MEM_COMMIT,
398         PAGE_READWRITE);
399     
400     // copy PE header to code
401     memcpy(headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders);
402     result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew];
403 
404     // update position
405     result->headers->OptionalHeader.ImageBase = (POINTER_TYPE)code;
406 
407     // copy sections from DLL file block to new memory location
408     CopySections((UCHAR *)data, old_header, result);
409 
410     // adjust base address of imported data
411     locationDelta = (SIZE_T)(code - old_header->OptionalHeader.ImageBase);
412     if (locationDelta != 0) {
413         PerformBaseRelocation(result, locationDelta);
414     }
415 
416     // load required dlls and adjust function table of imports
417     if (!BuildImportTable(result)) {
418         goto error;
419     }
420 
421     // mark memory pages depending on section headers and release
422     // sections that are marked as "discardable"
423     FinalizeSections(result);
424 
425     // get entry point of loaded library
426     if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) {
427         DllEntry = (DllEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint);
428         // notify library about attaching to process
429         successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);
430         if (!successfull) {
431             SetLastError(ERROR_DLL_INIT_FAILED);
432             goto error;
433         }
434         result->initialized = 1;
435     }
436 
437     return (HMEMORYMODULE)result;
438 
439 error:
440     // cleanup
441     MemoryFreeLibrary(result);
442     return NULL;
443 }
444 
445 FARPROC MemoryGetProcAddress(HMEMORYMODULE module, LPCSTR name)
446 {
447     unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase;
448     int idx=-1;
449     DWORD i, *nameRef;
450     WORD *ordinal;
451     PIMAGE_EXPORT_DIRECTORY exports;
452     PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT);
453     if (directory->Size == 0) {
454         // no export table found
455         SetLastError(ERROR_PROC_NOT_FOUND);
456         return NULL;
457     }
458 
459     exports = (PIMAGE_EXPORT_DIRECTORY) (codeBase + directory->VirtualAddress);
460     if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) {
461         // DLL doesn't export anything
462         SetLastError(ERROR_PROC_NOT_FOUND);
463         return NULL;
464     }
465 
466     // search function name in list of exported names
467     nameRef = (DWORD *) (codeBase + exports->AddressOfNames);
468     ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals);
469     for (i=0; i<exports->NumberOfNames; i++, nameRef++, ordinal++) {
470         if (_stricmp(name, (const char *) (codeBase + (*nameRef))) == 0) {
471             idx = *ordinal;
472             break;
473         }
474     }
475 
476     if (idx == -1) {
477         // exported symbol not found
478         SetLastError(ERROR_PROC_NOT_FOUND);
479         return NULL;
480     }
481 
482     if ((DWORD)idx > exports->NumberOfFunctions) {
483         // name <-> ordinal number don't match
484         SetLastError(ERROR_PROC_NOT_FOUND);
485         return NULL;
486     }
487 
488     // AddressOfFunctions contains the RVAs to the "real" functions
489     return (FARPROC) (codeBase + (*(DWORD *) (codeBase + exports->AddressOfFunctions + (idx*4))));
490 }
491 
492 void MemoryFreeLibrary(HMEMORYMODULE mod)
493 {
494     int i;
495     PMEMORYMODULE module = (PMEMORYMODULE)mod;
496 
497     if (module != NULL) {
498         if (module->initialized != 0) {
499             // notify library about detaching from process
500             DllEntryProc DllEntry = (DllEntryProc) (module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint);
501             (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0);
502             module->initialized = 0;
503         }
504 
505         if (module->modules != NULL) {
506             // free previously opened libraries
507             for (i=0; i<module->numModules; i++) {
508                 if (module->modules[i] != NULL) {
509                     module->freeLibrary(module->modules[i], module->userdata);
510                 }
511             }
512 
513             free(module->modules);
514         }
515 
516         if (module->codeBase != NULL) {
517             // release memory of library
518             VirtualFree(module->codeBase, 0, MEM_RELEASE);
519         }
520 
521         HeapFree(GetProcessHeap(), 0, module);
522     }
523 }
524 
525 #define DEFAULT_LANGUAGE        MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
526 
527 HMEMORYRSRC MemoryFindResource(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type)
528 {
529     return MemoryFindResourceEx(module, name, type, DEFAULT_LANGUAGE);
530 }
531 
532 static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry(
533     void *root,
534     PIMAGE_RESOURCE_DIRECTORY resources,
535     LPCTSTR key)
536 {
537     PIMAGE_RESOURCE_DIRECTORY_ENTRY entries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (resources + 1);
538     PIMAGE_RESOURCE_DIRECTORY_ENTRY result = NULL;
539     DWORD start;
540     DWORD end;
541     DWORD middle;
542     
543     if (!IS_INTRESOURCE(key) && key[0] == TEXT('#')) {
544         // special case: resource id given as string
545         TCHAR *endpos = NULL;
546 #if defined(UNICODE)
547         long int tmpkey = (WORD) wcstol((TCHAR *) &key[1], &endpos, 10);
548 #else
549         long int tmpkey = (WORD) strtol((TCHAR *) &key[1], &endpos, 10);
550 #endif
551         if (tmpkey <= 0xffff && lstrlen(endpos) == 0) {
552             key = MAKEINTRESOURCE(tmpkey);
553         }
554     }
555     
556     // entries are stored as ordered list of named entries,
557     // followed by an ordered list of id entries - we can do
558     // a binary search to find faster...
559     if (IS_INTRESOURCE(key)) {
560         WORD check = (WORD) (POINTER_TYPE) key;
561         start = resources->NumberOfNamedEntries;
562         end = start + resources->NumberOfIdEntries;
563         
564         while (end > start) {
565             WORD entryName;
566             middle = (start + end) >> 1;
567             entryName = (WORD) entries[middle].Name;
568             if (check < entryName) {
569                 end = (end != middle ? middle : middle-1);
570             } else if (check > entryName) {
571                 start = (start != middle ? middle : middle+1);
572             } else {
573                 result = &entries[middle];
574                 break;
575             }
576         }
577     } else {
578 #if !defined(UNICODE)
579         char *searchKey = NULL;
580         int searchKeyLength = 0;
581 #endif
582         start = 0;
583         end = resources->NumberOfIdEntries;
584         while (end > start) {
585             // resource names are always stored using 16bit characters
586             int cmp;
587             PIMAGE_RESOURCE_DIR_STRING_U resourceString;
588             middle = (start + end) >> 1;
589             resourceString = (PIMAGE_RESOURCE_DIR_STRING_U) (((char *) root) + (entries[middle].Name & 0x7FFFFFFF));
590 #if !defined(UNICODE)
591             if (searchKey == NULL || searchKeyLength < resourceString->Length) {
592                 void *tmp = realloc(searchKey, resourceString->Length);
593                 if (tmp == NULL) {
594                     break;
595                 }
596                 
597                 searchKey = (char *) tmp;
598             }
599             wcstombs(searchKey, resourceString->NameString, resourceString->Length);
600             cmp = strncmp(key, searchKey, resourceString->Length);
601 #else
602             cmp = wcsncmp(key, resourceString->NameString, resourceString->Length);
603 #endif
604             if (cmp < 0) {
605                 end = (middle != end ? middle : middle-1);
606             } else if (cmp > 0) {
607                 start = (middle != start ? middle : middle+1);
608             } else {
609                 result = &entries[middle];
610                 break;
611             }
612         }
613 #if !defined(UNICODE)
614         free(searchKey);
615 #endif
616     }
617     
618     
619     return result;
620 }
621 
622 HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type, WORD language)
623 {
624     unsigned char *codeBase = ((PMEMORYMODULE) module)->codeBase;
625     PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE) module, IMAGE_DIRECTORY_ENTRY_RESOURCE);
626     PIMAGE_RESOURCE_DIRECTORY rootResources;
627     PIMAGE_RESOURCE_DIRECTORY nameResources;
628     PIMAGE_RESOURCE_DIRECTORY typeResources;
629     PIMAGE_RESOURCE_DIRECTORY_ENTRY foundType;
630     PIMAGE_RESOURCE_DIRECTORY_ENTRY foundName;
631     PIMAGE_RESOURCE_DIRECTORY_ENTRY foundLanguage;
632     if (directory->Size == 0) {
633         // no resource table found
634         SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
635         return NULL;
636     }
637     
638     if (language == DEFAULT_LANGUAGE) {
639         // use language from current thread
640         language = LANGIDFROMLCID(GetThreadLocale());
641     }
642 
643     // resources are stored as three-level tree
644     // - first node is the type
645     // - second node is the name
646     // - third node is the language
647     rootResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress);
648     foundType = _MemorySearchResourceEntry(rootResources, rootResources, type);
649     if (foundType == NULL) {
650         SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
651         return NULL;
652     }
653     
654     typeResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundType->OffsetToData & 0x7fffffff));
655     foundName = _MemorySearchResourceEntry(rootResources, typeResources, name);
656     if (foundName == NULL) {
657         SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
658         return NULL;
659     }
660     
661     nameResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundName->OffsetToData & 0x7fffffff));
662     foundLanguage = _MemorySearchResourceEntry(rootResources, nameResources, (LPCTSTR) (POINTER_TYPE) language);
663     if (foundLanguage == NULL) {
664         // requested language not found, use first available
665         if (nameResources->NumberOfIdEntries == 0) {
666             SetLastError(ERROR_RESOURCE_LANG_NOT_FOUND);
667             return NULL;
668         }
669         
670         foundLanguage = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (nameResources + 1);
671     }
672     
673     return (codeBase + directory->VirtualAddress + (foundLanguage->OffsetToData & 0x7fffffff));
674 }
675 
676 DWORD MemorySizeofResource(HMEMORYMODULE module, HMEMORYRSRC resource)
677 {
678     PIMAGE_RESOURCE_DATA_ENTRY entry = (PIMAGE_RESOURCE_DATA_ENTRY) resource;
679     
680     return entry->Size;
681 }
682 
683 LPVOID MemoryLoadResource(HMEMORYMODULE module, HMEMORYRSRC resource)
684 {
685     unsigned char *codeBase = ((PMEMORYMODULE) module)->codeBase;
686     PIMAGE_RESOURCE_DATA_ENTRY entry = (PIMAGE_RESOURCE_DATA_ENTRY) resource;
687     
688     return codeBase + entry->OffsetToData;
689 }
690 
691 int
692 MemoryLoadString(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize)
693 {
694     return MemoryLoadStringEx(module, id, buffer, maxsize, DEFAULT_LANGUAGE);
695 }
696 
697 int
698 MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WORD language)
699 {
700     HMEMORYRSRC resource;
701     PIMAGE_RESOURCE_DIR_STRING_U data;
702     DWORD size;
703     if (maxsize == 0) {
704         return 0;
705     }
706     
707     resource = MemoryFindResourceEx(module, MAKEINTRESOURCE((id >> 4) + 1), RT_STRING, language);
708     if (resource == NULL) {
709         buffer[0] = 0;
710         return 0;
711     }
712     
713     data = (PIMAGE_RESOURCE_DIR_STRING_U)MemoryLoadResource(module, resource);
714     id = id & 0x0f;
715     while (id--) {
716         data = (PIMAGE_RESOURCE_DIR_STRING_U) (((char *) data) + (data->Length + 1) * sizeof(WCHAR));
717     }
718     if (data->Length == 0) {
719         SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
720         buffer[0] = 0;
721         return 0;
722     }
723     
724     size = data->Length;
725     if (size >= (DWORD) maxsize) {
726         size = maxsize;
727     } else {
728         buffer[size] = 0;
729     }
730 #if defined(UNICODE)
731     wcsncpy(buffer, data->NameString, size);
732 #else
733     wcstombs(buffer, data->NameString, size);
734 #endif
735     return size;
736 }

 

标签:RESOURCE,module,codeBase,MemLoadLibraryCPP,result,PIMAGE,NULL
来源: https://www.cnblogs.com/admrty/p/15270936.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有