jjzjj

Windows 权限,在不是管理员时获取 .dll 的句柄,不确定

coder 2024-06-21 原文

好的,我正在学习 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:\驱动器只是我硬盘上的另一个分区。

  1. 为什么会发生这种情况?
  2. 有哪些方法可以解决这个问题? (如果可能,需要引用、解释和示例)

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() 在管理模式下工作,但在标准模式下不工作。

最佳答案

我可以看到以下问题:

  1. 在对 WriteProcessMemory 的调用中,您传递了错误的长度。您需要传递 strlen(...)+1 才能编写空终止符。
  2. 无需使用未记录的 NtCreateThreadEx。使用 CreateRemoteThread 非常适合注入(inject)。
  3. 您只检查了一些 API 调用的错误。您需要检查所有 API 调用的错误。如果你不这样做,没有人知道他们是否成功。

就其值(value)而言,我从来不必使用 AdjustTokenPrivileges 进行注入(inject)。我相信您可以跳过这一步。


在评论中,您声明您正在注入(inject)到不同的 session 中。而且您发现您需要 NtCreateThreadEx 而不是 CreateRemoteThread,并且该注入(inject)仅在提升时有效。当然,在不同 session 中注入(inject)进程的要求非常重要。这应该包含在问题中而不是出现在评论中。

但是,对于需要提升才能注入(inject)到不同 session 中的进程,您不应该感到惊讶。对于这种情况,很可能需要添加 SE_DEBUG_NAME

简而言之,在我看来,系统告诉您以提升的方式运行,以便注入(inject)不同 session 中的进程。这似乎很合理。


另一方面,您还在注释中声明 CreateRemoteThread 返回一个非零值。这表明成功。这似乎是说你误诊了问题。如果 CreateRemoteThread 成功,则远程线程将运行。接下来您需要找出失败的原因。

而且你还说你正试图注入(inject) explorer 进程,它不在 session 0 中运行。所以这里有很多困惑。也许我草率地添加了这个答案。

无论如何,为了让您继续,我建议:

  1. 修复对 WriteProcessMemory 的调用。
  2. 找出目标进程所在的 session 。
  3. 添加错误检查。

关于Windows 权限,在不是管理员时获取 .dll 的句柄,不确定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23211328/

有关Windows 权限,在不是管理员时获取 .dll 的句柄,不确定的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了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

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  6. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  7. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  8. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  9. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署: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

  10. ruby - rbenv 安装权限被拒绝 - 2

    大家好,我正在尝试设置一个开发环境,并且我一直在关注以下教程: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

随机推荐