我有兴趣在我的Vista机器上将DLL注入到SYSTEM拥有的进程中。我正在使用VirtualAllocEx,WriteProcessMemory和CreateRemoteThread的传统方法。但是,因为这将在SYSTEM进程上运行,所以在打开目标进程之前,我在注入过程中启用了SeDebugPivilege。
int EnableDebugPriv(LPCTSTR name) {
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(),
/*TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY*/
TOKEN_ALL_ACCESS,
&hToken))
return 0;
if(!LookupPrivilegeValue(NULL,name,&luid))
return 0;
tkp.PrivilegeCount=1;
tkp.Privileges[0].Luid=luid;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,false,&tkp,sizeof(tkp),NULL,NULL))
{
printf("!AdjustTokenPrivileges - %d\n",GetLastError());
return 0;
}
if(GetLastError()==ERROR_NOT_ALL_ASSIGNED)
{
return 0;
}
CloseHandle(hToken);
return 1;
}
将SE_DEBUG_NAME
常量作为名称传递。
启用SeDebugPrivilege之后,我将完成打开目标进程,查找LoadLibrary,分配空间,将DLL路径写入内存以及创建线程(检查所有返回值)的过程:
if(NULL==(p=OpenProcess(PROCESS_ALL_ACCESS,FALSE,(DWORD)pid)))
...
if(NULL==(loadLib=(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"),
"LoadLibraryA")))
...
if(NULL==(dllBuff=(LPVOID)VirtualAllocEx(p,
NULL,
strlen(dllPath)+1,
MEM_RESERVE|MEM_COMMIT,
PAGE_READWRITE)))
...
if(NULL==WriteProcessMemory(p,
(LPVOID)dllBuff,
dllPath,
strlen(dllPath),
&written))
...
if(!CreateRemoteThread(p,
NULL,
NULL,
(LPTHREAD_START_ROUTINE)loadLib,
(LPVOID)dllBuff,
NULL,
NULL))
...
dllPath
是DLL路径的char *(显然),pid
是目标进程的PID。这两个值都通过命令行获取,并在使用之前进行验证。
我遇到的问题是,在CreateRemoteThread返回8(“存储空间不足”)之前,没有任何东西会返回错误。但是,WriteProcessMemory不会向进程写入任何字节。在调用之后,写入的变量始终为0.没有写入字节,但函数没有失败。我不确定为什么会这样。我查看了其他权限,比如SeRestorePrivilege,它承诺对所有进程进行写访问,但没有任何效果。
我正在以管理员权限执行此程序。
注意:只有当我针对更高权限的用户(SYSTEM,LOCAL SERVICE等)运行此程序时,才会发生此WriteProcessMemory和CreateRemoteThread问题。它完全适用于我拥有的程序(相同的权限)。
编辑:这是指向整个来源的链接。 http://pastebin.com/m77110d8e除了基本的错误检查之外没有其他的东西,但也许它会有帮助吗?
答案 0 :(得分:4)
这与Vista或更高版本Windows中的会话隔离有关。查看Cain和Abel等密码转储工具的源代码或反汇编,其中包含了Vista的功能。基本上这个过程是相同的,但你会为CreateRemoteThread调用一个不同的函数(对不起,我不认为函数是导出的,你只需要找到它,所以反编译工作软件可能是最好的选择)。 / p>
答案 1 :(得分:4)
您可以尝试使用RtlCreateUserThread,而不是CreateRemoteThread。此例程不关心目标进程所在的会话。只需记住在结束之前让线程调用RtlExitUserThread。这些线程不会自行清理,就像CreateThread / CreateRemoteThread那样。
reactos code可以让你很好地了解这些例程正在做什么。