-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathcode_injection.c
More file actions
134 lines (122 loc) · 4.49 KB
/
code_injection.c
File metadata and controls
134 lines (122 loc) · 4.49 KB
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
/*
code injection moudle
Copyright (C) 2020 iTruth
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
*/
#include <windows.h>
#include <string.h>
#include "cheatlib.h"
#include "code_injection.h"
void FreeCodeInjectionInfo(PCodeInjectionInfo ptInfo)
{
assert(ptInfo != NULL);
// 释放代码空间
if(ptInfo->pVirAddr != NULL){
VirtualFreeEx(ptInfo->hProcess, ptInfo->pVirAddr, 0, MEM_RELEASE);
}
FreeRequiredAsmInfo(ptInfo->ptRequiredAsmInfo);
free(ptInfo);
ptInfo = NULL;
}
PCodeInjectionInfo CodeInjection(HANDLE hProcess, LPVOID pAddress, LPCSTR pszAsmCode)
{
// 在pAddress处收集必要的信息
PCheatLibRequiredAsmInfo ptRequiredAsmInfo = GetRequiredAsmInfo(hProcess, pAddress);
PCodeInjectionInfo ptCodeInjectionInfo = (PCodeInjectionInfo)malloc(sizeof(CodeInjectionInfo));
ptCodeInjectionInfo->hProcess = hProcess;
ptCodeInjectionInfo->pOrigAddr = pAddress;
ptCodeInjectionInfo->ptRequiredAsmInfo = ptRequiredAsmInfo;
SIZE_T WrittenLen = 0;
// 如果pszAsmCode是空字符串或NULL就使用nop填充该指令
if(pszAsmCode == NULL || strlen(pszAsmCode) == 0){
ptCodeInjectionInfo->pVirAddr = NULL;
BYTE *nopCode = (BYTE*)malloc(sizeof(BYTE)*ptRequiredAsmInfo->iFirstCmdSize);
memset(nopCode, 0x90, ptRequiredAsmInfo->iFirstCmdSize);
// 写入空指令
WriteProcessMemory(hProcess,
(LPVOID)pAddress,
nopCode,
ptRequiredAsmInfo->iFirstCmdSize,
&WrittenLen);
free(nopCode);
nopCode = NULL;
return ptCodeInjectionInfo;
}
// 开始构造我们自己的代码
// 我们不知道pszAsmCode中的汇编指令在函数申请的空间中会生成多少机器码
// 但使用这种方式计算出来的大小一定不会小于实际所需大小
int nCodeSize = strlen(pszAsmCode)+JMP_SIZE;
// 在远程进程申请空间用于存放我们自己的代码
LPVOID virAddr = (PWSTR)VirtualAllocEx(hProcess,
NULL,
nCodeSize,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
ptCodeInjectionInfo->pVirAddr = virAddr;
// 汇编pszAsmCode,需要virAddr来正确计算指令中的偏移
PCheatLibAsmEncodeInfo ptAsmCodeInfo = EncodeAsm(pszAsmCode, virAddr);
// 大概率是pszAsmCode有问题导致的
if(ptAsmCodeInfo == NULL){
FreeCodeInjectionInfo(ptCodeInjectionInfo);
return NULL;
}
BYTE *exeCode = (BYTE*)malloc(sizeof(BYTE)*(nCodeSize));
// 先使用nop填充
memset(exeCode, 0x90, nCodeSize);
// 将生成的汇编代码拷贝到exeCode中
memcpy(exeCode, ptAsmCodeInfo->pbOpCode, ptAsmCodeInfo->nOpCodeSize);
// 构建跳转指令
#ifdef CHEATLIB_TARGET_X64
JmpBuilder_x64(exeCode+ptAsmCodeInfo->nOpCodeSize,
pAddress+ptRequiredAsmInfo->iRequiredSize);
#else
JmpBuilder(exeCode+ptAsmCodeInfo->nOpCodeSize,
(LPVOID)pAddress+ptRequiredAsmInfo->iRequiredSize,
(LPVOID)virAddr+ptAsmCodeInfo->nOpCodeSize);
#endif
// 把构建好的代码写入刚刚申请的空间中
WriteProcessMemory(hProcess, (LPVOID)virAddr, exeCode, nCodeSize, &WrittenLen);
free(exeCode);
exeCode = NULL;
FreeAsmEncodeInfo(ptAsmCodeInfo);
// 开始构造注入点跳转指令
BYTE *jmpCode = (BYTE*)malloc(sizeof(BYTE)*ptRequiredAsmInfo->iRequiredSize);
memset(jmpCode, 0x90, ptRequiredAsmInfo->iRequiredSize);
#ifdef CHEATLIB_TARGET_X64
JmpBuilder_x64(jmpCode, virAddr);
#else
JmpBuilder(jmpCode, (LPVOID)virAddr, (LPVOID)pAddress);
#endif
// 向注入点写入跳转指令
WriteProcessMemory(hProcess,
(LPVOID)pAddress,
jmpCode,
ptRequiredAsmInfo->iRequiredSize,
&WrittenLen);
free(jmpCode);
jmpCode = NULL;
return ptCodeInjectionInfo;
}
void CodeOutjection(PCodeInjectionInfo ptInfo)
{
assert(ptInfo != NULL && ptInfo->ptRequiredAsmInfo != NULL);
SIZE_T WrittenLen = 0;
// 恢复原始代码
WriteProcessMemory(ptInfo->hProcess,
ptInfo->pOrigAddr,
ptInfo->ptRequiredAsmInfo->pbOpCode,
ptInfo->ptRequiredAsmInfo->iRequiredSize,
&WrittenLen);
FreeCodeInjectionInfo(ptInfo);
}