求助:自动注入工具中创建远程线程失败?请大佬指导

zhouqunhai 2018-03-16 04:45:05
我现在写的一个自动注入工具,可将dll自动注入到某进程中,但调试时在创建获取远程地址时失败?
现在确定dll文件没有问题。发现在 hthread = CreateRemoteThread(process, NULL, 0, funstart, paddr, 0, 0);失败。
请大佬指导。
代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include<TlHelp32.h>


//通过令牌提升权限
BOOL opendebug()
{
//令牌
HANDLE htoken;
//是否提升权限成功
BOOL fok = FALSE;
//打开进程令牌,提升调试权限,
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &htoken))
{
//权限
TOKEN_PRIVILEGES tp;
//设置默认权限
tp.PrivilegeCount = 1;
//遍历权限
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
{

}
//开启
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//判断令牌是否生效
if (!AdjustTokenPrivileges(htoken, FALSE, &tp, sizeof(tp), NULL, NULL))
{

}
else
{
fok = TRUE;
}
CloseHandle(htoken);//关闭令牌
}
return fok;

}

//发现进程
DWORD findprocessid(char *name)
{
//使用快照,开启准备
HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
Process32First(hsnap, &pe32);//查找
do
{
if (_strcmpi(pe32.szExeFile, name) == 0)
{
puts("find it");
return pe32.th32ProcessID;//找到
}


} while (Process32Next(hsnap, &pe32));
CloseHandle(hsnap);//关闭
return 0;
}

//dll注入
int dllinject(HANDLE process, const char *dllname, const char *funname)
{
void(*pfun)() = NULL;//函数指针
//创建远程线程
HANDLE hthread = NULL;
//获取字符串长度
int dllnamelength = strlen(dllname) + 1;
//在别人的进程分配内存
LPVOID paddr = VirtualAllocEx(process, NULL, dllnamelength, MEM_COMMIT, PAGE_READWRITE);
//判断内存是否分配成功
if (paddr == NULL)
{
printf("进程内存分配失败");
}
else
{
//写入进程
WriteProcessMemory(process, paddr, (void*)dllname, dllnamelength, 0);
printf("\n进程内存分配成功并且拷贝成功");

//开启内核
HMODULE hmode = GetModuleHandleA("Kernel32.dll");
//获取内核地址
LPTHREAD_START_ROUTINE funstart = (LPTHREAD_START_ROUTINE)GetProcAddress(hmode, "LoadLibraryA");

//开启远程线程
hthread = CreateRemoteThread(process, NULL, 0, funstart, paddr, 0, 0);

//只能调用开始的那个函数
if (hthread == NULL)
{
puts("\n开启线程失败");
}
//等待线程开启
WaitForSingleObject(hthread, INFINITE);
printf("\n远程线程结束");


}
return 0;
}

// 进程名 模块名 模块的函数名
int insertdll(char *exename, const char *dllname, const char *funname)
{
//开启权限
opendebug();
//寻找线程id
DWORD processid = findprocessid(exename);

if (processid != 0)
{
//打开
HANDLE process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, processid);
if (process != NULL)
{
//注入
dllinject(process, dllname, funname);

}
CloseHandle(process);
}
else
{
printf("进程查找失败");
}
return 0;
}

//主函数
void main()
{
char *dllname = "C:\\Users\\Administrator\\Documents\\visual studio 2015\\Projects\\注入工具实现\\dll.dll";
insertdll("notepad.exe", dllname, "go");

system("pause");
}
...全文
1493 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-03-23
  • 打赏
  • 举报
回复
看自带的帮助。
归途醉染 2018-03-22
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/
这是什么工具,感觉好牛逼, 不会用
worldy 2018-03-21
  • 打赏
  • 举报
回复
策略组没有权限
赵4老师 2018-03-19
  • 打赏
  • 举报
回复
zhouqunhai 2018-03-18
  • 打赏
  • 举报
回复
求大佬指导啊
young_ms 2018-03-18
  • 打赏
  • 举报
回复
引用 7 楼 zhouqunhai 的回复:
求大佬指导啊
呃,32位注入32位进程,64位注入64位进程。 系统自带的记事本是64位的,你如果想32位去注入64位进程,你这代码,是不行的。 至于为什么不行,你可以百度,也可以再提问。
赵4老师 2018-03-17
  • 打赏
  • 举报
回复
关闭UAC、防火墙、杀毒软件 重启电脑并以管理员用户登录 以管理员身份运行 在dll对应的manifest文件中标记需要管理员权限 ……
zhouqunhai 2018-03-17
  • 打赏
  • 举报
回复
关闭UAC、防火墙、杀毒软件 重启电脑并以管理员用户登录 以管理员身份运行 我都试过了,但是一样出错,不知道为什么
zhouqunhai 2018-03-16
  • 打赏
  • 举报
回复
paschen老师,您好,我调用GetLastError,获得6,为句柄无效,也就是说在 hthread = CreateRemoteThread(process, NULL, 0, funstart, paddr, 0, 0)处出错,但我仔细检查各项参数都没有问题,但不知道为什么句柄无效
paschen 2018-03-16
  • 打赏
  • 举报
回复
https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms682437(v=vs.85).aspx 调用GetLastError获得失败原因,再作分析
zhouqunhai 2018-03-16
  • 打赏
  • 举报
回复
赵四老师,管理员身份运行也是在 hthread = CreateRemoteThread(process, NULL, 0, funstart, paddr, 0, 0);失败。 您能在帮我看一下吗,哪里错了
赵4老师 2018-03-16
  • 打赏
  • 举报
回复
以管理员身份运行。
从零开始讲述Java多线程的核心知识,通过板书和一步一步画图的方式,引领大家逐步去理解和掌握这些知识;并深入分析源码实现,理解背后的实现原理,知其然还要知其所以然。从多线程核心基础讲起,理解线程的风险,多种创建线程的方式;再到深入理解线程的状态;然后是线程的基本操作。系统、深入、快速上手实现多线程。 课程目标:    快速上手掌握Java多线程的经典课程,    系统、全面、深入掌握Java多线程的核心知识主讲老师:CC老师     20年Java开发和使用经验,多年的首席架构师和CTO,畅销原创书籍《研磨设计模式》的作者。         参与和领导了上百个大型项目的设计和开发,在互联网应用系统架构、系统设计、    应用级框架和间件开发等方面具有很多经验和领悟。    更为难得的是,入行20年,仍然奋战在技术一线,深知一线架构师需要掌握哪些技术、    掌握到什么程度、一线架构设计会遇到哪些坑、如何才能做出最合适的架构设计,经验最难得!适应人群:    想要系统、深入学习Java多线程    已有Java开发基础,想要快速掌握Java多线程    补充Java多线程知识,为进入一线大厂做准备学习方式:随到随学课程内容:第一节课:系统理解Java并发编程的知识体系    1:为什么要掌握Java并发编程    2:整个课程的目标    3:整个课程的学习内容第二节课:线程必备基础知识    1:理解线程是什么,理解进程,图示    2:理解轻量级的含义    3:理解时序调度,线程是时序调度的基本单元,图示    4:理解调度方式:抢占式,图示    5:理解我们写的程序基本都是多线程的应用,图示    6:理解并发和并行,图示    7:为什么需要线程第三节课:线程的风险    1:线程安全性问题,图示    2:线程的活跃度问题:死锁、饥饿、活锁,图示    3:线程的性能问题,这里主要是线程间切换 上下文的开销第四节课:创建线程的方式之一    1: 代码演示:实现Runnable接口的方式来创建线程    2:学习Thread类的方法和属性的应用    3:学习Thread类的源码第五节课:创建线程的方式之二    1:继承Thread的方式来创建线程    2:继续学习Thread类的源码,分析线程初始化过程    3: 代码演示:演示ThreadGroup    4: 代码演示:演示daemon线程,理解daemon线程和主线程的关系第六节课:创建线程的方式之三    1: 代码演示:匿名内部类的方式来创建线程    2:继续学习Thread类的源码,分析run方法的调用过程    3:代码演示:callable的方式来创建线程,带返回值    4: 学习FutureTask的部分源码,分析run方法到call方法的调用过程第七节课:线程状态详解    1:通过Thread源码来查看线程状态的定义    2:一步一步画图,讲述状态之间的变迁第八节课:线程的基本操作sleep 和yield    1:阅读Thread源码    2:代码演示:sleep的使用    3:代码演示:yield的使用    4:sleep和yield的对比理解第九节课:线程的基本操作join和interrupt    1:阅读Thread源码    2:代码演示:join的使用    3:代码演示:interrupt的使用这里是《Java并发编程与源码分析》的第一部分——讲述多线程核心基础实现快速上手多线程的经典之作   

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧