Windows
TLS
允许多线程程序中的每个线程拥有自己单独的变量实例,每个线程都可以访问和修改自己的变量,而不会干扰其他线程。
运行过ThreadFunc
函数后dw的值仍为0x123456
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#include <windows.h> #include <iostream> using namespace std;
DWORD WINAPI ThreadFunc(LPVOID lpParam) { DWORD dw = (DWORD)TlsGetValue(0); TlsSetValue(0, (LPVOID)0x44557788); return 0; } int main() { TlsSetValue(0, (LPVOID)0x123456); DWORD dw = (DWORD)TlsGetValue(0); DWORD dwThreadId, dwThrdParam = 1; HANDLE hThread; char szMsg[80]; hThread = CreateThread( NULL, 0, ThreadFunc, &dwThrdParam, 0, &dwThreadId ); WaitForSingleObject(hThread, INFINITE); dw = (DWORD)TlsGetValue(0); return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
#include <windows.h> #include <iostream> using namespace std;
void FuncC() { DWORD dw = (DWORD)TlsGetValue(0); printf("FuncC tid:%d \t dw:%d\r\n", GetCurrentThreadId(), dw); }
void FuncB() { DWORD dw = (DWORD)TlsGetValue(0); FuncC(); printf("FuncB tid:%d \t dw:%d\r\n", GetCurrentThreadId(), dw); }
void FuncA() { DWORD dw = (DWORD)TlsGetValue(0); FuncB(); printf("FuncA tid:%d \t dw:%d\r\n", GetCurrentThreadId(), dw); }
DWORD WINAPI ThreadFunc(LPVOID lpParam) { DWORD dwTest = 0x11223344; FuncA(); DWORD dw = (DWORD)TlsGetValue(0); TlsSetValue(0, (LPVOID)dwTest); return 0; } int main() { TlsSetValue(0, (LPVOID)0x123456); DWORD dw = (DWORD)TlsGetValue(0);
DWORD dwThreadId, dwThrdParam = 1; HANDLE hThread; char szMsg[80]; hThread = CreateThread( NULL, 0, ThreadFunc, &dwThrdParam, 0, &dwThreadId ); WaitForSingleObject(hThread, INFINITE); dw = (DWORD)TlsGetValue(0); return 0; }
|
三个线程互不干扰
修改文件大小的方法
1.
文件映射中createfilemapping 填写的size大小
将指定文件的物理文件大小设置为文件指针的当前位置。
物理文件大小也称为文件末尾。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| int main() { HANDLE hFile = CreateFile("example.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { return 1; }
SetFilePointer(hFile, 0x10000, NULL, FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);
return 0; }
|
原本文件的大小便被截断(将超出这个位置的部分删除)变为了64kb(0x10000)
高低位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| LARGE_INTEGER li; DWORD dwLow = 0x12345678; DWORD dwHi = 0x77778888; __int64 nVal = 0x7777888812345678;
union MyUnion { struct { DWORD dwLow; DWORD dwHi; }lh; __int64 m_n; }; MyUnion u; u.lh.dwLow = dwLow; u.lh.dwHi = dwHi;
|
修改文件权限
当文件夹属性为只读时是无法修改里面的文件的
检索指定文件或目录的文件系统属性。
参数lpFileName: 文件或目录的名称。
默认情况下,名称限制为MAX_PATH个字符
在装载文件夹的目录上调用**GetFileAttributes**
时,它将返回目录的文件系统属性,而不是装载的文件夹与目录关联的卷中根目录的属性。
设置文件或目录的属性。
参数lpFileName:要设置其属性的文件的名称
参数dwFileAttributes:为文件设置的文件属性
此参数可以是一个或多个值,使用按位 OR 运算符进行组合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| BOOL GetSeDebugPrivilegeState(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege, BOOL* bPrivilegeState = (BOOL*)0) { LUID luid; BOOL bRet = LookupPrivilegeValue(NULL, lpszPrivilege, &luid); if (!bRet) { return FALSE; }
_TOKEN_PRIVILEGES tp; _TOKEN_PRIVILEGES tpOld{}; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL ); if (!bRet) { return FALSE; } if (bPrivilegeState != NULL) { *bPrivilegeState = tpOld.Privileges[0].Attributes; } return TRUE; } int main() { HANDLE hToken; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
GetSeDebugPrivilegeState(hToken, "SeBackPrivilege", TRUE); GetSeDebugPrivilegeState(hToken, "SeRestorePrivilege", TRUE);
DWORD dwAttr = GetFileAttributes("C:\\CloudMusic\\test.doc"); DWORD dwNew = dwAttr ^ FILE_ATTRIBUTE_READONLY; BOOL bRet = SetFileAttributes("C:\\CloudMusic\\test.doc", dwNew); HANDLE hFile = CreateFile("C:\\CloudMusic\\test.doc", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { return 1; }
SetFilePointer(hFile, 0, NULL, FILE_END);
DWORD dw = 0x12345678; bRet = WriteFile(hFile, &dw, sizeof(dw), NULL, NULL);
CloseHandle(hFile);
return 0; }
|
原本的文件夹属性
运行后(运行了3遍):
恢复:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| BOOL GetSeDebugPrivilegeState(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege, BOOL* bPrivilegeState = (BOOL*)0) { LUID luid; BOOL bRet = LookupPrivilegeValue(NULL, lpszPrivilege, &luid); if (!bRet) { return FALSE; }
_TOKEN_PRIVILEGES tp; _TOKEN_PRIVILEGES tpOld{}; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL ); if (!bRet) { return FALSE; } if (bPrivilegeState != NULL) { *bPrivilegeState = tpOld.Privileges[0].Attributes; } return TRUE; } int main() { HANDLE hToken; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
GetSeDebugPrivilegeState(hToken, "SeBackPrivilege", TRUE); GetSeDebugPrivilegeState(hToken, "SeRestorePrivilege", TRUE);
DWORD dwAttr = GetFileAttributes("C:\\CloudMusic\\test.doc"); DWORD dwNew = dwAttr ^ FILE_ATTRIBUTE_READONLY; BOOL bRet = SetFileAttributes("C:\\CloudMusic\\test.doc", dwNew); HANDLE hFile = CreateFile("C:\\CloudMusic\\test.doc", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { return 1; }
SetFilePointer(hFile, -8, NULL, FILE_END); SetEndOfFile(hFile);
CloseHandle(hFile);
return 0; }
|