文章详情
C++入口点注入dll(x64创建挂起进程注入后注入dll)
Posted on 2019-01-02 18:05:16 by 主打一个C++
C++入口点注入dll(创建挂起进程注入后注入dll),也成为主线程注入。
- 以CREATE_SUSPENDED标志启动进程为挂起状态,
- 写入用于装载dll的shellcode
- 写入dll路径
- 获取程序入口点写入跳转代码
- 确保是x64进程和dll,因为shellcode是x64编码,可自行改x86
C++完整代码:
//入口点注入
int EntryInjectDll(const char* _exeFullPath, const char* _dllFullPath) {
STARTUPINFOA si = { sizeof(STARTUPINFOA) };// si.cb = sizeof(STARTUPINFOA);
PROCESS_INFORMATION pi = { 0 };
BOOL ret = CreateProcessA(_exeFullPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
if (ret == FALSE)
return 1;
int error = 0;
LPVOID addr = NULL;
do
{
addr = VirtualAllocEx(pi.hProcess, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (addr == NULL) {
error = 3;
break;
}
//加载代码
char code[] = {
0x51,0x52,0x41,0x50,0x41,0x51, //push rcx,rdx,r8,r9
0xFC, //cld
0x48,0xBE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //mov rsi,0000000000000000 - 数据地址
0x48,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //mov rdi,0000000000000000 - 要还原的地址
0x48,0xB9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //mov rcx,0000000000000000 - 还原字节的长度
0xF3,0xA4, //repe movsb
0x48,0xB9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //mov rcx,0000000000000000 - dll路径地址
0x51, //push rcx
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //mov rax,0000000000000000 - LoadLibraryA地址
0xFF,0xD0, //call rax
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //mov rax,0000000000000000 - 返回地址
0x41,0x59, //pop r9
0x41,0x58, //pop r8
0x5A, //pop rdx
0x59, //pop rcx
0x50, //push rax
0x50, //push rax
0xC3 //ret
};
//获取入口点
typedef INT(__stdcall* _ZwQueryInformationThread)(
_In_ HANDLE ThreadHandle,
_In_ INT ThreadInformationClass,
_In_ PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength,
_Out_opt_ PULONG ReturnLength);
_ZwQueryInformationThread ZwQueryInformationThread = (_ZwQueryInformationThread)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQueryInformationThread");
if (ZwQueryInformationThread == NULL) {
error = 1;
break;
}
ULONGLONG entry_addr = 0; ULONG len = 0;
ZwQueryInformationThread(pi.hThread, 9, &entry_addr, 8, &len);
if (entry_addr == 0) {
error = 2;
break;
}
//填充 数据地址
BYTE data1[16] = {};
SIZE_T rSize = 0;
ReadProcessMemory(pi.hProcess, (LPVOID)entry_addr, data1, sizeof(data1), &rSize);
//写入还原数据
ULONGLONG address = (ULONGLONG)addr + 500;
WriteProcessMemory(pi.hProcess, (LPVOID)address, data1, sizeof(data1), &rSize);
memcpy(&9[code], &address, sizeof(ULONGLONG));
//填充入口还原地址
memcpy(&19[code], &entry_addr, sizeof(ULONGLONG));
rSize = 16;//还原字节的长度
memcpy(&29[code], &rSize, sizeof(ULONGLONG));
//写入dll路径
address = (ULONGLONG)addr + 600;
WriteProcessMemory(pi.hProcess, (LPVOID)address, _dllFullPath, strlen(_dllFullPath) + 1, &rSize);
//填充dll路径地址
memcpy(&41[code], &address, sizeof(ULONGLONG));
//填充LoadLibraryA地址
address = (ULONGLONG)&LoadLibraryA;
memcpy(&52[code], &address, sizeof(ULONGLONG));
//填充返回地址
memcpy(&64[code], &entry_addr, sizeof(ULONGLONG));
WriteProcessMemory(pi.hProcess, addr, code, sizeof(code), &rSize);
//写入跳转代码
BYTE jmp[] = {
0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //mov rax,0000000000000000 - 跳转地址
0x50, //push rax
0xC3 //ret
};
address = (ULONGLONG)addr;
memcpy(&2[jmp], &address, sizeof(ULONGLONG));
//可能需要修改内存属性
DWORD pro = 0;
VirtualProtectEx(pi.hProcess, (LPVOID)entry_addr, 0x10, PAGE_EXECUTE_READWRITE, &pro);
WriteProcessMemory(pi.hProcess, (LPVOID)entry_addr, jmp, sizeof(jmp), &rSize);
ResumeThread(pi.hThread);
} while (false);
if (error != 0) {
TerminateProcess(pi.hProcess, 0);
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return error;
}
//测试注入
int main() {
int err = EntryInjectDll("Notepad.exe", "Dll1.dll");
printf("注入结果: %d\n", err);
system("pause");
return 0;
}
*转载请注明出处:原文链接:https://cpp.vin/page/72.html