1.函数定义
需要注意的是这个函数未文档话,网上随便找了个定义,发现报错
typedef NTSTATUS(CALLBACK* PZwProtectVirtualMemory)(
HANDLE ProcessHandle,
PVOID* BaseAddress,
PULONG NumberOfBytesToProtect,
ULONG NewAccessProtection,
PULONG OldAccessProtection);
0xC00000F1
STATUS_INVALID_PARAMETER_3
注意第三个参数应该是SIZE_T*类型了,PULONG传进去如果复制的时候是ULONG,前面的高4位不会清零会出错
typedef NTSTATUS(CALLBACK* PZwProtectVirtualMemory)(
HANDLE ProcessHandle,
PVOID* BaseAddress,
SIZE_T* NumberOfBytesToProtect,
ULONG NewAccessProtection,
PULONG OldAccessProtection);
2.函数的使用
第二个参数在传入之后,传出会发生改变,需要定义一个零时变量去存
printf("%p before %x", g_orgXXXXXAddresss, *(PULONG)g_orgXXXXXAddresss);
NTSTATUS status = ZwProtectVirtualMemory((HANDLE)-1, &g_orgXXXXXAddresss, &uSize, PAGE_EXECUTE_READWRITE,&oldProtect);
printf("status %x", status);
if (NT_SUCCESS(status))
{
printf("%p before %x", g_orgXXXXXAddresss, *(PULONG)g_orgXXXXXAddresss);
memcpy(g_orgXXXXXAddresss, g_pZwXXXXXAddresss,0x20);
printf("%p after %x", g_orgXXXXXAddresss, *(PULONG)g_orgXXXXXAddresss);
ZwProtectVirtualMemory((HANDLE)-1, &g_orgXXXXXAddresss, &uSize, oldProtect, &oldProtect);
}
输出结果:
before0 00007FFDDF13CA60 1735aae9
status 0
00007FFDDF13C000 before e1a225ff
00007FFDDF13C000 after b8d18b4c
修改代码之后
printf("%p before %x", g_orgXXXXXAddresss, *(PULONG)g_orgXXXXXAddresss);
PVOID address = g_orgXXXXXAddresss;
NTSTATUS status = ZwProtectVirtualMemory((HANDLE)-1, &address, &uSize, PAGE_EXECUTE_READWRITE,&oldProtect);
printf("status %x", status);
if (NT_SUCCESS(status))
{
printf("%p before %x", g_orgXXXXXAddresss, *(PULONG)g_orgXXXXXAddresss);
memcpy(g_orgXXXXXAddresss, g_pZwXXXXXAddresss,0x20);
printf("%p after %x", g_orgXXXXXAddresss, *(PULONG)g_orgXXXXXAddresss);
address = g_orgXXXXXAddresss;
ZwProtectVirtualMemory((HANDLE)-1, &address, &uSize, oldProtect, &oldProtect);
}
before0 00007FFDDF13CA60 1735aae9
status 0
00007FFDDF13CA60 before 1735aae9
00007FFDDF13CA60 after b8d18b4c
unsigned char*和char*的问题
一般我比较经常使用PUCHAR很少用char *,进行二进制比较的时候不要用char*
比如
UCHAR a={0xea}
if((char *)a[0]==0xea)
这里返回的是false,不注意的话会出错,高位为1,区分有符号和无符号