inline NTSTATUS AdjustPrivilege(bool is_enable, ULONG privilege) { TOKEN_PRIVILEGES new_privs = {}; HANDLE h_process_token = {}; auto status = ZwOpenProcessTokenEx(ZwCurrentProcess(), TOKEN_ALL_ACCESS, OBJ_KERNEL_HANDLE, &h_process_token); if (!NT_SUCCESS(status)) { return status; } DEFER(ZwClose(h_process_token)); new_privs.PrivilegeCount = 1; new_privs.Privileges[0].Luid = RtlConvertUlongToLuid(privilege); if (is_enable) { new_privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; } else { new_privs.Privileges[0].Attributes = 0; } return ZwAdjustPrivilegesToken(h_process_token, false, &new_privs, sizeof(new_privs), nullptr, nullptr); }
void arch_bfdDisasm(pid_t pid, uint8_t * mem, size_t size, char *instr) { MX_LOCK(&arch_bfd_mutex); DEFER(MX_UNLOCK(&arch_bfd_mutex)); bfd_init(); char fname[PATH_MAX]; snprintf(fname, sizeof(fname), "/proc/%d/exe", pid); bfd *bfdh = bfd_openr(fname, NULL); if (bfdh == NULL) { LOG_W("bfd_openr('/proc/%d/exe') failed", pid); return; } DEFER(bfd_close_all_done(bfdh)); if (!bfd_check_format(bfdh, bfd_object)) { LOG_W("bfd_check_format() failed"); return; } disassembler_ftype disassemble = disassembler(bfdh); if (disassemble == NULL) { LOG_W("disassembler() failed"); return; } struct disassemble_info info; init_disassemble_info(&info, instr, arch_bfdFPrintF); info.arch = bfd_get_arch(bfdh); info.mach = bfd_get_mach(bfdh); info.buffer = mem; info.buffer_length = size; info.section = NULL; info.endian = bfd_little_endian(bfdh) ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG; disassemble_init_for_target(&info); strcpy(instr, ""); if (disassemble(0, &info) <= 0) { snprintf(instr, _HF_INSTR_SZ, "[DIS-ASM_FAILURE]"); } }
void arch_bfdResolveSyms(pid_t pid, funcs_t * funcs, size_t num) { /* Guess what? libbfd is not multi-threading safe */ MX_LOCK(&arch_bfd_mutex); DEFER(MX_UNLOCK(&arch_bfd_mutex)); bfd_init(); __block bfd_t bfdParams = { .bfdh = NULL, .section = NULL, .syms = NULL, }; if (arch_bfdInit(pid, &bfdParams) == false) { return; } DEFER(arch_bfdDestroy(&bfdParams)); const char *func; const char *file; unsigned int line; for (unsigned int i = 0; i < num; i++) { snprintf(funcs[i].func, sizeof(funcs->func), "[UNKNOWN]"); if (funcs[i].pc == NULL) { continue; } long offset = (long)funcs[i].pc - bfdParams.section->vma; if ((offset < 0 || (unsigned long)offset > bfdParams.section->size)) { continue; } if (bfd_find_nearest_line (bfdParams.bfdh, bfdParams.section, bfdParams.syms, offset, &file, &func, &line)) { snprintf(funcs[i].func, sizeof(funcs->func), "%s", func); funcs[i].line = line; } } }
illegal_argument::illegal_argument(char const volatile *m, ...) { va_list ap; va_start(ap, m); DEFER(va_end(ap)); int err = vasprintf(&free_msg, (char const*)m, ap); if (err < 0) { msg = "<error formatting message>"; free_msg = 0; } else { msg = free_msg; } }
void Logger::vlog(LoggingLevel level, const char* format, va_list args) noexcept { if (!m_fp || level < this->get_level()) return; struct tm now; int now_ns = 0; OSService::get_current_time_in_tm(&now, &now_ns); flockfile(m_fp); DEFER(funlockfile(m_fp)); if (m_console_color) { switch (level) { case kLogWarning: m_console_color->use(Colour::Warning); break; case kLogError: m_console_color->use(Colour::Error); break; default: break; } } fprintf(m_fp, "[%s] [%p] [%d-%02d-%02d %02d:%02d:%02d.%09d UTC] ", stringify(level), current_thread_id(), now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec, now_ns); vfprintf(m_fp, format, args); if (m_console_color && (level == kLogWarning || level == kLogError)) { m_console_color->use(Colour::Default); } putc('\n', m_fp); fflush(m_fp); }
os_error::os_error(int e, char const volatile *m, ...) : err(e) { va_list ap; va_start(ap, m); DEFER(va_end(ap)); int err = vasprintf(&free_msg, (char const*)m, ap); if (err < 0) { msg = "<error formatting message>"; free_msg = 0; } else { msg = free_msg; } }
XID take_one(thread_data *t) { ASSERT(t->bitmap); DEFER(t->bitmap &= (t->bitmap-1)); auto id = t->base_id + __builtin_ctzll(t->bitmap); auto x = contexts[id].owner = XID::make(t->epoch, id); #ifdef USE_PARALLEL_SSN contexts[id].sstamp = ~uint64_t{0}; contexts[id].pstamp = 0; contexts[id].xct = NULL; #endif #ifdef USE_PARALLEL_SSI contexts[id].ct3 = ~uint64_t{0}; contexts[id].last_safesnap = 0; contexts[id].xct = NULL; #endif // Note: transaction needs to initialize xc->begin in ctor contexts[id].end = INVALID_LSN; contexts[id].state = TXN_EMBRYO; return x; }
bool CreateParentDirs(StringView PathArgument) { auto Sep = "/\\"_sv; auto FirstIndex = PathArgument.find_first_of(Sep); if (FirstIndex == PathArgument.npos) return true; // No directories. // Create our own copy so we can add zeroes. char Path[MFile::MaxPath]; strcpy_safe(Path, PathArgument); auto End = Path + PathArgument.size(); char* p = Path + FirstIndex; while (true) { // Set the current slash to zero, and revert this change before the next loop iteration. auto OldValue = *p; *p = 0; // Capture by value to ignore the change to p at the end. DEFER([=] { *p = OldValue; }); if (!MFile::IsDir(Path)) { if (!MFile::CreateDir(Path)) { return false; } } p = std::find_first_of(p + 1, End, Sep.begin(), Sep.end()); if (p == End) break; } return true; }
std::size_t StrStr(IteratorT itBegin, std::common_type_t<IteratorT> itEnd, ToFindIteratorT itToFindBegin, std::common_type_t<ToFindIteratorT> itToFindEnd) noexcept { ASSERT(itToFindEnd != itToFindBegin); ASSERT(static_cast<std::size_t>(itEnd - itBegin) >= static_cast<std::size_t>(itToFindEnd - itToFindBegin)); const auto uFindCount = static_cast<std::size_t>(itToFindEnd - itToFindBegin); if(uFindCount == 1){ return StrChrRep(itBegin, itEnd, *itToFindBegin, 1); } ASSERT(uFindCount >= 2); std::size_t *puKmpTable; bool bWasTableAllocatedFromHeap; const auto uSizeToAlloc = sizeof(std::size_t) * (uFindCount - 2); if((uSizeToAlloc >= 0x10000) || (uSizeToAlloc / sizeof(std::size_t) != uFindCount - 2)){ puKmpTable = static_cast<std::size_t *>(::operator new[](uSizeToAlloc, std::nothrow)); bWasTableAllocatedFromHeap = true; } else { puKmpTable = static_cast<std::size_t *>(ALLOCA(uSizeToAlloc)); bWasTableAllocatedFromHeap = false; } DEFER([&]{ if(bWasTableAllocatedFromHeap){ ::operator delete[](puKmpTable); }; }); if(puKmpTable){ std::size_t uPos = 0; std::size_t uCand = 0; while(uPos < uFindCount - 2){ if(itToFindBegin[static_cast<std::ptrdiff_t>(uPos)] == itToFindBegin[static_cast<std::ptrdiff_t>(uCand)]){ puKmpTable[uPos++] = ++uCand; } else if(uCand != 0){ uCand = puKmpTable[uCand]; } else { puKmpTable[uPos++] = 0; } } } auto itCur = itBegin; const auto itCurEnd = itEnd - static_cast<std::ptrdiff_t>(uFindCount) + 1; for(;;){ for(;;){ if(itCur == itCurEnd){ return kNpos; } if(*itCur == *itToFindBegin){ break; } ++itCur; } std::size_t uMatchLen = 1; for(;;){ ++itCur; if(uMatchLen == uFindCount){ return static_cast<std::size_t>(itCur - itBegin) - uFindCount; } if(itCur == itEnd){ return kNpos; } if(*itCur != itToFindBegin[static_cast<std::ptrdiff_t>(uMatchLen)]){ break; } ++uMatchLen; } if(itCur >= itCurEnd){ return kNpos; } itCur -= static_cast<std::ptrdiff_t>(uMatchLen - 1); if((uMatchLen >= 2) && puKmpTable){ itCur += static_cast<std::ptrdiff_t>(puKmpTable[uMatchLen - 2]); } } }
void logLog(enum llevel_t ll, const char *fn, int ln, bool perr, const char *fmt, ...) { char strerr[512]; if (perr == true) { snprintf(strerr, sizeof(strerr), "%s", strerror(errno)); } struct ll_t { char *descr; char *prefix; bool print_funcline; }; struct ll_t logLevels[] = { {"F", "\033[7;35m", true}, {"E", "\033[1;31m", true}, {"W", "\033[0;33m", true}, {"I", "\033[1m", true}, {"D", "\033[0;4m", true}, {"HR", "\033[0m", false}, {"HB", "\033[1m", false}, }; time_t ltstamp = time(NULL); struct tm utctime; localtime_r(<stamp, &utctime); char timestr[32]; if (strftime(timestr, sizeof(timestr) - 1, "%FT%T%z", &utctime) == 0) { timestr[0] = '\0'; } /* Start printing logs */ { pthread_mutex_lock(&log_mutex); DEFER(pthread_mutex_unlock(&log_mutex)); if (log_fd_isatty) { dprintf(log_fd, "%s", logLevels[ll].prefix); } if (logLevels[ll].print_funcline) { dprintf(log_fd, "[%s][%s][%d] %s():%d ", timestr, logLevels[ll].descr, __hf_pid(), fn, ln); } va_list args; va_start(args, fmt); vdprintf(log_fd, fmt, args); va_end(args); if (perr == true) { dprintf(log_fd, ": %s", strerr); } if (log_fd_isatty) { dprintf(log_fd, "\033[0m"); } dprintf(log_fd, "\n"); } /* End printing logs */ if (ll == FATAL) { exit(1); } }
static bool LoadElu(LoaderState& State, const char* name) { // HACK: Don't load shadowbox if (strstr(name, "shadowbox") != nullptr) return false; State.ObjectData.emplace_back(); auto& dest = State.ObjectData.back(); bool ReachedEnd = false; DEFER([&] { if (!ReachedEnd) State.ObjectData.pop_back(); }); MZFile File; auto success = TryForEachPath(State.Paths, name, [&](auto& Path) { return File.Open(Path.c_str(), RealSpace2::g_pFileSystem); }); if (!success) { MLog("LoadElu -- Failed to open elu file %s\n", name); return false; } EluHeader hdr; File.Read(hdr); dest.Meshes.reserve(hdr.meshCount); for (u32 i = 0; i < hdr.meshCount; ++i) { dest.Meshes.emplace_back(); auto& Mesh = dest.Meshes.back(); bool success{}; switch (hdr.Version) { case 0x5012: success = LoadMesh5012(File, Mesh); break; case 0x5013: success = LoadMesh5013(File, Mesh); break; default: DMLog("Unknown mesh version %X\n", hdr.Version); } if (!success) { MLog("Failed to load mesh index %d version %x for elu %s\n", i, hdr.Version, name); return false; } dest.VertexCount += Mesh.VertexCount; dest.IndexCount += Mesh.IndexCount; DMLog("%s mesh %s %d vert %d index\n", name, Mesh.Name.c_str(), Mesh.VertexCount, Mesh.IndexCount); for (size_t j{}; j < Mesh.DrawProps.size(); ++j) { auto& dp = Mesh.DrawProps[j]; DMLog("DrawProp %d: vb: %d, ib: %d, cnt: %d, mat: %d\n", j, dp.vertexBase, dp.indexBase, dp.count, dp.material); } } assert(File.Tell() == File.GetLength()); DMLog("%s -- Meshes.size() = %d\n", name, dest.Meshes.size()); dest.MaterialStart = State.Materials.size(); if (!loadMaterial(State, (std::string{ name } +".xml").c_str())) { MLog("Failed to load material for elu %s\n", name); return false; } dest.Name = name; State.EluMap[dest.Name] = State.ObjectData.size() - 1; ReachedEnd = true; return true; }