401 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			401 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "pch.h"
 | ||
| #include "BuildIn.h"
 | ||
| #include "Data.h"
 | ||
| 
 | ||
| extern "C" extern DLLAPI wchar_t ns_str[6192];
 | ||
| extern HMODULE hMod;
 | ||
| extern "C" extern DLLAPI wchar_t ms_str[3096];
 | ||
| extern "C" extern DLLAPI int nID;
 | ||
| extern "C" extern DLLAPI DWORD tPid;
 | ||
| extern MicroData* Index;
 | ||
| extern MicroBinary* Data;
 | ||
| extern "C" extern DLLAPI DWORD m_Addr;
 | ||
| extern "C" extern DLLAPI DWORD VioMode;
 | ||
| 
 | ||
| signed int (*Sur_Sub)() = (signed int(*)(void))m_Addr;//real function point
 | ||
| HMODULE SelfHandle = NULL;
 | ||
| 
 | ||
| bool start_falg = false;
 | ||
| bool start_g_flag = false;
 | ||
| bool start_t_flag = false;
 | ||
| 
 | ||
| PVOID GetProcAddressEx(HANDLE hProc, HMODULE hModule, LPCSTR lpProcName)
 | ||
| {
 | ||
|     PVOID pAddress = NULL;
 | ||
|     SIZE_T OptSize;
 | ||
|     IMAGE_DOS_HEADER DosHeader;
 | ||
|     SIZE_T ProcNameLength = lstrlenA(lpProcName) + sizeof(CHAR);//'\0'
 | ||
|     //读DOS头
 | ||
|     if (ReadProcessMemory(hProc, hModule, &DosHeader, sizeof(DosHeader), &OptSize))
 | ||
|     {
 | ||
|         IMAGE_NT_HEADERS NtHeader;
 | ||
|         //读NT头
 | ||
|         if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + DosHeader.e_lfanew), &NtHeader, sizeof(NtHeader), &OptSize))
 | ||
|         {
 | ||
|             IMAGE_EXPORT_DIRECTORY ExpDir;
 | ||
|             SIZE_T ExportVirtualAddress = NtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
 | ||
|             //读输出表
 | ||
|             if (ExportVirtualAddress && ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExportVirtualAddress), &ExpDir, sizeof(ExpDir), &OptSize))
 | ||
|             {
 | ||
|                 if (ExpDir.NumberOfFunctions)
 | ||
|                 {
 | ||
|                     //x64待定:地址数组存放RVA的数据类型是4字节还是8字节???
 | ||
|                     SIZE_T* pProcAddressTable = (SIZE_T*)GlobalAlloc(GPTR, ExpDir.NumberOfFunctions * sizeof(SIZE_T));
 | ||
|                     //读函数地址表
 | ||
|                     if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfFunctions), pProcAddressTable, ExpDir.NumberOfFunctions * sizeof(PVOID), &OptSize))
 | ||
|                     {
 | ||
|                         //x64待定:名称数组存放RVA的数据类型是4字节还是8字节???
 | ||
|                         SIZE_T* pProcNamesTable = (SIZE_T*)GlobalAlloc(GPTR, ExpDir.NumberOfNames * sizeof(SIZE_T));
 | ||
|                         //读函数名称表
 | ||
|                         if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfNames), pProcNamesTable, ExpDir.NumberOfNames * sizeof(PVOID), &OptSize))
 | ||
|                         {
 | ||
|                             CHAR* pProcName = (CHAR*)GlobalAlloc(GPTR, ProcNameLength);
 | ||
|                             //遍历函数名称
 | ||
|                             for (DWORD i = 0; i < ExpDir.NumberOfNames; i++)
 | ||
|                             {
 | ||
|                                 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + pProcNamesTable[i]), pProcName, ProcNameLength, &OptSize))
 | ||
|                                 {
 | ||
|                                     if (RtlEqualMemory(lpProcName, pProcName, ProcNameLength))
 | ||
|                                     {
 | ||
|                                         //x64待定:函数在地址数组索引的数据类型是2字节还是???
 | ||
|                                         WORD NameOrdinal;
 | ||
|                                         //获取函数在地址表的索引
 | ||
|                                         if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfNameOrdinals + sizeof(NameOrdinal) * i), &NameOrdinal, sizeof(NameOrdinal), &OptSize))
 | ||
|                                         {
 | ||
|                                             pAddress = (PVOID)((SIZE_T)hModule + pProcAddressTable[NameOrdinal]);
 | ||
|                                         }
 | ||
|                                         break;//for
 | ||
|                                     }
 | ||
|                                 }
 | ||
|                             }
 | ||
|                             GlobalFree(pProcName);
 | ||
|                         }
 | ||
|                         GlobalFree(pProcNamesTable);
 | ||
|                     }
 | ||
|                     GlobalFree(pProcAddressTable);
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
|     return pAddress;
 | ||
| }
 | ||
| BOOL InjectDLL(HANDLE hProcess, LPCWSTR dllFilePathName)
 | ||
| {
 | ||
|     if (!hProcess)
 | ||
|         return FALSE;
 | ||
|     int cch = 1 + lstrlenW(dllFilePathName);
 | ||
|     int cb = cch * sizeof(wchar_t);
 | ||
|     LPWSTR PszLibFileRemote = (LPWSTR)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
 | ||
|     if (!PszLibFileRemote)
 | ||
|         return FALSE;
 | ||
|     if (!WriteProcessMemory(hProcess, PszLibFileRemote, (LPVOID)dllFilePathName, cb, NULL))
 | ||
|         return FALSE;
 | ||
|     HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|         LoadLibraryW, PszLibFileRemote, 0, NULL);
 | ||
|     if (!hThread) return FALSE;
 | ||
|     WaitForSingleObject(hThread, INFINITE);
 | ||
|     return TRUE;
 | ||
| }
 | ||
| 
 | ||
| extern char IpfData[16];
 | ||
| #define PutInt(a) _itoa_s(a,IpfData,10);MessageBoxA(0,IpfData,"num",0);
 | ||
| 
 | ||
| DWORD(WINAPI* pGetGlyphOutlineW)(
 | ||
|     _In_ HDC hdc,
 | ||
|     _In_ UINT uChar,
 | ||
|     _In_ UINT fuFormat,
 | ||
|     _Out_ LPGLYPHMETRICS lpgm,
 | ||
|     _In_ DWORD cjBuffer,
 | ||
|     _Out_writes_bytes_opt_(cjBuffer) LPVOID pvBuffer,
 | ||
|     _In_ CONST MAT2* lpmat2
 | ||
|     ) = GetGlyphOutlineW;
 | ||
| BOOL(WINAPI* pTextOutW)(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCWSTR lpString, _In_ int c) = TextOutW;
 | ||
| 
 | ||
| HANDLE InjectSelfTo(LPCSTR inptr)
 | ||
| {
 | ||
|  //   MessageBoxA(0, inptr,"",0);
 | ||
|     HANDLE currentThread = NULL;
 | ||
|     LPPROCESS_INFORMATION info = new PROCESS_INFORMATION;
 | ||
|     STARTUPINFOA si = { sizeof(si) };
 | ||
|     do {
 | ||
|         BOOL hF = CreateProcessA(inptr, NULL,
 | ||
|             NULL, NULL, FALSE,
 | ||
|             CREATE_SUSPENDED, NULL, NULL, &si, info);
 | ||
|         if (!hF) {
 | ||
|             MessageBoxA(0, "Failed to create Process!", inptr, MB_ICONERROR);
 | ||
|             return 0;
 | ||
|         }
 | ||
|         //   MessageBox(0, L"1", L"", 0);
 | ||
|         wchar_t m_Path[MAX_PATH];
 | ||
|         GetModuleFileName(hMod, m_Path, MAX_PATH);
 | ||
|         if (!InjectDLL(info->hProcess, m_Path)) {
 | ||
|             MessageBoxA(0, "", "", 0);
 | ||
|             return 0;
 | ||
|         }
 | ||
|         currentThread = info->hThread;
 | ||
|         tPid = info->dwProcessId;
 | ||
|     } while (0);
 | ||
|     HANDLE hHookStart = CreateRemoteThread(info->hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|         ::GetProcAddressEx(info->hProcess, hMod, "LoadExerte"), 0, 0, NULL);
 | ||
|     if (!hHookStart)
 | ||
|     {
 | ||
|         PutInt(GetLastError());
 | ||
|         MessageBox(0, L"Failed to create remote thread(LoadExerte)", L"error", MB_ICONERROR);
 | ||
|         return 0;
 | ||
|     }
 | ||
|     WaitForSingleObject(hHookStart, 0xFFFFFFFF);
 | ||
|     ResumeThread(info->hThread);
 | ||
|     delete info;
 | ||
|     lstrcpyW(ms_str, L" ");
 | ||
|     ns_str[0] = L'\0';
 | ||
|     return  currentThread;
 | ||
| }
 | ||
| signed int Fake_Sub()
 | ||
| {
 | ||
|     DWORD leax, lebx, lecx, ledx, lesi, ledi;
 | ||
|     __asm {
 | ||
|         mov dword ptr[leax], eax
 | ||
|         mov dword ptr[lebx], ebx
 | ||
|         mov dword ptr[lecx], ecx
 | ||
|         mov dword ptr[ledx], edx
 | ||
|         mov dword ptr[lesi], esi
 | ||
|         mov dword ptr[ledi], edi
 | ||
|     }
 | ||
|     // SetWindowTextW(m_hWnd, L"<22><><EFBFBD><EFBFBD>hook");
 | ||
|     ((int(*)(DWORD))::GetProcAddress(SelfHandle, "TranSplete"))(lecx);
 | ||
|     //  SetWindowTextW(m_hWnd, L"hook<6F><6B><EFBFBD><EFBFBD>");
 | ||
|     __asm {
 | ||
|         mov  eax, dword ptr[leax]
 | ||
|         mov  ebx, dword ptr[lebx]
 | ||
|         mov ecx, dword ptr[lecx]
 | ||
|         mov edx, dword ptr[ledx]
 | ||
|         mov  esi, dword ptr[lesi]
 | ||
|         mov edi, dword ptr[ledi]
 | ||
|     }
 | ||
|     return Sur_Sub();
 | ||
| }
 | ||
| DWORD WINAPI Th(LPVOID lp) {
 | ||
|     char a[16];
 | ||
|     while (1) {
 | ||
|         _itoa_s(nID, a, 10);
 | ||
|         SetWindowTextA(GetForegroundWindow(), a);
 | ||
|         Sleep(100);
 | ||
|     }
 | ||
|     return 0;
 | ||
| }
 | ||
| DWORD WINAPI fGetGlyphOutlineW(
 | ||
|     _In_ HDC hdc,
 | ||
|     _In_ UINT uChar,
 | ||
|     _In_ UINT fuFormat,
 | ||
|     _Out_ LPGLYPHMETRICS lpgm,
 | ||
|     _In_ DWORD cjBuffer,
 | ||
|     _Out_writes_bytes_opt_(cjBuffer) LPVOID pvBuffer,
 | ||
|     _In_ CONST MAT2* lpmat2
 | ||
| )
 | ||
| {
 | ||
|     wstring loca = L"";
 | ||
|     loca += (WCHAR)uChar;
 | ||
|     if(lstrlenW(ns_str)>=5999)
 | ||
|         ns_str[0] = L'\0';
 | ||
|     lstrcatW(ns_str, loca.c_str());
 | ||
|     return pGetGlyphOutlineW(hdc, L'A', fuFormat, lpgm, cjBuffer, pvBuffer, lpmat2);
 | ||
| }
 | ||
| BOOL  WINAPI fTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCWSTR lpString, _In_ int c)
 | ||
| {
 | ||
|     return pTextOutW(hdc, x, y, L"A", c);
 | ||
| }
 | ||
| void start()
 | ||
| {
 | ||
|    // MessageBoxA(0,"b","",0);
 | ||
|     if (start_falg)
 | ||
|         return;
 | ||
|     DetourRestoreAfterWith();
 | ||
|     DetourTransactionBegin();
 | ||
|     DetourUpdateThread(GetCurrentThread());
 | ||
|     DetourAttach(&(PVOID&)Sur_Sub, Fake_Sub);
 | ||
|     DetourTransactionCommit();
 | ||
|  
 | ||
|     start_falg = TRUE;
 | ||
|    // CreateThread(0,0,Th,0,0,0);
 | ||
| }
 | ||
| void end()
 | ||
| {
 | ||
|    // MessageBoxA(0,"a","",0);
 | ||
|     if (!start_falg)
 | ||
|         return;
 | ||
|     start_falg = FALSE;
 | ||
|     DetourTransactionBegin();
 | ||
|     DetourUpdateThread(GetCurrentThread());
 | ||
|     DetourDetach(&(PVOID&)Sur_Sub, Fake_Sub);
 | ||
|     DetourTransactionCommit();
 | ||
|  
 | ||
| }
 | ||
|  void start_g()
 | ||
| {
 | ||
|     if (start_g_flag)
 | ||
|         return;
 | ||
|     start_g_flag = TRUE;
 | ||
|     DetourRestoreAfterWith();
 | ||
|     DetourTransactionBegin();
 | ||
|     DetourUpdateThread(GetCurrentThread());
 | ||
|     DetourAttach(&(PVOID&)pGetGlyphOutlineW, fGetGlyphOutlineW);
 | ||
|     DetourTransactionCommit();
 | ||
| }
 | ||
|  void end_g()
 | ||
| {
 | ||
|     if (!start_g_flag)
 | ||
|         return;
 | ||
|     start_g_flag = FALSE;
 | ||
|     DetourTransactionBegin();
 | ||
|     DetourUpdateThread(GetCurrentThread());
 | ||
|     DetourDetach(&(PVOID&)pGetGlyphOutlineW, fGetGlyphOutlineW);
 | ||
|     DetourTransactionCommit();
 | ||
| }
 | ||
| 
 | ||
|  void start_t()
 | ||
|  {
 | ||
|      if (start_t_flag)
 | ||
|          return;
 | ||
|      start_t_flag = TRUE;
 | ||
|      DetourRestoreAfterWith();
 | ||
|      DetourTransactionBegin();
 | ||
|      DetourUpdateThread(GetCurrentThread());
 | ||
|      DetourAttach(&(PVOID&)pTextOutW, fTextOutW);
 | ||
|      DetourTransactionCommit();
 | ||
|  }
 | ||
|  void end_t()
 | ||
|  {
 | ||
|      if (!start_t_flag)
 | ||
|          return;
 | ||
|      start_t_flag = FALSE;
 | ||
|      DetourTransactionBegin();
 | ||
|      DetourUpdateThread(GetCurrentThread());
 | ||
|      DetourDetach(&(PVOID&)pTextOutW, fTextOutW);
 | ||
|      DetourTransactionCommit();
 | ||
|  }
 | ||
| 
 | ||
| 
 | ||
| void StartReplace()
 | ||
| {
 | ||
|     HANDLE terp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, tPid);
 | ||
|     HANDLE hHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|         ::GetProcAddressEx(terp,hMod, "start"), 0, 0, NULL);
 | ||
|     if (!hHookStart)
 | ||
|     {
 | ||
|         MessageBox(0, L"Failed to create remote thread(StartReplace)", L"error", MB_ICONERROR);
 | ||
|         return;
 | ||
|     }
 | ||
|     WaitForSingleObject(hHookStart, 0xFFFFFFFF);
 | ||
|     if (VioMode == 0) {
 | ||
| 
 | ||
|         HANDLE hgHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|             ::GetProcAddressEx(terp, hMod, "end_g"), 0, 0, NULL);
 | ||
|         if (!hgHookStart)
 | ||
|         {
 | ||
|             MessageBox(0, L"Failed to create remote thread(StartReplace)", L"error", MB_ICONERROR);
 | ||
|             return;
 | ||
|         }
 | ||
|         WaitForSingleObject(hgHookStart, 0xFFFFFFFF);
 | ||
|     }
 | ||
|     if (VioMode == 1) {
 | ||
| 
 | ||
|         HANDLE hgHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|             ::GetProcAddressEx(terp, hMod, "end_t"), 0, 0, NULL);
 | ||
|         if (!hgHookStart)
 | ||
|         {
 | ||
|             MessageBox(0, L"Failed to create remote thread(StartReplace)", L"error", MB_ICONERROR);
 | ||
|             return;
 | ||
|         }
 | ||
|         WaitForSingleObject(hgHookStart, 0xFFFFFFFF);
 | ||
|     }
 | ||
|     CloseHandle(terp);
 | ||
| 
 | ||
| }
 | ||
|  void EndReplace()
 | ||
|  {
 | ||
|      HANDLE terp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, tPid);
 | ||
|      HANDLE hHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|          ::GetProcAddressEx(terp, hMod, "end"), 0, 0, NULL);
 | ||
|     if (!hHookStart)
 | ||
|     {
 | ||
|         MessageBox(0, L"Failed to create remote thread(EndReplace)", L"error", MB_ICONERROR);
 | ||
|         return;
 | ||
|     }
 | ||
|     WaitForSingleObject(hHookStart, 0xFFFFFFFF);
 | ||
| 
 | ||
|     if (VioMode == 0) {
 | ||
|         HANDLE hgHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|             ::GetProcAddressEx(terp, hMod, "start_g"), 0, 0, NULL);
 | ||
|         if (!hgHookStart)
 | ||
|         {
 | ||
|             MessageBox(0, L"Failed to create remote thread(EndReplace)", L"error", MB_ICONERROR);
 | ||
|             return;
 | ||
|         }
 | ||
|         WaitForSingleObject(hgHookStart, 0xFFFFFFFF);
 | ||
| 
 | ||
|     }
 | ||
|     if (VioMode == 1) {
 | ||
| 
 | ||
|         HANDLE hgHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|             ::GetProcAddressEx(terp, hMod, "start_t"), 0, 0, NULL);
 | ||
|         if (!hgHookStart)
 | ||
|         {
 | ||
|             MessageBox(0, L"Failed to create remote thread(StartReplace)", L"error", MB_ICONERROR);
 | ||
|             return;
 | ||
|         }
 | ||
|         WaitForSingleObject(hgHookStart, 0xFFFFFFFF);
 | ||
|     }
 | ||
|     CloseHandle(terp);
 | ||
|  }
 | ||
|   void ChangeGToT()
 | ||
|  {
 | ||
|       HANDLE terp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, tPid);
 | ||
|       HANDLE hgHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|           ::GetProcAddressEx(terp, hMod, "end_g"), 0, 0, NULL);
 | ||
|       if (!hgHookStart)
 | ||
|       {
 | ||
|           MessageBox(0, L"Failed to create remote thread(StartReplace)", L"error", MB_ICONERROR);
 | ||
|           return;
 | ||
|       }
 | ||
|       WaitForSingleObject(hgHookStart, 0xFFFFFFFF);
 | ||
| 
 | ||
|       HANDLE htHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|           ::GetProcAddressEx(terp, hMod, "start_t"), 0, 0, NULL);
 | ||
|       if (!htHookStart)
 | ||
|       {
 | ||
|           MessageBox(0, L"Failed to create remote thread(StartReplace)", L"error", MB_ICONERROR);
 | ||
|           return;
 | ||
|       }
 | ||
|       WaitForSingleObject(htHookStart, 0xFFFFFFFF);
 | ||
|       CloseHandle(terp);
 | ||
|  }
 | ||
|   void ChangeTToG()
 | ||
|  {
 | ||
|       HANDLE terp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, tPid);
 | ||
|       HANDLE hgHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|           ::GetProcAddressEx(terp, hMod, "end_t"), 0, 0, NULL);
 | ||
|       if (!hgHookStart)
 | ||
|       {
 | ||
|           MessageBox(0, L"Failed to create remote thread(StartReplace)", L"error", MB_ICONERROR);
 | ||
|           return;
 | ||
|       }
 | ||
|       WaitForSingleObject(hgHookStart, 0xFFFFFFFF);
 | ||
| 
 | ||
|       HANDLE htHookStart = CreateRemoteThread(terp, NULL, 0, (LPTHREAD_START_ROUTINE)
 | ||
|           ::GetProcAddressEx(terp, hMod, "start_g"), 0, 0, NULL);
 | ||
|       if (!htHookStart)
 | ||
|       {
 | ||
|           MessageBox(0, L"Failed to create remote thread(StartReplace)", L"error", MB_ICONERROR);
 | ||
|           return;
 | ||
|       }
 | ||
|       WaitForSingleObject(htHookStart, 0xFFFFFFFF);
 | ||
|       CloseHandle(terp);
 | ||
|  }
 | ||
|  void LoadExerte()
 | ||
| {
 | ||
|     Index = new MicroData(L"Index.ax", sizeof(IndexData));
 | ||
|     Data = new MicroBinary(L"Data.ax");
 | ||
|     Index->Load();
 | ||
|     Data->Load();
 | ||
| }
 | 
