好的,我正在学习 Windows API 以及如何创建线程/进程和获得调试权限等。非常新,如果这是一个愚蠢的问题,我深表歉意。
无论如何,我正在创建一个 .dll 注入(inject)器来玩,并且已经成功地能够注入(inject) 32 位和 64 位进程,包括通过注入(inject)我的 .dll 文件的 explorer.exe。但是,我试图在标准用户模式下对此进行测试,但在弄清楚如何进行时遇到了问题。
现在我正在为 .dll 和 injector.exe 编译为 x64。我正在尝试注入(inject) x64 进程,主要是 explorer.exe(适用于管理员)。使用 Visual Studio 2012,进行了一些优化,没有 list ,没有调试(仅在需要时)。 操作系统= Win 7 x64
此外,我尝试从多个位置访问 .dll,E:\驱动器只是我硬盘上的另一个分区。
NtCreateThreadEx();调用返回一个线程 0。因此它没有正确加载。
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <tlhelp32.h>
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
using namespace std;
DWORD getPid(string procName);
int privileges();
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef DWORD(WINAPI *NTCREATETHREADEX)
(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID Unknown
);
int main()
{
cout << sizeof(void*) << endl;
privileges(); //don't mind of the result, because maybe it fails because you already have that privilege
DWORD pid = getPid("explorer.exe");
if (pid == 0) return 1; //error
HANDLE p;
p = OpenProcess(CREATE_THREAD_ACCESS, false, pid);
if (p == NULL) return 1; //error
char * dll = "E:\\logger_mailer.dll";
BOOL is32 = FALSE;
BOOL fnWow64Ret = IsWow64Process(p, &is32);
if (!fnWow64Ret)
{
cout<<"Error!!!!!!"<<endl;
return 1;
}
//if (is32) //If true process is 32 bit
// dll = "D:\\logger_mailer.dll";
//else
//{
// dll = "D:\\logger_mailer.dll";
// //cout<<"Error"<<endl;
//}
unsigned long LoadLib = (unsigned long)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
LPVOID DataAddress = VirtualAllocEx(p, NULL, strlen(dll) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(p, DataAddress, dll, strlen(dll), NULL);
HANDLE thread;
NTCREATETHREADEX NtCreateThreadEx = (NTCREATETHREADEX)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtCreateThreadEx");
if (NtCreateThreadEx) {
NtCreateThreadEx(&thread, GENERIC_ALL, NULL, p, (LPTHREAD_START_ROUTINE)LoadLib, DataAddress, FALSE, NULL, NULL, NULL, NULL);
}
else {
thread = CreateRemoteThread(p, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLib, DataAddress, NULL, NULL);
}
if (thread != 0){
//injection completed
WaitForSingleObject(thread, INFINITE); //this waits untill thread thread has finished
VirtualFree(dll, 0, MEM_RELEASE); //free myFunc memory
VirtualFree(DataAddress, 0, MEM_RELEASE); //free data memory
CloseHandle(thread);
CloseHandle(p); //don't wait for the thread to finish, just close the handle to the process
cout << "Injection completed!" << endl;
}
else{
cout << "Error!" << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
DWORD getPid(string procName){
HANDLE hsnap;
PROCESSENTRY32 pt;
hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pt.dwSize = sizeof(PROCESSENTRY32);
do{
if (!strcmp(pt.szExeFile, procName.c_str())){
DWORD pid = pt.th32ProcessID;
CloseHandle(hsnap);
return pid;
}
} while (Process32Next(hsnap, &pt));
CloseHandle(hsnap);
return 0;
}
int privileges(){
HANDLE Token;
TOKEN_PRIVILEGES tp;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token))
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL) == 0){
return 1; //FAIL
}
else{
return 0; //SUCCESS
}
}
return 1;
}
编辑:所以,在 David 和 Harry 基本上通过一些东西来哄我之后,我发现是我的 .dll 代码失败了。此外,我不需要使用 NtCreateThreadEx(),因为 CreateRemoteThread() 确实适用于 win 7 x64。 SO 和其他网站上的许多帖子另有说明。显示一个简单的消息框以进行验证。
奇怪的是 NtCreateThreadEx() 在管理模式下工作,但在标准模式下不工作。
最佳答案
我可以看到以下问题:
WriteProcessMemory 的调用中,您传递了错误的长度。您需要传递 strlen(...)+1 才能编写空终止符。NtCreateThreadEx。使用 CreateRemoteThread 非常适合注入(inject)。就其值(value)而言,我从来不必使用 AdjustTokenPrivileges 进行注入(inject)。我相信您可以跳过这一步。
在评论中,您声明您正在注入(inject)到不同的 session 中。而且您发现您需要 NtCreateThreadEx 而不是 CreateRemoteThread,并且该注入(inject)仅在提升时有效。当然,在不同 session 中注入(inject)进程的要求非常重要。这应该包含在问题中而不是出现在评论中。
但是,对于需要提升才能注入(inject)到不同 session 中的进程,您不应该感到惊讶。对于这种情况,很可能需要添加 SE_DEBUG_NAME。
简而言之,在我看来,系统告诉您以提升的方式运行,以便注入(inject)不同 session 中的进程。这似乎很合理。
另一方面,您还在注释中声明 CreateRemoteThread 返回一个非零值。这表明成功。这似乎是说你误诊了问题。如果 CreateRemoteThread 成功,则远程线程将运行。接下来您需要找出失败的原因。
而且你还说你正试图注入(inject) explorer 进程,它不在 session 0 中运行。所以这里有很多困惑。也许我草率地添加了这个答案。
无论如何,为了让您继续,我建议:
WriteProcessMemory 的调用。关于Windows 权限,在不是管理员时获取 .dll 的句柄,不确定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23211328/
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
大家好,我正在尝试设置一个开发环境,并且我一直在关注以下教程:Linktotutorial我做得不是很好,除了最基本的版本控制内容外,我对终端命令没有任何实际经验。我点击了第一个链接并尝试运行source~/.bash_profile我得到了错误;mkdir:/usr/local/rbenv/shims:权限被拒绝mkdir:/usr/local/rbenv/versions:权限被拒绝现在每次我加载终端时都会出现错误。bash_profile的内容;exportPATH=/usr/local/rbenv/bin:$PATHexportRBENV_ROOT=/usr/local/rbe