DLL卸载
winxp测试成功(需要C:\windows\system32\msvcr100.dll)
// EjectDll.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<Windows.h>
#include<TlHelp32.h>
#include<tchar.h>
#define DEF_PROC_NAME (L"notepad.exe")
#define DEF_DLL_NAME (L"Myhack.dll")
DWORD FindProcessID(LPCTSTR szProcessName)
{
DWORD dwPID=0xFFFFFFFF;
HANDLE hSnapShot=INVALID_HANDLE_VALUE;
//用来存放快照进程信息的一个结构体。(存放进程信息和调用成员输出进程信息)用来 Process32First指向第一个进程信息,并将进程信息抽取到PROCESSENTRY32中。用Process32Next指向下一条进程信息。
PROCESSENTRY32 pe;
//获取系统快照
pe.dwSize=sizeof(PROCESSENTRY32);
//通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照。
//TH32CS_SNAPALL:包括系统中的所有进程和线程,以及th32ProcessID中指定的进程的堆和模块。
//the32ProcessID=NULL:代表当前进程
hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPALL,NULL);
//查找进程
Process32First(hSnapShot,&pe);
do
{
if(!_tcsicmp(szProcessName,(LPCTSTR)pe.szExeFile))
{
dwPID=pe.th32ProcessID;
break;
}
}
while(Process32Next(hSnapShot,&pe));
CloseHandle(hSnapShot);
return dwPID;
}
BOOL SetPrivilege(LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
{
//结构体,包含两个成员PrivilegeCount:特权数组个数,Privileges:一个LUID_AND_ATTRIBUTES结构体. 每个结构体包括LUID和特权的属性.
/*
typedef struct _LUID_AND_ATTRIBUTES {
LUID Luid;
DWORD Attributes;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
*/
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
_tprintf(L"OpenProcessToken error:%u\n",GetLastError());
return FALSE;
}
//NULL:查看本地系统;lpszPrivilege:指定特权名称;&luid:接收返回的特权名称的信息
if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
{
_tprintf(L"LookupPrivilegeValue error:%u\n",GetLastError());
return FALSE;
}
tp.PrivilegeCount=1;
tp.Privileges[0].Luid=luid;
if(bEnablePrivilege)
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes=0;
//提权或禁用特权
if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL))
{
_tprintf(L"AdjustTokenPrivileges error:%u\n",GetLastError());
return FALSE;
}
if(GetLastError()==ERROR_NOT_ALL_ASSIGNED)
{
_tprintf(L"The token dose not have the specified privilege.\n");
return FALSE;
}
return TRUE;
}
BOOL EjectDll(DWORD dwPID,LPCTSTR szDllName)
{
BOOL bMore=FALSE,bFound=FALSE;
HANDLE hSnapshot,hProcess,hThread;
HMODULE hModule=NULL;
MODULEENTRY32 me={sizeof(me)};
LPTHREAD_START_ROUTINE pThreadProc;
//dwPID=notepad进程ID
//使用TH32CS_SNAPMODULE参数,获取加载到notepad进程的DLL名称
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,dwPID);
//此函数检索与进程相关联的第一个模块的信息
bMore=Module32First(hSnapshot,&me);
for(;bMore;bMore=Module32Next(hSnapshot,&me))
{
if(!_tcsicmp((LPCTSTR)me.szModule,szDllName)||!_tcsicmp((LPCTSTR)me.szExePath,szDllName))
{
bFound=TRUE;
break;
}
}
if(!bFound)
{
CloseHandle(hSnapshot);
return FALSE;
}
if(!(hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID)))
{
_tprintf(L"OpenProcess(%d) failed!!![%d]\n",dwPID,GetLastError);
return FALSE;
}
hModule=GetModuleHandle(L"kernel32.dll");
pThreadProc=(LPTHREAD_START_ROUTINE)GetProcAddress(hModule,"FreeLibrary");
//modBaseAddr模块基址
hThread=CreateRemoteThread(hProcess,NULL,0,pThreadProc,me.modBaseAddr,0,NULL);
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
CloseHandle(hSnapshot);
return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwPID=0xFFFFFFFF;
//查找process
dwPID=FindProcessID(DEF_PROC_NAME);
if(dwPID==0xFFFFFFFF)
{
_tprintf(L"There is no %s process!\n",DEF_PROC_NAME);
return 1;
}
_tprintf(L"PID of \"%s\" is %d\n",DEF_PROC_NAME,dwPID);
//更改privilege
if(!SetPrivilege(SE_DEBUG_NAME,TRUE))
return 1;
if(EjectDll(dwPID,DEF_DLL_NAME))
_tprintf(L"EjectDll(%d,\"%s\") success!!!\n",dwPID,DEF_DLL_NAME);
else
_tprintf(L"EjectDll(%d,\"%s\") failed!!!\n",dwPID,DEF_DLL_NAME);
return 0;
}