WIN7如何从扇区读写文件

Geek青松 2014-09-02 07:28:34
我想复制SAM文件,在xp环境下复制成功,但是win7下不能成功。
#define _WIN32_WINNT 0x0400
#include <WINDOWS.H>
#include <WINIOCTL.H>
#include <MALLOC.H>
#include <stdio.h>


ULONGLONG *GetFileClusters(
LPCSTR lpFileName,
ULONG ClusterSize,
ULONG *ClCount,
ULONG *FileSize
)
{
HANDLE hFile;
ULONG OutSize;
ULONG Bytes, Cls, CnCount, r;
ULONGLONG *Clusters = NULL;
BOOLEAN Result = FALSE;
LARGE_INTEGER PrevVCN, Lcn;
STARTING_VCN_INPUT_BUFFER InBuf;
PRETRIEVAL_POINTERS_BUFFER OutBuf;

hFile = CreateFile(lpFileName, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, 0);

if (hFile != INVALID_HANDLE_VALUE)
{
*FileSize = GetFileSize(hFile, NULL);

OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER) + (*FileSize / ClusterSize) * sizeof(OutBuf->Extents);

OutBuf = (PRETRIEVAL_POINTERS_BUFFER)malloc(OutSize);

InBuf.StartingVcn.QuadPart = 0;

if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,
sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
{
*ClCount = (*FileSize + ClusterSize - 1) / ClusterSize;

Clusters = (PULONGLONG)malloc(*ClCount * sizeof(ULONGLONG));

PrevVCN = OutBuf->StartingVcn;

for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++)
{
Lcn = OutBuf->Extents[r].Lcn;

for (CnCount = (ULONG)(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart);
CnCount; CnCount--, Cls++, Lcn.QuadPart++) Clusters[Cls] = Lcn.QuadPart;

PrevVCN = OutBuf->Extents[r].NextVcn;
}
}

free(OutBuf);

CloseHandle(hFile);
}

return Clusters;
}

BOOL FileCopy(LPCSTR lpSrcName, LPCSTR lpDstName)
{
BOOL bResult = FALSE;

ULONG ClusterSize, BlockSize;
ULONGLONG *Clusters;
ULONG ClCount, FileSize, Bytes;
HANDLE hDrive, hFile;
ULONG SecPerCl, BtPerSec, r;
PVOID Buff;
LARGE_INTEGER Offset;
CHAR Name[7];

Name[0] = lpSrcName[0];
Name[1] = ':';
Name[2] = 0;

GetDiskFreeSpace(Name, &SecPerCl, &BtPerSec, NULL, NULL);

ClusterSize = SecPerCl * BtPerSec;

Clusters = GetFileClusters(lpSrcName, ClusterSize, &ClCount, &FileSize);
if(Clusters)
{
Name[0] = '//';
Name[1] = '//';
Name[2] = '.';
Name[3] = '//';
Name[4] = lpSrcName[0];
Name[5] = ':';
Name[6] = 0;

hDrive = CreateFile(Name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if (hDrive != INVALID_HANDLE_VALUE)
{
hFile = CreateFile(lpDstName, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
Buff = malloc(ClusterSize);

for (r = 0; r < ClCount; r++, FileSize -= BlockSize)
{
Offset.QuadPart = ClusterSize * Clusters[r];

SetFilePointer(hDrive, Offset.LowPart, &Offset.HighPart, FILE_BEGIN);

ReadFile(hDrive, Buff, ClusterSize, &Bytes, NULL);

BlockSize = FileSize < ClusterSize ? FileSize : ClusterSize;

WriteFile(hFile, Buff, BlockSize, &Bytes, NULL);
}

free(Buff);

CloseHandle(hFile);

bResult = TRUE;
}

CloseHandle(hDrive);
}

free(Clusters);
}
else
{
printf("GetFileClusters fail.\n");
}

return bResult;
}


void main()
{
FileCopy("C:\\Windows\\System32\\config\\SAM","C:\\test\\SAM");
// FileCopy("C:\\Windows\\System32\\config\\system","C:\\test\\system");
}
...全文
471 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-09-04
  • 打赏
  • 举报
回复
Module: SUPERUSR.C The following sample code demonstrates how to extract a token from a process running in the context of the local system and use it to create a child process running in that same context. The local system security context is very powerful because of its far-reaching security access. Once you have your superusr-mode console running, here are some interesting things to try: - Run WHOAMI.EXE - Run PVIEW from the reskit and look at the process tokens for the system services - Run REGEDT32 and have a look around in your SAM database Note: You must be a member of the local administrator group for this sample to work. Additionally, note that CreateProcessAsUser requires the SeAssignPrimaryToken (Replace a process level token) and SeIncreaseQuotaPrivilege (Increase Quotas) rights. Note: This sample relies on the fact that PID (2) is usually the "system" process. It is this process from which I extract the token that it used for CreateProcessAsUser(). If, for some reason, "system" is not PID (2), change SYSTEM_PID to reflect the PID of "system" on your machine. You can retrieve the PID with TLIST.EXE.
赵4老师 2014-09-03
  • 打赏
  • 举报
回复
以管理员身份运行 以XP兼容模式运行
Geek青松 2014-09-03
  • 打赏
  • 举报
回复
不好意思网页打不开,请您解释下程序的含义可以吗?看到您在其他的帖子上也引用了这个代码。
赵4老师 2014-09-03
  • 打赏
  • 举报
回复
摘自:Microsoft SDK\samples\winbase\Security\WinNT\SuperUsr\SuperUsr.c
Geek青松 2014-09-03
  • 打赏
  • 举报
回复
你好,请问这个程序的作用是什么?获取system 权限吗?
赵4老师 2014-09-03
  • 打赏
  • 举报
回复
C:\>runas /? RUNAS 用法: RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly] ] /user:<UserName> program RUNAS [ [/noprofile | /profile] [/env] [/savecred] ] /smartcard [/user:<UserName>] program /noprofile 指定不应该加载用户的配置文件。 这会加速应用程序加载,但 可能会造成一些应用程序运行不正常。 /profile 指定应该加载用户的配置文件。 这是默认值。 /env 要使用当前环境,而不是用户的环境。 /netonly 只在指定的凭据限于远程访问的情况下才使用。 /savecred 用用户以前保存的凭据。 Windows XP Home Edition 上没有这个选项。 该选项会被忽略。 /smartcard 如果凭据是智能卡提供的,则使用这个选项。 /user <UserName> 应使用 USER@DOMAIN 或 DOMAIN\USER 形式 program EXE 的命令行。请参阅下面的例子 例如: > runas /noprofile /user:mymachine\administrator cmd > runas /profile /env /user:mydomain\admin "mmc %windir%\system32\dsa.msc" > runas /env /user:user@domain.microsoft.com "notepad \"my file.txt\"" 注意: 只在得到提示时才输入用户的密码。 注意: USER@DOMAIN 跟 /netonly 不兼容。 注意: /profile 跟 /netonly 不兼容。 注意: /savecred 跟 /smartcard 不兼容。
/*
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Copyright (C) 1998 - 2000.  Microsoft Corporation.  All rights reserved.


This code sample requires the following import library:
    advapi32.lib

Note:  This sample does not run on Windows 2000.
*/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <accctrl.h>
#include <aclapi.h>

#define SD_SIZE (65536 + SECURITY_DESCRIPTOR_MIN_LENGTH)
#define SYSTEM_PID 2

#define PERR(s) fprintf(stderr, "%s(%d) %s : Error %d\n%s\n", \
                   __FILE__, __LINE__, (s), GetLastError(), \
         GetLastErrorText())

BOOL EnableDebugPriv(void);
BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess);
LPSTR GetLastErrorText(void);


void main( int argc, char * argv[] )
{

   HANDLE hProc;
   HANDLE hToken;
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   BOOL                bResult;

   if(!EnableDebugPriv())
   {
      printf("You probably don't have the SE_DEBUG_NAME privilege\n");
      exit(0);
   }

   //
   // PID 2 is always(?) associated with the
   // "system" process which has the context we
   // are after - local system
   //
   if(!(hProc = OpenProcess(
      PROCESS_ALL_ACCESS,
      FALSE,
      SYSTEM_PID)))
   {
      PERR("OpenProcess");
      printf("You are probably not a member of the administrator group\n");
      exit(0);
   }

   //
   // Open the process token with this access
   // so that we can modify the DACL and add
   // TOKEN_DUPLICATE & TOKEN_ASSIGN_PRIMARY
   // rights for this user
   //
   bResult = OpenProcessToken(
      hProc,
      READ_CONTROL|WRITE_DAC,
      &hToken);
   if (bResult == FALSE)
   {
      PERR("OpenProcessToken");
      exit(0);
   }

   if(!ModifySecurity(
      hToken,
      TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_QUERY))
   {
      exit(0);
   }

   CloseHandle(hToken);

   //
   // Close that handle and get a new one with the right
   // privilege level
   //

   bResult = OpenProcessToken(
      hProc,
      TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY,
      &hToken);
   if (FALSE == bResult)
   {
      PERR("OpenProcessToken");
      exit(0);
   }

   //
   // setup STARTUPINFO structure
   //
   memset( &si, 0, sizeof(STARTUPINFO) );
   si.cb = sizeof(STARTUPINFO);
   si.lpDesktop = "winsta0\\default";

   if( !CreateProcessAsUser(
      hToken,
      NULL,
      "cmd.exe",
      NULL, // default process attributes
      NULL, // default thread attributes
      FALSE, // don't inherit handles
      CREATE_NEW_CONSOLE,
      NULL,  // inherit environment
      NULL,  // same directory
      &si,
      &pi ) )

      PERR( "CreateProcessAsUser" );
   else
      printf( "\"SuperUsr\" mode console started!\n" );

   CloseHandle(hProc);
   CloseHandle(hToken);

}

BOOL EnableDebugPriv(void)
{
   TOKEN_PRIVILEGES tp;
   HANDLE hToken;
   LUID luid;

   if(!OpenProcessToken(
      GetCurrentProcess(),
      TOKEN_ADJUST_PRIVILEGES,
      &hToken ))
   {
      PERR("OpenProcessToken");
      return(FALSE);
   }

   if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
   {
      PERR("LookupPrivilegeValue");
      CloseHandle(hToken);
      return(FALSE);
   }

   tp.PrivilegeCount           = 1;
   tp.Privileges[0].Luid       = luid;
   tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

   if(!AdjustTokenPrivileges(
      hToken,
      FALSE,
      &tp,
      sizeof(TOKEN_PRIVILEGES),
      NULL,
      NULL ))
   {
      PERR("AdjustTokenPrivileges");
      CloseHandle(hToken);
      return(FALSE);
   }

   CloseHandle(hToken);

   return(TRUE);

}


BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess)
{
   UCHAR          ucSDbuf[SD_SIZE];
   PSECURITY_DESCRIPTOR pSD=(PSECURITY_DESCRIPTOR)ucSDbuf;
   DWORD          dwSDLengthNeeded;

   PACL           pAcl;
   PACL           pNewAcl;

   EXPLICIT_ACCESS explicitaccess;

   BOOL fDaclPresent,fDaclDefaulted;
   DWORD dwResult;

   UCHAR          ucAbsSDbuf[SD_SIZE];
   PSECURITY_DESCRIPTOR pAbsSD=(PSECURITY_DESCRIPTOR)ucAbsSDbuf;
   DWORD dwSDLength;

#define ACL_SIZE 2048
#define SID_SIZE 1024

   PACL pacl,psacl;
   DWORD dwAclSize=ACL_SIZE, dwSaclSize=ACL_SIZE;
   PSID pSidOwner,pSidPrimary;
   DWORD dwSidOwnLen=SID_SIZE,dwSidPrimLen=SID_SIZE;


   if(!GetKernelObjectSecurity(
      hProc,
      DACL_SECURITY_INFORMATION,
      pSD,
      SD_SIZE,
      &dwSDLengthNeeded))
   {
      PERR("GetKernelObjectSecurity");
      return(FALSE);
   }

   if(!GetSecurityDescriptorDacl(
      pSD,
      &fDaclPresent,
      &pAcl,
      &fDaclDefaulted))
   {
      PERR("GetSecurityDescriptorDacl");
      return(FALSE);
   }


   BuildExplicitAccessWithName(
      &explicitaccess,
      "administrators",
      dwAccess,
      GRANT_ACCESS,
      0 );

   if( dwResult = SetEntriesInAcl(
      1,
      &explicitaccess,
      pAcl,
      &pNewAcl ) )
   {
      SetLastError(dwResult);
      PERR("SetEntriesInAcl");
      return( FALSE );
   }


   pacl = malloc(ACL_SIZE);
   psacl = malloc(ACL_SIZE);
   pSidOwner = malloc(SID_SIZE);
   pSidPrimary = malloc(SID_SIZE);

   dwSDLength = SD_SIZE;

   if(!MakeAbsoluteSD(
      pSD,
      pAbsSD,
      &dwSDLength,
      pacl, &dwAclSize,
      psacl, &dwSaclSize,
      pSidOwner, &dwSidOwnLen,
      pSidPrimary, &dwSidPrimLen))
   {
      PERR("MakeAbsoluteSD");
      return(FALSE);
   }

   if(!SetSecurityDescriptorDacl(
      pAbsSD,
      fDaclPresent,
      pNewAcl,
      fDaclDefaulted))
   {
      PERR("SetSecurityDescriptorDacl");
      return(FALSE);
   }

   if(!SetKernelObjectSecurity(
      hProc,
      DACL_SECURITY_INFORMATION,
      pAbsSD))
   {
      PERR("SetKernelObjectSecurity");
      return(FALSE);
   }

   return (TRUE);
}


LPSTR GetLastErrorText()
{
   #define MAX_MSG_SIZE 256

   static char szMsgBuf[MAX_MSG_SIZE];
   DWORD dwError, dwRes;

   dwError = GetLastError ();

   dwRes = FormatMessage (
      FORMAT_MESSAGE_FROM_SYSTEM,
      NULL,
      dwError,
      MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
      szMsgBuf,
      MAX_MSG_SIZE,
      NULL);
   if (0 == dwRes) {
      fprintf(stderr, "FormatMessage failed with %d\n", GetLastError());
      ExitProcess(EXIT_FAILURE);
   }

   return szMsgBuf;
}

Geek青松 2014-09-03
  • 打赏
  • 举报
回复
就是我想以编程的方式,不想用网上说的什么通过pe拉,或者类似赵4老师说的以其他身份运行拉,例如system身份等等。 用户就是 普通的administrator身份。直接通过程序来获取。
解决 第一次开机慢,开机后假死/卡顿 问题,转载+补充! 大家可能都明白,最近我在纠结这个问题,但是一直不知道问题根本,只知道出现在硬盘上面,更谈不上解决办法,因为本人对硬件不是那么深入的了解,基础的原理知识从课本上学过,只是我学专业偏软的,如果问我网络方面只是还能搞定,一些软件问题还能解释,但是例如硬盘扇区,扇区没有对齐导致的第一次开机慢问题,还真无法解释,那么就不用详细解释了,遇到此问题的,按照以下方法解决吧,软件也是WDC官方出的! 警告:此贴的操作有一定概率引起磁盘文件丢失,在进行操作前建议备份重要数据。(据说我没备份,对齐后文件无任何丢失) 症状描述:不管是xp还是Win7,关机隔三四个小时再开机硬盘灯一直亮,大概八分钟后开始闪烁,启动到系统界面大概四分钟,然后进系统卡四分钟。之后系统一切正常,不卡了。再重启启动速度也快了,一分钟(原版系统未作任何优化)。 症状原因:极有可能是西数的技术 高级格式化使用的4K扇区,在分区时未对齐。有这个情况的应该都是在pe下用分区软件分的区然后装的系统吧。只有使用win7或者ubuntu的分区工具才不会出现未对齐情况。有些说只在大硬盘上采用了这个技术,不得不说,4830TG上使用的西数bpvt系列确实采用了这个技术。另外,有部分朋友反映日立硬盘也会出现这个问题,这时候可以上日立官网下载同样功能的工具进行对齐操作。 解决方法:很简单,下载西数wd align软件。WD align下载地址:http://dl.dbank.com/c0pegwpbtu。(注:如果你在西数官网注册你的硬盘产品,会发现下边就有提示要你安装wd align软件检测扇区是否对齐。)软件使用很简单,相信会点分区知识的都会用。有这个问题的可以去试下。

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧