ShellCode注入程序

程序功能是利用NtQueueApcThreadEx注入ShellCode到一个进程中,程序运行后会让你选择模式,按1为普通模式,所需的常规API接口都是使用Windows原本正常的API;在有游戏保护的进程中Windows原本正常的API无法使用,这时候需要选择内核模式,按2选择内核模式。

内核模式下使用的一些关键API都是我自己在ring0从0实现的,本帖仅开源普通模式下的代码。内核模式下使用的关键API以及调用框架不开源。

选择模式之后需要输入被注入进程的PID

项目包含三个源代码文件:1.源.cpp
2.fun.asm
3.fun.h

首先是源.cpp文件代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

插入代码

```/*

* 函数原型:

NTSTATUS NtQueueTHreadApcEx(

_in HANDLE thread,

_in UCHAR flags,0:常规用户APC,1:特殊用户APC

_in PAPCFUNC apcRoutine,

_in PVOID context1,

_in PVOID arg1,

_in PVOID arg2

);

需要从Ntdll.dll模块显式导出(GetProcAddress)

*/

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<Windows.h>

#include<Tlhelp32.h>

#include"fun.h"

HWND hwndG = 0;

BOOL CALLBACK EnumWindowsProc(

    HWND hwnd,

    LPARAM lParam)

{

    WCHAR path[MAX_PATH] = 0 };

    WCHAR* text = (WCHAR*)lParam;

    GetWindowText(hwnd, path, MAX_PATH);

    if (lstrcmpW(text, path) == 0)

    {

        hwndG = hwnd;

        return FALSE;

    }

    else

    {

        hwndG = 0;

        return TRUE;

    }

}

DWORD WINAPI GetThreadIdByProcessId(DWORD dwProcessId)

{

    THREADENTRY32 th32;

    th32.dwSize = sizeof(THREADENTRY32);

    DWORD dwThreadId = 0;

    HANDLE hdTool = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessId);

    if (Thread32First(hdTool, &th32))

    {

        do

        {

            if (th32.th32OwnerProcessID == dwProcessId)

            {

                dwThreadId = th32.th32ThreadID;

                //printf("%d\n", dwThreadId);

                break;

            }

        while (Thread32Next(hdTool, &th32));

    }

    else

    {

        DWORD dwErro = GetLastError();

        //printf("遍历进程失败!——%d", dwErro);

        return dwErro;

    }

     

    return dwThreadId;

}

BOOL WINAPI PrivilegeAdjust()

{

    BOOL flag;

    HANDLE token;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))

    {

        //printf("打开令牌失败!\n");

        flag = FALSE;

    }

    LUID pid;

    if (!LookupPrivilegeValueA(NULL, "SeDebugPrivilege", &pid))

    {

        //printf("查看特权ID失败\n");

        flag = FALSE;

    }

    TOKEN_PRIVILEGES tp;

    tp.PrivilegeCount = 1;

    tp.Privileges[0].Luid = pid;

    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))

    {

        //printf("提升特权失败!\n");

        flag = FALSE;

    }

    return TRUE;

}

typedef BOOL(*MYTYPE)(HANDLE, LPVOID, LPVOID, SIZE_T, SIZE_T*);

typedef HANDLE(*OPPS)(DWORD, BOOL, DWORD);

typedef BOOL(*WRMEMEX)(HANDLE, LPVOID, LPVOID, SIZE_T, SIZE_T*);

typedef HANDLE(*OPTS)();

typedef ULONG64(*GETPEB)(DWORD);

typedef NTSTATUS(*NTQUEAPC)(HANDLE, UCHAR, PVOID, PVOID, PVOID, PVOID);

WRMEMEX Read;

WRMEMEX Write;

OPPS OpenPro;

OPTS OpenThr;

NTQUEAPC NtQueueUserApcEx;

VOID InitFrmak()

{

    printf("内核\n");

    NtQueueUserApcEx = NULL;

    HMODULE mod = LoadLibraryA("ApiSystemCall.dll");

    Read = (WRMEMEX)GetProcAddress(mod, "YhReadProcessMemory");

    Write = (WRMEMEX)GetProcAddress(mod, "YhWriteProcessMemory");

    OpenPro = (OPPS)GetProcAddress(mod, "YhOpenProcess");

    OpenThr = (OPTS)GetProcAddress(mod, "YhOpenThread");

    NtQueueUserApcEx = (NTQUEAPC)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueueApcThreadEx");

    if (NtQueueUserApcEx == NULL)

    {

        MessageBoxA(NULL, "获取函数失败"00);

    }

}

VOID InitFrmakEx()

{

    NtQueueUserApcEx = NULL;

     

    printf("普通\n");

    Read = ReadProcessMemory;

    Write = WriteProcessMemory;

    OpenPro = OpenProcess;

    OpenThr = OpenThread;

    NtQueueUserApcEx = (NTQUEAPC)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueueApcThreadEx");

    if (NtQueueUserApcEx == NULL)

    {

        MessageBoxA(NULL, "获取函数失败"00);

    }

}

typedef VOID(*FUN)();

int main()

{

    DWORD pid;

    SIZE_T size=0;

    CONTEXT text;

    VirtualProtect(fun, 0x60, PAGE_EXECUTE_READWRITE, &pid);

    *(ULONG64*)(&(((UCHAR*)fun2)[0x34])) = MessageBoxA;

    *(ULONG64*)(&(((UCHAR*)fun2)[0x9f])) = SetWindowsHookExA;

    //fun(NULL,NULL,NULL);

    printf("请输入模式:\n1.普通模式\n2.内核模式\n");

    scanf("%d", &size);

    (size==1)? InitFrmakEx(): InitFrmak();

    printf("请输入进程PID:\n");

    scanf("%d", &pid);

    PrivilegeAdjust();

     

    HANDLE hd = OpenPro(PROCESS_ALL_ACCESS, FALSE, pid);

    PVOID mem = VirtualAllocEx(hd, NULL, 0X1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    DWORD tid = GetThreadIdByProcessId(pid);

    HANDLE td;

    if (size == 1)

    {

        td = OpenThr(THREAD_ALL_ACCESS,FALSE,tid);

    }

    else

    {

        td = OpenThr(tid, hd, THREAD_ALL_ACCESS, FALSE);

    }

    if (!Write(hd, mem, fun2, 0x100, &size))

    {

        MessageBoxA(0"写入失败"00);

    }

    SuspendThread(td);

    NTSTATUS code = NtQueueUserApcEx(td, 1, (PVOID)(((ULONG64)mem)+0x53), tid, 00);

    if(code!=0)

    {

         

        printf("%x\n", code);

        MessageBox(0000);

    }

    ResumeThread(td);

    system("pause");

    return 0;

}

fun.asm文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

.code

MessageBoxA proto

fun2 proc

    push rbp;

    mov rbp,rsp;

    sub rsp,060h;

    xor rax,rax;

    cmp rcx,rax;

    jnz sub_1;

    cmp rdx,09h;;虚拟键代码0x9为键盘的TAB键

    jnz sub_1;

    xor rcx,rcx;

    lea rdx,qword ptr[lab_2];

    xor r8,r8;

    xor r9,r9;

    mov rax,qword ptr[lab_1];

    call rax;

sub_1:

    mov rsp,rbp;

    pop rbp;

    ret;

fun2 endp

lab_1:

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

lab_2:

    db 0c2h;

    db 0edh;

    db 0bbh;

    db 0afh;

    db 0cch;

    db 0dah;

    db 0cah;

    db 0c7h;

    db 0c9h;

    db 0b5h;

    db 0b1h;

    db 0c6h;

    db 0a3h;

    db 0a1h;

    db 00ah;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

fun proc

     

    push rbp;

    mov rbp,rsp;

    sub rsp,080h;

    mov r9,rcx;

    mov rcx,02h;

    lea rdx,qword ptr [fun2];

    xor r8,r8;

    mov rax,qword ptr [sub_2];

    call rax;

    cmp rax,0;

    jnz lab_3;

    xor rcx,rcx;

    xor rdx,rdx;

    xor r8,r8;

    mov r9,02h;

    mov rax,qword ptr [lab_1];

    call rax;

lab_3:

    mov rsp,rbp;

    pop rbp;

    ret;

sub_2:

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

    db 00h;

fun endp

end

fun.h文件

1

2

3

#pragma once

#include<Windows.h>

void fun(PVOID a, PVOID b, PVOID c);

shellCode的功能是给被注入进程设置一个键盘钩子,TAB键。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/277228.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android自定义图片涂鸦View实现绘制和橡皮擦功能

在Android应用开发中,涂鸦功能是一个常见的需求,用户可以在画布上进行自由绘制和擦除操作。本文将介绍如何使用自定义View来实现一个具备绘制和橡皮擦功能的涂鸦View,并提供了相关示例代码。 1. 引言 在移动应用开发中,涂鸦功能为用户提供了一种直观的绘图体验,并广泛应用…

怎么制作GIF动图?教你这几个简单方法

怎么制作gif动图&#xff1f;GIF动图是一种非常有趣且实用的图片格式&#xff0c;它能够以短小精悍的方式展示动画效果&#xff0c;因此在社交媒体和聊天应用中备受追捧。本文将向您介绍几种制作GIF动图的方法&#xff0c;让您轻松制作出自己的动图。 GIF动图制作方法一&#x…

音视频技术开发周刊 | 323

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 Meta牵头组建开源「AI复仇者联盟」&#xff0c;AMD等盟友800亿美元力战OpenAI英伟达 超过50家科技大厂名校和机构&#xff0c;共同成立了全新的人工智能联盟。以开源为旗号…

建立海外SD-WAN专线网络的成本分析

高速、稳定的网络连接是企业成功拓宽海外市场和开展海外业务的关键因素之一。作为一种提供更高质量和性能的连接的网络解决方案&#xff0c;海外SD-WAN专线被越来越多的企业选择。以下将详细介绍建立海外SD-WAN专线网络的成本组成&#xff0c;以协助企业更全面地了解和规划对网…

C#基础——类、对象和属性

C# 属于 面向对象 的编程&#xff0c;“万物皆对象” 面向对象编程的三大特性&#xff1a;封装、继承、多态。 通过类能过较好的体现该语言的特点 类&#xff1a;是具有相同属性和行为特征的集合 类的语法格式&#xff1a; 访问修饰符 class关键字 类名 两种创建类的方式 第…

单片机Freertos入门(二)任务的创建、删除

1、串口配置 首先将串口进行配置&#xff0c;后续经常会应用&#xff0c;具体步骤点击&#xff1a;串口配置。 2、任务 创建一个任务&#xff0c;就是开辟一个空间、每个任务中都会有while&#xff08;1&#xff09;死循环。 2.1相关函数 动态创建&#xff1a;xTaskCreate…

Attention机制学习

写在前面 注意力机制是一个很不错的科研创新点方向&#xff0c;但是没有系统记录过学习过程&#xff0c;这里记录科研中遇到的各种注意力机制。 1. Attention机制解释 本质上来说用到attention的任务都有Query&#xff0c;Key&#xff0c;Value三个关键components&#xff0c;…

Tekton 基于 gitlab 触发流水线

Tekton 基于 gitlab 触发流水线 Tekton EventListener 在8080端口监听事件&#xff0c;Gitlab 提交代码产生push 事件&#xff0c;gitlab webhook触发tekton流水线执行。 前置要求&#xff1a; kubernetes集群中已部署 tekton pipeline、tekton triggers以及tekton dashboa…

c YUV 转 JPEG(准备霍夫曼编码)

先取yuv 文件中一个168的块&#xff0c;跑通全流程 理解与思路&#xff1a; 1.块分割 YUV 文件分为&#xff1a;YUV444 YUV 422 YUV420。444:就是&#xff1a;12个char 有4个Y&#xff0c;4个U&#xff0c;4个 U&#xff0c;422&#xff1a;8个char 中有4个Y &#x…

Python (九)requests

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

C++之模板

目录 泛型编程 模板 函数模板 函数模板的实例化 隐式实例化 显示实例化 类模板 我们知道STL&#xff08;标准模板库&#xff09;是C学习的精华所在&#xff0c;在学习STL之前我们得先学习一个新的知识点-------模板。那么模板究竟是什么呢&#xff1f;围绕着这个问题&a…

算法训练营Day14

#Java #二叉树层次遍历 #反转二叉树 开源学习资料 二叉树的层次遍历&#xff1a;力扣题目链接 二叉树的层次遍历很好理解&#xff1a; 就是从根结点一层一层地往下遍历&#xff08;同一层&#xff0c;从左到右&#xff09;&#xff1a; 迭代的方式很好理解&#xff1a;就是…