|
|
#include "stdafx.h"
#include <Windows.h>
#include <Tlhelp32.h>
#include < sapi.h.>
#include <vector>
using std::vector;
using std::vector;
BOOL byPassHscrc(DWORD dwGameProcessId);
BOOL getProcessIdByName(LPWSTR lpProcessName, vector *pProcessarray);
bool EnableDebugPrivilege();
void *GetFilename( char *fullpathname) ;
void fakeX64ImagePath();
void fakeX86ImagePath();
#pragma comment (lib, "psapi.lib")
BOOL IsWow64 = FALSE;
WCHAR szPath32[MAX_PATH];
WCHAR szPath64[MAX_PATH];
//wchar_t *lpwcImagePathNameWith32bit = L"C:Windowssystem32svchost.exe";
//wchar_t *lpwcImagePathNameWith64bit = L"C:Windowssystem32svchost.exe";
typedef enum _THREADINFOCLASS
{
ThreadBasicInformation,
ThreadTimes,
ThreadPriority,
ThreadBasePriority,
ThreadAffinityMask,
ThreadImpersonationToken,
ThreadDescriptorTableEntry,
ThreadEnableAlignmentFaultFixup,
ThreadEventPair_Reusable,
ThreadQuerySetWin32StartAddress,
ThreadZeroTlsCell,
ThreadPerformanceCount,
ThreadAmILastThread,
ThreadIdealProcessor,
ThreadPriorityBoost,
ThreadSetTlsArrayAddress,
ThreadIsIoPending,
ThreadHideFromDebugger,
ThreadBreakOnTermination,
MaxThreadInfoClass
} THREADINFOCLASS;
extern "C" LONG (__stdcall *ZwQueryInformationThread) (
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL
) = NULL;
extern "C" LONG (__stdcall *RtlNtStatusToDosError) (
IN ULONG status) = NULL;
//wchar_t *x64_ImagePath = L"C:Windowssystem32winlogon.exe";
int _tmain(int argc, _TCHAR *argv[])
{
//
int a = NULL ;
vector pProcessArray ;
//fakeX86ImagePath(lpwcImagePathNameWith32bit);
if (NULL == EnableDebugPrivilege())
{
wprintf(L"EnableDebugPrivilege() failed, n");
return 0;
}
if(!IsWow64Process(GetCurrentProcess(), &IsWow64))
{
wprintf(L"OpenThread failed, %d n", GetLastError());
return 0;
}
if (!IsWow64)
{
wprintf(L"the process is running under X86 - 32, n");
fakeX86ImagePath();
}
else
{
wprintf(L"the process is running under WOW64, n");
fakeX64ImagePath();
//fakeX64ImagePath(lpwcImagePathNameWith64bit);
}
//getchar();
wprintf(L"begin by pass CRC .. . . . ... .. .., n");
[COLOR="Red"]getProcessIdByName(L"iexplore.exe", &pProcessArray); //替换成带HS保护的游戏的进程名即可[/COLOR]
int nSize = pProcessArray.empty() ? -1 : static_cast(pProcessArray.size());
if (-1 == nSize)
{
wprintf(L" rocess is non-existent n");
getchar();
return 0;
}
for (int i = 0; i < nSize; i++)
{
wprintf(L" ID ->%d.. n", pProcessArray.at(i));
if (FALSE == byPassHscrc(pProcessArray.at(i)))
{
wprintf(L"byPassHscrc() failed, n");
}
else
{
wprintf(L" byPassHscrc() success, n" );
};
}getchar();
/*if (FALSE == byPassHscrc())
{
wprintf(L"byPassHscrc() failed, n");
}
else
{
wprintf(L" byPassHscrc() success, n" );
};*/
//useToolHelp();
//return 0;
return 0;
}
bool EnableDebugPrivilege()
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return FALSE;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
{
CloseHandle(hToken);
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
CloseHandle(hToken);
return false;
}
return true;
}
void *GetFilename( char *fullpathname)
{
char *save_name, *pos;
int name_len;
name_len = strlen(fullpathname);
pos = fullpathname + name_len;
while(*pos != '' && pos != fullpathname)
pos --;
if(pos == fullpathname)
{
save_name = fullpathname + 1;
return save_name;
}
name_len = name_len - (pos - fullpathname);
save_name = (char *) malloc(name_len + 1);
memcpy(save_name, pos + 1, name_len);
return save_name;
}
void fakeX64ImagePath()
{
int a = NULL;
GetSystemDirectoryW(szPath64, MAX_PATH);
lstrcatW(szPath64, L"svchost.exe");
__asm
{
pushad
mov eax, dword ptr fs:[0x30]
add eax, 0x1000
mov eax, [eax+0x020]
add eax, 0x060
mov [a], eax
add eax, 0x8
lea ebx, szPath64
mov [eax], ebx
popad
}
wprintf(L"x64 pImagePathName: (0x%08x) n", a);
}
void fakeX86ImagePath()
{
int a = NULL;
wprintf(L"jdjjf32 n");
GetSystemDirectoryW(szPath32, MAX_PATH);
lstrcatW(szPath32, L"svchost.exe");
__asm
{
pushad
mov eax, dword ptr fs:[0x30]
mov eax, [eax+0x10]
add eax, 0x38
add eax, 0x4
lea ebx, szPath32;
mov [eax], ebx
mov [a], eax
popad
}
wprintf(L"x86 pImagePathName: (0x%08x) n", a);
}
BOOL byPassHscrc(DWORD dwGameProcessId)
{
HANDLE hThreadSnap , hProcess , hThread;
char *cszFileName;
PVOID startaddr = NULL;
LONG status = NULL;
char szModuleFileName[MAX_PATH] = {0};
BYTE byPachCode[10] = { 0x68 , 0x00 , 0x00, 0x00, 0x10 , 0xE9 , 0x00 , 0x00 , 0x00 , 0x00};
THREADENTRY32 te32 = {0};
CONTEXT context = {0};
LPVOID lpbaseAddress = NULL;
FARPROC lpSleep = GetProcAddress(GetModuleHandle (TEXT ("Kernel32")), "Sleep");
HINSTANCE hNTDLL = ::GetModuleHandle (TEXT ("ntdll"));
//printf("lpSleep:0x%08x n",lpSleep);
//buffer2 += 0x0A;
(FARPROC &)ZwQueryInformationThread =
::GetProcAddress (hNTDLL, "ZwQueryInformationThread");
(FARPROC &)RtlNtStatusToDosError =
::GetProcAddress (hNTDLL, "RtlNtStatusToDosError");
hThreadSnap = hProcess = hThread = NULL ;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwGameProcessId);
if (NULL == hProcess)
{
printf("OpenProcess failed, %d n", GetLastError());
return FALSE ;
}
lpbaseAddress = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//wprintf(L"lpbaseAddress == 0x%08x n", lpbaseAddress) ;
if (NULL == lpbaseAddress)
{
printf("VirtualAllocEx failed, %d n", GetLastError());
return FALSE ;
}
*(DWORD *)((DWORD)&byPachCode + 6) = (DWORD)lpSleep - (DWORD)lpbaseAddress - 10 ;
if (!WriteProcessMemory(hProcess, lpbaseAddress, (LPVOID)&byPachCode, sizeof(byPachCode), NULL))
{
printf("WriteProcessMemory failed, %d n", GetLastError());
return FALSE ;
}
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if ( hThreadSnap == INVALID_HANDLE_VALUE )
{
printf("CreateToolhelp32Snapshot failed, %d n", GetLastError());
return FALSE ;
}
memset(&te32, 0, sizeof(te32));
te32.dwSize = sizeof(THREADENTRY32);
BOOL bRet = Thread32First(hThreadSnap, &te32);
while(bRet)
{
if (te32.th32OwnerProcessID == dwGameProcessId)
{
hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
if (NULL == hThread)
{
wprintf(L"OpenThread failed, %d n", GetLastError());
return FALSE;
}
else
{
status = ZwQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &startaddr, sizeof(startaddr), NULL);
if (status < 0)
{
CloseHandle (hThread);
SetLastError (RtlNtStatusToDosError (status));
return FALSE;
}
else
{
if (0 == GetMappedFileNameA(hProcess, startaddr, szModuleFileName, MAX_PATH))
{
wprintf(L"GetMappedFileNameW failed, %d n", GetLastError());
}
else
{
cszFileName = (char *)GetFilename(szModuleFileName);
if (!strcmp(cszFileName, "ehsvc.dll") ||
!strcmp(cszFileName, "ole32.dll") ||
!strcmp(cszFileName, "ntdll.dll") ||
!strcmp(cszFileName, "winmm.dll")) // 某些游戏不需要处理ntdll、ole32、winmm线程,请自行决定。
{
//printf("ModuleFileName: (%s) n", cszFileName);
if (-1 != SuspendThread(hThread))
{
context.ContextFlags = CONTEXT_ALL | CONTEXT_CONTROL;
if (!GetThreadContext(hThread, &context))
{
wprintf(L"GetThreadContext failed, %d n", GetLastError());
return FALSE;
};
context.Eip = (DWORD)lpbaseAddress;
context.ContextFlags = CONTEXT_ALL | CONTEXT_CONTROL;
if (!SetThreadContext(hThread, &context))
{
wprintf(L"SetThreadContext failed, %d n", GetLastError());
return FALSE;
};
if (-1 == ResumeThread(hThread))
{
printf(" Treatment failed :{ %s } , startaddr :: 0x%08x.n", cszFileName, startaddr);
return FALSE;
}
printf(" Treatment success :{ %s } , startaddr :: 0x%08x.n", cszFileName, startaddr);
}
else
{
wprintf(L" SuspendThread failed :{ %d }n", GetLastError());
return FALSE;
};
}
}
}
}
CloseHandle(hThread);
}
bRet = Thread32Next(hThreadSnap, &te32);
}
CloseHandle(hThreadSnap);
CloseHandle(hProcess);
return TRUE;
}
BOOL getProcessIdByName(LPWSTR lpProcessName, vector *pProcessarray)
{
HANDLE hProcessSnap;
hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hProcessSnap)
{
wprintf(L"CreateToolhelp32Snapshot failed : { %d }n", GetLastError());
return FALSE;
}
memset(&pe32, 0, sizeof(pe32));
pe32.dwSize = sizeof(PROCESSENTRY32);
BOOL bRet = Process32First(hProcessSnap, &pe32);
if (bRet == FALSE)
{
wprintf(L" rocess32First failed : { %d }n", GetLastError());
}
while(bRet)
{
wprintf(L"%s n", pe32.szExeFile);
if (!wcscmp(lpProcessName, pe32.szExeFile))
{
pProcessarray->push_back(pe32.th32ProcessID);
}
bRet = Process32Next(hProcessSnap, &pe32);
}
}
)//整体上处理还是比较完美的,crc线程原本是多层检测的(某条检测某条),用这样的方式可以直接绕过多层检测。干叼HS的crc
|
|