PB Screenshot Blocker Tutorial

社区服务
高级搜索
猴岛论坛CSGO反恐精英CS作弊器交流讨论PB Screenshot Blocker Tutorial
发帖 回复
倒序阅读 最近浏览的帖子最近浏览的版块
0个回复

PB Screenshot Blocker Tutorial

楼层直达
作弊辅导员_h

ZxID:1019634

等级: 元老
定做作弊器
举报 只看楼主 使用道具 楼主   发表于: 2007-06-28 0

PB Screenshot Blocker Tutorial           

--------------------------------------------------------------------------------
Alright, I'm going to assume you know how to hook. (Since blocking a PB screenshot revolves around hooking). There are multiple ways to block a screenshot, but what I use us hooking GetForegroundWindow.


What you need

Knowledge of the C/C++ language and some WIN32 API

the detours package(detours.h;detours.lib)

A logger

Alright, now I want you to create a new *.cpp file called PB Bypass.cpp, and to create a header file PB Bypass.h.

Now, inside of PB Bypass.cpp, I want to include some files.
code:
1:
2:
3:
4:

 #include <detours.h>
#include <windows.h>

 
 


Create a void now, right below the includes and lets call it PB_SCREENSHOT_BLOCKER. No parameters. It should look like this:

code:
1:
2:
3:
4:
5:

 void PB_SCREENSHOT_BLOCKER ( void )
{
}

 
 

Now, I want you to nest a detour inside of this void.
Nest this:

code:
1:
2:
3:

 DetourFunctionWithTrampoline((PBYTE)pGetForegroundWindow,(PBYTE)NewGetForegroundWindow);

 
 


Now, don't try to compile this. It won't work. At the very top of the code, right below the includes, make this:

code:
1:
2:
3:

 DETOUR_TRAMPOLINE( HWND __stdcall pGetForegroundWindow(void),GetForegroundWindow );

 
 


Now, all you've got to do is create a body for NewGetForegroundWindow. This should look like this:


code:
1:
2:
3:
4:
5:

 HWND __stdcall NewGetForegroundWindow(void)
{
}

 
 


Now, that may not compile, because it doesn't return anything.
Next thing we've got to do, is make a void to capture the return address. How? Just like this:

code:
1:
2:
3:
4:
5:
6:

 void * _ReturnAddress(void);
unsigned retaddr;
DWORD ReturnAddress=(DWORD)_ReturnAddress();
extern "C" void * _ReturnAddress(void);//put this in your header

 
 

Declare those globaly. No use in putting them in headers.
You may also want to include this, some compilers need it. If you do need it, put it right below the #includes.
code:
1:
2:
3:

 #pragma  intrinsic(_ReturnAddress)

 
 

Add this inside of your NewGetForegroundWindow.
code:
1:
2:
3:
4:
5:

  HWND__ *  retval = 0;
DWORD ReturnAddress=(DWORD)_ReturnAddress();
 unsigned int *pbID = (unsigned int *)ReturnAddress;

 
 


We'll be using this to return the real foreground window if PB isn't calling. Now, this is where your nice little logger comes into play. Once all of this is added, insert:

code:
1:
2:
3:

 print_log("0x%x",*pbID);//or however you log

 
 


That will give you PB's calling address. Then, you just make a simple if statement.

For example, for SoF2 the newest version of Pb uses the address: 0x448df88b. So I'd put:
code:
1:
2:
3:
4:
5:

 if(*pbID==0x448df88b)
return 0;
//This would return a black screenshot, because the return 0 isn't giving PB a handle.

 
 


Alright, now if you go to compile all of this, it won't work. Why?

It's not being called

Even if you do call it, you'll get no sound.


So, let's fix our first problem. In your header, put:
code:
1:
2:
3:

 void PB_SCREENSHOT_BLOCKER ( void );

 
 

There, all set. You're ready to call it, so now put this in your PROCESS_DLL_ATTATCH:
code:
1:
2:
3:
4:
5:
6:

 case DLL_PROCESS_ATTATCH:
 PB_SCREENSHOT_BLOCKER();
//rest of your code
break;

 
 

Alright, now if you test this all should work good. BUT, you'll get no sound. How do we fix this? Well, let's retur the RIGHT value.


After the if statement, put at th ebottem this:


code:
1:
2:
3:
4:
5:

 retval = 0;
 retval = pGetForegroundWindow();
 return retval;

 
 

It should only be that when PB's calling, that the hack returns 0. When pb's NOT calling, the hack returns the regular window, thus resulting in sound. If and when you log your PB's memory address, you may get a number of memory address. Usually the one that has no other copies is the one. You might get 19 total memory address. 18 are the same. The one that's not, is your address.


Want to disable hacks, then return a clean PB screenshot? This is what you do:

delete the return 0; that we put in the nested function that tests if PB is calling. Make another if statement.This time test if a hack you'd like to turn off is on. i.e a wallhack.

So, say your integer/bool to test if a wallhack is on is
code:
1:
2:
3:

 int wallhac;

 
 

You would place the following code underneath the PB if statement that tests if PB is calling:

code:
1:
2:
3:
4:
5:
6:
7:

 if(wallhack!=0)//assuming 0 means it's off
{
wallhack = 0;
return 0; //after the wallhack's disabled, give PB a handle
}

 
 


Now, it turns it off. Want to make it so it turns it on? Do this:


Declare a global integar. i.e readyToEnableWallhack

Use it

If you want to re-enable the hacks after the wallhack's disabled, above the return put this:
code:
1:
2:
3:

 readyToEnableWallhack = 1;

 
 


Then, after the block that tests if PB is calling, insert this:

code:
1:
2:
3:
4:
5:
6:
7:

 if(readyToEnableWallhack)
{
wallhack = 1;
readyToEnableWallhack=0;
}

 
 


So, you're code inside of NewGetForegroundWindow should look like:

code:
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:

 HWND__ *  retval = 0;
 DWORD ReturnAddress=(DWORD)_ReturnAddress();
 unsigned int *pbID = (unsigned int *)ReturnAddress;
//print_log("0x%x",*pbID);
 if(*pbID==0x448df88b)
 {
  if(wallhack)
  {
 wallhack = 0;
    readyToEnableWallhack = 1;
 return 0;
  }
 }

  if(readyToEnableWallhack)
  {
   wallhack = 1;
   readyToEnableWallhack = 0;
  }

 retval = 0;
 retval = pGetForegroundWindow();
 return retval;
}

 
 


Questions? Did I make a mistake? Did I leave out something? Tell me!!

密码被盗,请联系cscheat取回
« 返回列表
发帖 回复