diff options
Diffstat (limited to 'sandbox/src/sandbox_nt_util.cc')
-rw-r--r-- | sandbox/src/sandbox_nt_util.cc | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/sandbox/src/sandbox_nt_util.cc b/sandbox/src/sandbox_nt_util.cc index 008c02d..a7f1be0 100644 --- a/sandbox/src/sandbox_nt_util.cc +++ b/sandbox/src/sandbox_nt_util.cc @@ -277,22 +277,31 @@ UNICODE_STRING* AnsiToUnicode(const char* string) { return out_string; } -UNICODE_STRING* GetImageNameFromModule(HMODULE module) { +UNICODE_STRING* GetImageInfoFromModule(HMODULE module, uint32* flags) { UNICODE_STRING* out_name = NULL; __try { do { + *flags = 0; PEImage pe(module); if (!pe.VerifyMagic()) break; + *flags |= MODULE_IS_PE_IMAGE; PIMAGE_EXPORT_DIRECTORY exports = pe.GetExportDirectory(); - if (!exports) - break; + if (exports) { + char* name = reinterpret_cast<char*>(pe.RVAToAddr(exports->Name)); + out_name = AnsiToUnicode(name); + } - char* name = reinterpret_cast<char*>(pe.RVAToAddr(exports->Name)); + PIMAGE_NT_HEADERS headers = pe.GetNTHeaders(); + if (headers) { + if (headers->OptionalHeader.AddressOfEntryPoint) + *flags |= MODULE_HAS_ENTRY_POINT; + if (headers->OptionalHeader.SizeOfCode) + *flags |= MODULE_HAS_CODE; + } - out_name = AnsiToUnicode(name); } while (false); } __except(EXCEPTION_EXECUTE_HANDLER) { } @@ -332,6 +341,51 @@ UNICODE_STRING* GetBackingFilePath(PVOID address) { } } +UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path) { + if ((!module_path) || (!module_path->Buffer)) + return NULL; + + wchar_t* sep = NULL; + int start_pos = module_path->Length / sizeof(wchar_t) - 1; + int ix = start_pos; + + for(; ix >= 0; --ix) { + if (module_path->Buffer[ix] == L'\\') { + sep = &module_path->Buffer[ix]; + break; + } + } + + // Ends with path separator. Not a valid module name. + if ((ix == start_pos) && sep) + return NULL; + + // No path separator found. Use the entire name. + if ((ix == 0) && !sep) { + sep = &module_path->Buffer[-1]; + } + + // Add one to the size so we can null terminate the string. + size_t size_bytes = (start_pos - ix + 1) * sizeof(wchar_t); + char* str_buffer = new(NT_ALLOC) char[size_bytes + sizeof(UNICODE_STRING)]; + if (!str_buffer) + return NULL; + + UNICODE_STRING* out_string = reinterpret_cast<UNICODE_STRING*>(str_buffer); + out_string->Buffer = reinterpret_cast<wchar_t*>(&out_string[1]); + out_string->Length = size_bytes - sizeof(wchar_t); + out_string->MaximumLength = size_bytes; + + NTSTATUS ret = CopyData(out_string->Buffer, &sep[1], out_string->Length); + if (!NT_SUCCESS(ret)) { + operator delete(out_string, NT_ALLOC); + return NULL; + } + + out_string->Buffer[out_string->Length / sizeof(wchar_t)] = L'\0'; + return out_string; +} + NTSTATUS AutoProtectMemory::ChangeProtection(void* address, size_t bytes, ULONG protect) { DCHECK_NT(!changed_); |