my_pro.h
/************************************************
MY_PRO.H 文件注释
文件名:MY_PRO.H
作者:czl
创建时间:2021/3/31 21:22
*************************************************/
#ifndef FINDID_H_INCLUDED
#define FINDID_H_INCLUDED
/**
在window7 32位 gcc 4.7.1 编译运行通过
**/
#include <stdio.h>
#include "windows.h"
#include "tlhelp32.h"
#include <tchar.h>
#include <shlobj.h>
/**
函数名称: 找到进程id
功能描述:通过文件名找到进程id,找不到则返回0
参数: char * filename
返回值: int
**/
int findProcessID(WCHAR * filename)
{
HANDLE snap = NULL;
snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 first;
first.dwSize=sizeof(PROCESSENTRY32);
BOOL flag=FALSE;
BOOL findFlag = FALSE;
flag = Process32First(snap,&first);
for(; flag; flag =Process32Next(snap,&first))
{
if(!wcscmp(first.szExeFile,filename))
{
findFlag = TRUE;
break;
}
}
if(findFlag==TRUE)
{
return (int)first.th32ProcessID;
}
return 0;
}
/**
函数名称: 找到进程id
功能描述:通过窗口名打开获取进程id
参数: char * filename
返回值: int 失败则返回0
**/
int findProcessIDByWindowName(WCHAR * filename)
{
HWND hWnd;
DWORD pid;
hWnd = FindWindow(NULL,filename);
if(!hWnd)
{
return 0;
}
GetWindowThreadProcessId(hWnd, &pid);
return pid;
}
///**
// 函数名称: 运行CMD
// 功能描述:通过cmd字符串运行CMD
// 参数: char * CMD
// 返回值: BOOL
//**/
//BOOL runCMD(char * CMD)
//{
// STARTUPINFO si = {0,};
// PROCESS_INFORMATION pi = {0,};
// si.cb = sizeof(STARTUPINFO);
// si.dwFlags = STARTF_USESHOWWINDOW;
// si.wShowWindow = SW_SHOW;//取值为SW_SHOW则表示正常执行,若为SW_HIDE则表示后台运行
// if(!CreateProcess(NULL,CMD,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi)){
// return FALSE;
// }
// return TRUE;
//}
/**
名称:获得模块句柄
功能:通过进程号与模块名获取模块句柄
参数:DWORD pid,char * moduleName
返回值:HANDLE 成功返回句柄,失败返回0
**/
HANDLE getModuleHandlebyName(DWORD pid,WCHAR * moduleName)
{
HANDLE dllMessage;
dllMessage = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pid);
BOOL findFlag = FALSE;
/**
LPMODULEENTRY32 是 MODULEENTRY32的指针
MODULEENTRY32的dwSize必须要赋值 sizeof(MODULEENTRY32)
*/
MODULEENTRY32 first;
first.dwSize = sizeof(MODULEENTRY32);
BOOL flag=FALSE;
flag = Module32First(dllMessage,&first);
for(; flag; flag = Module32Next(dllMessage,&first))
{
if(!wcscmp(first.szModule,moduleName) || !wcscmp(first.szExePath,moduleName))
{
findFlag = TRUE;
break;
}
}
if(findFlag==TRUE){
return first.modBaseAddr;
}
else{
return 0;
}
}
///***
// 名称:设置最高权限
// 功能:将进程的权限提升到系统级别
// 返回值: BOOL TRUE 成功 FALSE 失败
//*/
//BOOL setDebugPrivilege(){
// TOKEN_PRIVILEGES tkp;
// HANDLE hToken;
// if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken))
// {
// // MessageBox(NULL,"OpenProcessToken failed!","",MB_OK); //获得进程句柄失败
// return FALSE;
// }
// if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME,&tkp.Privileges[0].Luid))
// {
//
// // MessageBox(NULL,"LookupPrivilegeValue","",MB_OK); //获得进程句柄失败
// return FALSE;
// }
// tkp.PrivilegeCount = 1;
// tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,NULL, 0))
// {
// //MessageBox(NULL,"AdjustTokenPrivileges enable failed!","",MB_OK); //修改权限失败
// return FALSE;
// }
// return TRUE;
//}
/**
函数名称:通过进程号找到窗口句柄
参数:
**/
HWND g_windowHandle = 0;
BOOL WINAPI windowProc(HWND hwnd,LPARAM lparam){
DWORD pid = 0;
GetWindowThreadProcessId(hwnd,&pid);
if((DWORD)lparam == pid){
g_windowHandle = hwnd;
return FALSE;
}
return TRUE;
}
HWND findwindowByPid(DWORD pid){
EnumWindows(windowProc,pid);
return g_windowHandle;
}
///**
// 名称:发送信息给窗口
// 功能:通过窗口句柄把信息发送给目标窗口
// 参数:HWND hWindow,char * message
// 返回值: BOOL
//**/
//BOOL sendMessageToWindow(HWND hWindow,char * message)
//{ DROPFILES * pDrop;
// DWORD size = sizeof(DROPFILES) + strlen(message)+1;
// HGLOBAL hGlo = GlobalAlloc(GMEM_ZEROINIT,size);
// LPVOID pBuf = GlobalLock(hGlo);
//// DROPFILE dropf = {0,};
//// dropf.drop.pFiles = sizeof(DROPFILES);
//// strcpy(dropf.msg,message);
// pDrop = (DROPFILES *)pBuf;
// pDrop->pFiles = sizeof(DROPFILES);
// strcpy((pBuf+sizeof(DROPFILES)),message);
// GlobalUnlock(hGlo);
// return PostMessage(hWindow,WM_DROPFILES,(WPARAM)pBuf,0);
//}
#endif // FINDID_H_INCLUDED
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
//EnumWindows设置的回调函数,系统每发现一个窗口都会调用该回调函数
//HWND是窗口句柄类型
//第一个参数返回的是当前窗口句柄,第二个参数类型可以自己定,我传入的是目标进程id
{
DWORD CurrentWindowProcessId; //当前窗口进程id
DWORD CurrentWindowThreadId; //当前窗口线程id
CurrentWindowThreadId = GetWindowThreadProcessId(hwnd, &CurrentWindowProcessId);
//GetWindowThreadProcessId()可以通过窗口句柄,获取该窗口的所在的进程及线程
//第一个参数是输入参数,输入目标窗口句柄
//第二个参数是输出参数,类型是LPDWORD,及指向DWORD的指针,所以要取地址,函数执行成功后CurrentWindowProcessId值就是返回的当前窗口进程id
//返回值是值传递的,DWORD类型,直接赋值给DWORD类型就行了,值是当前窗口线程id
if (CurrentWindowProcessId == lParam) {
//如果当前窗口进程id等于目标进程的进程id
//则得到的当前窗口线程id就是目标窗口线程id
threadID = CurrentWindowThreadId;
//得到了线程id后就可以注入了
return false; //当找到后就返回false,这样才会终止遍历
}
return true; //不是当前窗口,返回true,继续遍历
}
DWORD getTheadIDByProcessID(DWORD processID) {
EnumWindows(EnumWindowsProc, processID);
return threadID;
}
process_plus.h
/************************************************
PROCESS_PLUS.H 文件注释
文件名:PROCESS_PLUS.H
作者:czl
创建时间:2021/3/31 21:19
*************************************************/
#include "my_pro.h"
#include <io.h>
BOOL isVistaOrLater(){
OSVERSIONINFO osVersion;
ZeroMemory(&osVersion,sizeof(OSVERSIONINFO));
osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osVersion);
if(osVersion.dwMajorVersion==6)
return TRUE;
else
return FALSE;
}
/**
功能:通过进程名称找到进程句柄
getHANDLEFromName(char* processName)
*/
HANDLE getHANDLEFromName(TCHAR* processName){
DWORD pid = findProcessID(processName);
if(!pid){
//printf("calc.exe not open!\n");
return 0;
}
else{
//printf("get calc pid successful\n");
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
if(!hProcess){
// printf("get Process Handle failed!\n");
return 0;
}
else{
// printf("get Process Handle successful!\n");
}
return hProcess;
}
/**
名称: writeStringToObjectProcess
功能: 向目标进程空间写入字符串
参数:HANDLE hProcess 被写入字符串的进程句柄 TCHAR * dllName 写入的字符串 注意:是宽字符
返回值:PVOID 写入的地址(目标进程的地址)
**/
PVOID writeStringToObjectProcess(HANDLE hProcess,TCHAR * dllName){
int dllNameSize = wcslen(dllName)*2;
PVOID pBuf = VirtualAllocEx(hProcess,NULL,dllNameSize+1,MEM_COMMIT,PAGE_READWRITE);
if(!pBuf)
{
return 0;
}
BOOL flag = WriteProcessMemory(hProcess,pBuf, dllName, dllNameSize+2, NULL);
if(!flag){
return 0;
}
// printf("write to %X\n",(int)pBuf);
return pBuf;
}
/**
名称:getAPIAddress
功能: 根据模块名称和函数名称获取函数地址
参数: TCHAR * moduleName 模块名称 TCHAR * funcName 函数名称
返回值:return 1 represent moduleName is wrong
return 0 represent funcName is wrong
**/
FARPROC getAPIAddress(TCHAR * moduleName,TCHAR * wFuncName){
char funcName[MAX_PATH] = {0,};
WideCharToMultiByte(CP_ACP, NULL,(LPCWSTR)wFuncName,-1,funcName,MAX_PATH,0,0);
HMODULE hKer;
hKer = GetModuleHandle(moduleName);
if(!hKer)
return (FARPROC)-1;
return GetProcAddress(hKer,funcName);
}
/**
名称:getAPIAddress
功能: 根据模块名称和函数名称获取函数地址
参数: TCHAR * moduleName 模块名称 CHAR * wFuncName 函数名称
返回值:return 1 represent moduleName is wrong
return 0 represent funcName is wrong
**/
FARPROC getAPIAddress(TCHAR * moduleName,CHAR * wFuncName){
/*char funcName[MAX_PATH] = {0,};
WideCharToMultiByte(CP_ACP, NULL,(LPCWSTR)wFuncName,-1,funcName,MAX_PATH,0,0);
*/
HMODULE hKer;
hKer = GetModuleHandle(moduleName);
if(!hKer)
return (FARPROC)-1;
return GetProcAddress(hKer,wFuncName);
}
FARPROC getAPIAddress(CHAR * moduleName,CHAR * wFuncName){
/*char funcName[MAX_PATH] = {0,};
WideCharToMultiByte(CP_ACP, NULL,(LPCWSTR)wFuncName,-1,funcName,MAX_PATH,0,0);
*/
HMODULE hKer;
hKer = GetModuleHandleA(moduleName);
if(!hKer)
return (FARPROC)-1;
return GetProcAddress(hKer,wFuncName);
}
//检查字符串是否为文件
BOOL isFile(TCHAR * wDllName){
char dllName[MAX_PATH] = {0,};
WideCharToMultiByte(CP_ACP, NULL,wDllName,-1,dllName,MAX_PATH,0,0);
if (!_access(dllName,0))
{
char * typeOfFile = strrchr(dllName,'.');
if (typeOfFile&&!strcmp(typeOfFile,".dll"))
{
return TRUE;
}
;
}
return FALSE;
}
typedef DWORD (WINAPI *PFNTCREATETHREADEX)
(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD
dw1,
DWORD dw2,
LPVOID Unknown
);
BOOL MyCreateRemoteThread(HANDLE hProcess,LPTHREAD_START_ROUTINE pThreadPorc,PVOID pRemoteBuf){
PFNTCREATETHREADEX ntCreateThreadEx;
HANDLE hThread;
if (isVistaOrLater()==TRUE) //如果内核版本为6以上则采用NtCreateThreadEx创建远程线程
{
ntCreateThreadEx = (PFNTCREATETHREADEX)getAPIAddress((char *)"ntdll.dll",(char *)"NtCreateThreadEx"); //获取NtCreateThreadEx的地址
if (!ntCreateThreadEx)
{
char bugBuf[MAX_PATH];
char * errorMsg= (char*)"NtCreateThreadEx函数获取失败 可能是没有导入ntdll.dll(一般不太可能)";
sprintf_s(bugBuf,MAX_PATH,"\n%s/%s/%s: %s\n",__FILE__,__FUNCTION__,__LINE__,errorMsg);
OutputDebugStringA(bugBuf);
return FALSE;
}
ntCreateThreadEx(&hThread,0x1fffff,NULL,hProcess,pThreadPorc,pRemoteBuf,FALSE,NULL,NULL,NULL,NULL);
if (hThread==0)
{
char bugBuf[MAX_PATH];
char * errorMsg= (char*)"获取线程失败 ";
sprintf_s(bugBuf,MAX_PATH,"\n%s/%s/%s: %s\n",__FILE__,__FUNCTION__,__LINE__,errorMsg);
OutputDebugStringA(bugBuf);
return FALSE;
}
}
else{ //否则则采用CreateRemoteThread创建远程线程
hThread = CreateRemoteThread(hProcess,0,0,pThreadPorc,pRemoteBuf,0,0);
if (hThread==0)
{
char bugBuf[MAX_PATH];
char * errorMsg= (char*)"获取线程失败 ";
sprintf_s(bugBuf,MAX_PATH,"\n%s/%s/%s: %s\n",__FILE__,__FUNCTION__,__LINE__,errorMsg);
OutputDebugStringA(bugBuf);
return FALSE;
}
}
if (WaitForSingleObject(hThread,INFINITE)==WAIT_FAILED)
{
char bugBuf[MAX_PATH];
char * errorMsg= (char*)"WaitForSingleObject失败";
sprintf_s(bugBuf,MAX_PATH,"\n%s/%s/%s: %s\n",__FILE__,__FUNCTION__,__LINE__,errorMsg);
OutputDebugStringA(bugBuf);
return FALSE;
}
return TRUE;
}
/**
名称:dllInject
功能: 将dll文件注入到目标进程空间
参数:DWORD pid 目标进程的pid TCHAR * wDllName dll路径
返回值:bool 是否成功
**/
void dllInject(DWORD pid,TCHAR * wDllName){
//获取目标进程句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(!hProcess)
OutputDebugStringA("\n1:进程句柄获取失败 dllInject(DWORD pid,TCHAR * wDllName) 错误原因: 有可能是pid错误\n");
//检查字符串是否为dll文件
if (!isFile(wDllName)) {
OutputDebugStringA("\n2:输入得文件路径不是dll dllInject(DWORD pid,TCHAR * wDllName) 错误原因: 有可能是字符串写错了\n");
}
//将字符串注入目标进程地址空间
PVOID pBuf = writeStringToObjectProcess(hProcess,wDllName);
if(!pBuf)
OutputDebugStringA("\n3:将字符串注入目标进程地址空间失败 dllInject(DWORD pid,TCHAR * wDllName) 错误原因: 有可能是pid错误\n");
//获取loadlibary函数地址
FARPROC pFun = getAPIAddress((wchar_t*)L"kernel32.dll", (wchar_t*)L"LoadLibraryW");
if(!pFun)
OutputDebugStringA("\n4:获取loadlibary函数地址失败 dllInject(DWORD pid,TCHAR * wDllName) 错误原因: 有可能是本进程没有导入LoadLibraryW函数\n");
//创建远程
MyCreateRemoteThread(hProcess,(LPTHREAD_START_ROUTINE)pFun,pBuf);
}
/**
名称:dllEnject
功能: 卸载目标进程的模块
参数:DWORD pid 目标进程的pid TCHAR * wDllName dll路径
返回值:bool 是否成功
**/
void dllEnject(DWORD pid,TCHAR * wDllName){
//获取目标进程句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(!hProcess)
OutputDebugStringA("\n1:进程句柄获取失败 dllEnject(DWORD pid,TCHAR * wDllName) 错误原因: 有可能是pid错误\n");
//通过进程id和模块名找到目标进程的模块地址
HANDLE hModule = getModuleHandlebyName(pid,wDllName);
if (!hModule) {
OutputDebugStringA("\n2: 获取模块地址失败 dllEnject(DWORD pid,TCHAR * wDllName) 错误原因: 有可能是字符串写错了或目标进程没有该模块\n");
}
//获取freelibary函数地址
FARPROC pFun = getAPIAddress((wchar_t*)L"kernel32.dll", (wchar_t*)L"FreeLibrary");
if(!pFun)
OutputDebugStringA("\n3:获取FreeLibrary函数地址失败 dllInject(DWORD pid,TCHAR * wDllName) 错误原因: 有可能是本进程没有导入FreeLibrary函数\n");
//创建远程线程
CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pFun,hModule,0,NULL);
}
/**
名称:GlobalInjectOrEnject
功能: 将所有进程中的某个dll卸载(可以选定下限)
参数: TCHAR * wDllName 被卸载的dll路径 int line 进程pid下限,pid低于line的不会被卸载 BOOL mode 是否为注入模式
返回值: void
**/
void GlobalInjectOrEnject(TCHAR * wDllName,int line,BOOL mode){
//获取所有进程的pid
HANDLE hSnapShot = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe;
// Get the snapshot of the system
pe.dwSize = sizeof( PROCESSENTRY32 );
hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );
// find process
Process32First(hSnapShot, &pe);
do
{
//排除不能注入的pid
if(pe.th32ProcessID>=(unsigned int)line)
if(mode==TRUE)
dllInject(pe.th32ProcessID,wDllName);
else
dllEnject(pe.th32ProcessID,wDllName);
}
while( Process32Next(hSnapShot, &pe) );
CloseHandle(hSnapShot);
}
/**
名称:GlobalInject
功能: 将dll注入到所有进程中(可以选定下限)
参数: TCHAR * wDllName 被用来注入的dll路径 int line 进程pid下限,pid低于line的不会被注入
返回值: void
**/
void GlobalInject(TCHAR * wDllName,int line){
GlobalInjectOrEnject(wDllName,line,TRUE);
}
/**
名称:GlobalEnject
功能: 将所有进程中的某个dll卸载(可以选定下限)
参数: TCHAR * wDllName 被卸载的dll路径 int line 进程pid下限,pid低于line的不会被卸载
返回值: void
**/
void GlobalEnject(TCHAR * wDllName,int line){
GlobalInjectOrEnject(wDllName,line,FALSE);
}
/**
名称:hookByCode
功能: 在某个API下钩子
参数:PVOID APIAddr 被钩取的函数地址 PVOID hookProc 钩子函数 PBYTE pBuf 保存前五个字节的缓冲区
返回值:PBYTE 返回被下钩子的API的前5个字节 用于脱钩
**/
VOID hookByCode(PVOID APIAddr,PVOID hookProc,PBYTE pBuf){
memcpy(pBuf,APIAddr,5);
//计算跳转距离
// 若已经被钩取则返回FALSE
if( ((PBYTE)APIAddr)[0] == 0xE9 )
return ;
//目标位置
DWORD desPos = (DWORD)hookProc;
//源位置
DWORD srcPos = (DWORD)APIAddr+5;
DWORD jmpDistance = desPos-srcPos;
//取得可写权限
DWORD lpflOldProtect;
VirtualProtect(APIAddr,5,PAGE_READWRITE,&lpflOldProtect);
//设置跳转语句
memcpy((byte *)APIAddr+1,&jmpDistance,4);
*(BYTE *)APIAddr = 0xE9;
VirtualProtect(APIAddr,5,lpflOldProtect,&lpflOldProtect);
}
BOOL hookByCode(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)
{
FARPROC pfnOrg;
BYTE pBuf[5] = {0xE9, 0, };
PBYTE pByte;
// 获取要钩取的API地址
pfnOrg = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
pByte = (PBYTE)pfnOrg;
//hookByCode((PVOID)pfnOrg,(PVOID)pfnNew,pOrgBytes);
PVOID APIAddr = pfnOrg;
PVOID hookProc = pfnNew;
memcpy(pOrgBytes,APIAddr,5);
//计算跳转距离
// 若已经被钩取则返回FALSE
if( ((PBYTE)APIAddr)[0] == 0xE9 )
return TRUE;
//目标位置
DWORD desPos = (DWORD)hookProc;
//源位置
DWORD srcPos = (DWORD)APIAddr+5;
DWORD jmpDistance = desPos-srcPos;
//取得可写权限
DWORD lpflOldProtect;
VirtualProtect(APIAddr,5,PAGE_EXECUTE_READWRITE,&lpflOldProtect);
//设置跳转语句
memcpy((byte *)APIAddr+1,&jmpDistance,4);
*(BYTE *)APIAddr = 0xE9;
VirtualProtect(APIAddr,5,lpflOldProtect,&lpflOldProtect);
return TRUE;
}
BOOL hookByCode(WCHAR* szDllName, WCHAR* szFuncName, PROC pfnNew, PBYTE pOrgBytes)
{ char muti1[MAX_PATH];
WideCharToMultiByte(CP_ACP, NULL,szDllName,-1,muti1,MAX_PATH,NULL, NULL);
char muti2[MAX_PATH];
WideCharToMultiByte(CP_ACP, NULL,szFuncName,-1,muti2,MAX_PATH,NULL, NULL);
hookByCode(muti1,muti2,pfnNew,pOrgBytes);
return TRUE;
}
/**
名称:unhookByCode
功能: 解除某个API的钩子
参数:TCHAR * moduleName 模块名 TCHAR * funcName 函数名 PVOID hookProc 钩子函数
返回值:PBYTE 返回被下钩子的API的前5个字节 用于脱钩
**/
PBYTE unhookByCode(PVOID APIAddr,PBYTE pBuf){
//取得可写权限
DWORD lpflOldProtect;
VirtualProtect(APIAddr,5,PAGE_EXECUTE_READWRITE,&lpflOldProtect);
//检查是否被下钩子
PBYTE pByte =(PBYTE)APIAddr;
if(*pByte==0xE9)
memcpy(APIAddr,pBuf,5);
VirtualProtect(APIAddr,5,lpflOldProtect,&lpflOldProtect);
return pBuf;
}
BOOL unhookByCode(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)
{
FARPROC pFunc;
PBYTE pByte;
// 获取API地址
pFunc = GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
pByte = (PBYTE)pFunc;
unhookByCode((PVOID)pFunc,pOrgBytes);
return TRUE;
}
BOOL unhookByCode(WCHAR *szDllName, WCHAR *szFuncName, PBYTE pOrgBytes)
{
char muti1[MAX_PATH];
WideCharToMultiByte(CP_ACP, NULL,szDllName,-1,muti1,MAX_PATH,NULL, NULL);
char muti2[MAX_PATH];
WideCharToMultiByte(CP_ACP, NULL,szFuncName,-1,muti2,MAX_PATH,NULL, NULL);
return unhookByCode(muti1,muti2,pOrgBytes);;
}
标签:封装,windows,pid,TCHAR,char,DWORD,进程,return,NULL
From: https://www.cnblogs.com/czlnb/p/16875632.html