看流星社区

 找回密码
 注册账号
查看: 1975|回复: 0

反调试检测三

[复制链接]

该用户从未签到

发表于 2013-4-4 08:51:48 | 显示全部楼层 |阅读模式
Peinfo.h


代码:
#pragma once
#define  PATH_MAX  20
/*注意在定义结构的时候用到了两种方式,一种是typedef结构定义方式,一种是struct 结构名方式;
之前一直用后者,后来发现有人用TypeDef方式;发现该方式在编译的时候
对于结构中用到的其他自定义结构不需要在他之前定义,而第二种方式则需要在调用之前定义(新手莫见笑!)
*/


//定义导出表模块结构
typedef struct _tagExportDllNode
{
  LPCSTR  pExprotDllName;            //存储导出DLL名称
  struct _tagExportFuncNode  *pChild;    //DLL孩子节点指向DLL下的函数结构

}ExportDllNode;
//定义导出表模块中调用函数结构
typedef struct _tagExportFuncNode
{
  LPCSTR  pExportFuncName;          //存储函数名称
  DWORD  ExportFuncAddr;            //存储函数地址
  DWORD  ExportFuncInFileAddr;        //存储函数地址在文件中的位置,便于以后(使用钩子时)修改地址
  DWORD  ExportFuncIndex;          //存储函数按序号方式导出的索引  
  struct _tagExportFuncNode  *pBrother;    //兄弟节点指向其他函数结构
}ExportFuncNode;




//函数声明

BOOL IsFindSod(LPWSTR lpszFilePath);
bool IsCheckSod(PVOID lpModuleAddr);
LPVOID JudgePEFile(LPWSTR lpFileName);
peinfo.cpp

代码:
// PEInfo.cpp : 定义控制台应用程序的入口点。
//

//#include "stdafx.h"
#include "windows.h"
#include "Dbghelp.h"
#include "PEInfo.h"
#include "Commdlg.h"
#include <process.h>
#include <shlwapi.h>
#include <stdio.h>
#pragma comment(lib,"Dbghelp")

#pragma comment(lib,"shlwapi")
BOOL RvaToOffset(LPVOID lpMoudle,DWORD Rva);

//定义各个结构的头节点指针
ExportDllNode  *pExportTableHead;


/*
HeadLine:  PE结构部分
Discription:判断文件是否为PE格式,如果是返回文件在内存中的地址,否则返回0
input:    文件名
output:    SUCCESS:返回模块地址;FAILE:返回0;
*/
LPVOID JudgePEFile(LPWSTR lpFileName)
{
  //打开文件
  
  HANDLE hFile=CreateFile(lpFileName,FILE_READ_DATA,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
  
  if(INVALID_HANDLE_VALUE ==hFile)
  {
   
    return 0;
  }
  //创建文件映像
  HANDLE hMapFile=::CreateFileMapping((HANDLE)hFile,NULL,PAGE_READONLY,NULL,NULL,NULL);
  if(NULL==hMapFile)
  {
   
    ::CloseHandle((HANDLE)hFile);
    return 0;
  }

  //将文件映射到内存空间并模块地址指向DOS结构
  LPVOID lpMapAddr=::MapViewOfFile(hMapFile, FILE_MAP_READ,NULL,NULL,0);
  IMAGE_DOS_HEADER *lpDosHead;
  lpDosHead=(IMAGE_DOS_HEADER*)lpMapAddr;

  //判断是否MZ标志
  if(lpDosHead->e_magic!='ZM')//IMAGE_DOS_SIGNATURE
  {
    ::CloseHandle((HANDLE)hFile);
    ::CloseHandle(hMapFile);
    ::UnmapViewOfFile(lpMapAddr);
   
    return 0;
  }

  //映射NT头
  IMAGE_NT_HEADERS *lpNTHead;
  lpNTHead=(IMAGE_NT_HEADERS*)((DWORD)lpDosHead+lpDosHead->e_lfanew);

  //是否PE标志
  if(lpNTHead->Signature!='EP')//IMAGE_NT_SIGNATURE
  {  
    ::CloseHandle((HANDLE)hFile);
    ::CloseHandle(hMapFile);
    ::UnmapViewOfFile(lpMapAddr);
   
    return 0;
  }
  return lpMapAddr;

}

/*
HeadLine:  获取输出表结构
Discription:根据模块地址获取输出表结构
input:    模块地址
output:    SUCCESS:返回1;FAILE:返回0;
*/
bool IsCheckSod(PVOID lpModuleAddr)
{
  //定义PE头结构
  PIMAGE_NT_HEADERS pNTHead;
  //取PE头地址
  pNTHead=::ImageNtHeader(lpModuleAddr);
  if(pNTHead!=NULL)
  {
    DWORD pExportDisp;
    //取导入表地址位于数据目录第一个项
    pExportDisp=RvaToOffset(lpModuleAddr,pNTHead->OptionalHeader.DataDirectory[0].VirtualAddress);
    if (pExportDisp==NULL)
    {
      return FALSE;
    }
    IMAGE_EXPORT_DIRECTORY *pIED;
    pIED=(IMAGE_EXPORT_DIRECTORY*)((DWORD)lpModuleAddr+pExportDisp);
    DWORD* pExprotDllNameDisp,*pExprotDllNameAddr;
    pExprotDllNameDisp=(DWORD*)RvaToOffset(lpModuleAddr,pIED->Name);
    pExprotDllNameAddr=(DWORD*)((DWORD)lpModuleAddr+(DWORD)pExprotDllNameDisp);
    DWORD *pFunAddrDisp=(DWORD*)((DWORD)lpModuleAddr+RvaToOffset(lpModuleAddr,pIED->AddressOfFunctions));
    if(pExprotDllNameDisp!=0)
    {
      //定义DLL名称指针--字节类型要按字符取
      //创建新节点将模块信息存入链表结构中
      ExportDllNode* pNewDll=(ExportDllNode*)::LocalAlloc(LPTR,sizeof(ExportDllNode));
      pNewDll->pExprotDllName=(char*)pExprotDllNameAddr;
      pExportTableHead=pNewDll;
      ExportFuncNode **pFuncTemp;
      DWORD nExportFuncNum;
      DWORD nIndexBase;
      nExportFuncNum=pIED->NumberOfFunctions;
      nIndexBase=pIED->Base;

      //取函数名称
      DWORD *pFunAddr;
      WORD *pFuncIndexDisp;
      pFuncIndexDisp=(WORD*)((DWORD)lpModuleAddr+RvaToOffset(lpModuleAddr,pIED->AddressOfNameOrdinals));
      if (nExportFuncNum)
      {
//将函数地址存入结构
        ExportFuncNode *pNewFunc=(ExportFuncNode*)::LocalAlloc(LPTR,sizeof(ExportFuncNode));
        pFunAddr=(DWORD*)((DWORD)lpModuleAddr+RvaToOffset(lpModuleAddr,*pFunAddrDisp));//*pFunAddrDisp;
        pNewFunc->ExportFuncAddr=*pFunAddr;//*(DWORD*)((DWORD)lpModuleAddr+RvaToOffset(lpModuleAddr,*pFunAddr));//*pFuncAddrDisp;//(DWORD)lpModuleAddr+RvaToOffset(lpModuleAddr,pFuncAddrDisp);
        pNewFunc->ExportFuncInFileAddr=(DWORD)pFunAddr;
        //将函数序号存入结构;从1开始
        
        pNewFunc->ExportFuncIndex=(WORD)(*pFuncIndexDisp)+nIndexBase;

        //将函数名称存入(注意无名称方式)
        DWORD *NameAddrDisp;
        NameAddrDisp=(DWORD*)((DWORD)lpModuleAddr+RvaToOffset(lpModuleAddr,pIED->AddressOfNames));
        pNewFunc->pExportFuncName=(LPCSTR)((DWORD)lpModuleAddr+RvaToOffset(lpModuleAddr,*NameAddrDisp));
        if (StrStrIA(pNewFunc->pExportFuncName,"_ODBG_"))
        {
          if (pNewFunc)
          {
            LocalFree(pNewFunc);
          }
          if (pNewDll)
          {
            LocalFree(pNewDll);
          }
          return TRUE;
        }
        else
        {
          if (pNewFunc)
          {
            LocalFree(pNewFunc);
          }
        }

        //printf("FuncName is %s\n",(char*)pIIBN->Name);
      }
   
        
        
      
   
      if (pNewDll)
      {
        LocalFree(pNewDll);
      }
      
      
    }
  }

  return FALSE;
}



BOOL RvaToOffset(LPVOID lpMoudle,DWORD Rva)
{

  //定义变量存储转换后的偏移值和节表数
  DWORD FileOffset;
  WORD nSectionNum;

  //取NT结构头
  IMAGE_NT_HEADERS  *pNTHead;
  pNTHead=ImageNtHeader(lpMoudle);
  nSectionNum=pNTHead->FileHeader.NumberOfSections;

  //取节表结构头
  IMAGE_SECTION_HEADER *pSectionHead;
  pSectionHead=(IMAGE_SECTION_HEADER *)((DWORD)pNTHead+sizeof(IMAGE_NT_HEADERS));
  
  //循环比较Rva值所对应节表的偏移
  for(int i=0; i<nSectionNum; i++)
  {
    if((pSectionHead->VirtualAddress<=Rva) && (Rva<(pSectionHead->SizeOfRawData+pSectionHead->VirtualAddress)))
    {
      FileOffset=Rva-pSectionHead->VirtualAddress+pSectionHead->PointerToRawData;
      return FileOffset;
    }
    pSectionHead=(IMAGE_SECTION_HEADER *)((DWORD)pSectionHead+sizeof(IMAGE_SECTION_HEADER));
  }
  return FALSE;
}

BOOL IsFindSod( LPWSTR lpszFilePath )
{
  BOOL bResult=FALSE;
  LPVOID Res=JudgePEFile(lpszFilePath);

  if(Res==NULL)
  goto Finally;
    if (IsCheckSod(Res))
    {
      bResult=TRUE;
    }
    ::UnmapViewOfFile(Res);
  
Finally:
  return bResult;
}
Test.cpp

代码:
#include <stdio.h>
#include <shlwapi.h>
#include "PEInfo.h"
#pragma comment(lib,"shlwapi")

BOOL IsOdPath(LPWSTR lpszFilePath)
{
  BOOL bResult=FALSE;
  WCHAR wFilePath[MAX_PATH]={0};
  WCHAR wSearchPath[MAX_PATH]={0};
  WCHAR wDllPath[MAX_PATH]={0};
  WIN32_FIND_DATA wfd;
  if (!lpszFilePath||!wcslen(lpszFilePath))
  {
    goto Finally;
  }
  wcscpy(wFilePath,lpszFilePath+4);
  PathRemoveFileSpec(wFilePath);
  wcscpy(wSearchPath,wFilePath);
  
  wcscat(wSearchPath,L"\\*.dll");
  if (FindFirstFile(wSearchPath,&wfd)!=INVALID_HANDLE_VALUE)
  {
    wnsprintfW(wDllPath,MAX_PATH,L"%s\\%s",wFilePath,wfd.cFileName);
    if (IsFindSod(wDllPath))
    {
      bResult=TRUE;
    }
  }
  
  /*wcscat(wFilePath,L"\\ODbgScript.dll");
  if (PathFileExists(wFilePath))
  {
    bResult=TRUE;
  }*/


Finally:
  return  bResult;
}
BOOL isFindOd()
{
  LPENUM_SERVICE_STATUS_PROCESS pPssp=NULL;
  DWORD dwNeed=0;
  DWORD dwRet=0;
  SC_HANDLE hSrv=0;
  int dwServiceType;
  DWORD i=0;
  LPQUERY_SERVICE_CONFIG pQsc=NULL;
  dwServiceType   =SERVICE_DRIVER|SERVICE_WIN32|SERVICE_KERNEL_DRIVER|SERVICE_FILE_SYSTEM_DRIVER;
  BOOL bFind=FALSE;

  SC_HANDLE  hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  if (!hSCM)
  {
    goto Finally;
  }
  EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO,
    dwServiceType, SERVICE_STATE_ALL,
    (PBYTE)pPssp,
    0, &dwNeed,
    &dwRet, NULL, NULL);  
  if (dwNeed == 0)
    goto Finally;
  pPssp = (LPENUM_SERVICE_STATUS_PROCESS)malloc(dwNeed);  
  ZeroMemory(pPssp, dwNeed);  
  if (!EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, dwServiceType,
    SERVICE_STATE_ALL, (PBYTE)pPssp, dwNeed, &dwNeed, &dwRet, NULL, NULL))  
  {  
    free(pPssp);  
    goto Finally;
  }
  for ( i = 0; i < dwRet; i++)  
  {  
    hSrv = OpenServiceW(hSCM, pPssp[i].lpServiceName, SERVICE_QUERY_CONFIG);

    QueryServiceConfig(hSrv, pQsc, 0, &dwNeed);  
    if (dwNeed > 0)  
    {  
      pQsc = (LPQUERY_SERVICE_CONFIG)malloc(dwNeed);  
      ZeroMemory(pQsc, dwNeed);  
      if (QueryServiceConfig(hSrv, pQsc, dwNeed, &dwNeed))  
      {  

        if (IsOdPath(pQsc->lpBinaryPathName))
        {
          bFind=TRUE;
        }


      }  
      free(pQsc);  
    }
    CloseServiceHandle(hSrv);
    if (bFind)
    {
      break;
    }
  }  
Finally:
  if (pPssp)
  {
    free(pPssp);
  }
  if (hSCM)
  {
    CloseServiceHandle(hSCM);
  }
  return bFind;
}
void main()
{
  if (isFindOd())
  {
    printf("发现被调试");

  }
  else
  {
    printf("没有发现");

  }
  getchar();
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-30 10:00

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表