版权声明: https://blog.csdn.net/dashoumeixi/article/details/83656447
先来提升下完整性级别:
代码中所有失败的情况都没判断
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
TOKEN_PRIVILEGES tp;
LUID luid;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
远程注入:
CreateRemoteThread 也就这个函数了. 现在的想法是把一个dll 仍到另一个进程里去执行;
看原型: LoadLibrary 和 线程函数类似, 那么就可以把 LoadLibrary 作为线程函数;
需要注意 DLL 有导出段, 其中导出函数地址都是 RVA 即相对虚拟地址 .
而exe中的如果使用到了dll 则会有相应的导入段. 而导入段中也有 RVA .
解决办法:
CreateRemoteThread(hRemoteProcess ,NULL,0, LoadLibrary,"d:/xxx/aaa.dll",0,NULL);
这里问题来了;
LoadLibrary 这个函数地址是自己程序的RVA, 所以不能这样使用;
解决办法是 :
LPTHREAD_START_ROUTINE rt = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryW");
获取 kernel32 ,其在所有进程中的位置都一样, 所以其导出的函数位置也一样.
接下来 "d:/xxx/aaa.dll" 也不能这样使用. 因为这个字符串在自己的进程中,
解决办法是为目标进程分配一块内存, VirtualAllocEx
分配好了之后把自己进程中的字符串复制过去 ,WriteProcessMemory.
这样就完成了
int _tmain(int argc, _TCHAR* argv[])
{
_tsetlocale(LC_CTYPE, TEXT(""));
//提升完整性级别
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
TOKEN_PRIVILEGES tp;
LUID luid;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
TCHAR path[] = TEXT("D:/xxx.dll");
int pathlen = lstrlen(path) + sizeof(TCHAR);
//获取目标进程
HANDLE hp = OpenProcess(PROCESS_VM_OPERATION |
PROCESS_CREATE_THREAD |
PROCESS_VM_WRITE,
FALSE,
4296); //进程id
// 获取 LoadLibraryW 的地址
LPTHREAD_START_ROUTINE rt = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryW");
//给目标进程分配内存 , 用于存放 dll 路径
TCHAR * alloc = (TCHAR*)VirtualAllocEx(hp, NULL,pathlen,MEM_COMMIT,PAGE_READWRITE);
DWORD writeNum = 0;
//把路径写入目标进程
WriteProcessMemory(hp, alloc, path, pathlen, &writeNum);
printf("WriteProcessMemory :%d\n", writeNum);
//启动远程线程
HANDLE remoteHandle = CreateRemoteThread(hp,NULL,0,rt,(void*)alloc,0,NULL);
CloseHandle(remoteHandle);
CloseHandle(hp);
return 0;
}
卸载dll:
void freedll(DWORD pid , TCHAR * dllname)
{
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pid);
MODULEENTRY32 me32;
me32.dwSize = sizeof(MODULEENTRY32);
Module32First(hSnap, &me32);
BOOL bFound = FALSE;
do{
if (lstrcmp(me32.szModule, dllname) == 0){
bFound = TRUE;
break;
}
} while (Module32Next(hSnap, &me32));
if (!bFound){
printf("not found");
return;
}
HANDLE hp = OpenProcess(PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION |
PROCESS_CREATE_THREAD , FALSE, pid);
LPTHREAD_START_ROUTINE pt = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "FreeLibrary");
HANDLE hThread = CreateRemoteThread(hp, NULL, 0, pt, (void*)me32.hModule, 0, NULL);
WaitForSingleObject(hThread, -1);
CloseHandle(hThread);
CloseHandle(hp);
}