static inline bool get_system_time_of_day_information(system_timeofday_information &info) { NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t) get_proc_address(get_module_handle("ntdll.dll"), "NtQuerySystemInformation"); unsigned long res; long status = pNtQuerySystemInformation(system_time_of_day_information, &info, sizeof(info), &res); if(status){ return false; } return true; }
void inject_init() { HANDLE kern32 = get_module_handle(L"KERNEL32.DLL"); ASSERT(kern32 != NULL); addr_getprocaddr = (ptr_uint_t) GET_PROC_ADDR(kern32, "GetProcAddress"); ASSERT(addr_getprocaddr != 0); addr_loadlibrarya = (ptr_uint_t) GET_PROC_ADDR(kern32, "LoadLibraryA"); ASSERT(addr_loadlibrarya != 0); # ifdef LOAD_DYNAMO_DEBUGBREAK addr_debugbreak = (ptr_uint_t) GET_PROC_ADDR(kern32, "DebugBreak"); ASSERT(addr_debugbreak != NULL); # endif inject_initialized = true; }
static inline bool unlink_file(const char *filename) { try{ NtSetInformationFile_t pNtSetInformationFile = (NtSetInformationFile_t)get_proc_address(get_module_handle("ntdll.dll"), "NtSetInformationFile"); if(!pNtSetInformationFile){ return false; } NtQueryObject_t pNtQueryObject = (NtQueryObject_t)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject"); //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths void *fh = create_file(filename, generic_read | delete_access, open_existing, file_flag_backup_semantics | file_flag_delete_on_close); if(fh == invalid_handle_value){ return false; } class handle_closer { void *handle_; public: handle_closer(void *handle) : handle_(handle){} ~handle_closer(){ close_handle(handle_); } } handle_closer(fh); const std::size_t CharArraySize = 32767; //Max name length union mem_t { object_name_information_t name; struct ren_t { file_rename_information_t info; wchar_t buf[CharArraySize]; } ren; }; class auto_ptr { public: explicit auto_ptr(mem_t *ptr) : ptr_(ptr){} ~auto_ptr(){ delete ptr_; } mem_t *get() const{ return (ptr_); } mem_t *operator->() const{ return this->get(); } private: mem_t *ptr_; } pmem(new mem_t); file_rename_information_t *pfri = (file_rename_information_t*)&pmem->ren.info; const std::size_t RenMaxNumChars = ((char*)pmem.get() - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t); //Obtain file name unsigned long size; if(pNtQueryObject(fh, object_name_information, pmem.get(), sizeof(mem_t), &size)){ return false; } //Copy filename to the rename member std::memmove(pmem->ren.info.FileName, pmem->name.Name.Buffer, pmem->name.Name.Length); std::size_t filename_string_length = pmem->name.Name.Length/sizeof(wchar_t); //Second step: obtain the complete native-nt filename //if(!get_file_name_from_handle_function(fh, pfri->FileName, RenMaxNumChars, filename_string_length)){ //return 0; //} //Add trailing mark if((RenMaxNumChars-filename_string_length) < (SystemTimeOfDayInfoLength*2)){ return false; } //Search '\\' character to replace it for(std::size_t i = filename_string_length; i != 0; --filename_string_length){ if(pmem->ren.info.FileName[--i] == L'\\') break; } //Add random number std::size_t s = RenMaxNumChars - filename_string_length; if(!get_boot_and_system_time_wstr(&pfri->FileName[filename_string_length], s)){ return false; } filename_string_length += s; //Fill rename information (FileNameLength is in bytes) pfri->FileNameLength = static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length)); pfri->Replace = 1; pfri->RootDir = 0; //Final step: change the name of the in-use file: io_status_block_t io; if(0 != pNtSetInformationFile(fh, &io, pfri, sizeof(mem_t::ren_t), file_rename_information)){ return false; } return true; } catch(...){ return false; } }