逆向工程核心原理--代码注入

代码注入

代码注入是一种向目标进程插入独立运行代码的技术。一般调用CreateRemoteThread()API以远程线程形式运行插入的代码,也被称之为线程注入。

代码注入与DLL注入

使用代码注入的原因

  • 占用内存少
  • 难以查找痕迹
  • 其他:不需要额外的DLL文件,只要又代码注入程序。

InjectCode

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
#include<stdio.h>
#include<Windows.h>

typedef struct _THREAD_PARAM
{
//typedef int (FAR WINAPI *FARPROC)();
FARPROC pFunc[2]; //LoadLibraryA(),GetProcAddress()
char szBuf[4][128]; //user32.dll , MessageBoxA
//www.reversecode.com , ReverseCore
}THREAD_PARAM,*PTHREAD_PARAM;

/*
* 函数指针名为PFLOADLIBRARYA,参数为lpLibFileName
*/
typedef HMODULE(WINAPI* PFLOADLIBRARYA)
(
LPCSTR lpLibFileName
);

typedef FARPROC(WINAPI* PFGETPROCADDRESS)
(
HMODULE hModule,
LPCSTR lpProcName
);

typedef int (WINAPI* PFMESSAGEBOX)
(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCation,
UINT uType
);

DWORD WINAPI ThreadProc(LPVOID lParam)
{
PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;
HMODULE hMod = NULL;
FARPROC pFunc = NULL;

/*
* Loadlibrary("user32.dll")
* pParam->pFunc[0]->kernel32!LoadLibraryA()
* pParam->szBuf[0]->user32.dll
*/
hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);

/*
* GetProcAddress("MessageBoxA")
* pParam->pFunc[1] -> kernel32!GetProcAddress()
* pParam->szBuf[1] -> MessageBoxA
*/
pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]);

/*
* MessageBoxA(NULL,www.reversecode.com,ReverseCore,MB_OK)
* pParam->szBuf[2]->www.reversecode.com
* pParam->szBuf[3]->ReverseCore
*/
((PFMESSAGEBOX)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
return 0;
}

BOOL InjectCode(DWORD dwPID)
{
HMODULE hMod = NULL;
THREAD_PARAM param = { 0, };
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
LPVOID pRemoteBuf[2] = { 0, };
DWORD dwSize = 0;

hMod = GetModuleHandleA("kernel32.dll");
param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");

strcpy_s(param.szBuf[0], "user32.dll");
strcpy_s(param.szBuf[1], "MessageBoxA");
strcpy_s(param.szBuf[2], "www.reversecore.com");
strcpy_s(param.szBuf[3], "ReverseCore");

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
dwSize = sizeof(THREAD_PARAM);
pRemoteBuf[0] = VirtualAllocEx(
hProcess,
NULL,
dwSize,
MEM_COMMIT,
PAGE_READWRITE
);

WriteProcessMemory(
hProcess,
pRemoteBuf[0],
(LPVOID)&param,
dwSize,
NULL
);

dwSize = (DWORD)InjectCode - (DWORD)ThreadProc;
pRemoteBuf[1] = VirtualAllocEx(
hProcess,
NULL,
dwSize,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE
);
WriteProcessMemory(
hProcess,
pRemoteBuf[1],
(LPVOID)ThreadProc,
dwSize,
NULL
);

hThread = CreateRemoteThread(
hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)pRemoteBuf[1],
pRemoteBuf[0],
0,
NULL
);
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);

return TRUE;
}

int main(int argc, char* argv[])
{
DWORD dwPID = 0;

if (argc != 2)
{
printf("\n USAGE : %ss pid \n", argv[0]);
return 1;
}

dwPID = (DWORD)atol(argv[1]);
InjectCode(dwPID);
}

使用汇编语言编写注入代码

OllyDbg的汇编命令

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
068C0000   55               PUSH EBP
068C0001 8BEC MOV EBP,ESP
068C0003 8B75 08 MOV ESI,DWORD PTR SS:[EBP+0x8];取出第一个参数
068C0006 68 6C6C0000 PUSH 0x6C6C
068C000B 68 33322E64 PUSH 0x642E3233
068C0010 68 75736572 PUSH 0x72657375
068C0015 54 PUSH ESP ;压入user32.dll字符串
068C0016 FF16 CALL DWORD PTR DS:[ESI];调用LoadLibraryA("user32.dll")
068C0018 68 6F784100 PUSH 0x41786F
068C001D 68 61676542 PUSH 0x42656761
068C0022 68 4D657373 PUSH 0x7373654D
068C0027 54 PUSH ESP;压入MessageBoxA字符串
068C0028 50 PUSH EAX;压入user32.dll模块的地址
068C0029 FF56 04 CALL DWORD PTR DS:[ESI+0x4];调用GetProcess(hMod,"MessageBoxA")
068C002C 6A 00 PUSH 0x0
068C002E E8 0C000000 CALL 068C003F ;call指令是先push然后执行jmp,即可将字符串压入栈中
068C0033 52 PUSH EDX
068C0034 65:76 65 JBE SHORT 068C009C
068C0037 72 73 JB SHORT 068C00AC
068C0039 65:43 INC EBX
068C003B 6F OUTS DX,DWORD PTR DS:[ESI]
068C003C 72 65 JB SHORT 068C00A3
068C003E 00E8 ADD AL,CH ;调用call068C0058,也是将字符串压入栈中
068C0040 14 00 ADC AL,0x0
068C0042 0000 ADD BYTE PTR DS:[EAX],AL
068C0044 77 77 JA SHORT 068C00BD
068C0046 77 2E JA SHORT 068C0076
068C0048 72 65 JB SHORT 068C00AF
068C004A 76 65 JBE SHORT 068C00B1
068C004C 72 73 JB SHORT 068C00C1
068C004E 65:636F 72 ARPL WORD PTR GS:[EDI+0x72],BP
068C0052 65 GS:
068C0053 2E:636F 6D ARPL WORD PTR CS:[EDI+0x6D],BP
068C0057 006A 00 ADD BYTE PTR DS:[EDX],CH
068C005A FFD0 CALL EAX
068C005C 33C0 XOR EAX,EAX
068C005E 8BE5 MOV ESP,EBP
068C0060 5D POP EBP
068C0061 C3 RETN

OD保存文件

image-20220203211222663

image-20220203211310547

image-20220203211327879

image-20220203211454786

image-20220203211530544


逆向工程核心原理--代码注入
https://h0pe-ay.github.io/逆向工程核心原理--代码注入/
作者
hope
发布于
2024年3月17日
许可协议