仅通过 CreateRemoteThread 注入函数和 运行 它? C++
Injecting only function and running it through CreateRemoteThread? c++
我正在尝试注入这个函数:
void doubleValue(int pointer){
*((int*)pointer) *= 2;
}
通过VirtualAllocEx
& WriteProcessMemory
:
进入进程
int size = 1024 * 1024 * 4;
HANDLE h = GetCurrentProcess();
void * func = &doubleValue;
int arg = (int)&HP;
DWORD adr = (DWORD)VirtualAllocEx(h, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(h, (LPVOID)adr, func, size, 0);
unsigned long i = 0;
VirtualProtectEx(h, (LPVOID)(adr - size), size * 2, PAGE_EXECUTE_READWRITE, &i);
HANDLE thread = CreateRemoteThread(h, NULL, 0, (LPTHREAD_START_ROUTINE)(adr), &arg, 0, NULL);
注意:
出于测试目的,我将该函数注入同一进程 (GetCurrentProcess()
)。
注入时复制的行是jmp xxxxxxx
而不是真正的函数;
00660000 - push ebp
00660001 - mov ebp,esp
00660003 - sub esp,000000C0
00660009 - push ebx
0066000A - push esi
0066000B - push edi
0066000C - lea edi,[ebp-000000C0]
00660012 - mov ecx,00000030
00660017 - mov eax,CCCCCCCC
0066001C - repe stosd
0066001E - mov eax,[ebp+08]
00660021 - mov ecx,[eax]
00660023 - shl ecx,1
00660025 - mov edx,[ebp+08]
00660028 - mov [edx],ecx
0066002A - pop edi
0066002B - pop esi
0066002C - pop ebx
0066002D - mov esp,ebp
0066002F - pop ebp
所以我得到了函数的转储
\x55\x8B\xEC\x81\xEC\xC0\x00\x00\x00\x53\x56\x57\x8D\xBD\x40\xFF\xFF\xFF\xB9\x30\x00\x00\x00\xB8\xCC\xCC\xCC\xCC\xF3\xAB\x8B\x45\x08\x8B\x08\xD1\xE1\x8B\x55\x08\x89\x0A\x5F\x5E\x5B\x8B\xE5\x5D
并尝试写入它而不是 &func 的数据。但仍然没有任何反应。
另外,由于我将跳转地址注入到我自己的进程中,所以它非常好,而且应该也能正常工作。 [仅供测试,我没有尝试将代码注入我自己的进程]
图片来自cheatengine+visualstudio
adr=00443F5B
http://puu.sh/ghRtv/6b87c44154.png
跳转地址:
http://puu.sh/ghRum/a612d67e11.png
无论我如何更改代码,我都会得到 Access violation executing location 0xXXXXXXXX
或字面上的 什么都没有发生.
编辑:我知道我可以只写 procmem -> HP,但这不是重点。
嗯,我看不出你的代码到底有什么问题。
您获得 JMP 而不是函数代码的事实可能是由于增量链接。
您不需要调用 VirtualProtect,因为您已经拥有正确的页面保护标志。
获取函数的一种可能方法是将其设置到可执行文件的另一部分并在运行时获取它。
这是一个简单的例子,错误检查很少:
// Test.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <Windows.h>
#define SECTION_NAME ".my_func"
// put the function in its dedicated section
#pragma code_seg (push)
#pragma code_seg(SECTION_NAME)
static int foo = 0;
void doubleValue(int* pointer){
*pointer *= 2;
}
#pragma code_seg (pop)
typedef struct _tag_SECTION_INFORMATION {
// virtual address of the section
void* section_address;
// raw size of the section
DWORD section_size;
} SECTION_INFORMATION;
// given the name of a section, gets information from it.
BOOL GetSectionInformation(char* sec_name, SECTION_INFORMATION* sec_info){
char current_sec_name[IMAGE_SIZEOF_SHORT_NAME];
BOOL bresult = FALSE;
HMODULE hMyself = GetModuleHandle(NULL);
IMAGE_DOS_HEADER* pidh = (IMAGE_DOS_HEADER*)hMyself;
IMAGE_NT_HEADERS* pinh = (IMAGE_NT_HEADERS*)((ULONG_PTR)(hMyself)+pidh->e_lfanew);
WORD numsec = pinh->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER* pish = IMAGE_FIRST_SECTION(pinh);
for (WORD i = 0; i < numsec; ++i){
memcpy_s(current_sec_name, IMAGE_SIZEOF_SHORT_NAME, &pish->Name, IMAGE_SIZEOF_SHORT_NAME);
if (memcmp(SECTION_NAME, current_sec_name, IMAGE_SIZEOF_SHORT_NAME) == 0)
{
sec_info->section_address = (void*)((ULONG_PTR)hMyself + pish->VirtualAddress);
sec_info->section_size = pish->SizeOfRawData;
bresult = TRUE;
break;
}
pish++;
}
return bresult;
}
int main(int argc, char *argv[])
{
SECTION_INFORMATION sec_info;
// force compiler to not optimize away the function.
printf("%08lX\n", &doubleValue);
// get VA and size of section where 'doubleValue' resides.
if (!GetSectionInformation(SECTION_NAME, &sec_info)) {
printf("[-] error GetSectionInformation()\n");
return -1;
}
// open this process
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE,
GetCurrentProcessId());
if (!hProcess){
printf("[-] Error: couldn't open process...\n");
return -1;
}
// allocate page, size is the size of the section where 'doubleValue' is.
void* page = VirtualAllocEx(hProcess, NULL, sec_info.section_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!page){
printf("[-] Error: couldn't allocate remote page.\n");
return -1;
}
DWORD nobw = 0;
if(!WriteProcessMemory(hProcess, page, sec_info.section_address, sec_info.section_size, &nobw) && nobw < sec_info.section_size){
printf("[-] Error: couldn't write to page.\n");
return -1;
}
int i = 42;
printf("parameter: %i\n", i);
// Note: you should obviously *not* pass an address from this address space to another process address space.
// It is fine here to pass the address of 'i' as we are still in the same address space.
if (!CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)page, &i, 0, NULL)){
printf("[-] CreateRemoteThread() failed.\n");
return -1;
}
Sleep(1000);
// should print '84'.
printf("result: %i\n", i);
return 0;
}
edit :相同的代码,但在远程进程中,在 calc.exe 中注入函数,调用 doubleValue() 函数并从 [=26 中读取结果=]:
#include <stdio.h>
#include <Windows.h>
#define SECTION_NAME ".my_func"
// put the function in its dedicated section
#pragma code_seg (push)
#pragma code_seg(SECTION_NAME)
static int foo = 0;
void doubleValue(int* pointer){
*pointer *= 2;
}
#pragma code_seg (pop)
typedef struct _tag_SECTION_INFORMATION {
// virtual address of the section
void* section_address;
// raw size of the section
DWORD section_size;
} SECTION_INFORMATION;
// given the name of a section, gets information from it.
BOOL GetSectionInformation(char* sec_name, SECTION_INFORMATION* sec_info){
char current_sec_name[IMAGE_SIZEOF_SHORT_NAME];
BOOL bresult = FALSE;
HMODULE hMyself = GetModuleHandle(NULL);
IMAGE_DOS_HEADER* pidh = (IMAGE_DOS_HEADER*)hMyself;
IMAGE_NT_HEADERS* pinh = (IMAGE_NT_HEADERS*)((ULONG_PTR)(hMyself)+pidh->e_lfanew);
WORD numsec = pinh->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER* pish = IMAGE_FIRST_SECTION(pinh);
for (WORD i = 0; i < numsec; ++i){
memcpy_s(current_sec_name, IMAGE_SIZEOF_SHORT_NAME, &pish->Name, IMAGE_SIZEOF_SHORT_NAME);
if (memcmp(SECTION_NAME, current_sec_name, IMAGE_SIZEOF_SHORT_NAME) == 0)
{
sec_info->section_address = (void*)((ULONG_PTR)hMyself + pish->VirtualAddress);
sec_info->section_size = pish->SizeOfRawData;
bresult = TRUE;
break;
}
pish++;
}
return bresult;
}
int main(int argc, char *argv[])
{
SECTION_INFORMATION sec_info;
// force compiler to not optimize away the function.
printf("%08lX\n", &doubleValue);
// get VA and size of section where 'doubleValue' resides.
if (!GetSectionInformation(SECTION_NAME, &sec_info)) {
printf("[-] error GetSectionInformation()\n");
return -1;
}
PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
if (!CreateProcessW(L"c:\windows\system32\calc.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)){
printf("[-] Error: couldn't create process.\n");
return -1;
}
// open this process
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE,
pi.dwProcessId);
if (!hProcess){
printf("[-] Error: couldn't open process...\n");
return -1;
}
// allocate page for function code, size is the size of the section where 'doubleValue' is.
void* page_function = VirtualAllocEx(hProcess, NULL, sec_info.section_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!page_function){
printf("[-] Error: couldn't allocate remote page for function code.\n");
return -1;
}
// write function code to remote process.
DWORD nobw = 0;
if (!WriteProcessMemory(hProcess, page_function, sec_info.section_address, sec_info.section_size, &nobw) && nobw < sec_info.section_size){
printf("[-] Error: couldn't write to code page.\n");
return -1;
}
// page for result
void* page_result = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!page_result){
printf("[-] Error: couldn't allocate remote page for result.\n");
return -1;
}
int i = 42;
printf("parameter: %i\n", i);
// write parameter to remote process.
nobw = 0;
if (!WriteProcessMemory(hProcess, page_result, &i, sizeof(i), &nobw) && nobw < sizeof(i)){
printf("[-] Error: couldn't write to result page.\n");
return -1;
}
// call remote doubleValue() function, passing the address where the argument lies (42)
if (!CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)page_function, page_result, 0, NULL)){
printf("[-] CreateRemoteThread() failed.\n");
return -1;
}
Sleep(1000);
// now read result in remote process, should be: 84.
DWORD nobr;
if (!ReadProcessMemory(hProcess, page_result, &i, sizeof(i), &nobr)){
printf("[-] ReadProcessMemory failed.\n");
return -1;
}
// should print '84'.
printf("result: %i\n", i);
return 0;
}
我正在尝试注入这个函数:
void doubleValue(int pointer){
*((int*)pointer) *= 2;
}
通过VirtualAllocEx
& WriteProcessMemory
:
int size = 1024 * 1024 * 4;
HANDLE h = GetCurrentProcess();
void * func = &doubleValue;
int arg = (int)&HP;
DWORD adr = (DWORD)VirtualAllocEx(h, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(h, (LPVOID)adr, func, size, 0);
unsigned long i = 0;
VirtualProtectEx(h, (LPVOID)(adr - size), size * 2, PAGE_EXECUTE_READWRITE, &i);
HANDLE thread = CreateRemoteThread(h, NULL, 0, (LPTHREAD_START_ROUTINE)(adr), &arg, 0, NULL);
注意:
出于测试目的,我将该函数注入同一进程 (GetCurrentProcess()
)。
注入时复制的行是jmp xxxxxxx
而不是真正的函数;
00660000 - push ebp
00660001 - mov ebp,esp
00660003 - sub esp,000000C0
00660009 - push ebx
0066000A - push esi
0066000B - push edi
0066000C - lea edi,[ebp-000000C0]
00660012 - mov ecx,00000030
00660017 - mov eax,CCCCCCCC
0066001C - repe stosd
0066001E - mov eax,[ebp+08]
00660021 - mov ecx,[eax]
00660023 - shl ecx,1
00660025 - mov edx,[ebp+08]
00660028 - mov [edx],ecx
0066002A - pop edi
0066002B - pop esi
0066002C - pop ebx
0066002D - mov esp,ebp
0066002F - pop ebp
所以我得到了函数的转储
\x55\x8B\xEC\x81\xEC\xC0\x00\x00\x00\x53\x56\x57\x8D\xBD\x40\xFF\xFF\xFF\xB9\x30\x00\x00\x00\xB8\xCC\xCC\xCC\xCC\xF3\xAB\x8B\x45\x08\x8B\x08\xD1\xE1\x8B\x55\x08\x89\x0A\x5F\x5E\x5B\x8B\xE5\x5D
并尝试写入它而不是 &func 的数据。但仍然没有任何反应。 另外,由于我将跳转地址注入到我自己的进程中,所以它非常好,而且应该也能正常工作。 [仅供测试,我没有尝试将代码注入我自己的进程]
图片来自cheatengine+visualstudio
adr=00443F5B
http://puu.sh/ghRtv/6b87c44154.png
跳转地址:
http://puu.sh/ghRum/a612d67e11.png
无论我如何更改代码,我都会得到 Access violation executing location 0xXXXXXXXX
或字面上的 什么都没有发生.
编辑:我知道我可以只写 procmem -> HP,但这不是重点。
嗯,我看不出你的代码到底有什么问题。
您获得 JMP 而不是函数代码的事实可能是由于增量链接。
您不需要调用 VirtualProtect,因为您已经拥有正确的页面保护标志。
获取函数的一种可能方法是将其设置到可执行文件的另一部分并在运行时获取它。
这是一个简单的例子,错误检查很少:
// Test.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <Windows.h>
#define SECTION_NAME ".my_func"
// put the function in its dedicated section
#pragma code_seg (push)
#pragma code_seg(SECTION_NAME)
static int foo = 0;
void doubleValue(int* pointer){
*pointer *= 2;
}
#pragma code_seg (pop)
typedef struct _tag_SECTION_INFORMATION {
// virtual address of the section
void* section_address;
// raw size of the section
DWORD section_size;
} SECTION_INFORMATION;
// given the name of a section, gets information from it.
BOOL GetSectionInformation(char* sec_name, SECTION_INFORMATION* sec_info){
char current_sec_name[IMAGE_SIZEOF_SHORT_NAME];
BOOL bresult = FALSE;
HMODULE hMyself = GetModuleHandle(NULL);
IMAGE_DOS_HEADER* pidh = (IMAGE_DOS_HEADER*)hMyself;
IMAGE_NT_HEADERS* pinh = (IMAGE_NT_HEADERS*)((ULONG_PTR)(hMyself)+pidh->e_lfanew);
WORD numsec = pinh->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER* pish = IMAGE_FIRST_SECTION(pinh);
for (WORD i = 0; i < numsec; ++i){
memcpy_s(current_sec_name, IMAGE_SIZEOF_SHORT_NAME, &pish->Name, IMAGE_SIZEOF_SHORT_NAME);
if (memcmp(SECTION_NAME, current_sec_name, IMAGE_SIZEOF_SHORT_NAME) == 0)
{
sec_info->section_address = (void*)((ULONG_PTR)hMyself + pish->VirtualAddress);
sec_info->section_size = pish->SizeOfRawData;
bresult = TRUE;
break;
}
pish++;
}
return bresult;
}
int main(int argc, char *argv[])
{
SECTION_INFORMATION sec_info;
// force compiler to not optimize away the function.
printf("%08lX\n", &doubleValue);
// get VA and size of section where 'doubleValue' resides.
if (!GetSectionInformation(SECTION_NAME, &sec_info)) {
printf("[-] error GetSectionInformation()\n");
return -1;
}
// open this process
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE,
GetCurrentProcessId());
if (!hProcess){
printf("[-] Error: couldn't open process...\n");
return -1;
}
// allocate page, size is the size of the section where 'doubleValue' is.
void* page = VirtualAllocEx(hProcess, NULL, sec_info.section_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!page){
printf("[-] Error: couldn't allocate remote page.\n");
return -1;
}
DWORD nobw = 0;
if(!WriteProcessMemory(hProcess, page, sec_info.section_address, sec_info.section_size, &nobw) && nobw < sec_info.section_size){
printf("[-] Error: couldn't write to page.\n");
return -1;
}
int i = 42;
printf("parameter: %i\n", i);
// Note: you should obviously *not* pass an address from this address space to another process address space.
// It is fine here to pass the address of 'i' as we are still in the same address space.
if (!CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)page, &i, 0, NULL)){
printf("[-] CreateRemoteThread() failed.\n");
return -1;
}
Sleep(1000);
// should print '84'.
printf("result: %i\n", i);
return 0;
}
edit :相同的代码,但在远程进程中,在 calc.exe 中注入函数,调用 doubleValue() 函数并从 [=26 中读取结果=]:
#include <stdio.h>
#include <Windows.h>
#define SECTION_NAME ".my_func"
// put the function in its dedicated section
#pragma code_seg (push)
#pragma code_seg(SECTION_NAME)
static int foo = 0;
void doubleValue(int* pointer){
*pointer *= 2;
}
#pragma code_seg (pop)
typedef struct _tag_SECTION_INFORMATION {
// virtual address of the section
void* section_address;
// raw size of the section
DWORD section_size;
} SECTION_INFORMATION;
// given the name of a section, gets information from it.
BOOL GetSectionInformation(char* sec_name, SECTION_INFORMATION* sec_info){
char current_sec_name[IMAGE_SIZEOF_SHORT_NAME];
BOOL bresult = FALSE;
HMODULE hMyself = GetModuleHandle(NULL);
IMAGE_DOS_HEADER* pidh = (IMAGE_DOS_HEADER*)hMyself;
IMAGE_NT_HEADERS* pinh = (IMAGE_NT_HEADERS*)((ULONG_PTR)(hMyself)+pidh->e_lfanew);
WORD numsec = pinh->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER* pish = IMAGE_FIRST_SECTION(pinh);
for (WORD i = 0; i < numsec; ++i){
memcpy_s(current_sec_name, IMAGE_SIZEOF_SHORT_NAME, &pish->Name, IMAGE_SIZEOF_SHORT_NAME);
if (memcmp(SECTION_NAME, current_sec_name, IMAGE_SIZEOF_SHORT_NAME) == 0)
{
sec_info->section_address = (void*)((ULONG_PTR)hMyself + pish->VirtualAddress);
sec_info->section_size = pish->SizeOfRawData;
bresult = TRUE;
break;
}
pish++;
}
return bresult;
}
int main(int argc, char *argv[])
{
SECTION_INFORMATION sec_info;
// force compiler to not optimize away the function.
printf("%08lX\n", &doubleValue);
// get VA and size of section where 'doubleValue' resides.
if (!GetSectionInformation(SECTION_NAME, &sec_info)) {
printf("[-] error GetSectionInformation()\n");
return -1;
}
PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
if (!CreateProcessW(L"c:\windows\system32\calc.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)){
printf("[-] Error: couldn't create process.\n");
return -1;
}
// open this process
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE,
pi.dwProcessId);
if (!hProcess){
printf("[-] Error: couldn't open process...\n");
return -1;
}
// allocate page for function code, size is the size of the section where 'doubleValue' is.
void* page_function = VirtualAllocEx(hProcess, NULL, sec_info.section_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!page_function){
printf("[-] Error: couldn't allocate remote page for function code.\n");
return -1;
}
// write function code to remote process.
DWORD nobw = 0;
if (!WriteProcessMemory(hProcess, page_function, sec_info.section_address, sec_info.section_size, &nobw) && nobw < sec_info.section_size){
printf("[-] Error: couldn't write to code page.\n");
return -1;
}
// page for result
void* page_result = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!page_result){
printf("[-] Error: couldn't allocate remote page for result.\n");
return -1;
}
int i = 42;
printf("parameter: %i\n", i);
// write parameter to remote process.
nobw = 0;
if (!WriteProcessMemory(hProcess, page_result, &i, sizeof(i), &nobw) && nobw < sizeof(i)){
printf("[-] Error: couldn't write to result page.\n");
return -1;
}
// call remote doubleValue() function, passing the address where the argument lies (42)
if (!CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)page_function, page_result, 0, NULL)){
printf("[-] CreateRemoteThread() failed.\n");
return -1;
}
Sleep(1000);
// now read result in remote process, should be: 84.
DWORD nobr;
if (!ReadProcessMemory(hProcess, page_result, &i, sizeof(i), &nobr)){
printf("[-] ReadProcessMemory failed.\n");
return -1;
}
// should print '84'.
printf("result: %i\n", i);
return 0;
}