/*卸载其他进程的dll
加入了权限提升,并改为直接用进程名,这样也方便一点
freedll.exe explorer.exe adson.dll============
还没有解决:卸载模块成功后,宿主进程可能过会儿会发生异常,有待下会解决,郁闷!
--------------------------------------------------------------*/
#include
<
windows.h
>
#include
<
stdio.h
>
#include
<
Tlhelp32.h
>

typedef
struct
RemoteInfo

...
{
DWORD dwLoadLibrary;//FreeLibrary函数地址
DWORD ModuleAddr; //模块地址
}
RemotePara;
//
传递给远程线程的参数
DWORD WINAPI ThreadProc (RemotePara
*
lpPara)

...
{
typedef BOOL (__stdcall *pFreeLibrary)(DWORD);
pFreeLibrary pFuckLibrary;
pFuckLibrary = (pFreeLibrary)lpPara->dwLoadLibrary;
pFuckLibrary(lpPara->ModuleAddr); //模块基地址
return 0;
}
int
Uninject(DWORD pid,
char
*
dll);
//
卸载模块函数
int
EnableDebugPriv(
const
char
*
name);
//
提升权限
unsigned
long
GetProcessID(
char
*
sProcName);
//
获得进程对应的PID
int
main(
int
argc,
char
*
argv[])

...
{
DWORD id;
if(argc!=3)

...{
printf("Remote Modules Uninject Tool by Rhett 2006.1.16 ");
printf("%s Module name Process id ",argv[0]);
return 1;
}
id = GetProcessID(argv[1]);
if (id==0)
return 1;
//----------------------------------------------------------------------------
if ((Uninject(id, argv[2]))==0)

...{
puts("卸载模块失败,请确定该模块确实存在于进程中! ");
return 1;
}
else

...{
puts("卸载模块成功");
}


return 0;
}

int
Uninject(DWORD pid,
char
*
dll)

...
{
MODULEENTRY32 ModuleStor;
RemotePara pRemoteCallParam;
RemotePara *pRPCParam = NULL;
if(EnableDebugPriv(SE_DEBUG_NAME))//提升权限

...{
printf("add privilege error");
return 0;
}
//获取进程快照
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pid);
if(INVALID_HANDLE_VALUE==hSnapshot)

...{
printf("snapshot failed ");
return 0;
}
ModuleStor.dwSize = sizeof(MODULEENTRY32);
//遍历进程所有模块,直到找到目标DLL
int bFind = Module32First(hSnapshot,&ModuleStor);
while (bFind)

...{
printf("%s",ModuleStor.szModule);
printf(" %8x ",ModuleStor.modBaseAddr);
if(!strcmp(ModuleStor.szModule,dll))

...{
pRemoteCallParam.ModuleAddr = (unsigned long)ModuleStor.modBaseAddr;//模块地址赋值?

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
if(hProcess==NULL)

...{
//printf(" open process failed ");
return 0;
}

HMODULE hModule = LoadLibrary("kernel32.dll");

pRemoteCallParam.dwLoadLibrary = (DWORD)GetProcAddress(hModule,"FreeLibrary");
// pRemoteCallParam.ModuleAddr = 0x10000000;
//在目标进程的内存范围内分配一个足够长度的内存
pRPCParam = (RemotePara *)VirtualAllocEx(hProcess,NULL,sizeof(RemotePara),MEM_COMMIT,PAGE_READWRITE);
if (pRPCParam == NULL)

...{
//printf("virtualallocex failed ");
CloseHandle(hProcess);
return 0;
}
WriteProcessMemory(hProcess,pRPCParam,&pRemoteCallParam,sizeof(pRemoteCallParam),0);
//在远程分配一块内存
PVOID pRemoteThread = VirtualAllocEx(hProcess,NULL,2048,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(pRemoteThread==NULL)

...{
//printf("second virtualallocex failed ");
CloseHandle(hProcess);
return 0;
}
WriteProcessMemory(hProcess,pRemoteThread,&ThreadProc,2048,0);

HANDLE hThread = CreateRemoteThread(hProcess,0,0,(DWORD (__stdcall *)(void *))pRemoteThread,pRPCParam,0,NULL);
if(hThread==NULL)

...{
//printf("createremotethread failed ");
CloseHandle(hProcess);
return 0;
}
CloseHandle(hProcess);
return 1;
}
bFind = Module32Next(hSnapshot,&ModuleStor);
}

CloseHandle(hSnapshot);//
return 0;
}

unsigned
long
GetProcessID(
char
*
sProcName)

...
{
int done;
HANDLE hProcSnap;
PROCESSENTRY32 ProcessEntry32;
hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcSnap == INVALID_HANDLE_VALUE)

...{
return 0;
}
ProcessEntry32.dwSize = sizeof(PROCESSENTRY32);
done = Process32First(hProcSnap, &ProcessEntry32);
while (done)

...{
if (strcmp(ProcessEntry32.szExeFile,sProcName)==0)
return ProcessEntry32.th32ProcessID;
done = Process32Next(hProcSnap, &ProcessEntry32);
}
return 0;
}


int
EnableDebugPriv(
const
char
*
name)

...
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
//打开进程令牌环
if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
&hToken) )

...{
printf("OpenProcessToken error. ");
return 1;
}
//获得进程本地唯一ID
if(!LookupPrivilegeValue(NULL,name,&luid) )

...{
printf("LookupPrivilege error! ");
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
//调整权限
if(!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL) )

...{
printf("AdjustTokenPrivileges error! ");
return 1;
}

return 0;
}