ceoguang 发表于 2010-8-16 16:06:47

关于防多开类游戏,高分悬赏C TO A 的代码转换

HMODULE hNtDll = NULL;
ZWQUERYSYSTEMINFORMATION pfnZwQuerySystemInformation = NULL;
NTQUERYOBJECT pfnNtQueryObject = NULL;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = NULL;
POBJECT_ALL_INFORMATION pAllInfo =NULL;
POBJECT_NAME_INFORMATION pNameInfo = NULL;


ULONG nNumberHandle =0;
NTSTATUS ntStatus = 0;
ULONG ulSize,ulCount;
char cBuffer,cInfoBuffer;

hNtDll = GetModuleHandle(TEXT("ntdll.dll"));
pfnZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,"ZwQuerySystemInformation");
pfnNtQueryObject = (NTQUERYOBJECT)GetProcAddress(hNtDll,"NtQueryObject");

ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation,cBuffer,0x80000,&ulSize);

   if(NT_SUCCESS(ntStatus))
   {
   DWORD n = ulSize/sizeof(SYSTEM_HANDLE_INFORMATION);
   nNumberHandle = *(PULONG)cBuffer;
   pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)(cBuffer +4);
   ulCount = 0;

   for(ULONG i=0;i!=nNumberHandle;++i)
{

         if(pSysHandleInfo.ProcessId != ProcessId) continue;
         ntStatus = pfnNtQueryObject((HANDLE)pSysHandleInfo.Handle,ObjectAllInformation,cInfoBuffer,0x10000,&ulSize);
         ntStatus = pfnNtQueryObject((HANDLE)pSysHandleInfo.Handle,ObjectNameInformation,cInfoBuffer,0x10000,&ulSize);
         if(NT_SUCCESS(ntStatus))
   {
         pAllInfo = (POBJECT_ALL_INFORMATION)cInfoBuffer;
         pNameInfo = (POBJECT_NAME_INFORMATION)cInfoBuffer;
               if(_tcsstr(pNameInfo->NameBuffer,TEXT("QQGame_Mutex03/01/2003")) !=NULL)
   {
               return (HWND)pSysHandleInfo.Handle;
   }
   }
}
   }
return NULL;
hMuTex = GetProcessKernelObject(GetCurrentProcessId());
CloseHandle(hMuTex);以上代码转自互联网,据说能突破90%的游戏限制.
参考:http://bbs.vrbrothers.com/forum.php?mod=viewthread&tid=124224
现高分悬赏,高手会的帮忙转换下.谢谢!

ceoguang 发表于 2010-8-16 16:11:07


见图说明

pusofalse 发表于 2010-8-16 16:53:54

用NtQuerySystemInformation的16号功能枚举系统中的所有句柄,DuplicateHandle将句柄复制到自身进程空间中,再用NtQueryObject的1号功能获取句柄所指的对象名称。

ceoguang 发表于 2010-8-16 17:39:37

本帖最后由 ceoguang 于 2010-9-3 03:28 编辑

感谢P版的关注,问题依然没解决.
在官方找到个例子,可以取系统所有内核对象的句柄,不过有些BUG,贴上代码,以供研究

#include <WinAPI.au3>   ; _GetPrivilege_SEDEBUG() - by wraithdu - uses this include.
#include <array.au3>    ; Needed to display array in example.

#RequireAdmin

; SystemHandleInformation = 16

;~ typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
;~   USHORT UniqueProcessId;
;~   USHORT CreatorBackTraceIndex;
;~   UCHAR ObjectTypeIndex;
;~   UCHAR HandleAttributes;
;~   USHORT HandleValue;
;~   PVOID Object;
;~   ULONG GrantedAccess;
;~ } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;

;~ typedef struct _SYSTEM_HANDLE_INFORMATION {
;~   ULONG NumberOfHandles;
;~   SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[ 1 ];
;~ } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

;~ BOOL DuplicateHandle(

;~   HANDLE hSourceProcessHandle, // handle to process with handle to duplicate       OpenProcess             PROCESS_DUP_HANDLE
;~   HANDLE hSourceHandle,    // handle to duplicate                                 
;~   HANDLE hTargetProcessHandle, // handle to process to duplicate to                GetCurrentProcess       PROCESS_DUP_HANDLE
;~   LPHANDLE lpTargetHandle, // pointer to duplicate handle                        
;~   DWORD dwDesiredAccess,   // access for duplicate handle                        0
;~   BOOL bInheritHandle, // handle inheritance flag                                  0
;~   DWORD dwOptions// optional actions                                             const $DUPLICATE_SAME_ACCESS = 0x2
;~    );
;~ NtQueryObject(
;~ IN HANDLE ObjectHandle,
;~ IN OBJECT_INFORMATION_CLASS ObjectInformationClass,         ObjectTypeInformation = 2 , ObjectNameInformation=1
;~ OUT PVOID ObjectInformation,
;~ IN ULONG Length,
;~ OUT PULONG ResultLength );
;~ $tag_OBJECT_TYPE=
;~"ushort Length;" & _
;~"ushort MaximumLength;" & _
;~"ptr    ProcessName;" & _
;~"byte"
$tag_SYSTEM_HANDLE_INFO= _
    "USHORT UniqueProcessId;" & _;
    "USHORT CreatorBackTraceIndex;" & _;
    "ubyte ObjectTypeIndex;" & _;
    "ubyte HandleAttributes;" & _;
    "USHORT HandleValue;" & _;
    "ptr Object;" & _;
    "ptr GrantedAccess";
$tag_OBJECT_TYPE= _             ; TYPE / NAME Doesnt matter... I just want the unicodestring.
    "ushort Length;" & _
    "ushort MaximumLength;" & _
    "ptr    Name;" & _
    "byte"


; ############# Needed Constants ###################
Global Const $PROCESS_VM_READ=0x10
Global Const $PROCESS_QUERY_INFORMATION = 0x400



; ############ Example code #######################
_GetPrivilege_SEDEBUG()
$temp=_Handles()
_ArrayDisplay($temp)
; ###############################################




; ############ Here be func! ####################
Func _Handles()
    Local $times
    Local $Mem=DllStructCreate("byte[" & 40000000 & "]")
    Local $ret=dllcall("ntdll.dll", "int", "ZwQuerySystemInformation","int", 16, "ptr", DllStructGetPtr($MEM), "int", DllStructGetSize($MEM), "int*",0)
    Local $SysHnd=DllStructCreate($tag_SYSTEM_HANDLE_INFO, $ret+4)
    Local $dw=DllStructCreate("dword",$ret)
    Local $Count=DllStructGetData($dw,1)
    Local $SysHnd_ptr=$ret+4
    Local $SysHnd_Size=DllStructGetSize($SysHnd)
    Local $buffer, $i=0, $lastthread, $m=0, $NextEntryDelta, $k, $temp, $space, $l
    Local $avArray
    Const $PROCESS_DUP_HANDLE = 0x40
    const $DUPLICATE_SAME_ACCESS = 0x2
    Local $types
    Local $ObjType=DllStructCreate($tag_OBJECT_TYPE)
    While 1
      if $m=$count Then ExitLoop
      $avArray[$i]=DllStructGetData($SysHnd, "UniqueProcessId")
      $avArray[$i]=DllStructGetData($SysHnd, "CreatorBackTraceIndex")
      if not $avArray[$i] Then $avArray[$i]=""
      $avArray[$i]=DllStructGetData($SysHnd, "ObjectTypeIndex")
      $avArray[$i]=DllStructGetData($SysHnd, "HandleAttributes")
      if not $avArray[$i] Then $avArray[$i]=""
      $avArray[$i]=ptr(DllStructGetData($SysHnd, "HandleValue"))
      $avArray[$i]=DllStructGetData($SysHnd, "Object")
      $avArray[$i]=DllStructGetData($SysHnd, "GrantedAccess")
      $hProcSource=_WinAPI_OpenProcess(0x1f0fff, 0, $avarray[$i])
      $hProcDest=_WinAPI_OpenProcess(0x1f0fff, 0, @AutoItPID)
      $ret=dllcall("kernel32.dll","int","DuplicateHandle","hwnd", $hProcSource, "hwnd", $avarray[$i], "hwnd", $hProcDest, _
                                                      "hwnd*", 0, "int",0, "int", 0, "int", $DUPLICATE_SAME_ACCESS)
      $avArray[$i]=$ret
      if not $types[$avArray[$i]] Then
            dllcall("ntdll.dll", "int", "NtQueryObject", "hwnd", $ret, "int", 2, "ptr", dllstructgetptr($ObjType, 1), _
                                                            "int" ,DllStructGetSize($ObjType), "int*", 0)
            $buffer=DllStructCreate("wchar", DllStructGetData($ObjType, "Name"))
            $avArray[$i]=DllStructGetData($buffer, 1)
            $types[$avArray[$i]]=$avArray[$i]
      Else
            $avArray[$i]=$types[$avArray[$i]]
      EndIf
            
            ; Try to filter out NAMED PIPES to not deadlock. Writing a driver to get names would be best. I'm researching...
            if $avArray[$i]=28 Then
                if $avArray[$i]=0x00120189 Then
                  $avArray[$i]="    NAMED PIPES ??? - DANGER OF DEADLOCK - SKIPPED ..."
                  $m+=1
                  $i+=1
                  $SysHnd=DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr+$SysHnd_Size*$m)
                  Continueloop
                EndIf
                if $avArray[$i]=0x00100000 Then
                  $avArray[$i]="    NAMED PIPES ??? - DANGER OF DEADLOCK - SKIPPED ..."
                  $m+=1
                  $i+=1
                  $SysHnd=DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr+$SysHnd_Size*$m)
                  Continueloop
                EndIf
                if$avArray[$i]=0x0012019F Then
                  if $avArray[$i]<2 Then
                        $avArray[$i]="    NAMED PIPES ??? - DANGER OF DEADLOCK - SKIPPED ..."
                        $m+=1
                        $i+=1
                        $SysHnd=DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr+$SysHnd_Size*$m)
                        Continueloop
                  EndIf
                EndIf
            EndIf
      
;~      if $avArray[$i]<>1452 Then   ; single out one PID
;~          $m+=1
;~          ;$i+=1
;~          $SysHnd=DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr+$SysHnd_Size*$m)
;~          Continueloop
;~      EndIf

      ; Still checking which accesrights deadlock - Consolewrite...
      ConsoleWrite($avArray[$i] & " " & $avArray[$i] & " " & $avArray[$i] & $avArray[$i] & " " & @LF)
      
      Switch $avArray[$i]
            Case 5
                $ret1=dllcall("kernel32.dll", "int", "GetProcessId", "hwnd", $ret)
                $avArray[$i]=$ret1
            Case Else
                if not $avArray[$i] Then
                  $ObjType=DllStructCreate($tag_OBJECT_TYPE)
                  dllcall("ntdll.dll", "int", "NtQueryObject", "hwnd", $ret, "int", 1, "ptr", dllstructgetptr($ObjType, 1), _
                                                                                          "int" ,DllStructGetSize($ObjType), "int*", 0)
                  $buffer=DllStructCreate("wchar", DllStructGetData($ObjType, "Name"))
                  $avArray[$i]=DllStructGetData($buffer, 1)
                  if not $avArray[$i] Then $avArray[$i]=""
                EndIf
      EndSwitch
      _WinAPI_CloseHandle($hProcSource)
      _WinAPI_CloseHandle($hProcDest)
      $i+=1
      $m+=1
      $SysHnd=DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr+$SysHnd_Size*$m)
      ContinueLoop   
    WEnd
    Redim $avArray[$i]
    Return $avArray
EndFunc


; #######################
; ####################### Thanks to wraithdu!
Func _GetPrivilege_SEDEBUG()
    Local $tagLUIDANDATTRIB = "int64 Luid;dword Attributes"
    Local $count = 1
    Local $tagTOKENPRIVILEGES = "dword PrivilegeCount;byte LUIDandATTRIB[" & $count * 12 & "]" ; count of LUID structs * sizeof LUID struct
    Local $TOKEN_ADJUST_PRIVILEGES = 0x20
    Local $call = DllCall("advapi32.dll", "int", "OpenProcessToken", "ptr", _WinAPI_GetCurrentProcess(), "dword", $TOKEN_ADJUST_PRIVILEGES, "ptr*", "")
    Local $hToken = $call
    $call = DllCall("advapi32.dll", "int", "LookupPrivilegeValue", "str", Chr(0), "str", "SeDebugPrivilege", "int64*", "")
    ;msgbox(0,"",$call & " " & _WinAPI_GetLastErrorMessage())
    Local $iLuid = $call
    Local $TP = DllStructCreate($tagTOKENPRIVILEGES)
    Local $LUID = DllStructCreate($tagLUIDANDATTRIB, DllStructGetPtr($TP, "LUIDandATTRIB"))
    DllStructSetData($TP, "PrivilegeCount", $count)
    DllStructSetData($LUID, "Luid", $iLuid)
    DllStructSetData($LUID, "Attributes", $SE_PRIVILEGE_ENABLED)
    $call = DllCall("advapi32.dll", "int", "AdjustTokenPrivileges", "ptr", $hToken, "int", 0, "ptr", DllStructGetPtr($TP), "dword", 0, "ptr", Chr(0), "ptr", Chr(0))
    Return ($call <> 0) ; $call <> 0 is success
EndFunc   ;==>_GetPrivilege_SEDEBUG

rolaka 发表于 2010-8-16 22:37:43

C++就无能为力了... 而且用"c++ test.cpp"编译不能...缺.h了把... 而且看起来代码也不全

刚开始折腾c 帮不上忙了- -

ceoguang 发表于 2010-8-16 23:49:20

代码是全的,参考某高手找到的资料
http://topic.csdn.net/u/20100209/22/43678cfa-0716-4936-96eb-2300a22ed533.html

UUpig 发表于 2010-8-17 09:54:40

我太菜鸟了,都看不懂,需要继续努力

sim_best 发表于 2010-8-17 23:57:40

看不懂啊,能说详细吗?

G,man。 发表于 2010-8-18 14:24:01

好诱惑的财富啊,可惜没本事拿。

liufenglg 发表于 2010-8-23 11:37:43

真是太多诱惑,加油啊

yiruirui 发表于 2010-8-23 12:43:24

看得我都流口水了,可惜啊可惜!

zzz867 发表于 2010-8-23 14:53:26

钱,是没那么好拿的

独孤伊狼 发表于 2010-8-23 23:21:39

确实比较难转换!

独孤伊狼 发表于 2010-8-23 23:22:22

其实防多开没必要那么麻烦吧!

独孤伊狼 发表于 2010-8-23 23:22:42

循环检测进程,出现2个就Kill了!
页: [1] 2
查看完整版本: 关于防多开类游戏,高分悬赏C TO A 的代码转换