如何用delphi程序获取cheat engine中显示的EAX=00000003,EDX=00000002等寄存器的值

解决方案 »

  1.   

    procedure TForm1.Button2Click(Sender: TObject);
    var
      Context: TContext;
    begin
      Context.ContextFlags := CONTEXT_FULL;
      GetThreadContext(GetCurrentThread, Context);
      memo1.Clear;
      memo1.Lines.Add('EAX:' + IntToHex(Context.Eax, 8));
      memo1.Lines.Add('EBX:' + IntToHex(Context.Ebx, 8));
      memo1.Lines.Add('ECX:' + IntToHex(Context.Ecx, 8));
      memo1.Lines.Add('EDX:' + IntToHex(Context.Edx, 8));
      memo1.Lines.Add('ESI:' + IntToHex(Context.Esi, 8));
      memo1.Lines.Add('EDI:' + IntToHex(Context.Edi, 8));
      memo1.Lines.Add('Ebp:' + IntToHex(Context.Ebp, 8));
      memo1.Lines.Add('Eip:' + IntToHex(Context.Eip, 8));
      memo1.Lines.Add('Esp:' + IntToHex(Context.Esp, 8));
    end;
      

  2.   

    wxieyang正在为升星而努力啊。
    貌似还差两千多。
      

  3.   

    用delphi做这个真不错,另外能稍微给点解释么,我第一次用delphi好多东西不懂比如Context: TContext;
    取寄存器的值,必须定义成Context吗?这个类型有什么特点吗?为什么不用integer这种类型?Context.ContextFlags := CONTEXT_FULL;
    CONTEXT_FULL是一个固定参数吗?这个函数中参数是不是可以替换成其他程序的,如果可以的话,那其它程序的GetCurrentThread值如何获取?最重要的是这个问题,谢谢了
    GetThreadContext(GetCurrentThread, Context);
      

  4.   

    呵呵,闲人来了。TContext = _CONTEXT;            //其实就是结构_CONTEXT
    _CONTEXT = record              //结构如下,其中就有一个你说的ContextFlags: DWORD;
      {$EXTERNALSYM _CONTEXT}  { The flags values within this flag control the contents of
        a CONTEXT record.    If the context record is used as an input parameter, then
        for each portion of the context record controlled by a flag
        whose value is set, it is assumed that that portion of the
        context record contains valid context. If the context record
        is being used to modify a threads context, then only that
        portion of the threads context will be modified.    If the context record is used as an IN OUT parameter to capture
        the context of a thread, then only those portions of the thread's
        context corresponding to set flags will be returned.    The context record is never used as an OUT only parameter. }    ContextFlags: DWORD;  { This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
        set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
        included in CONTEXT_FULL. }    Dr0: DWORD;
        Dr1: DWORD;
        Dr2: DWORD;
        Dr3: DWORD;
        Dr6: DWORD;
        Dr7: DWORD;  { This section is specified/returned if the
        ContextFlags word contians the flag CONTEXT_FLOATING_POINT. }    FloatSave: TFloatingSaveArea;  { This section is specified/returned if the
        ContextFlags word contians the flag CONTEXT_SEGMENTS. }    SegGs: DWORD;
        SegFs: DWORD;
        SegEs: DWORD;
        SegDs: DWORD;  { This section is specified/returned if the
        ContextFlags word contians the flag CONTEXT_INTEGER. }    Edi: DWORD;
        Esi: DWORD;
        Ebx: DWORD;
        Edx: DWORD;
        Ecx: DWORD;
        Eax: DWORD;  { This section is specified/returned if the
        ContextFlags word contians the flag CONTEXT_CONTROL. }    Ebp: DWORD;
        Eip: DWORD;
        SegCs: DWORD;
        EFlags: DWORD;
        Esp: DWORD;
        SegSs: DWORD;
      end;
      

  5.   

    继续CONTEXT_FULL如下:CONTEXT_FULL = (CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_SEGMENTS);
    CONTEXT_CONTROL         = (CONTEXT_i386 or $00000001); { SS:SP, CS:IP, FLAGS, BP }
      {$EXTERNALSYM CONTEXT_CONTROL}
    CONTEXT_INTEGER         = (CONTEXT_i386 or $00000002); { AX, BX, CX, DX, SI, DI }
      {$EXTERNALSYM CONTEXT_INTEGER}
    CONTEXT_SEGMENTS        = (CONTEXT_i386 or $00000004); { DS, ES, FS, GS }
      {$EXTERNALSYM CONTEXT_SEGMENTS}
      

  6.   

    最后是GetThreadContext(GetCurrentThread, Context);
    其中的GetCurrentThread和GetThreadContext都是API。The GetCurrentThread function returns a pseudohandle for the current thread. HANDLE GetCurrentThread(VOID)
     ParametersThis function has no parameters. Return ValuesThe return value is a pseudohandle for the current thread. ResA pseudohandle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudohandles are not inherited by child processes. 
    This handle has the maximum possible access to the thread object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is THREAD_ALL_ACCESS. The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle of itself that can be used by other threads, or inherited by other processes, by specifying the pseudohandle as the source handle in a call to the DuplicateHandle function. 
    The pseudohandle need not be closed when it is no longer needed. Calling the CloseHandle function with this handle has no effect. If the pseudohandle is duplicated by DuplicateHandle, the duplicate handle must be closed. The GetThreadContext function retrieves the context of the specified thread. BOOL GetThreadContext(    HANDLE hThread, // handle of thread with context  
        LPCONTEXT lpContext  // address of context structure 
       );
     ParametershThreadIdentifies an open handle of a thread whose context is to be retrieved. 
    Windows NT: The handle must have THREAD_GET_CONTEXT access to the thread. For more information, see Thread Objects. lpContextPoints to the address of a CONTEXT structure that receives the appropriate context of the specified thread. The value of the ContextFlags member of this structure specifies which portions of a thread's context are retrieved. The CONTEXT structure is highly computer specific. Currently, there are CONTEXT structures defined for Intel, MIPS, Alpha, and PowerPC processors. Refer to the header file WINNT.H for definitions of these structures.  Return ValuesIf the function succeeds, the return value is nonzero.
    If the function fails, the return value is zero. To get extended error information, call GetLastError. ResThe GetThreadContext function is used to retrieve the context of the specified thread. The function allows a selective context to be retrieved based on the value of the ContextFlags member of the CONTEXT structure. The thread handle identified by the hThread parameter is typically being debugged, but the function can also operate when it is not being debugged. 
    You cannot get a valid context for a running thread. Use the SuspendThread function to suspend the thread before calling GetThreadContext.要获取其他的线程句柄的话,用openthread
    OpenThread 
    The OpenThread function opens an existing thread object. HANDLE OpenThread( 
    DWORD dwDesiredAccess, // access right 
    BOOL bInheritHandle, // handle inheritance option 
    DWORD dwThreadId // thread identifier 
    ); 
    Parameters 
    dwDesiredAccess 
    [in] Specifies the desired access to the thread object. For operating systems that support security checking, this access level is checked against any security descriptor for the target thread. This parameter can be STANDARD_RIGHTS_REQUIRED or any combination of the following values. Value Description 
    SYNCHRONIZE Enables the use of the thread handle in any of the wait functions. 
    THREAD_ALL_ACCESS Specifies all possible access flags for the thread object. 
    THREAD_GET_CONTEXT Enables the use of the thread handle in the GetThreadContext function. 
    THREAD_QUERY_INFORMATION Enables the use of the thread handle to read certain information from the thread object, such as the exit code (see GetExitCodeThread). 
    THREAD_SET_CONTEXT Enables the use of the thread handle in the SetThreadContext function. 
    THREAD_SET_INFORMATION Enables the use of the thread handle to set certain information for the thread object. 
    THREAD_SET_THREAD_TOKEN Enables the use of the thread handle in the SetTokenInformation function to set the thread token. 
    THREAD_SUSPEND_RESUME Enables the use of the thread handle in the SuspendThread or ResumeThread function to suspend and resume the thread. 
    THREAD_TERMINATE Enables the use of the thread handle in the TerminateThread function to terminate the thread. 
    bInheritHandle 
    [in] Indicates whether the returned handle is to be inherited by a new process created by the current process. If this parameter is TRUE, the new process will inherit the handle. 
    dwThreadId 
    [in] Specifies the identifier of the thread to open. 
    Return Values 
    If the function succeeds, the return value is an open handle to the specified process. If the function fails, the return value is NULL. To get extended error information, call GetLastError. Res 
    The handle returned by OpenThread can be used in any function that requires a handle to a thread, such as the wait functions, provided you requested the appropriate access rights. The handle is granted access to the thread object only to the extent it was specified in the dwDesiredAccess parameter. When you are finished with the handle, be sure to close it by using the CloseHandle function. Requirements 
    Windows NT/2000 or later: Requires Windows 2000 or later. 
    Windows 95/98/Me: Requires Windows Me. 
    Header: Declared in Winbase.h; include Windows.h. 
    Library: Use Kernel32.lib. 不过我看你应该是要别的程序的句柄就可以了,不是要线程句柄,那么用
    FindProcessID('calc.exe')
    没了,就这么多了。最后是关键。其他的,算长点知识。 
      

  7.   

    我需要的是GetThreadContext(GetCurrentThread, Context);
    这里面的GetCurrentThread的值换成其他程序对应的这个值比如其他程序的窗口名称是"Cheat Engine Tutorial v3",那如何取道这个窗口的GetCurrentThread对应的值
      

  8.   

    呵呵,你的问题够原始的哦。
    var
      Context: TContext;
    变量的名称不一定非是Context,但类型一定要是TContext
    比如
    var
      a: TContext;GetThreadContext(GetCurrentThread, a);
    这也可以至于为什么一定要是TContext类型,那是因为GetThreadContext函数就接受这样类型的参数,你给别的类型编译不过去,呵呵。
    下面是TContext的定义,你自己看看吧。(这个定义在Windows单元可以找到)  _CONTEXT = record
      {$EXTERNALSYM _CONTEXT}  { The flags values within this flag control the contents of
        a CONTEXT record.    If the context record is used as an input parameter, then
        for each portion of the context record controlled by a flag
        whose value is set, it is assumed that that portion of the
        context record contains valid context. If the context record
        is being used to modify a threads context, then only that
        portion of the threads context will be modified.    If the context record is used as an IN OUT parameter to capture
        the context of a thread, then only those portions of the thread's
        context corresponding to set flags will be returned.    The context record is never used as an OUT only parameter. }    ContextFlags: DWORD;  { This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
        set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
        included in CONTEXT_FULL. }    Dr0: DWORD;
        Dr1: DWORD;
        Dr2: DWORD;
        Dr3: DWORD;
        Dr6: DWORD;
        Dr7: DWORD;  { This section is specified/returned if the
        ContextFlags word contians the flag CONTEXT_FLOATING_POINT. }    FloatSave: TFloatingSaveArea;  { This section is specified/returned if the
        ContextFlags word contians the flag CONTEXT_SEGMENTS. }    SegGs: DWORD;
        SegFs: DWORD;
        SegEs: DWORD;
        SegDs: DWORD;  { This section is specified/returned if the
        ContextFlags word contians the flag CONTEXT_INTEGER. }    Edi: DWORD;
        Esi: DWORD;
        Ebx: DWORD;
        Edx: DWORD;
        Ecx: DWORD;
        Eax: DWORD;  { This section is specified/returned if the
        ContextFlags word contians the flag CONTEXT_CONTROL. }    Ebp: DWORD;
        Eip: DWORD;
        SegCs: DWORD;
        EFlags: DWORD;
        Esp: DWORD;
        SegSs: DWORD;
      end;
      TContext = _CONTEXT;下面是一个获得记事本主线程的寄存器信息的代码
    var
      Context: TContext;
      si: TStartupInfo;
      pi: TProcessInformation;
    begin
      //Context.ContextFlags := CONTEXT_FULL;
      //GetThreadContext(GetCurrentThread, Context);  ZeroMemory(@si, SizeOf(TStartupInfo));
      si.cb := SizeOf(TStartupInfo);
      if CreateProcess(nil, 'notepad.exe', nil, nil, False, 0, nil, nil, si, pi) then
      begin
        Sleep(1000);
        Context.ContextFlags := CONTEXT_FULL;
        SuspendThread(pi.hThread);
        GetThreadContext(pi.hThread, Context);
        ResumeThread(pi.hThread);
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
      end;  memo1.Clear;
      memo1.Lines.Add('EAX:' + IntToHex(Context.Eax, 8));
      memo1.Lines.Add('EBX:' + IntToHex(Context.Ebx, 8));
      memo1.Lines.Add('ECX:' + IntToHex(Context.Ecx, 8));
      memo1.Lines.Add('EDX:' + IntToHex(Context.Edx, 8));
      memo1.Lines.Add('ESI:' + IntToHex(Context.Esi, 8));
      memo1.Lines.Add('EDI:' + IntToHex(Context.Edi, 8));
      memo1.Lines.Add('Ebp:' + IntToHex(Context.Ebp, 8));
      memo1.Lines.Add('Eip:' + IntToHex(Context.Eip, 8));
      memo1.Lines.Add('Esp:' + IntToHex(Context.Esp, 8));
    end;
      

  9.   

    我不是回答了吗?
    最后那个红色的字啊。不过我看你应该是要别的程序的句柄就可以了,不是要线程句柄,那么用
    FindProcessID('calc.exe')
    'calc.exe'就是你那个程序啊。
      

  10.   

    非常感谢上面的回答,总的来说我还是比较能理解wxieyang的回答内容,谢了