Solved DLL unable to be injected after adding PlaceJMP call, protection error

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
I was able to get my program working with the right tweaks, but when I finally went and added in the line to direct where I wanted the jump placed, the DLL no longer injects. Winject tells me: both injection methods failed, target is protected? err: 0

Here is the PlaceJMP function I am using, from the tutorial:
C++:
void PlaceJMP(BYTE *Address, DWORD jumpTo, DWORD length)
{
	DWORD dwOldProtect, dwBkup, dwRelAddr;
	VirtualProtect(Address, length, PAGE_EXECUTE_READWRITE, &dwOldProtect);

	dwRelAddr = (DWORD)(jumpTo - (DWORD)Address) - 5;

	*Address = 0xE9;
	*((DWORD *)(Address + 0x1)) = dwRelAddr;

	for (DWORD x = 0x5; x < length; x++)
		*(Address + x) = 0x90;
	
	VirtualProtect(Address, length, dwOldProtect, &dwBkup);
}

and here is the line that 'broke' my dll, for lack of a better term. When I added this, the DLL stopped injecting.

C++:
PlaceJMP((BYTE*)fCall, (DWORD)ASM, 5);
I figured maybe Cheatengine being hooked to it was interfering, but restarting everything didn't help. I've auto-assembled functions in cheat engine many times, so I don't think the game is somehow at fault. Maybe something is missing from the code.
 

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
C++:
//fstp dword ptr [ecx+000000B0]
//xWrite = DWORD function that updates x
//xA = angular multiplier
_declspec (naked) void xASM()
{

	if (GetAsyncKeyState(VK_CONTROL))
	{
		*(float*)x = *(float*)x + *(float*)xA * 5;
	}
	else
	{
		__asm fstp dword ptr [ecx+0xB0]; //6 bit code removed for jump, writes to x.
	}

	__asm jmp(xWrite+0x6) // jump back 6 bits after jump
}
You need
_asm pushad; _asm pushfd;

at the beginning and
_asm popfd; _asm popad;

at the end. At the first glance one might not see this but:

GetAsyncKeyState and the call to it modifies the registers
and *(float*)pointer modifies registers aswell. What you need is this:

C++:
_declspec (naked) void xASM()
{
        _asm pushad;
        _asm pushfd;
	if (GetAsyncKeyState(VK_CONTROL))
	{
		*(float*)x = *(float*)x + *(float*)xA * 5;
	}
	else
	{
                _asm popfd;
                _asm popad;
		__asm fstp dword ptr [ecx+0xB0]; //6 bit code removed for jump, writes to x.
                goto ret;
	}
        _asm popfd;
        _asm popad;

ret:

	__asm jmp(xWrite+0x6) // jump back 6 bits after jump
}

You need the label (ret:) because otherwise you'd save the registers once and restore them twice.
 

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
MSDN said:
BOOL WINAPI VirtualProtect [...]

Return value

If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Also, you should, in your DllMain() create a new thread which does your hooking and other stuff, which means you'd have another thread handling the hooking and your DLL should at least get injected
 

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
That seemed to work. Before my code was

C++:
InitiateHooks();
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)OverwriteValues, NULL, NULL, NULL);
I put the InitiateHooks in the Overwrite values function. The DLL was able to be injected, but then the program crashed, so I am guessing that now there is something else in my code that needs to be fixed... Thank you till0sch


Edit:

Oh wait.. I may have spoke too soon.
 

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
So after some messing around, I managed to get it to inject, and I managed to get the jump placed since I can see it in memory. As a test, I made my ASM code match exactly the ASM instructions that were overwritten for the jump, meaning I made a code cave that redirects to 3 lines that were identical to what I overwrote to make that code cave, meaning the game should have executed the function normally, yet, it crashed when it hits my jump.

The 3 instructions commented below were copied from the original game memory. The return jump should be return directly to the valid and correct line that is right after my placed-jump.

C++:
void ASM()
{
	_asm{
			push ecx // from game 1 bit
			mov ecx,edi // from game 2 bits
			fstp dword ptr [esp] //from game 5 bits
			jmp[fCallRet] // base + 0x1EE920;
	}

}
C++:
	fCall = base + 0x1EE91A; //declared globally
	fCallRet = fCall + 6; //declared globally // 
	////////////////
	PlaceJMP((BYTE*)fCall, (DWORD)ASM, 6);
Here is a picture of the before and after

 
Last edited:

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
Instead of
void ASM ()

Write
_declspec (naked) void ASM ()

If you want an explanation I can give that as soon as I am on PC.
 

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
Yep that works :). I knew it was something simply I was missing. I think I removed that earlier to try to get variables to be accepted by the function, but forgot to add it back since it was compiling.
 

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
Instead of
void ASM ()

Write
_declspec (naked) void ASM ()

If you want an explanation I can give that as soon as I am on PC.
Maybe I can pick your brain real quick..

Something in my ASM code here is crashing my game. All of the addresses being used lead to correct values and by looking at the memory before the crash I can tell the code was successfully injected. In this code, I have it set so if CTRL is being pressed, then execute the code differently, if not, then execute the default instruction. However, the game crashes instantly upon injecting, before I can even get a chance to press CTRL. I figure something is probably wrong with the syntax, but I am not sure what.

C++:
//fstp dword ptr [ecx+000000B0]
//xWrite = DWORD function that updates x
//xA = angular multiplier
_declspec (naked) void xASM()
{

	if (GetAsyncKeyState(VK_CONTROL))
	{
		*(float*)x = *(float*)x + *(float*)xA * 5;
	}
	else
	{
		__asm fstp dword ptr [ecx+0xB0]; //6 bit code removed for jump, writes to x.
	}

	__asm jmp(xWrite+0x6) // jump back 6 bits after jump
}
 

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
What particular purpose does that push and pop serve, since I am not actively pushing any variables onto the stack for use? The only variables being used by the assembly itself are those which came from the code leading to the jump I set. Or is my understanding of the registers wrong? Does the stack prior to my jump not get carried into my code if i don't push it?

I thought *(float*)x = ?? was directly modifying the address? This is how the address has been directly modified in other cases.

EDIT:

The modified code you posted did not change anything, the game still crashes directly upon injection.

EDIT:

Okay so I played around with a bunch of different things, nothing worked. Notably I reduced it to the bare minimum. Neither of these work, client crashes immediately upon injection.

C++:
_declspec (naked) void xASM()
{
	__asm fstp dword ptr[ecx + 0xB0];
	__asm jmp(xWrite + 0x6); // jump back 6 bits after jump
}
C++:
_declspec (naked) void xASM()
{

	__asm fstp dword ptr[ecx + 0xB0];
	goto ret;
	ret:
	__asm jmp(xWrite + 0x6); // jump back 6 bits after jump
}
For reference sake, here is what I placed the jump with, and this address is not incorrect.:

C++:
PlaceJMP((BYTE*)xWrite, (DWORD)xASM, 6);
 
Last edited:

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
What particular purpose does that push and pop serve, since I am not actively pushing any variables onto the stack for use? The only variables being used by the assembly itself are those which came from the code leading to the jump I set. Or is my understanding of the registers wrong? Does the stack prior to my jump not get carried into my code if i don't push it?

I thought *(float*)x = ?? was directly modifying the address? This is how the address has been directly modified in other cases.

EDIT:

The modified code you posted did not change anything, the game still crashes directly upon injection.
Maybe your pointer is invalid
 

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
Maybe your pointer is invalid
It's not.

I was using this (with the jump disabled) in the mainloop bound to a hotkey and it did exactly as intended.

C++:
				*(float*)x = *(float*)x + *(float*)xA*0.3;
				*(float*)y = *(float*)y + *(float*)yA*0.3;


I noticed that your post went to the second page before I had last edited my previous post, so I'm guessing you didn't see what's below. I reduced the code to the bare minimum and tried the variations below, along with some other ones, all of them caused the client to instantly crash upon injecting.

C++:
_declspec (naked) void xASM()
{
	__asm fstp dword ptr[ecx + 0xB0];
	__asm jmp(xWrite + 0x6); // jump back 6 bits after jump
}
C++:
_declspec (naked) void xASM()
{

	__asm fstp dword ptr[ecx + 0xB0];
	goto ret;
	ret:
	__asm jmp(xWrite + 0x6); // jump back 6 bits after jump
}
For reference sake, here is what I placed the jump with, and this address is not incorrect.:

C++:
PlaceJMP((BYTE*)xWrite, (DWORD)xASM, 6);
Even this is failing.... and this is basically the equivalent to noping, as it is jumping to my code, and then jumping back, effectively skipping the one line that I was intending to modify. I also looked at the memory-view in cheat engine, when I inject the jump gets placed directly in the right spot, at which point the client has crashed.

C++:
_declspec (naked) void xASM()
{
	__asm jmp(xWrite + 0x6); // jump back 6 bits after jump
}
 

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
It's not.

I was using this (with the jump disabled) in the mainloop bound to a hotkey and it did exactly as intended.

C++:
				*(float*)x = *(float*)x + *(float*)xA*0.3;
				*(float*)y = *(float*)y + *(float*)yA*0.3;


I noticed that your post went to the second page before I had last edited my previous post, so I'm guessing you didn't see what's below. I reduced the code to the bare minimum and tried the variations below, along with some other ones, all of them caused the client to instantly crash upon injecting.

C++:
_declspec (naked) void xASM()
{
	__asm fstp dword ptr[ecx + 0xB0];
	__asm jmp(xWrite + 0x6); // jump back 6 bits after jump
}
C++:
_declspec (naked) void xASM()
{

	__asm fstp dword ptr[ecx + 0xB0];
	goto ret;
	ret:
	__asm jmp(xWrite + 0x6); // jump back 6 bits after jump
}
For reference sake, here is what I placed the jump with, and this address is not incorrect.:

C++:
PlaceJMP((BYTE*)xWrite, (DWORD)xASM, 6);
Even this is failing.... and this is basically the equivalent to noping, as it is jumping to my code, and then jumping back, effectively skipping the one line that I was intending to modify. I also looked at the memory-view in cheat engine, when I inject the jump gets placed directly in the right spot, at which point the client has crashed.

C++:
_declspec (naked) void xASM()
{
	__asm jmp(xWrite + 0x6); // jump back 6 bits after jump
}
Instead of
__asm jmp(xWrite + 0x6);

try increasing xWrite by 6 after hooking and then do
_asm jmp(xWrite)
 

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
I knew it was something simple throwing everything off..... thank you!

Now I just need to figure out how to prevent my game from crashing when the pointers that I'm using in my program temporarily go blank. If they are attempted to be accessed by my program in this temporary transition/changing state, such as when the map is loading, my game crashes. Not really sure how to work around that.
 

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
I knew it was something simple throwing everything off..... thank you!

Now I just need to figure out how to prevent my game from crashing when the pointers that I'm using in my program temporarily go blank. If they are attempted to be accessed by my program in this temporary transition/changing state, such as when the map is loading, my game crashes. Not really sure how to work around that.
There are ways to check that.

Take a look at VirtualQuery:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366902(v=vs.85).aspx

MSDN said:
SIZE_T WINAPI VirtualQuery(
_In_opt_ LPCVOID lpAddress,
_Out_ PMEMORY_BASIC_INFORMATION lpBuffer,
_In_ SIZE_T dwLength
);
MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery( The address of your pointer here,
&mbi,
sizeof(mbi) ) != 0)

is what you need.
Additionally check mbi.Protect then for every flag which conains "write" and "read"
(PAGE_READWRITE, PAGE_EXECUTE_READWRITE ...)

If it is either of them and VirtualQuery didn't return 0, you can safely write and read there.
Otherwise, skip your reading and writing of the pointer.
 

Lunoz

Newbie
Full Member
Jun 18, 2015
18
102
0
Would I need to apply that function for each level of the pointer? For example, my pointers are set up like this. (I've been searching on this for the last 2 days and haven't found a way that works to condense a multi level pointer into a single line.

C++:
	z = *(DWORD*)(base + 0x5EC5E4);
	z = *(DWORD*)(z + 0x5A8);
	z = *(DWORD*)(z + 0x4);
	z = (z + 0xB4);
If I can find, or if you can suggest a way to condense such a multi level pointer easily into a single line, would I need to call the VirtualQuery function at every single time my pointer is read or wrote to? Seems a bit tedious. I don't recall seeing such redundancy in other cpp dll injection hacks that I've looked at in the past, but I could be mistaken.
 

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
Would I need to apply that function for each level of the pointer? For example, my pointers are set up like this. (I've been searching on this for the last 2 days and haven't found a way that works to condense a multi level pointer into a single line.

C++:
	z = *(DWORD*)(base + 0x5EC5E4);
	z = *(DWORD*)(z + 0x5A8);
	z = *(DWORD*)(z + 0x4);
	z = (z + 0xB4);
If I can find, or if you can suggest a way to condense such a multi level pointer easily into a single line, would I need to call the VirtualQuery function at every single time my pointer is read or wrote to? Seems a bit tedious. I don't recall seeing such redundancy in other cpp dll injection hacks that I've looked at in the past, but I could be mistaken.
If you use ReadProcessMemory, it doesn't matter anymore if the pointers are valid.
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,140
78,998
2,394
You can't really condense the multilevel pointer because it has to be calculated at runtime. If you use reclass to create classes you can access the variable by assigning a base pointer and accessing the variable like this world->currentgame->playerarray[4]->currentweapon->ammo. Buy as you can see it is still verbose
 

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
What is this supposed to mean? Where is the context?
 
Last edited by a moderator:

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
You can't really condense the multilevel pointer because it has to be calculated at runtime. If you use reclass to create classes you can access the variable by assigning a base pointer and accessing the variable like this world->currentgame->playerarray[4]->currentweapon->ammo. Buy as you can see it is still verbose
Well if one of them was invalid the same thing would happen ;)
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods