zoukankan      html  css  js  c++  java
  • 反调试功能<CheckRemoteDebuggerPresent>

    CheckRemoteDebuggerPresent这个API可以检测是否有调试器的存在,而且这个和PEB里面的BeingDebugged无关了。看一下CheckRemoteDebuggerPresent的声明:

     __in          HANDLE hProcess,
      __in_out      PBOOL pbDebuggerPresent
    );


    第一个参数是进程句柄,第二参数用于存放结果。返回值表示函数是否执行成功,

    ; 堆栈示意图
    ;push		pBool		; ebp + c
    ;push		hProcess	; ebp + 8
    ;push		retaddr		; ebp + 4
    ;push		ebp		<-------------------------------------------
                                                                   |
    7C85AA22 >  8BFF            MOV EDI,EDI						;  |
    7C85AA24    55              PUSH EBP							;  |
    7C85AA25    8BEC            MOV EBP,ESP						;<-|
    7C85AA27    837D 08 00      CMP DWORD PTR SS:[EBP+8],0					; hProcess == 0 ?
    7C85AA2B    56              PUSH ESI							;
    7C85AA2C    74 35           JE SHORT 7C85AA63						; jmp exit
    7C85AA2E    8B75 0C         MOV ESI,DWORD PTR SS:[EBP+C]					; esi = pBool
    7C85AA31    85F6            TEST ESI,ESI						; esi == 0?
    7C85AA33    74 2E           JE SHORT 7C85AA63						; jmp exit
    7C85AA35    6A 00           PUSH 0							; push 0
    7C85AA37    6A 04           PUSH 4							; push 4
    7C85AA39    8D45 08         LEA EAX,DWORD PTR SS:[EBP+8]	; 
    7C85AA3C    50              PUSH EAX							; push offset hProcess
    7C85AA3D    6A 07           PUSH 7							; push ProcessDebugPort
    7C85AA3F    FF75 08         PUSH DWORD PTR SS:[EBP+8]					; push hProcess
    7C85AA42    FF15 AC10807C   CALL DWORD PTR DS:[<&ntdll.NtQueryInform>			; ntdll.ZwQueryInformationProcess
    7C85AA48    85C0            TEST EAX,EAX						; eax == 0 ?
    7C85AA4A    7D 08           JGE SHORT 7C85AA54						; eax >= 0 -----------
    7C85AA4C    50              PUSH EAX							; push eax           |
    7C85AA4D    E8 ABE9FAFF     CALL 7C8093FD						; call 7C8093FD      |
    7C85AA52    EB 16           JMP SHORT 7C85AA6A						; jmp                |
    7C85AA54    33C0            XOR EAX,EAX						; eax = 0 <-----------
    7C85AA56    3945 08         CMP DWORD PTR SS:[EBP+8],EAX	; hProcess == 0 ?
    7C85AA59    0F95C0          SETNE AL							; hProcess != 0 --> al = 1 (else al = 0)
    7C85AA5C    8906            MOV DWORD PTR DS:[ESI],EAX					; *pBool = eax
    7C85AA5E    33C0            XOR EAX,EAX						; eax = 0
    7C85AA60    40              INC EAX							; eax = 1
    7C85AA61    EB 09           JMP SHORT 7C85AA6C						; jmp ----------------
    7C85AA63    6A 57           PUSH 57							; push 57            |
    7C85AA65    E8 D8E8FAFF     CALL 7C809342						; call 7C809342      |
    7C85AA6A    33C0            XOR EAX,EAX						; eax = 0            |
    7C85AA6C    5E              POP ESI							; <-------------------
    7C85AA6D    5D              POP EBP							; 
    7C85AA6E    C2 0800         RETN 8							; return 
    
    --------------------------------------------------------------------------------
    
    

    CheckRemoteDebuggerPresent实际上调用了ntdll里面的ZwQueryInformationProcess来检测。这是一个Native API,声明如下:

    NTSTATUS NtQueryInformationProcess (
    	__in HANDLE ProcessHandle,
    	__in PROCESSINFOCLASS ProcessInformationClass,
    	__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
    	__in ULONG ProcessInformationLength,
    	__out_opt PULONG ReturnLength
    	);
    
    

    这里第二个参数是7,实际上被定义为ProcessDebugPort

    测试代码如下:

    HMODULE hKernel32Dll = ::LoadLibrary(TEXT("kernel32.dll"));
    
    	if (NULL != hKernel32Dll)
    	{
    		fnCheckRemoteDebuggerPresent fn = 
    			(fnCheckRemoteDebuggerPresent)::GetProcAddress(hKernel32Dll, "CheckRemoteDebuggerPresent");
    		if (!fn)
    		{
    			::FreeLibrary(hKernel32Dll);
    			return DGBTOOL_NO;
    		}
    
    		BOOL bDebuggerPresent = FALSE;
    		if(fn(GetCurrentProcess(), &bDebuggerPresent)
    			&&bDebuggerPresent)
    		{
    			::FreeLibrary(hKernel32Dll);
    			return DBGTOOL_CUSTOM;
    		}
    		else
    		{
    			::FreeLibrary(hKernel32Dll);
    			return DGBTOOL_NO;
    		}
    	}
    
    	return DGBTOOL_NO;


    过掉方法:Hook住CheckRemoteDebuggerPresent,调用了ZwQueryInformationProcess之前的je改成jmp来跳过Zw这个函数~~OD还会在ZwQueryInformationProcess这个函数的调用地址强行改了,去调用作者的一个函数,该函数中根据是否查询的是7来决定时候调用ZwQueryInformationProcess:

  • 相关阅读:
    自动登录跳板机->开发机
    关于写代码的一下规范
    vscode 配置 GOPATH
    thinkphp6.0 nginx 配置
    vue-cli 3.x 构建项目,webpack没有了?
    Laravel6.0 使用 Jwt-auth 实现多用户接口认证
    怎么在 localhost 下访问多个 Laravel 项目,通过一个IP访问多个项目(不仅仅是改变端口哦)
    laravel 5.8 实现消息推送
    vs code 设置 保存自动格式化vue代码
    项目开发规范(编码规范、命名规范、安全规范、前端优化、源码提交规范、代码维护规范、产品发布规范)
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693453.html
Copyright © 2011-2022 走看看