VirtualProtect 中的最后一个参数是做什么用的?
What is the last parameter in VirtualProtect used for?
我想同时使用 VirtualAlloc
和 VirtualProtect
将 shellcode 注入本地进程,但我不知道最后一个参数是什么 (lpflOldProtect
) 以及如何我要申报吗
void fun()
{
size_t dwSize = 511; // size of shellcode
LPVOID base_add = VirtualAlloc(NULL , dwSize , MEM_RESERVE, PAGE_NOACCESS);
if (base_add == NULL )
{
cout << "Failed to allocate space " << endl;
return ;
}
LPVOID end_add = base_add + dwSize;
// change mem protection option
PDWORD lpflOldProtect = 0;
bool change_protection = VirtualProtect(base_add,dwSize,PAGE_EXECUTE_READWRITE, lpflOldProtect );
if (change_protection)
{
cout << "Successfully changed protection" << endl;
}
else
{
cout << " Failed" << endl;
}
}
根据 Microsoft documentation,VirtualProtect
中的最后一个参数是:
A pointer to a variable that receives the previous access protection value of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.
这是什么意思?指定区域首页的值是多少?那不是基地址吗?
VirtualProtect
函数的第四个(最后一个)参数应该是 DWORD
变量的地址,在该变量中接收内存块的先前保护标志的值(或者,确切地说,是该块的第一页)。如果您愿意,可以在完成需要更改该保护的任何操作后将其用于 'reset' 该保护级别。
在您的代码中,您在 PDWORD lpflOldProtect = 0;
行中声明了一个指针并为该指针分配了一个 NULL
(零)值 – 因此,根据您链接的文档,您对 VirtualProtect
会失败。
相反,您应该声明一个 actual DWORD
变量并将该变量的地址作为最后一个参数传递。在您的情况下,修改后的代码将如下所示:
DWORD flOldProtect = 0;
BOOL change_protection = VirtualProtect(base_add, dwSize, PAGE_EXECUTE_READWRITE, &flOldProtect);
// Pass address of the DWORD variable ^
if (change_protection)
{
//...
请注意,在链接文档中,最后一个参数被标记为 [out]
– 这意味着它在调用之前的值未被函数使用,因此您实际上不需要对其进行初始化;然而,一些编译器 and/or 代码分析器 可能 抱怨使用未初始化的值,这就是我将其设置为零的原因。
另请注意,函数的 return 值是 BOOL
类型(在 Windows 系统头文件中声明为 typedef int BOOL;
),而不是 bool
;在大多数情况下,您的代码进行的隐式转换不会导致任何问题,但同样,某些编译器可能会发出有关该转换的警告。
我想同时使用 VirtualAlloc
和 VirtualProtect
将 shellcode 注入本地进程,但我不知道最后一个参数是什么 (lpflOldProtect
) 以及如何我要申报吗
void fun()
{
size_t dwSize = 511; // size of shellcode
LPVOID base_add = VirtualAlloc(NULL , dwSize , MEM_RESERVE, PAGE_NOACCESS);
if (base_add == NULL )
{
cout << "Failed to allocate space " << endl;
return ;
}
LPVOID end_add = base_add + dwSize;
// change mem protection option
PDWORD lpflOldProtect = 0;
bool change_protection = VirtualProtect(base_add,dwSize,PAGE_EXECUTE_READWRITE, lpflOldProtect );
if (change_protection)
{
cout << "Successfully changed protection" << endl;
}
else
{
cout << " Failed" << endl;
}
}
根据 Microsoft documentation,VirtualProtect
中的最后一个参数是:
A pointer to a variable that receives the previous access protection value of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.
这是什么意思?指定区域首页的值是多少?那不是基地址吗?
VirtualProtect
函数的第四个(最后一个)参数应该是 DWORD
变量的地址,在该变量中接收内存块的先前保护标志的值(或者,确切地说,是该块的第一页)。如果您愿意,可以在完成需要更改该保护的任何操作后将其用于 'reset' 该保护级别。
在您的代码中,您在 PDWORD lpflOldProtect = 0;
行中声明了一个指针并为该指针分配了一个 NULL
(零)值 – 因此,根据您链接的文档,您对 VirtualProtect
会失败。
相反,您应该声明一个 actual DWORD
变量并将该变量的地址作为最后一个参数传递。在您的情况下,修改后的代码将如下所示:
DWORD flOldProtect = 0;
BOOL change_protection = VirtualProtect(base_add, dwSize, PAGE_EXECUTE_READWRITE, &flOldProtect);
// Pass address of the DWORD variable ^
if (change_protection)
{
//...
请注意,在链接文档中,最后一个参数被标记为 [out]
– 这意味着它在调用之前的值未被函数使用,因此您实际上不需要对其进行初始化;然而,一些编译器 and/or 代码分析器 可能 抱怨使用未初始化的值,这就是我将其设置为零的原因。
另请注意,函数的 return 值是 BOOL
类型(在 Windows 系统头文件中声明为 typedef int BOOL;
),而不是 bool
;在大多数情况下,您的代码进行的隐式转换不会导致任何问题,但同样,某些编译器可能会发出有关该转换的警告。