How fixed this error template argument

Hello ,


code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename T, bool EnableVirtual = true>
inline void Write(LPVOID lpAddress, T _tValue) const
{
if (EnableVirtual) {

DWORD dwOldProtect=0;
VirtualProtect(lpAddress, sizeof(T), PAGE_EXECUTE_READWRITE, &dwOldProtect);
*(T*)lpAddress = _tValue;
VirtualProtect(lpAddress, sizeof(T), dwOldProtect, &dwOldProtect);
}
else
{
*(T*)lpAddress = _tValue;
}
}



--------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Patch::CallPatch(LPVOID lpAddress, LPVOID lpTarget) const
{
	DWORD dwOldProtect=0;
	 auto PatchSize = 5;//constexpr
	VirtualProtect(lpAddress, PatchSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
	memory.Write<BYTE, FALSE>(lpAddress, 0xE8);

	auto lpCallPatchAddress = reinterpret_cast<LPVOID>((DWORD)lpAddress + 1);
	auto dwRelativePatchAddress = (DWORD)lpTarget - (DWORD)lpAddress - 5;

	memory.Write<DWORD>(lpCallPatchAddress, dwRelativePatchAddress);


	VirtualProtect(lpAddress, PatchSize, dwOldProtect, &dwOldProtect);



}



1
2
3
4
5
errors :

error C4519: default template arguments are only allowed on a class template
error C2783: 'void Memory::Write(LPVOID,T) const' : could not deduce template argument for 'EnableVirtual'
see declaration of 'Memory::Write'




VS 2010 ,
Last edited on
Is your function:
1
2
template<typename T, bool EnableVirtual = true>
inline void Write(LPVOID lpAddress, T _tValue) const

a member of a class called Memory?

You haven't shown enough code.
thanks kbw for reply , its full code write memory internal(Dll Inject) not external


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
class Memory
{
public:
	Memory()
	{
		DWORD dwModuleBase = (DWORD)GetModuleHandle(NULL);
		if (dwModuleBase == 0x00)
		{
			//logger.log_windows_error("Memory::GetModuleHandle failed");
		}
	}

	template <typename T>
	inline T Read(LPVOID lpAddress) const
	{
		return *(T*)lpAddress;
	}
	//memory.Write<BYTE, FALSE>(lpAddress, 0xE8);
		template<typename T, bool >
	inline void Write(LPVOID lpAddress, T _tValue) const
	{
		if (EnableVirtual) {
			//if (EnableVirtual) {
			DWORD dwOldProtect=0;
			VirtualProtect(lpAddress, sizeof(T), PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(T*)lpAddress = _tValue;
			VirtualProtect(lpAddress, sizeof(T), dwOldProtect, &dwOldProtect);
		}
		else
		{
			*(T*)lpAddress = _tValue;
		}
	}


	

	
};
Last edited on
This compiles (MS VS2022):

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
class Memory
{
public:
	Memory() {
		DWORD dwModuleBase = (DWORD)GetModuleHandle(NULL);
		if (dwModuleBase == 0x00) {
			//logger.log_windows_error("Memory::GetModuleHandle failed");
		}
	}

	template <typename T>
	inline T Read(LPVOID lpAddress) const {
		return *(T*)lpAddress;
	}
	//memory.Write<BYTE, FALSE>(lpAddress, 0xE8);
	template<typename T, bool EnableVirtual = true>
	inline void Write(LPVOID lpAddress, T _tValue) const {
		if constexpr (EnableVirtual) {
			//if (EnableVirtual) {
			DWORD dwOldProtect = 0;
			VirtualProtect(lpAddress, sizeof(T), PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(T*)lpAddress = _tValue;
			VirtualProtect(lpAddress, sizeof(T), dwOldProtect, &dwOldProtect);
		} else {
			*(T*)lpAddress = _tValue;
		}
	}
};

Memory memory;

void CallPatch(LPVOID lpAddress, LPVOID lpTarget) {
	DWORD dwOldProtect = 0;
	auto PatchSize = 5;
	VirtualProtect(lpAddress, PatchSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
	memory.Write<BYTE, false>(lpAddress, 0xE8);

	auto lpCallPatchAddress = reinterpret_cast<LPVOID>((DWORD)lpAddress + 1);
	auto dwRelativePatchAddress = (DWORD)lpTarget - (DWORD)lpAddress - 5;

	memory.Write<DWORD>(lpCallPatchAddress, dwRelativePatchAddress);

	VirtualProtect(lpAddress, PatchSize, dwOldProtect, &dwOldProtect);
}

// FOR COMPILE TEST ONLY
int main() {
	char a[20], b[20];

	CallPatch(a, b);
}


As enableVirtual is a template parameter, it's value is known at compile time so constexpr is used for the if test.

Also note that this code is valid only for 32-bit compile. There are truncation issues if compiled as 64-bit. You can't use DWORD for a pointer with 64-bit compiles - the type should be DWORD_PTR which is correct for both 32 and 64 bit compiles.


Last edited on
Thanks for reply seeplus , and Thanks for the clarification, but how can I convert the code to work on VS 2010 ,
Upgrade VS2010 to the latest VS2022. The Community version is free.
https://visualstudio.microsoft.com/free-developer-offers/

The issue is probably constexpr. This was introduced into C++ from C++11. VS2010 is C++98 - a very, very, very old version of C++. I really, very, strongly urge you to update the C++ compiler.
seeplus wrote:
Upgrade VS2010 to the latest VS2022.

That requires x64 Windows, as you know. :)

VS 2019 is still available and can be installed on x86 or x64 Windows.

VS 2017 is also currently available, though I wouldn't recommend it.

2019 or 2022 are 100% compliant with the C++20 standard, if that matters. There are C standard enhancement as well, along with WinAPI updates that are not part of VS2010. Crucial updates for modern Windows versions.
Registered users can post here. Sign in or register to post.