- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
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();
} |
|