Windows

TLS

允许多线程程序中的每个线程拥有自己单独的变量实例,每个线程都可以访问和修改自己的变量,而不会干扰其他线程。

img

img

运行过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
// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#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
// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#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(dwTest)
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;
}

img

三个线程互不干扰

修改文件大小的方法

1.img

文件映射中createfilemapping 填写的size大小

img

将指定文件的物理文件大小设置为文件指针的当前位置。

物理文件大小也称为文件末尾。

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;
}

img

原本文件的大小便被截断(将超出这个位置的部分删除)变为了64kb(0x10000)

高低位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
LARGE_INTEGER li;
//0x7777888812345678
DWORD dwLow = 0x12345678;
DWORD dwHi = 0x77778888;
__int64 nVal = 0x7777888812345678;

union MyUnion//共用体,lh和m_n
{
struct
{
DWORD dwLow;
DWORD dwHi;
}lh;
__int64 m_n;
};
MyUnion u;
u.lh.dwLow = dwLow;
u.lh.dwHi = dwHi;

img

修改文件权限

img

当文件夹属性为只读时是无法修改里面的文件的

img

检索指定文件或目录的文件系统属性。

参数lpFileName: 文件或目录的名称。

​ 默认情况下,名称限制为MAX_PATH个字符

​ 在装载文件夹的目录上调用**GetFileAttributes**时,它将返回目录的文件系统属性,而不是装载的文件夹与目录关联的卷中根目录的属性。

img

设置文件或目录的属性。

参数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)
{
//获取特权ID
LUID luid;
BOOL bRet = LookupPrivilegeValue(NULL, lpszPrivilege, &luid);
if (!bRet)
{
return FALSE;
}
//获取当前特权状态

//设置SeDebugPrivilege为enable
_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);
//特权 backup store

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;
}

原本的文件夹属性

img

运行后(运行了3遍):

img

恢复:

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)
{
//获取特权ID
LUID luid;
BOOL bRet = LookupPrivilegeValue(NULL, lpszPrivilege, &luid);
if (!bRet)
{
return FALSE;
}
//获取当前特权状态

//设置SeDebugPrivilege为enable
_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);
//特权 backup store

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);//修改
//DWORD dw = 0x12345678;
//bRet = WriteFile(hFile, &dw, sizeof(dw), NULL, NULL);


CloseHandle(hFile);

return 0;
}

img