[toc]

使用c语言将C语言函数注入到x86程序中

1.用c语言写一个弹出消息框MessageBoxA的程序

  1. 在项目中属性->高级->随机基地址中选择关闭
  2. 代码如下
1
2
3
4
5
6
7
8
9
//message.c
#include <windows.h>
#include <stdio.h>
int main(int argc,char**argv)
{
MessageBoxA(NULL,"HellWorld","Text",MB_OK);
getchar();
return 0;
}

3.编译后运行查看结果

2. 用c语言写一个注入内联x86汇编指令的程序

1.完善Hello,World程序,打印出函数地址与进程pid

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
//message.c
#include <windows.h>
#include <stdio.h>

void Message()
{
MessageBoxA(NULL, "HellWorld", "Text", MB_OK);
}
void AsmMessage(void* addr)
{
__asm {
mov edx, addr //addr is Message() address
call edx
}
}
int main(int argc, char** argv)
{
printf("MessageBoxA address is 0x%p\n", &MessageBoxA);
printf("Message() address is 0x%p\n", &Message);
printf("AsmMessage() address is 0x%p\n", &AsmMessage);
printf("Current pid is %d\n",GetCurrentProcessId());
AsmMessage(&Message);
MSG msg;
while (GetMessageW(&msg, NULL, NULL, NULL))
{
}
return 0;
}

编译后运行查看结果

2. c语言编写完整代码并运行

  • 注意:注入C语言代码与注入机器指令不同,经测试,注入C语言代码需要在vs2022中将项目设置为Release,Debug模式下会失败,原因还未知
  1. 运行Message程序查看Pid与函数地址

  2. 将以下三句汇编代码写在C语言函数中

1
2
3
mov edx, 0x00401040
call edx
ret
  1. 编写完整代码
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
//main.c
#include <windows.h>
#include <stdio.h>

//Message() address is 0x00401040
//char AddSunc[] = { 0xBA,0x40,0x10,0x40,0x00,0xFF,0xD2,0xC3 };
void AddSun()
{
_asm {
mov edx, 0x00401040
call edx
}
}
void InjectCode(DWORD dwProcId, LPVOID mFunc)
{
HANDLE hProcess, hThread;
LPVOID mFuncAddr, ParamAddr=NULL;
DWORD NumberOfByte;

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
mFuncAddr = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, mFuncAddr, mFunc, 1024, &NumberOfByte);
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)mFuncAddr, ParamAddr, 0, &NumberOfByte);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, mFuncAddr, 1024, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
}

int main()
{
InjectCode(57852, AddSun);
return 0;
}
  1. 编译运行后成功注入

不同写法的函数注入记录

1. 将内联汇编写到裸函数中再进行注入

步骤同上,main.c代码如下

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

//Message() address is 0x00401040
void __declspec(naked) AddSun()
{
_asm {
mov edx, 0x00401040
call edx
ret
}
}
void InjectCode(DWORD dwProcId, LPVOID mFunc)
{
HANDLE hProcess, hThread;
LPVOID mFuncAddr, ParamAddr=NULL;
DWORD NumberOfByte;

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
mFuncAddr = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, mFuncAddr, mFunc, 1024, &NumberOfByte);
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)mFuncAddr, ParamAddr, 0, &NumberOfByte);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, mFuncAddr, 1024, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
}

int main()
{
InjectCode(57852, AddSun);
return 0;
}

2. 将汇编指令与C语言代码写在不同文件中在进行注入

步骤同上,代码如下

main.c

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
//main.c
#include <windows.h>
#include <stdio.h>

int AddSun_();
void InjectCode(DWORD dwProcId, LPVOID mFunc)
{
HANDLE hProcess, hThread;
LPVOID mFuncAddr, ParamAddr = NULL;
DWORD NumberOfByte;

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
mFuncAddr = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, mFuncAddr, mFunc, 1024, &NumberOfByte);
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)mFuncAddr, ParamAddr, 0, &NumberOfByte);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, mFuncAddr, 1024, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
}

int main()
{
InjectCode(57852, AddSun_);
return 0;
}

AsmAddSun.asm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;AsmAddSun.asm
.586
.model flat,stdcall,c
option casemap:none

.data
.code
AddSun_ proc
mov eax,00401040h
call eax
ret
AddSun_ endp
end