1

我一直在学习如何在 C++ 甚至 C 中使用 NOP 函数,但是网上关于它的教程很少。在过去的几个小时里,我一直在谷歌上搜索,但我被困住了。这是我的代码。

#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
using namespace std;

//#define NOP 0x90
byte NOP[] = {0x90};

void enableDebugPrivileges() {
    HANDLE hcurrent=GetCurrentProcess();
    HANDLE hToken;
    BOOL bret=OpenProcessToken(hcurrent,40,&hToken);
    LUID luid;
    bret=LookupPrivilegeValue(NULL,"SeDebugPrivilege",&luid);
    TOKEN_PRIVILEGES NewState,PreviousState;
    DWORD ReturnLength;
    NewState.PrivilegeCount =1;
    NewState.Privileges[0].Luid =luid;
    NewState.Privileges[0].Attributes=2;
    AdjustTokenPrivileges(hToken,FALSE,&NewState,28,&PreviousState,&ReturnLength);
}
DWORD GetProcId(char* ProcName)
{
    PROCESSENTRY32   pe32;
    HANDLE         hSnapshot = NULL;

    pe32.dwSize = sizeof( PROCESSENTRY32 );
    hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

    if( Process32First( hSnapshot, &pe32 ) )
    {
        do{
            if( strcmp( pe32.szExeFile, ProcName ) == 0 )
                break;
        }while( Process32Next( hSnapshot, &pe32 ) );
    }

    if( hSnapshot != INVALID_HANDLE_VALUE )
        CloseHandle( hSnapshot );

    return pe32.th32ProcessID;
}
void WriteMem(DWORD Address, void* Value, size_t Size) {
    DWORD Protect = NULL;
    VirtualProtect((LPVOID)Address, 3, PAGE_READWRITE, &Protect);
    memcpy((void*)Address, Value, 3);
    VirtualProtect((LPVOID)Address, 3, Protect, &Protect);
}
void nop_(PVOID address, int bytes){ 
    DWORD d, ds; 
    VirtualProtect(address, bytes, PAGE_EXECUTE_READWRITE, &d); 
    memset(address, 144, bytes);
    VirtualProtect(address,bytes,d,&ds); 
}  

void MemCopy(HANDLE pHandle, void* Dest, const void* Src, int Len)
{
 DWORD OldProtect;
 DWORD OldProtect2; 
 VirtualProtect(Dest, Len, PAGE_EXECUTE_READWRITE, &OldProtect);
 memcpy(Dest, Src, Len);
 VirtualProtect(Dest, Len, OldProtect, &OldProtect2);
 FlushInstructionCache(pHandle, Dest, Len);
}

int main()
{
   enableDebugPrivileges();

   DWORD pid;
   HANDLE phandle;

   // Obtain the process ID
   pid = GetProcId("gr.exe");
    if(GetLastError())
   {
      cout << "Error_PID_: " << GetLastError() << endl;
      system("pause");
      return -1;
   }

   // Obtain the process handle
   phandle = OpenProcess(PROCESS_ALL_ACCESS,0,pid);
   if(GetLastError())
   {
      cout << "Error_HANDLE_: " << GetLastError() << endl;
      system("pause");
      return -1;
   }

   // Debug info, 0 = bad
   cout <<"pid   : " << pid << endl;
   cout <<"HANDLE: " << phandle << endl << endl;
   system("pause");


   // Change value to
   short iValue   =   -1;
   int choice   =   0;

   BYTE * bGodMode  = (BYTE *) (0x409A7E); // Lives Address


   bool hack = true;
   while(hack)
   {
      system("cls");
      cout << "What hack?\n0. Exit\n1. Lives\n\n!> ";
      cin >> choice;
      switch(choice)
      {
      case 0:
         {
            hack=false;
            break;
         }
      case 1:
         // Modify Time
         cout << "God Mode On\n!> ";
//  cin >> iValue;
//  nop_((PVOID)(0x409A7E), 3);
//   MemCopy(phandle, (PVOID)0x409A7E, &NOP, 1);
   WriteMem((DWORD)(0x00409A7E), (void*)NOP, sizeof NOP);
         if(GetLastError())
         {
            cout << "Error: " << GetLastError() << endl;
            system("pause");
         }
         break;
      default:
         cout << "ERROR!\n";
         break;
      }
      Sleep(100);
   }

   system("pause");
   return 0;
}

这是假设 NOP 的 3 个字节长的 DEC 函数可以防止我失去生命。但是每次我尝试它时,它都会使黑客崩溃并说我有访问冲突。我试图查找原因,其中大多数涉及我正在写入的位置的大小以及我正在复制的内容。否则,我完全不知道。你能帮忙的话,我会很高兴。游戏是 GunRoar,基地址“0x409A7E”是 DEC 函数所在的位置。

4

4 回答 4

1

几个要点:

“VirtualProtect”仅适用于您当前的进程。使用“VirtualProtectEx”更改目标进程的权限。我建议你设置权限'PAGE_EXECUTE_READWRITE'——可写,但仍然可执行。

如前所述,您需要使用“WriteProcessMemory”来编写这些 NOP;memset 是不够的。

要正确执行您在此处讨论的那种 hack,应该在处理其代码之前真正暂停目标进程中的线程,然后在完成后恢复它们。但在这种特殊情况下,这种关心可能无关紧要。

于 2010-05-16T06:46:59.700 回答
1

我对 Windows 调试不太熟悉(如果这是你想在这里利用的),但我不认为你在做你认为你在做的事情:)

每个进程都有自己的虚拟内存(这就是它是virtual的原因)。您正在尝试写入0x00409A7E当前进程的虚拟地址空间,而不是您尝试破解的游戏进程。获取另一个进程的句柄并不会神奇地将其地址映射到您的地址——您必须通过一些额外的 Win API 调用来完成。

编辑:

我认为您需要作为调试器附加到受害者进程,例如DebugActiveProcess. 否则游戏的文本段(即说明所在的位置)不能由您的进程写入。

于 2010-05-16T03:55:25.490 回答
0

您确定您尝试写入的页面实际上具有写入权限吗?

于 2010-05-16T05:04:21.780 回答
0

如果我错了,请纠正我,但你只是在玩 ABA Games 的 GunRoar 吗?如果是这样,代码显然是开源的,实际上是在 zip 文件中提供的。快速浏览一下,您可能只需要使用 InGameState 的 shipDestroyed() 方法中的“左”成员(参见 gamemanager.d)。进行您想要“godmode”的必要修复,构建,然后向他们发送邮件以集成您的更改。:)

于 2010-05-16T05:14:00.783 回答