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.
Topic archived. No new replies allowed.