⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 patch.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
   
   p = m_patchBuffer + SIZEOF_PATCH_BUFFER_MAGIC;
   patch = (Patch *)p;
   
   if (patch->name == NULL)
   {
      return -1;
   }
   
   m_patch.name = p + (int)patch->name;
   m_patch.fileCount = patch->fileCount;
   m_patch.files = (PatchedFile *)(p + (int)patch->files);

   for (i = 0; i < m_patch.fileCount; i++)
   {
      m_patch.files[i].name = p + (int)m_patch.files[i].name;
      m_patch.files[i].patches = (PatchedByte *)(p + (int)m_patch.files[i].patches);
   }
   
   printf("Patch %s loaded...\n", m_patch.name);
   return 0;
}


/** MAIN FUNCTIONS ************************************************************/

static int
createPatch()
{
   int i, status;
   const char *outputFileName;

   /* Check argument count */
   if (m_argc < 6 || (m_argc % 2) != 0)
   {
      printUsage();
      return -1;
   }

   outputFileName = m_argv[3];
   m_patch.name = m_argv[2];

   /* Allocate PatchedFiles array */
   m_patch.fileCount = (m_argc - 4) / 2;
   m_patch.files = malloc(m_patch.fileCount * sizeof (PatchedFile));
   if (m_patch.files == NULL)
   {
      printf("Out of memory!\n");
      return -1;
   }
   memset(m_patch.files, 0, m_patch.fileCount * sizeof (PatchedFile));

   /* Compare original to patched files and fill m_patch.files array */
   for (i = 0; i < m_patch.fileCount; i++)
   {
      m_patch.files[i].name = m_argv[4 + (i * 2) + 1];
      status = compareFiles(m_patch.files + i, m_argv[4 + (i * 2) + 0]);
      if (status < 0)
      {
         for (i = 0; i < m_patch.fileCount; i++)
         {
            if (m_patch.files[i].patches != NULL)
               free(m_patch.files[i].patches);
         }
         free(m_patch.files);
         m_patch.files = NULL;
         m_patch.fileCount = 0;
         return status;
      }
   }
   
   /* Output patch */
   return outputPatch(outputFileName);
}


static int
applyPatch()
{
   int c, i, j, fileSize, makeBackup;
   unsigned char *file;
   char *p;
   const char *fileName;
   char buffer[MAX_PATH];
   

   if (m_argc > 1 && strcmp(m_argv[1], "-d") != 0)
   {
      printUsage();
      return -1;
   }

   /* Load patch */
   if (loadPatch() < 0)
   {
      printf("This executable doesn't contain a patch, use -c to create one.\n");
      return -1;
   }

   if (m_argc > 1)
   {
      /* Dump patch */
      printf("Patch name: %s\n", m_patch.name);
      printf("File count: %d\n", m_patch.fileCount);
      for (i = 0; i < m_patch.fileCount; i++)
      {
         printf("----------------------\n"
                "File name:   %s\n"
                "File size:   %d bytes\n",
                m_patch.files[i].name, m_patch.files[i].fileSize);
         printf("Patch count: %d\n", m_patch.files[i].patchCount);
         for (j = 0; j < m_patch.files[i].patchCount; j++)
         {
            printf("  Offset 0x%x   0x%02x -> 0x%02x\n",
                   m_patch.files[i].patches[j].offset,
                   m_patch.files[i].patches[j].expected,
                   m_patch.files[i].patches[j].patched);
         }
      }
   }
   else
   {
      /* Apply patch */
      printf("Applying patch...\n");
      for (i = 0; i < m_patch.fileCount; i++)
      {
         /* Load original file */
         fileName = m_patch.files[i].name;
applyPatch_retry_file:
         file = loadFile(fileName, &fileSize);
         if (file == NULL)
         {
            printf("File %s not found! ", fileName);
applyPatch_file_open_error:
            printf("(S)kip, (R)etry, (A)bort, (M)anually enter filename");
            do
            {
               c = getch();
            }
            while (c != 's' && c != 'r' && c != 'a' && c != 'm');
            printf("\n");
            if (c == 's')
            {
               continue;
            }
            else if (c == 'r')
            {
               goto applyPatch_retry_file;
            }
            else if (c == 'a')
            {
               return 0;
            }
            else if (c == 'm')
            {
               if (fgets(buffer, sizeof (buffer), stdin) == NULL)
               {
                  printf("fgets() failed!\n");
                  return -1;
               }
               p = strchr(buffer, '\r');
               if (p != NULL)
                  *p = '\0';
               p = strchr(buffer, '\n');
               if (p != NULL)
                  *p = '\0';

               fileName = buffer;
               goto applyPatch_retry_file;
            }
         }

         /* Check file size */
         if (fileSize != m_patch.files[i].fileSize)
         {
            free(file);
            printf("File %s has unexpected filesize of %d bytes (%d bytes expected)\n",
                   fileName, fileSize, m_patch.files[i].fileSize);
            if (fileName != m_patch.files[i].name) /* manually entered filename */
            {
               goto applyPatch_file_open_error;
            }
            return -1;
         }
         
         /* Ask for backup */
         printf("Do you want to make a backup of %s? (Y)es, (N)o, (A)bort", fileName);
         do
         {
            c = getch();
         }
         while (c != 'y' && c != 'n' && c != 'a');
         printf("\n");
         if (c == 'y')
         {
            char buffer[MAX_PATH];
            _snprintf(buffer, MAX_PATH, "%s.bak", fileName);
            buffer[MAX_PATH-1] = '\0';
            makeBackup = 1;
            if (access(buffer, 0) >= 0) /* file exists */
            {
               printf("File %s already exists, overwrite? (Y)es, (N)o, (A)bort", buffer);
               do
               {
                  c = getch();
               }
               while (c != 'y' && c != 'n' && c != 'a');
               printf("\n");
               if (c == 'n')
                  makeBackup = 0;
               else if (c == 'a')
               {
                  free(file);
                  return 0;
               }
            }
            if (makeBackup && saveFile(buffer, file, fileSize) < 0)
            {
               free(file);
               return -1;
            }
         }
         else if (c == 'a')
         {
            free(file);
            return 0;
         }
         
         /* Patch file */
         for (j = 0; j < m_patch.files[i].patchCount; j++)
         {
            int offset = m_patch.files[i].patches[j].offset;
            if (file[offset] != m_patch.files[i].patches[j].expected)
            {
               printf("Unexpected value in file %s at offset 0x%x: expected = 0x%02x, found = 0x%02x\n",
                      fileName, offset, m_patch.files[i].patches[j].expected, file[offset]);
               free(file);
               return -1;
            }
            file[offset] = m_patch.files[i].patches[j].patched;
         }
         
         /* Save file */
         if (saveFile(fileName, file, fileSize) < 0)
         {
            free(file);
            return -1;
         }
         free(file);
      }
      
      printf("Patch applied sucessfully!\n");
   }

   return 0;
}


static void
printUsage()
{
   printf("Usage:\n"
          "%s -c     - Create patch\n"
          "%s -d     - Dump patch\n"
          "%s        - Apply patch\n"
          "\n"
          "A patch can be created like this:\n"
          "%s -c \"patch name\" output.exe file1.orig file1.patched[ file2.orig file2.patched[ ...]]\n",
          m_argv[0], m_argv[0], m_argv[0], m_argv[0]);
}


int
main(
   int argc,
   char *argv[])
{
   m_argc = argc;
   m_argv = argv;

   if (argc >= 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0))
   {
      printUsage();
      return 0;
   }
   else if (argc >= 2 && argv[1][0] == '-')
   {
      if (strcmp(argv[1], "-c") == 0)
      {
         return createPatch();
      }
      else if (strcmp(argv[1], "-d") == 0)
      {
         return applyPatch();
      }
      else
      {
         printf("Unknown option: %s\n"
                "Use -h for help.\n",
                argv[1]);
         return -1;
      }
   }
   
   return applyPatch();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -